From 79430bf10b553f62f13e50a36c67cf9cef915ac0 Mon Sep 17 00:00:00 2001 From: Vitaliy Lyudvichenko Date: Thu, 16 Nov 2017 22:03:32 +0300 Subject: [PATCH 0001/1165] Fixed SummingMergeTree. [#CLICKHOUSE-2] --- .../SummingSortedBlockInputStream.cpp | 95 +++++++++++-------- .../SummingSortedBlockInputStream.h | 18 ++-- .../00084_summing_merge_tree.reference | 2 + .../0_stateless/00084_summing_merge_tree.sql | 10 ++ 4 files changed, 75 insertions(+), 50 deletions(-) diff --git a/dbms/src/DataStreams/SummingSortedBlockInputStream.cpp b/dbms/src/DataStreams/SummingSortedBlockInputStream.cpp index 7d0f94e997e..bc5c5dfc7dc 100644 --- a/dbms/src/DataStreams/SummingSortedBlockInputStream.cpp +++ b/dbms/src/DataStreams/SummingSortedBlockInputStream.cpp @@ -36,7 +36,7 @@ String SummingSortedBlockInputStream::getID() const } -void SummingSortedBlockInputStream::insertCurrentRow(ColumnPlainPtrs & merged_columns) +void SummingSortedBlockInputStream::insertCurrentRowIfNeeded(ColumnPlainPtrs & merged_columns, bool force_insertion) { for (auto & desc : columns_to_aggregate) { @@ -46,6 +46,19 @@ void SummingSortedBlockInputStream::insertCurrentRow(ColumnPlainPtrs & merged_co try { desc.function->insertResultInto(desc.state.data(), *desc.merged_column); + + /// Update zero status of current row + if (desc.column_numbers.size() == 1) + { + // Flag row as non-empty if at least one column number if non-zero + current_row_is_zero = current_row_is_zero && desc.merged_column->get64(desc.merged_column->size() - 1) == 0; + } + else + { + /// It is sumMap aggregate function. + /// Assume that the row isn't empty in this case (just because it is compatible with previous version) + current_row_is_zero = false; + } } catch (...) { @@ -60,8 +73,22 @@ void SummingSortedBlockInputStream::insertCurrentRow(ColumnPlainPtrs & merged_co desc.merged_column->insertDefault(); } + /// If it is "zero" row and it is not the last row of the result block, then + /// rollback the insertion (at this moment we need rollback only cols from columns_to_aggregate) + if (!force_insertion && current_row_is_zero) + { + for (auto & desc : columns_to_aggregate) + desc.merged_column->popBack(1); + + return; + } + for (auto i : column_numbers_not_to_aggregate) merged_columns[i]->insert(current_row[i]); + + /// Update per-block and per-group flags + ++merged_rows; + output_is_non_empty = true; } @@ -155,6 +182,7 @@ Block SummingSortedBlockInputStream::readImpl() desc.column_numbers = {i}; desc.function = factory.get("sumWithOverflow", {column.type}); desc.function->setArguments({column.type}); + desc.add_function = desc.function->getAddressOfAddFunction(); desc.state.resize(desc.function->sizeOfData()); columns_to_aggregate.emplace_back(std::move(desc)); } @@ -237,6 +265,7 @@ Block SummingSortedBlockInputStream::readImpl() // Create summation for all value columns in the map desc.function = factory.get("sumMap", argument_types); desc.function->setArguments(argument_types); + desc.add_function = desc.function->getAddressOfAddFunction(); desc.state.resize(desc.function->sizeOfData()); columns_to_aggregate.emplace_back(std::move(desc)); } @@ -279,7 +308,7 @@ Block SummingSortedBlockInputStream::readImpl() template void SummingSortedBlockInputStream::merge(ColumnPlainPtrs & merged_columns, std::priority_queue & queue) { - size_t merged_rows = 0; + merged_rows = 0; /// Take the rows in needed order and put them in `merged_block` until rows no more than `max_block_size` while (!queue.empty()) @@ -308,12 +337,7 @@ void SummingSortedBlockInputStream::merge(ColumnPlainPtrs & merged_columns, std: if (key_differs) { /// Write the data for the previous group. - if (!current_row_is_zero) - { - ++merged_rows; - output_is_non_empty = true; - insertCurrentRow(merged_columns); - } + insertCurrentRowIfNeeded(merged_columns, false); current_key.swap(next_key); @@ -327,11 +351,12 @@ void SummingSortedBlockInputStream::merge(ColumnPlainPtrs & merged_columns, std: } // Start aggregations with current row - current_row_is_zero = !addRow(current_row, current); + addRow(current_row, current); + current_row_is_zero = true; } else { - current_row_is_zero = !addRow(current_row, current); + addRow(current_row, current); // Merge maps only for same rows for (auto & desc : maps_to_sum) @@ -355,12 +380,7 @@ void SummingSortedBlockInputStream::merge(ColumnPlainPtrs & merged_columns, std: /// We will write the data for the last group, if it is non-zero. /// If it is zero, and without it the output stream will be empty, we will write it anyway. - if (!current_row_is_zero || !output_is_non_empty) - { - ++merged_rows; /// Dead store (result is unused). Left for clarity. - insertCurrentRow(merged_columns); - } - + insertCurrentRowIfNeeded(merged_columns, !output_is_non_empty); finished = true; } @@ -449,38 +469,29 @@ bool SummingSortedBlockInputStream::mergeMap(const MapDescription & desc, Row & template -bool SummingSortedBlockInputStream::addRow(Row & row, TSortCursor & cursor) +void SummingSortedBlockInputStream::addRow(Row & row, TSortCursor & cursor) { - bool res = false; for (auto & desc : columns_to_aggregate) { - if (desc.created) - { - // Specialized case for unary functions - if (desc.column_numbers.size() == 1) - { - auto & col = cursor->all_columns[desc.column_numbers[0]]; - desc.function->add(desc.state.data(), &col, cursor->pos, nullptr); - // Flag row as non-empty if at least one column number if non-zero - // Note: This defers compaction of signed type rows that sum to zero by one merge - if (!res) - res = col->get64(cursor->pos) != 0; - } - else - { - // Gather all source columns into a vector - ConstColumnPlainPtrs columns(desc.column_numbers.size()); - for (size_t i = 0; i < desc.column_numbers.size(); ++i) - columns[i] = cursor->all_columns[desc.column_numbers[i]]; + if (!desc.created) + throw Exception("Logical error in SummingSortedBlockInputStream, there are no description", ErrorCodes::LOGICAL_ERROR); - desc.function->add(desc.state.data(), columns.data(), cursor->pos, nullptr); - // Note: we can't detect whether the aggregation result is non-empty here yet - res = true; - } + // Specialized case for unary functions + if (desc.column_numbers.size() == 1) + { + auto & col = cursor->all_columns[desc.column_numbers[0]]; + desc.add_function(desc.function.get(), desc.state.data(), &col, cursor->pos, nullptr); + } + else + { + // Gather all source columns into a vector + ConstColumnPlainPtrs columns(desc.column_numbers.size()); + for (size_t i = 0; i < desc.column_numbers.size(); ++i) + columns[i] = cursor->all_columns[desc.column_numbers[i]]; + + desc.add_function(desc.function.get(),desc.state.data(), columns.data(), cursor->pos, nullptr); } } - - return res; } } diff --git a/dbms/src/DataStreams/SummingSortedBlockInputStream.h b/dbms/src/DataStreams/SummingSortedBlockInputStream.h index f21d79d01a6..493e32d5326 100644 --- a/dbms/src/DataStreams/SummingSortedBlockInputStream.h +++ b/dbms/src/DataStreams/SummingSortedBlockInputStream.h @@ -73,6 +73,7 @@ private: struct AggregateDescription { AggregateFunctionPtr function; + IAggregateFunction::AddFunc add_function = nullptr; std::vector column_numbers; ColumnPtr merged_column; std::vector state; @@ -100,9 +101,10 @@ private: RowRef next_key; /// The primary key of the next row. Row current_row; - bool current_row_is_zero = true; /// The current row is summed to zero, and it should be deleted. + bool current_row_is_zero = true; /// Are all summed columns zero (or empty)? It is updated incrementally. - bool output_is_non_empty = false; /// Have we given out at least one row as a result. + bool output_is_non_empty = false; /// Have we given out at least one row as a result. + size_t merged_rows = 0; /// Number of rows merged into current result block /** We support two different cursors - with Collation and without. * Templates are used instead of polymorphic SortCursor and calls to virtual functions. @@ -110,17 +112,17 @@ private: template void merge(ColumnPlainPtrs & merged_columns, std::priority_queue & queue); - /// Insert the summed row for the current group into the result. - void insertCurrentRow(ColumnPlainPtrs & merged_columns); + /// Insert the summed row for the current group into the result and updates some of per-block flags if the row is not "zero". + /// If force_insertion=true, then the row will be inserted even if it is "zero" + void insertCurrentRowIfNeeded(ColumnPlainPtrs & merged_columns, bool force_insertion); + /// Returns true is merge result is not empty template bool mergeMap(const MapDescription & map, Row & row, TSortCursor & cursor); - /** Add the row under the cursor to the `row`. - * Returns false if the result is zero. - */ + // Add the row under the cursor to the `row`. template - bool addRow(Row & row, TSortCursor & cursor); + void addRow(Row & row, TSortCursor & cursor); }; } diff --git a/dbms/tests/queries/0_stateless/00084_summing_merge_tree.reference b/dbms/tests/queries/0_stateless/00084_summing_merge_tree.reference index 7142e1ca063..72f24941378 100644 --- a/dbms/tests/queries/0_stateless/00084_summing_merge_tree.reference +++ b/dbms/tests/queries/0_stateless/00084_summing_merge_tree.reference @@ -2,3 +2,5 @@ 2000-01-01 Hello 5 7 9 2000-01-01 Goodbye 1 2 3 2000-01-01 Hello 1 7 9 +0 2 +666 1 diff --git a/dbms/tests/queries/0_stateless/00084_summing_merge_tree.sql b/dbms/tests/queries/0_stateless/00084_summing_merge_tree.sql index 82b5117625f..c03092d0277 100644 --- a/dbms/tests/queries/0_stateless/00084_summing_merge_tree.sql +++ b/dbms/tests/queries/0_stateless/00084_summing_merge_tree.sql @@ -29,3 +29,13 @@ SELECT * FROM test.summing_merge_tree ORDER BY d, a, x, y, z; DROP TABLE test.summing_merge_tree; + +-- +DROP TABLE IF EXISTS test.summing; +CREATE TABLE test.summing (p Date, k UInt64, s UInt64) ENGINE = SummingMergeTree(p, k, 1); + +INSERT INTO test.summing (k, s) VALUES (0, 1); +INSERT INTO test.summing (k, s) VALUES (0, 1), (666, 1), (666, 0); +OPTIMIZE TABLE test.summing PARTITION 197001; + +SELECT k, s FROM test.summing ORDER BY k; From 1b50717c7543ce2fef5273491c392ab6ef07195d Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Thu, 16 Nov 2017 23:29:30 +0300 Subject: [PATCH 0002/1165] Update SummingSortedBlockInputStream.h --- dbms/src/DataStreams/SummingSortedBlockInputStream.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/DataStreams/SummingSortedBlockInputStream.h b/dbms/src/DataStreams/SummingSortedBlockInputStream.h index 493e32d5326..4e12bf45827 100644 --- a/dbms/src/DataStreams/SummingSortedBlockInputStream.h +++ b/dbms/src/DataStreams/SummingSortedBlockInputStream.h @@ -116,7 +116,7 @@ private: /// If force_insertion=true, then the row will be inserted even if it is "zero" void insertCurrentRowIfNeeded(ColumnPlainPtrs & merged_columns, bool force_insertion); - /// Returns true is merge result is not empty + /// Returns true if merge result is not empty template bool mergeMap(const MapDescription & map, Row & row, TSortCursor & cursor); From 40b5fb292e29d38de7beb2af3657632d6ef9d560 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Thu, 16 Nov 2017 23:37:45 +0300 Subject: [PATCH 0003/1165] Update SummingSortedBlockInputStream.h --- dbms/src/DataStreams/SummingSortedBlockInputStream.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/DataStreams/SummingSortedBlockInputStream.h b/dbms/src/DataStreams/SummingSortedBlockInputStream.h index 4e12bf45827..e4207daf88d 100644 --- a/dbms/src/DataStreams/SummingSortedBlockInputStream.h +++ b/dbms/src/DataStreams/SummingSortedBlockInputStream.h @@ -45,8 +45,8 @@ private: /// Read up to the end. bool finished = false; - /// Columns with which numbers should be summed. - Names column_names_to_sum; /// If set, it is converted to column_numbers_to_sum when initialized. + /// Columns with which values should be summed. + Names column_names_to_sum; /// If set, it is converted to column_numbers_to_aggregate when initialized. ColumnNumbers column_numbers_not_to_aggregate; /** A table can have nested tables that are treated in a special way. From 9229961721a2bcb521617577f02f9aca2422239c Mon Sep 17 00:00:00 2001 From: Vitaliy Lyudvichenko Date: Mon, 20 Nov 2017 22:33:12 +0300 Subject: [PATCH 0004/1165] Add multi index for data_parts storage. And fixed bugs. [#CLICKHOUSE-3452] Fixed handling of obsolete parts. Fixed conflict resolution between simultaneous PreCommitted covering parts. Fixed memory leak caused by ordinary MergeTree parts stucked in Deleting state. Added hidden _state column into system.parts. --- contrib/poco | 2 +- dbms/src/Core/ErrorCodes.cpp | 1 + dbms/src/Storages/MergeTree/MergeTreeData.cpp | 483 +++++++++++------- dbms/src/Storages/MergeTree/MergeTreeData.h | 149 +++++- .../MergeTree/MergeTreeDataMerger.cpp | 2 +- .../Storages/MergeTree/MergeTreeDataPart.cpp | 13 + .../Storages/MergeTree/MergeTreeDataPart.h | 15 +- dbms/src/Storages/StorageMergeTree.cpp | 6 +- .../Storages/StorageReplicatedMergeTree.cpp | 49 +- .../Storages/System/StorageSystemParts.cpp | 40 +- dbms/src/Storages/System/StorageSystemParts.h | 4 + .../Storages/tests/gtest_range_filtered.cpp | 44 -- .../integration/test_random_inserts/test.py | 5 +- .../integration/test_random_inserts/test.sh | 5 +- libs/libcommon/include/common/RangeFiltered.h | 127 ----- 15 files changed, 524 insertions(+), 421 deletions(-) delete mode 100644 dbms/src/Storages/tests/gtest_range_filtered.cpp delete mode 100644 libs/libcommon/include/common/RangeFiltered.h diff --git a/contrib/poco b/contrib/poco index 1366df1c7e0..bcf9ebad48b 160000 --- a/contrib/poco +++ b/contrib/poco @@ -1 +1 @@ -Subproject commit 1366df1c7e068bb2efd846bc8dc8e286b090904e +Subproject commit bcf9ebad48b2162d25f5fc432b176d74a09f498d diff --git a/dbms/src/Core/ErrorCodes.cpp b/dbms/src/Core/ErrorCodes.cpp index ffeda42047b..bd4914ea08b 100644 --- a/dbms/src/Core/ErrorCodes.cpp +++ b/dbms/src/Core/ErrorCodes.cpp @@ -386,6 +386,7 @@ namespace ErrorCodes extern const int HTTP_LENGTH_REQUIRED = 381; extern const int CANNOT_LOAD_CATBOOST_MODEL = 382; extern const int CANNOT_APPLY_CATBOOST_MODEL = 383; + extern const int PART_IS_TEMPORARILY_LOCKED = 384; extern const int KEEPER_EXCEPTION = 999; extern const int POCO_EXCEPTION = 1000; diff --git a/dbms/src/Storages/MergeTree/MergeTreeData.cpp b/dbms/src/Storages/MergeTree/MergeTreeData.cpp index 8e7146e4bfa..0a63dc2348b 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeData.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeData.cpp @@ -74,6 +74,7 @@ namespace ErrorCodes extern const int CORRUPTED_DATA; extern const int INVALID_PARTITION_VALUE; extern const int METADATA_MISMATCH; + extern const int PART_IS_TEMPORARILY_LOCKED; } @@ -106,7 +107,9 @@ MergeTreeData::MergeTreeData( database_name(database_), table_name(table_), full_path(full_path_), columns(columns_), broken_part_callback(broken_part_callback_), - log_name(log_name_), log(&Logger::get(log_name + " (Data)")) + log_name(log_name_), log(&Logger::get(log_name + " (Data)")), + data_parts_by_name(data_parts_indexes.get()), + data_parts_by_state_and_name(data_parts_indexes.get()) { merging_params.check(*columns); @@ -381,7 +384,7 @@ Int64 MergeTreeData::getMaxDataPartIndex() std::lock_guard lock_all(data_parts_mutex); Int64 max_block_id = 0; - for (const auto & part : data_parts) + for (const DataPartPtr & part : data_parts_by_name) max_block_id = std::max(max_block_id, part->info.max_block); return max_block_id; @@ -392,9 +395,6 @@ void MergeTreeData::loadDataParts(bool skip_sanity_checks) { LOG_DEBUG(log, "Loading data parts"); - std::lock_guard lock(data_parts_mutex); - data_parts.clear(); - Strings part_file_names; Poco::DirectoryIterator end; for (Poco::DirectoryIterator it(full_path); it != end; ++it) @@ -410,6 +410,9 @@ void MergeTreeData::loadDataParts(bool skip_sanity_checks) DataPartsVector broken_parts_to_detach; size_t suspicious_broken_parts = 0; + std::lock_guard lock(data_parts_mutex); + data_parts_indexes.clear(); + for (const String & file_name : part_file_names) { MergeTreePartInfo part_info; @@ -496,7 +499,8 @@ void MergeTreeData::loadDataParts(bool skip_sanity_checks) /// Assume that all parts are Committed, covered parts will be detected and marked as Outdated later part->state = DataPartState::Committed; - data_parts.insert(part); + if (!data_parts_indexes.insert(part).second) + throw Exception("Part " + part->name + " already exists", ErrorCodes::DUPLICATE_DATA_PART); } if (suspicious_broken_parts > settings.max_suspicious_broken_parts && !skip_sanity_checks) @@ -512,13 +516,21 @@ void MergeTreeData::loadDataParts(bool skip_sanity_checks) /// were merged), but that for some reason are still not deleted from the filesystem. /// Deletion of files will be performed later in the clearOldParts() method. - if (data_parts.size() >= 2) + if (data_parts_indexes.size() >= 2) { - auto committed_parts = getDataPartsRange({DataPartState::Committed}); - auto prev_jt = committed_parts.begin(); + /// Now all parts are committed, so data_parts_by_state_and_name == committed_parts_range + auto prev_jt = data_parts_by_state_and_name.begin(); auto curr_jt = std::next(prev_jt); - while (curr_jt != committed_parts.end()) + auto deactivate_part = [&] (DataPartIteratorByStateAndName it) + { + (*it)->remove_time = (*it)->modification_time; + modifyPartState(it, DataPartState::Outdated); + }; + + (*prev_jt)->assertState({DataPartState::Committed}); + + while (curr_jt != data_parts_by_state_and_name.end() && (*curr_jt)->state == DataPartState::Committed) { /// Don't consider data parts belonging to different partitions. if ((*curr_jt)->info.partition_id != (*prev_jt)->info.partition_id) @@ -530,16 +542,15 @@ void MergeTreeData::loadDataParts(bool skip_sanity_checks) if ((*curr_jt)->contains(**prev_jt)) { - (*prev_jt)->remove_time = (*prev_jt)->modification_time; - (*prev_jt)->state = DataPartState::Outdated; /// prev_jt becomes invalid here + deactivate_part(prev_jt); prev_jt = curr_jt; ++curr_jt; } else if ((*prev_jt)->contains(**curr_jt)) { - (*curr_jt)->remove_time = (*curr_jt)->modification_time; - (*curr_jt)->state = DataPartState::Outdated; /// curr_jt becomes invalid here - ++curr_jt; + auto next = std::next(curr_jt); + deactivate_part(curr_jt); + curr_jt = next; } else { @@ -551,7 +562,7 @@ void MergeTreeData::loadDataParts(bool skip_sanity_checks) calculateColumnSizesImpl(); - LOG_DEBUG(log, "Loaded data parts (" << data_parts.size() << " items)"); + LOG_DEBUG(log, "Loaded data parts (" << data_parts_indexes.size() << " items)"); } @@ -619,21 +630,30 @@ MergeTreeData::DataPartsVector MergeTreeData::grabOldParts() return res; time_t now = time(nullptr); + std::vector parts_to_delete; { std::lock_guard lock_parts(data_parts_mutex); - for (auto it = data_parts.begin(); it != data_parts.end(); ++it) + auto outdated_parts_range = getDataPartsStateRange(DataPartState::Outdated); + for (auto it = outdated_parts_range.begin(); it != outdated_parts_range.end(); ++it) { - if ((*it)->state == DataPartState::Outdated && - it->unique() && /// Grab only parts that is not using by anyone (SELECTs for example) - (*it)->remove_time < now && - now - (*it)->remove_time > settings.old_parts_lifetime.totalSeconds()) + const DataPartPtr & part = *it; + + if (part.unique() && /// Grab only parts that is not using by anyone (SELECTs for example) + part->remove_time < now && + now - part->remove_time > settings.old_parts_lifetime.totalSeconds()) { - (*it)->state = DataPartState::Deleting; - res.push_back(*it); + parts_to_delete.emplace_back(it); } } + + res.reserve(parts_to_delete.size()); + for (const auto & it_to_delete : parts_to_delete) + { + res.emplace_back(*it_to_delete); + modifyPartState(it_to_delete, DataPartState::Deleting); + } } if (!res.empty()) @@ -650,7 +670,7 @@ void MergeTreeData::rollbackDeletingParts(const MergeTreeData::DataPartsVector & { /// We should modify it under data_parts_mutex part->assertState({DataPartState::Deleting}); - part->state = DataPartState::Outdated; + modifyPartState(part, DataPartState::Outdated); } } @@ -661,26 +681,27 @@ void MergeTreeData::removePartsFinally(const MergeTreeData::DataPartsVector & pa /// TODO: use data_parts iterators instead of pointers for (auto & part : parts) { - if (part->state != DataPartState::Deleting) - throw Exception("An attempt to delete part " + part->getNameWithState() + " with unexpected state", ErrorCodes::LOGICAL_ERROR); - - auto it = data_parts.find(part); - if (it == data_parts.end()) + auto it = data_parts_by_name.find(part->info); + if (it == data_parts_by_name.end()) throw Exception("Deleting data part " + part->name + " is not exist", ErrorCodes::LOGICAL_ERROR); - data_parts.erase(it); + (*it)->assertState({DataPartState::Deleting}); + + data_parts_indexes.erase(it); } } -void MergeTreeData::clearOldParts() +void MergeTreeData::clearOldPartsFromFilesystem() { auto parts_to_remove = grabOldParts(); for (const DataPartPtr & part : parts_to_remove) { - LOG_DEBUG(log, "Removing part " << part->name); + LOG_DEBUG(log, "Removing part from filesystem " << part->name); part->remove(); } + + removePartsFinally(parts_to_remove); } void MergeTreeData::setPath(const String & new_full_path, bool move_data) @@ -710,7 +731,7 @@ void MergeTreeData::dropAllData() LOG_TRACE(log, "dropAllData: removing data from memory."); - data_parts.clear(); + data_parts_indexes.clear(); column_sizes.clear(); context.dropCaches(); @@ -1319,9 +1340,13 @@ MergeTreeData::DataPartsVector MergeTreeData::renameTempPartAndReplace( part->assertState({DataPartState::Temporary}); - DataPartsVector replaced; + MergeTreePartInfo part_info = part->info; + String part_name; + + DataPartsVector replaced_parts; + std::vector replaced_iterators; { - std::lock_guard lock(data_parts_mutex); + std::unique_lock lock(data_parts_mutex); if (DataPartPtr existing_part_in_partition = getAnyPartInPartition(part->info.partition_id, lock)) { @@ -1336,141 +1361,163 @@ MergeTreeData::DataPartsVector MergeTreeData::renameTempPartAndReplace( * Otherwise there is race condition - merge of blocks could happen in interval that doesn't yet contain new part. */ if (increment) - part->info.min_block = part->info.max_block = increment->get(); + part_info.min_block = part_info.max_block = increment->get(); - String new_name; if (format_version < MERGE_TREE_DATA_MIN_FORMAT_VERSION_WITH_CUSTOM_PARTITIONING) - new_name = part->info.getPartNameV0(part->getMinDate(), part->getMaxDate()); + part_name = part_info.getPartNameV0(part->getMinDate(), part->getMaxDate()); else - new_name = part->info.getPartName(); + part_name = part_info.getPartName(); - LOG_TRACE(log, "Renaming temporary part " << part->relative_path << " to " << new_name << "."); + LOG_TRACE(log, "Renaming temporary part " << part->relative_path << " to " << part_name << "."); - auto it_duplicate = data_parts.find(part); - if (it_duplicate != data_parts.end()) + auto it_duplicate = data_parts_by_name.find(part_info); + if (it_duplicate != data_parts_by_name.end()) { String message = "Part " + (*it_duplicate)->getNameWithState() + " already exists"; + if ((*it_duplicate)->checkState({DataPartState::Outdated, DataPartState::Deleting})) - message += ", but it will be deleted soon"; + { + throw Exception(message + ", but it will be deleted soon", ErrorCodes::PART_IS_TEMPORARILY_LOCKED); + } throw Exception(message, ErrorCodes::DUPLICATE_DATA_PART); } - /// Rename the part only in memory. Will rename it on disk only if all check is passed. - /// It allows us maintain invariant: if non-temporary parts in filesystem then they are in data_parts - part->name = new_name; + /// Check that part is not covered and doesn't cover other in-progress parts, it makes sense only for Replicated* engines + if (out_transaction) + { + auto check_coverage = [&part_info, &part_name] (const DataPartPtr & part) + { + if (part_info.contains(part->info)) + { + throw Exception("Cannot add part " + part_name + " covering pre-committed part " + part->name, ErrorCodes::PART_IS_TEMPORARILY_LOCKED); + } + else + { + if (part->info.contains(part_info)) + throw Exception("Cannot add part " + part_name + " covered by pre-committed part " + part->name + ". It is a bug", ErrorCodes::LOGICAL_ERROR); + } + }; + + auto it_middle = data_parts_by_state_and_name.lower_bound(DataPartStateAndInfo(DataPartState::PreCommitted, part_info)); + + auto precommitted_parts_range = getDataPartsStateRange(DataPartState::PreCommitted); + + for (auto it = it_middle; it != precommitted_parts_range.begin();) + { + --it; + check_coverage(*it); + } + + for (auto it = it_middle; it != precommitted_parts_range.end();) + { + check_coverage(*it); + ++it; + } + } /// Is the part covered by some other part? - bool obsolete = false; + DataPartPtr covering_part; - auto check_replacing_part_state = [&] (const DataPartPtr & cur_part) - { - cur_part->assertState({DataPartState::PreCommitted, DataPartState::Committed}); - if (cur_part->state == DataPartState::PreCommitted) - throw Exception("Could not add part " + new_name + " while replacing part " + cur_part->name + " is in pre-committed state", ErrorCodes::LOGICAL_ERROR); - }; + auto it_middle = data_parts_by_state_and_name.lower_bound(DataPartStateAndInfo(DataPartState::Committed, part_info)); - /// Don't consider parts going to be deleted - auto active_parts = getDataPartsRange({DataPartState::Committed, DataPartState::PreCommitted}); /// Parts contained in the part are consecutive in data_parts, intersecting the insertion place for the part itself. - auto it_middle = active_parts.convert(data_parts.lower_bound(part)); + auto committed_parts_range = getDataPartsStateRange(DataPartState::Committed); /// Go to the left. - for (auto it = it_middle; it != active_parts.begin();) + for (auto it = it_middle; it != committed_parts_range.begin();) { --it; - if (!part->contains(**it)) + if (!part_info.contains((*it)->info)) { - if ((*it)->contains(*part)) - obsolete = true; - ++it; + if ((*it)->info.contains(part_info)) + covering_part = *it; break; } - check_replacing_part_state(*it); - replaced.push_back(*it); -// replaced.push_back(*it); -// (*it)->remove_time = time(nullptr); -// (*it)->state = replaced_parts_state; -// removePartContributionToColumnSizes(*it); -// data_parts.erase(it++); /// Yes, ++, not --. + replaced_iterators.push_back(it); } /// Parts must be in ascending order. - std::reverse(replaced.begin(), replaced.end()); + std::reverse(replaced_iterators.begin(), replaced_iterators.end()); /// Go to the right. - for (auto it = it_middle; it != active_parts.end();) + for (auto it = it_middle; it != committed_parts_range.end();) { - if ((*it)->name == part->name) - throw Exception("Unexpected duplicate part " + part->getNameWithState() + ". It is a bug.", ErrorCodes::LOGICAL_ERROR); + if ((*it)->name == part_name) + throw Exception("Unexpected duplicate part " + (*it)->getNameWithState() + ". It is a bug.", ErrorCodes::LOGICAL_ERROR); - if (!part->contains(**it)) + if (!part_info.contains((*it)->info)) { - if ((*it)->contains(*part)) - obsolete = true; + if ((*it)->info.contains(part_info)) + covering_part = *it; break; } - check_replacing_part_state(*it); - replaced.push_back(*it); + replaced_iterators.push_back(it); ++it; -// replaced.push_back(*it); -// (*it)->remove_time = time(nullptr); -// (*it)->state = replaced_parts_state; -// removePartContributionToColumnSizes(*it); -// data_parts.erase(it++); } - if (obsolete) + if (covering_part) { - LOG_WARNING(log, "Obsolete part " << part->name << " added"); + LOG_WARNING(log, "Tried to add obsolete part " << part_name << " covered by " << covering_part->getNameWithState()); + + /// It is a temporary part, we want to delete it from filesystem immediately + /// Other fields remain the same part->remove_time = time(nullptr); - /// I case of fail, we want to delete part from filesystem immediately (to avoid any conflicts) part->is_temp = true; + + /// Nothing to commit or rollback + if (out_transaction) + { + out_transaction->data = this; + out_transaction->parts_to_add_on_rollback = {}; + out_transaction->parts_to_remove_on_rollback = {}; + } + + /// We replaced nothing + return {}; + } + + /// All checks are passed. Now we can rename the part on disk. + /// So, we maintain invariant: if a non-temporary part in filesystem then it is in data_parts + /// + /// Ordinary MergeTree engines (they don't use out_transaction) commit parts immediately, + /// whereas ReplicatedMergeTree uses intermediate PreCommitted state + part->name = part_name; + part->info = part_info; + part->is_temp = false; + part->state = (out_transaction) ? DataPartState::PreCommitted : DataPartState::Committed; + part->renameTo(part_name); + + data_parts_indexes.insert(part); + + replaced_parts.reserve(replaced_iterators.size()); + for (auto it_replacing_part : replaced_iterators) + replaced_parts.emplace_back(*it_replacing_part); + + if (!out_transaction) + { + addPartContributionToColumnSizes(part); + + auto current_time = time(nullptr); + for (auto it_replacing_part : replaced_iterators) + { + (*it_replacing_part)->remove_time = current_time; + modifyPartState(it_replacing_part, DataPartState::Outdated); + removePartContributionToColumnSizes(*it_replacing_part); + } } else { - /// Now we can rename part on filesystem - part->is_temp = false; - part->renameTo(new_name); - - if (!out_transaction) - { - /// Ordinary MergeTree engines (they don't use out_transaction) commit parts immediately - part->state = DataPartState::Committed; - addPartContributionToColumnSizes(part); - } - else - { - /// Whereas ReplicatedMergeTree uses intermediate PreCommitted state - part->state = DataPartState::PreCommitted; - } - - data_parts.insert(part); - - auto current_time = time(nullptr); - for (auto & replacing_part : replaced) - { - if (!out_transaction) - { - replacing_part->remove_time = current_time; - replacing_part->state = DataPartState::Outdated; - removePartContributionToColumnSizes(replacing_part); - } - } + out_transaction->data = this; + out_transaction->parts_to_add_on_rollback = replaced_parts; + out_transaction->parts_to_remove_on_rollback = {part}; } } - if (out_transaction) - { - out_transaction->data = this; - out_transaction->parts_to_add_on_rollback = replaced; - out_transaction->parts_to_remove_on_rollback = {part}; - } - - return replaced; + return replaced_parts; } void MergeTreeData::removePartsFromWorkingSet(const DataPartsVector & remove, bool clear_without_timeout) @@ -1479,7 +1526,7 @@ void MergeTreeData::removePartsFromWorkingSet(const DataPartsVector & remove, bo for (auto & part : remove) { - if (!data_parts.count(part)) + if (!data_parts_by_name.count(part->info)) throw Exception("Part " + part->getNameWithState() + " not found in data_parts", ErrorCodes::LOGICAL_ERROR); part->assertState({DataPartState::PreCommitted, DataPartState::Committed, DataPartState::Outdated}); @@ -1490,7 +1537,8 @@ void MergeTreeData::removePartsFromWorkingSet(const DataPartsVector & remove, bo { if (part->state == DataPartState::Committed) removePartContributionToColumnSizes(part); - part->state = DataPartState::Outdated; + + modifyPartState(part, DataPartState::Outdated); part->remove_time = remove_time; } } @@ -1502,65 +1550,93 @@ void MergeTreeData::renameAndDetachPart(const DataPartPtr & part_to_detach, cons LOG_INFO(log, "Renaming " << part_to_detach->relative_path << " to " << prefix << part_to_detach->name << " and detaching it."); std::lock_guard lock(data_parts_mutex); - //std::lock_guard lock_all(all_data_parts_mutex); - auto it_part = data_parts.find(part_to_detach); - if (it_part == data_parts.end()) + auto it_part = data_parts_by_name.find(part_to_detach->info); + if (it_part == data_parts_by_name.end()) throw Exception("No such data part " + part_to_detach->getNameWithState(), ErrorCodes::NO_SUCH_DATA_PART); /// What if part_to_detach is reference to *it_part? Make a new owner just in case. - auto part = *it_part; + DataPartPtr part = *it_part; - removePartContributionToColumnSizes(part); - part->state = DataPartState::Deleting; + if (part->state == DataPartState::Committed) + removePartContributionToColumnSizes(part); + modifyPartState(it_part, DataPartState::Deleting); if (move_to_detached || !prefix.empty()) part->renameAddPrefix(move_to_detached, prefix); + data_parts_indexes.erase(it_part); + + if (restore_covered && part->info.level == 0) + { + LOG_WARNING(log, "Will not recover parts covered by zero-level part " << part->name); + return; + } if (restore_covered) { - auto suitable_parts = getDataPartsRange({DataPartState::PreCommitted, DataPartState::Committed, DataPartState::Outdated}); - auto it = suitable_parts.convert(data_parts.lower_bound(part)); - Strings restored; bool error = false; + String error_parts; Int64 pos = part->info.min_block; - if (it != suitable_parts.begin()) + auto is_appropriate_state = [] (DataPartState state) { - --it; - if (part->contains(**it)) + return state == DataPartState::Committed || state == DataPartState::Outdated; + }; + + auto update_error = [&] (DataPartIteratorByAndName it) + { + error = true; + error_parts += (*it)->getNameWithState() + " "; + }; + + auto it_middle = data_parts_by_name.lower_bound(part->info); + + /// Restore the leftmost part covered by the part + if (it_middle != data_parts_by_name.begin()) + { + auto it = std::prev(it_middle); + + if (part->contains(**it) && is_appropriate_state((*it)->state)) { + /// Maybe, we must consider part level somehow if ((*it)->info.min_block != part->info.min_block) - error = true; + update_error(it); if ((*it)->state != DataPartState::Committed) { addPartContributionToColumnSizes(*it); - (*it)->state = DataPartState::Committed; + modifyPartState(it, DataPartState::Committed); // iterator is not invalidated here } pos = (*it)->info.max_block + 1; restored.push_back((*it)->name); } else - error = true; - ++it; + update_error(it); } else error = true; - for (; it != suitable_parts.end() && part->contains(**it); ++it) + /// Restore "right" parts + for (auto it = it_middle; it != data_parts_by_name.end() && part->contains(**it); ++it) { if ((*it)->info.min_block < pos) continue; + + if (!is_appropriate_state((*it)->state)) + { + update_error(it); + continue; + } + if ((*it)->info.min_block > pos) - error = true; + update_error(it); if ((*it)->state != DataPartState::Committed) { addPartContributionToColumnSizes(*it); - (*it)->state = DataPartState::Committed; + modifyPartState(it, DataPartState::Committed); } pos = (*it)->info.max_block + 1; @@ -1576,18 +1652,24 @@ void MergeTreeData::renameAndDetachPart(const DataPartPtr & part_to_detach, cons } if (error) - LOG_ERROR(log, "The set of parts restored in place of " << part->name << " looks incomplete. There might or might not be a data loss."); + { + LOG_ERROR(log, "The set of parts restored in place of " << part->name << " looks incomplete." + << " There might or might not be a data loss." + << (error_parts.empty() ? "" : " Suspicious parts: " + error_parts)); + } } } size_t MergeTreeData::getTotalActiveSizeInBytes() const { - std::lock_guard lock(data_parts_mutex); - size_t res = 0; - for (auto & part : getDataPartsRange({DataPartState::Committed})) - res += part->size_in_bytes; + { + std::lock_guard lock(data_parts_mutex); + + for (auto & part : getDataPartsStateRange(DataPartState::Committed)) + res += part->size_in_bytes; + } return res; } @@ -1601,7 +1683,7 @@ size_t MergeTreeData::getMaxPartsCountForPartition() const size_t cur_count = 0; const String * cur_partition_id = nullptr; - for (const auto & part : getDataPartsRange({DataPartState::Committed})) + for (const auto & part : getDataPartsStateRange(DataPartState::Committed)) { if (cur_partition_id && part->info.partition_id == *cur_partition_id) { @@ -1656,11 +1738,12 @@ MergeTreeData::DataPartPtr MergeTreeData::getActiveContainingPart(const String & std::lock_guard lock(data_parts_mutex); - /// The part can be covered only by the previous or the next one in data_parts. - auto committed_parts = getDataPartsRange({DataPartState::Committed}); - auto it = committed_parts.convert(data_parts.lower_bound(part_info)); + auto committed_parts_range = getDataPartsStateRange(DataPartState::Committed); - if (it != committed_parts.end()) + /// The part can be covered only by the previous or the next one in data_parts. + auto it = data_parts_by_state_and_name.lower_bound(DataPartStateAndInfo(DataPartState::Committed, part_info)); + + if (it != committed_parts_range.end()) { if ((*it)->name == part_name) return *it; @@ -1668,7 +1751,7 @@ MergeTreeData::DataPartPtr MergeTreeData::getActiveContainingPart(const String & return *it; } - if (it != committed_parts.begin()) + if (it != committed_parts_range.begin()) { --it; if ((*it)->info.contains(part_info)) @@ -1685,10 +1768,15 @@ MergeTreeData::DataPartPtr MergeTreeData::getPartIfExists(const String & part_na std::lock_guard lock(data_parts_mutex); - auto filtered_parts = getDataPartsRange(valid_states); - auto it = filtered_parts.convert(data_parts.find(part_info)); - if (it != filtered_parts.end() && (*it)->name == part_name) - return *it; + auto it = data_parts_by_name.find(part_info); + if (it == data_parts_by_name.end()) + return nullptr; + + for (auto state : valid_states) + { + if ((*it)->state == state) + return *it; + } return nullptr; } @@ -1742,7 +1830,8 @@ void MergeTreeData::calculateColumnSizesImpl() column_sizes.clear(); /// Take into account only committed parts - for (const auto & part : getDataPartsRange({DataPartState::Committed})) + auto committed_parts_range = getDataPartsStateRange(DataPartState::Committed); + for (const auto & part : committed_parts_range) addPartContributionToColumnSizes(part); } @@ -1953,7 +2042,7 @@ String MergeTreeData::getPartitionIDFromQuery(const ASTPtr & ast, const Context String partition_id = partition.getID(*this); { - std::lock_guard data_parts_lock(data_parts_mutex); + std::unique_lock data_parts_lock(data_parts_mutex); DataPartPtr existing_part_in_partition = getAnyPartInPartition(partition_id, data_parts_lock); if (existing_part_in_partition && existing_part_in_partition->partition.value != partition.value) { @@ -1969,28 +2058,48 @@ String MergeTreeData::getPartitionIDFromQuery(const ASTPtr & ast, const Context return partition_id; } -MergeTreeData::DataPartsVector MergeTreeData::getDataPartsVector(const DataPartStates & affordable_states) const +MergeTreeData::DataPartsVector MergeTreeData::getDataPartsVector(const DataPartStates & affordable_states, DataPartStateVector * out_states) const { DataPartsVector res; + DataPartsVector buf; { std::lock_guard lock(data_parts_mutex); - std::copy_if(data_parts.begin(), data_parts.end(), std::back_inserter(res), DataPart::getStatesFilter(affordable_states)); + + for (auto state : affordable_states) + { + buf = std::move(res); + res.clear(); + + auto range = getDataPartsStateRange(state); + std::merge(range.begin(), range.end(), buf.begin(), buf.end(), std::back_inserter(res), LessDataPart()); + } + + if (out_states != nullptr) + { + out_states->resize(res.size()); + for (size_t i = 0; i < res.size(); ++i) + (*out_states)[i] = res[i]->state; + } } + return res; } -MergeTreeData::DataPartsVector MergeTreeData::getDataPartsVector(const MergeTreeData::DataPartStates & affordable_states, - MergeTreeData::DataPartStateVector & out_states_snapshot) const +MergeTreeData::DataPartsVector MergeTreeData::getAllDataPartsVector(MergeTreeData::DataPartStateVector * out_states) const { DataPartsVector res; { std::lock_guard lock(data_parts_mutex); - std::copy_if(data_parts.begin(), data_parts.end(), std::back_inserter(res), DataPart::getStatesFilter(affordable_states)); + res.assign(data_parts_by_name.begin(), data_parts_by_name.end()); - out_states_snapshot.resize(res.size()); - for (size_t i = 0; i < res.size(); ++i) - out_states_snapshot[i] = res[i]->state; + if (out_states != nullptr) + { + out_states->resize(res.size()); + for (size_t i = 0; i < res.size(); ++i) + (*out_states)[i] = res[i]->state; + } } + return res; } @@ -1999,7 +2108,11 @@ MergeTreeData::DataParts MergeTreeData::getDataParts(const DataPartStates & affo DataParts res; { std::lock_guard lock(data_parts_mutex); - std::copy_if(data_parts.begin(), data_parts.end(), std::inserter(res, res.end()), DataPart::getStatesFilter(affordable_states)); + for (auto state : affordable_states) + { + auto range = getDataPartsStateRange(state); + res.insert(range.begin(), range.end()); + } } return res; } @@ -2014,28 +2127,23 @@ MergeTreeData::DataPartsVector MergeTreeData::getDataPartsVector() const return getDataPartsVector({DataPartState::Committed}); } -MergeTreeData::DataParts MergeTreeData::getAllDataParts() const -{ - return getDataParts({DataPartState::PreCommitted, DataPartState::Committed, DataPartState::Outdated}); -} - MergeTreeData::DataPartPtr MergeTreeData::getAnyPartInPartition( - const String & partition_id, std::lock_guard & data_parts_lock) + const String & partition_id, std::unique_lock & data_parts_lock) { auto min_block = std::numeric_limits::min(); MergeTreePartInfo dummy_part_info(partition_id, min_block, min_block, 0); - auto committed_parts = getDataPartsRange({DataPartState::Committed}); - auto it = committed_parts.convert(data_parts.lower_bound(dummy_part_info)); + auto it = data_parts_by_state_and_name.lower_bound(DataPartStateAndInfo(DataPartState::Committed, dummy_part_info)); - if (it != committed_parts.end() && (*it)->info.partition_id == partition_id) + if (it != data_parts_by_state_and_name.end() && (*it)->state == DataPartState::Committed && (*it)->info.partition_id == partition_id) return *it; - return {}; + + return nullptr; } void MergeTreeData::Transaction::rollback() { - if (data && (!parts_to_remove_on_rollback.empty() || !parts_to_add_on_rollback.empty())) + if (!isEmpty()) { std::stringstream ss; if (!parts_to_remove_on_rollback.empty()) @@ -2057,14 +2165,19 @@ void MergeTreeData::Transaction::rollback() /// PreCommitted -> Outdated replaceParts(DataPartState::Outdated, DataPartState::Committed, true); - clear(); } + + clear(); } void MergeTreeData::Transaction::commit() { - /// PreCommitted -> Committed, Committed -> Outdated - replaceParts(DataPartState::Committed, DataPartState::Outdated, false); + if (!isEmpty()) + { + /// PreCommitted -> Committed, Committed -> Outdated + replaceParts(DataPartState::Committed, DataPartState::Outdated, false); + } + clear(); } @@ -2088,9 +2201,9 @@ void MergeTreeData::Transaction::replaceParts(MergeTreeData::DataPartState move_ /// If it is rollback then do nothing, else make it Outdated and remove their size contribution if (move_committed_to != DataPartState::Committed) { - for (auto & part : committed_parts) + for (const DataPartPtr & part : committed_parts) { - part->state = move_committed_to; + data->modifyPartState(part, move_committed_to); part->remove_time = remove_time; data->removePartContributionToColumnSizes(part); } @@ -2099,7 +2212,7 @@ void MergeTreeData::Transaction::replaceParts(MergeTreeData::DataPartState move_ /// If it is rollback just change state to Outdated, else change state to Committed and add their size contribution for (auto & part : precommitted_parts) { - part->state = move_precommitted_to; + data->modifyPartState(part, move_precommitted_to); if (move_precommitted_to == DataPartState::Committed) data->addPartContributionToColumnSizes(part); else diff --git a/dbms/src/Storages/MergeTree/MergeTreeData.h b/dbms/src/Storages/MergeTree/MergeTreeData.h index 2235a73dbf1..fe793c5da9c 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeData.h +++ b/dbms/src/Storages/MergeTree/MergeTreeData.h @@ -15,7 +15,10 @@ #include #include -#include +#include +#include +#include +#include namespace DB { @@ -104,7 +107,16 @@ public: using DataPartStates = std::initializer_list; using DataPartStateVector = std::vector; - struct DataPartPtrLess + /// Auxiliary structure for index comparison. Keep in mind lifetime of MergeTreePartInfo. + struct DataPartStateAndInfo + { + DataPartState state; + const MergeTreePartInfo & info; + + DataPartStateAndInfo(DataPartState state, const MergeTreePartInfo & info) : state(state), info(info) {} + }; + + struct LessDataPart { using is_transparent = void; @@ -113,11 +125,32 @@ public: bool operator()(const DataPartPtr & lhs, const DataPartPtr & rhs) const { return lhs->info < rhs->info; } }; - using DataParts = std::set; + struct LessStateDataPart + { + using is_transparent = void; + + bool operator() (const DataPartStateAndInfo & lhs, const DataPartStateAndInfo & rhs) const + { + return std::forward_as_tuple(static_cast(lhs.state), lhs.info) + < std::forward_as_tuple(static_cast(rhs.state), rhs.info); + } + + bool operator() (DataPartStateAndInfo info, const DataPartState & state) const + { + return static_cast(info.state) < static_cast(state); + } + + bool operator() (const DataPartState & state, DataPartStateAndInfo info) const + { + return static_cast(state) < static_cast(info.state); + } + }; + + using DataParts = std::set; using DataPartsVector = std::vector; /// For resharding. - using MutableDataParts = std::set; + using MutableDataParts = std::set; using PerShardDataParts = std::unordered_map; /// Some operations on the set of parts return a Transaction object. @@ -131,6 +164,11 @@ public: void rollback(); + bool isEmpty() const + { + return parts_to_add_on_rollback.empty() && parts_to_remove_on_rollback.empty(); + } + ~Transaction() { try @@ -310,22 +348,17 @@ public: /// Returns a copy of the list so that the caller shouldn't worry about locks. DataParts getDataParts(const DataPartStates & affordable_states) const; - DataPartsVector getDataPartsVector(const DataPartStates & affordable_states) const; - DataPartsVector getDataPartsVector(const DataPartStates & affordable_states, DataPartStateVector & out_states_snapshot) const; + /// Returns sorted list of the parts with specified states + /// out_states will contain snapshot of each part state + DataPartsVector getDataPartsVector(const DataPartStates & affordable_states, DataPartStateVector * out_states = nullptr) const; - /// Returns a virtual container iteration only through parts with specified states - decltype(auto) getDataPartsRange(const DataPartStates & affordable_states) const - { - return createRangeFiltered(DataPart::getStatesFilter(affordable_states), data_parts); - } + /// Returns absolutely all parts (and snapshot of their states) + DataPartsVector getAllDataPartsVector(DataPartStateVector * out_states = nullptr) const; /// Returns Committed parts DataParts getDataParts() const; DataPartsVector getDataPartsVector() const; - /// Returns all parts except Temporary and Deleting ones - DataParts getAllDataParts() const; - /// Returns an comitted part with the given name or a part containing it. If there is no such part, returns nullptr. DataPartPtr getActiveContainingPart(const String & part_name); @@ -375,8 +408,8 @@ public: /// Removes parts from data_parts, they should be in Deleting state void removePartsFinally(const DataPartsVector & parts); - /// Delete irrelevant parts. - void clearOldParts(); + /// Delete irrelevant parts from memory and disk. + void clearOldPartsFromFilesystem(); /// Deleate all directories which names begin with "tmp" /// Set non-negative parameter value to override MergeTreeSettings temporary_directories_lifetime @@ -538,15 +571,81 @@ private: String log_name; Logger * log; - /// Current set of data parts. - DataParts data_parts; - mutable std::mutex data_parts_mutex; - /// The set of all data parts including already merged but not yet deleted. Usually it is small (tens of elements). - /// The part is referenced from here, from the list of current parts and from each thread reading from it. - /// This means that if reference count is 1 - the part is not used right now and can be deleted. -// DataParts all_data_parts; -// mutable std::mutex all_data_parts_mutex; + /// Work with data parts + + struct TagByName{}; + struct TagByStateAndName{}; + + static const MergeTreePartInfo & dataPartPtrToInfo(const DataPartPtr & part) + { + return part->info; + } + + static DataPartStateAndInfo dataPartPtrToStateAndInfo(const DataPartPtr & part) + { + return {part->state, part->info}; + }; + + using DataPartsIndexes = boost::multi_index_container, + boost::multi_index::global_fun + >, + /// Index by (State, Name), is used to obtain ordered slices of parts with the same state + boost::multi_index::ordered_unique< + boost::multi_index::tag, + boost::multi_index::global_fun, + LessStateDataPart + > + > + >; + + /// Current set of data parts. + mutable std::mutex data_parts_mutex; + DataPartsIndexes data_parts_indexes; + DataPartsIndexes::index::type & data_parts_by_name; + DataPartsIndexes::index::type & data_parts_by_state_and_name; + + using DataPartIteratorByAndName = DataPartsIndexes::index::type::iterator; + using DataPartIteratorByStateAndName = DataPartsIndexes::index::type::iterator; + + boost::iterator_range getDataPartsStateRange(DataPartState state) const + { + auto begin = data_parts_by_state_and_name.lower_bound(state, LessStateDataPart()); + auto end = data_parts_by_state_and_name.upper_bound(state, LessStateDataPart()); + return {begin, end}; + } + + static decltype(auto) getStateModifier(DataPartState state) + { + return [state] (const DataPartPtr & part) { part->state = state; }; + } + + void modifyPartState(DataPartIteratorByStateAndName it, DataPartState state) + { + if (!data_parts_by_state_and_name.modify(it, getStateModifier(state))) + throw Exception("Can't modify " + (*it)->getNameWithState(), ErrorCodes::LOGICAL_ERROR); + } + + void modifyPartState(DataPartIteratorByAndName it, DataPartState state) + { + if (!data_parts_by_state_and_name.modify(data_parts_indexes.project(it), getStateModifier(state))) + throw Exception("Can't modify " + (*it)->getNameWithState(), ErrorCodes::LOGICAL_ERROR); + } + + void modifyPartState(const DataPartPtr & part, DataPartState state) + { + auto it = data_parts_by_name.find(part->info); + if (it == data_parts_by_name.end() || (*it).get() != part.get()) + throw Exception("Part " + part->name + " is not exists", ErrorCodes::LOGICAL_ERROR); + + if (!data_parts_by_state_and_name.modify(data_parts_indexes.project(it), getStateModifier(state))) + throw Exception("Can't modify " + (*it)->getNameWithState(), ErrorCodes::LOGICAL_ERROR); + } + /// Used to serialize calls to grabOldParts. std::mutex grab_old_parts_mutex; @@ -582,7 +681,7 @@ private: void removePartContributionToColumnSizes(const DataPartPtr & part); /// If there is no part in the partition with ID `partition_id`, returns empty ptr. Should be called under the lock. - DataPartPtr getAnyPartInPartition(const String & partition_id, std::lock_guard & data_parts_lock); + DataPartPtr getAnyPartInPartition(const String & partition_id, std::unique_lock & data_parts_lock); }; } diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataMerger.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataMerger.cpp index 280e1cc30a6..cc8094b8ee5 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataMerger.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataMerger.cpp @@ -187,7 +187,7 @@ bool MergeTreeDataMerger::selectPartsToMerge( if (prev_part && part->info.partition_id == (*prev_part)->info.partition_id && part->info.min_block < (*prev_part)->info.max_block) { - LOG_ERROR(log, "Part " << part->name << " intersects previous part " << (*prev_part)->name); + LOG_ERROR(log, "Part " << part->getNameWithState() << " intersects previous part " << (*prev_part)->getNameWithState()); } prev_part = ∂ diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp index a893a8d26d3..d8e35552065 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp @@ -38,6 +38,7 @@ namespace ErrorCodes extern const int FORMAT_VERSION_TOO_OLD; extern const int UNKNOWN_FORMAT; extern const int UNEXPECTED_FILE_IN_DATA_PART; + extern const int NOT_FOUND_EXPECTED_DATA_PART; } @@ -935,4 +936,16 @@ String MergeTreeDataPart::stateString() const return stateToString(state); } +void MergeTreeDataPart::assertState(const std::initializer_list & affordable_states) const +{ + if (!checkState(affordable_states)) + { + String states_str; + for (auto state : affordable_states) + states_str += stateToString(state) + " "; + + throw Exception("Unexpected state of part " + getNameWithState() + ". Expected: " + states_str, ErrorCodes::NOT_FOUND_EXPECTED_DATA_PART); + } +} + } diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataPart.h b/dbms/src/Storages/MergeTree/MergeTreeDataPart.h index 1863fcbc0f2..b767eb6414b 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataPart.h +++ b/dbms/src/Storages/MergeTree/MergeTreeDataPart.h @@ -190,17 +190,7 @@ struct MergeTreeDataPart } /// Throws an exception if state of the part is not in affordable_states - void assertState(const std::initializer_list & affordable_states) const - { - if (!checkState(affordable_states)) - { - String states_str; - for (auto state : affordable_states) - states_str += stateToString(state) + " "; - - throw Exception("Unexpected state of part " + getNameWithState() + ". Expected: " + states_str); - } - } + void assertState(const std::initializer_list & affordable_states) const; /// In comparison with lambdas, it is move assignable and could has several overloaded operator() struct StatesFilter @@ -327,4 +317,7 @@ private: void checkConsistency(bool require_part_metadata); }; + +using MergeTreeDataPartState = MergeTreeDataPart::State; + } diff --git a/dbms/src/Storages/StorageMergeTree.cpp b/dbms/src/Storages/StorageMergeTree.cpp index 035d01de38d..c11ee29b10a 100644 --- a/dbms/src/Storages/StorageMergeTree.cpp +++ b/dbms/src/Storages/StorageMergeTree.cpp @@ -68,7 +68,7 @@ StorageMergeTree::StorageMergeTree( } else { - data.clearOldParts(); + data.clearOldPartsFromFilesystem(); } /// Temporary directories contain incomplete results of merges (after forced restart) @@ -188,7 +188,7 @@ void StorageMergeTree::alter( if (primary_key_is_modified && supportsSampling()) throw Exception("MODIFY PRIMARY KEY only supported for tables without sampling key", ErrorCodes::BAD_ARGUMENTS); - MergeTreeData::DataParts parts = data.getAllDataParts(); + auto parts = data.getDataParts({MergeTreeDataPartState::PreCommitted, MergeTreeDataPartState::Committed, MergeTreeDataPartState::Outdated}); for (const MergeTreeData::DataPartPtr & part : parts) { if (auto transaction = data.alterDataPart(part, columns_for_parts, new_primary_key_ast, false)) @@ -291,7 +291,7 @@ bool StorageMergeTree::merge( /// Clear old parts. It does not matter to do it more frequently than each second. if (auto lock = time_after_previous_cleanup.lockTestAndRestartAfter(1)) { - data.clearOldParts(); + data.clearOldPartsFromFilesystem(); data.clearOldTemporaryDirectories(); } diff --git a/dbms/src/Storages/StorageReplicatedMergeTree.cpp b/dbms/src/Storages/StorageReplicatedMergeTree.cpp index 8e745721434..55f72ca520b 100644 --- a/dbms/src/Storages/StorageReplicatedMergeTree.cpp +++ b/dbms/src/Storages/StorageReplicatedMergeTree.cpp @@ -109,6 +109,7 @@ namespace ErrorCodes extern const int RECEIVED_ERROR_TOO_MANY_REQUESTS; extern const int TOO_MUCH_FETCHES; extern const int BAD_DATA_PART_NAME; + extern const int PART_IS_TEMPORARILY_LOCKED; } @@ -800,7 +801,7 @@ void StorageReplicatedMergeTree::checkParts(bool skip_sanity_checks) /// Parts in ZK. NameSet expected_parts(expected_parts_vec.begin(), expected_parts_vec.end()); - MergeTreeData::DataParts parts = data.getAllDataParts(); + auto parts = data.getDataParts({MergeTreeDataPartState::PreCommitted, MergeTreeDataPartState::Committed, MergeTreeDataPartState::Outdated}); /// Local parts that are not in ZK. MergeTreeData::DataParts unexpected_parts; @@ -1179,7 +1180,21 @@ bool StorageReplicatedMergeTree::executeLogEntry(const LogEntry & entry) if (!do_fetch) { merger.renameMergedTemporaryPart(part, parts, &transaction); - getZooKeeper()->multi(ops); /// After long merge, get fresh ZK handle, because previous session may be expired. + + /// Do not commit if the part is obsolete + if (!transaction.isEmpty()) + { + getZooKeeper()->multi(ops); /// After long merge, get fresh ZK handle, because previous session may be expired. + transaction.commit(); + } + + /** Removing old chunks from ZK and from the disk is delayed - see ReplicatedMergeTreeCleanupThread, clearOldParts. + */ + + /** With `ZCONNECTIONLOSS` or `ZOPERATIONTIMEOUT`, we can inadvertently roll back local changes to the parts. + * This is not a problem, because in this case the merge will remain in the queue, and we will try again. + */ + merge_selecting_event.set(); if (auto part_log = context.getPartLog(database_name, table_name)) { @@ -1212,15 +1227,6 @@ bool StorageReplicatedMergeTree::executeLogEntry(const LogEntry & entry) } } - /** Removing old chunks from ZK and from the disk is delayed - see ReplicatedMergeTreeCleanupThread, clearOldParts. - */ - - /** With `ZCONNECTIONLOSS` or `ZOPERATIONTIMEOUT`, we can inadvertently roll back local changes to the parts. - * This is not a problem, because in this case the merge will remain in the queue, and we will try again. - */ - transaction.commit(); - merge_selecting_event.set(); - ProfileEvents::increment(ProfileEvents::ReplicatedPartMerges); } } @@ -1443,8 +1449,9 @@ void StorageReplicatedMergeTree::executeDropRange(const StorageReplicatedMergeTr /// It's important that no old parts remain (after the merge), because otherwise, /// after adding a new replica, this new replica downloads them, but does not delete them. /// And, if you do not, the parts will come to life after the server is restarted. - /// Therefore, we use getAllDataParts. - auto parts = data.getAllDataParts(); + /// Therefore, we use all data parts. + auto parts = data.getDataParts({MergeTreeDataPartState::PreCommitted, MergeTreeDataPartState::Committed, MergeTreeDataPartState::Outdated}); + for (const auto & part : parts) { if (!entry_part_info.contains(part->info)) @@ -1616,6 +1623,11 @@ bool StorageReplicatedMergeTree::queueTask() /// Interrupted merge or downloading a part is not an error. LOG_INFO(log, e.message()); } + else if (e.code() == ErrorCodes::PART_IS_TEMPORARILY_LOCKED) + { + /// Part cannot be added temporarily + LOG_INFO(log, e.displayText()); + } else tryLogCurrentException(__PRETTY_FUNCTION__); @@ -2205,6 +2217,13 @@ bool StorageReplicatedMergeTree::fetchPart(const String & part_name, const Strin MergeTreeData::Transaction transaction; auto removed_parts = data.renameTempPartAndReplace(part, nullptr, &transaction); + /// Do not commit if the part is obsolete + if (!transaction.isEmpty()) + { + getZooKeeper()->multi(ops); + transaction.commit(); + } + if (auto part_log = context.getPartLog(database_name, table_name)) { PartLogElement elem; @@ -2236,10 +2255,6 @@ bool StorageReplicatedMergeTree::fetchPart(const String & part_name, const Strin } } - - getZooKeeper()->multi(ops); - transaction.commit(); - /** If a quorum is tracked for this part, you must update it. * If you do not have time, in case of losing the session, when you restart the server - see the `ReplicatedMergeTreeRestartingThread::updateQuorumIfWeHavePart` method. */ diff --git a/dbms/src/Storages/System/StorageSystemParts.cpp b/dbms/src/Storages/System/StorageSystemParts.cpp index aba6db5fbbc..02cad078f02 100644 --- a/dbms/src/Storages/System/StorageSystemParts.cpp +++ b/dbms/src/Storages/System/StorageSystemParts.cpp @@ -39,7 +39,7 @@ StorageSystemParts::StorageSystemParts(const std::string & name_) {"database", std::make_shared()}, {"table", std::make_shared()}, - {"engine", std::make_shared()}, + {"engine", std::make_shared()} } { } @@ -53,9 +53,12 @@ BlockInputStreams StorageSystemParts::read( const size_t max_block_size, const unsigned num_streams) { - check(column_names); + //check(column_names); processed_stage = QueryProcessingStage::FetchColumns; + auto it_state_column = std::find(column_names.begin(), column_names.end(), "_state"); + bool has_state_column = it_state_column != column_names.end(); + /// Will apply WHERE to subset of columns and then add more columns. /// This is kind of complicated, but we use WHERE to do less work. @@ -142,6 +145,8 @@ BlockInputStreams StorageSystemParts::read( /// Finally, create the result. Block block = getSampleBlock(); + if (has_state_column) + block.insert(ColumnWithTypeAndName(std::make_shared(), "_state")); for (size_t i = 0; i < filtered_database_column->size();) { @@ -198,10 +203,18 @@ BlockInputStreams StorageSystemParts::read( using State = MergeTreeDataPart::State; MergeTreeData::DataPartStateVector all_parts_state; MergeTreeData::DataPartsVector all_parts; + if (need[0]) - all_parts = data->getDataPartsVector({State::Committed, State::Outdated}, all_parts_state); + { + /// If has_state_column is requested, return all states + if (!has_state_column) + all_parts = data->getDataPartsVector({State::Committed, State::Outdated}, &all_parts_state); + else + all_parts = data->getAllDataPartsVector(&all_parts_state); + } else - all_parts = data->getDataPartsVector({State::Committed}, all_parts_state); + all_parts = data->getDataPartsVector({State::Committed}, &all_parts_state); + /// Finally, we'll go through the list of parts. for (size_t part_number = 0; part_number < all_parts.size(); ++part_number) @@ -248,11 +261,30 @@ BlockInputStreams StorageSystemParts::read( block.getByPosition(i++).column->insert(database); block.getByPosition(i++).column->insert(table); block.getByPosition(i++).column->insert(engine); + + if (has_state_column) + block.getByPosition(i++).column->insert(part->stateString()); } } return BlockInputStreams(1, std::make_shared(block)); } +NameAndTypePair StorageSystemParts::getColumn(const String & column_name) const +{ + if (column_name == "_state") + return NameAndTypePair("_state", std::make_shared()); + + return ITableDeclaration::getColumn(column_name); +} + +bool StorageSystemParts::hasColumn(const String & column_name) const +{ + if (column_name == "_state") + return true; + + return ITableDeclaration::hasColumn(column_name); +} + } diff --git a/dbms/src/Storages/System/StorageSystemParts.h b/dbms/src/Storages/System/StorageSystemParts.h index 17c6a7f4e5c..09b14d72e56 100644 --- a/dbms/src/Storages/System/StorageSystemParts.h +++ b/dbms/src/Storages/System/StorageSystemParts.h @@ -21,6 +21,10 @@ public: const NamesAndTypesList & getColumnsListImpl() const override { return columns; } + NameAndTypePair getColumn(const String & column_name) const override; + + bool hasColumn(const String & column_name) const override; + BlockInputStreams read( const Names & column_names, const SelectQueryInfo & query_info, diff --git a/dbms/src/Storages/tests/gtest_range_filtered.cpp b/dbms/src/Storages/tests/gtest_range_filtered.cpp deleted file mode 100644 index 1a3b82f1a68..00000000000 --- a/dbms/src/Storages/tests/gtest_range_filtered.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include -#include - - -TEST(RangeFiltered, simple) -{ - std::vector v; - - for (int i = 0; i < 10; ++i) - v.push_back(i); - - auto v30 = createRangeFiltered([] (int i) { return i % 3 == 0; }, v); - auto v31 = createRangeFiltered([] (int i) { return i % 3 != 0; }, v); - - for (const int & i : v30) - ASSERT_EQ(i % 3, 0); - - for (const int & i : v31) - ASSERT_NE(i % 3, 0); - - { - auto it = v30.begin(); - ASSERT_EQ(*it, 0); - - auto it2 = std::next(it); - ASSERT_EQ(*it2, 3); - - it = std::next(it2); - ASSERT_EQ(*it, 6); - } - - { - auto it = std::next(v30.begin()); - ASSERT_EQ(*it, 3); - - *it = 2; /// it becomes invalid - ASSERT_EQ(*(++it), 6); /// but iteration is sucessfull - - *v30.begin() = 1; - ASSERT_EQ(*v30.begin(), 6); - } -} diff --git a/dbms/tests/integration/test_random_inserts/test.py b/dbms/tests/integration/test_random_inserts/test.py index d9325c91191..bfa5c451f44 100644 --- a/dbms/tests/integration/test_random_inserts/test.py +++ b/dbms/tests/integration/test_random_inserts/test.py @@ -26,6 +26,7 @@ def started_cluster(): pass cluster.shutdown() + def test_random_inserts(started_cluster): # Duration of the test, reduce it if don't want to wait DURATION_SECONDS = 10# * 60 @@ -55,7 +56,9 @@ def test_random_inserts(started_cluster): inserter.get_answer() answer="{}\t{}\t{}\t{}\n".format(num_timestamps, num_timestamps, min_timestamp, max_timestamp) + for node in nodes: - assert TSV(node.query("SELECT count(), uniqExact(i), min(i), max(i) FROM simple")) == TSV(answer), node.name + " : " + node.query("SELECT groupArray(_part), i, count() AS c FROM simple GROUP BY i ORDER BY c DESC LIMIT 1") + res = node.query("SELECT count(), uniqExact(i), min(i), max(i) FROM simple") + assert TSV(res) == TSV(answer), node.name + " : " + node.query("SELECT groupArray(_part), i, count() AS c FROM simple GROUP BY i ORDER BY c DESC LIMIT 1") node1.query("""DROP TABLE simple ON CLUSTER test_cluster""") diff --git a/dbms/tests/integration/test_random_inserts/test.sh b/dbms/tests/integration/test_random_inserts/test.sh index d743ffe4e91..006ee673fe9 100755 --- a/dbms/tests/integration/test_random_inserts/test.sh +++ b/dbms/tests/integration/test_random_inserts/test.sh @@ -4,6 +4,7 @@ [[ -n "$1" ]] && host="$1" || host="127.0.0.1" [[ -n "$2" ]] && min_timestamp="$2" || min_timestamp=$(( $(date +%s) - 10 )) [[ -n "$3" ]] && max_timestamp="$3" || max_timestamp=$(( $(date +%s) + 10 )) +[[ -n "$4" ]] && iters_per_timestamp="$4" || iters_per_timestamp=1 timestamps=`seq $min_timestamp $max_timestamp` @@ -40,6 +41,6 @@ for i in $timestamps; do cur_timestamp=$(date +%s) done - #echo $i >> $host".txt" reliable_insert "$i" -done \ No newline at end of file +done +sleep 1 diff --git a/libs/libcommon/include/common/RangeFiltered.h b/libs/libcommon/include/common/RangeFiltered.h deleted file mode 100644 index cdb8f902409..00000000000 --- a/libs/libcommon/include/common/RangeFiltered.h +++ /dev/null @@ -1,127 +0,0 @@ -#pragma once -#include - - -/// Similar to boost::filtered_range but a little bit easier and allows to convert ordinary iterators to filtered -template -struct RangeFiltered -{ - /// Template parameter C may be const. Then const_iterator is used. - using RawIterator = decltype(std::declval().begin()); - class Iterator; - - /// Will iterate over elements for which filter(*it) == true - template /// Another template for universal references to work. - RangeFiltered(F_ && filter, C_ && container) - : filter(std::move(filter)), container(container) {} - - Iterator begin() const - { - return Iterator{*this, std::begin(container)}; - } - - Iterator end() const - { - return Iterator{*this, std::end(container)}; - } - - /// Convert ordinary iterator to filtered one - /// Real position will be in range [ordinary_iterator; end()], so it is suitable to use with lower[upper]_bound() - inline Iterator convert(RawIterator ordinary_iterator) const - { - return Iterator{*this, ordinary_iterator}; - } - - - /// It is similar to boost::filtered_iterator, but has additional features: - /// it doesn't store end() iterator - /// it doesn't store predicate, so it allows to implement operator=() - /// it guarantees that operator++() works properly in case of filter(*it) == false - class Iterator - { - public: - using Range = RangeFiltered; - - typedef Iterator self_type; - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::reference reference; - typedef const value_type & const_reference; - typedef typename std::iterator_traits::pointer pointer; - typedef const value_type * const_pointer; - typedef typename std::iterator_traits::difference_type difference_type; - typedef std::bidirectional_iterator_tag iterator_category; - - Iterator(const Range & range_, RawIterator iter_) - : range(&range_), iter(iter_) - { - for (; iter != std::end(range->container) && !range->filter(*iter); ++iter); - } - - Iterator(const Iterator & rhs) = default; - Iterator(Iterator && rhs) noexcept = default; - - Iterator operator++() - { - ++iter; - for (; iter != std::end(range->container) && !range->filter(*iter); ++iter); - return *this; - } - - Iterator operator--() - { - --iter; - for (; !range->filter(*iter); --iter); /// Don't check std::begin() bound - return *this; - } - - pointer operator->() - { - return iter.operator->(); - } - - const_pointer operator->() const - { - return iter.operator->(); - } - - reference operator*() - { - return *iter; - } - - const_reference operator*() const - { - return *iter; - } - - bool operator==(const self_type & rhs) const - { - return iter == rhs.iter; - } - - bool operator!=(const self_type & rhs) const - { - return iter != rhs.iter; - } - - self_type & operator=(const self_type & rhs) = default; - self_type & operator=(self_type && rhs) noexcept = default; - - ~Iterator() = default; - - private: - const Range * range = nullptr; - RawIterator iter; - }; - -protected: - F filter; - C & container; -}; - - -template -inline RangeFiltered, std::remove_reference_t> createRangeFiltered(F && filter, C && container) -{ - return {std::forward(filter), std::forward(container)}; -}; From 2afbd8bceebeb4422009e4f48b3e6581a2737b3c Mon Sep 17 00:00:00 2001 From: Vitaliy Lyudvichenko Date: Wed, 29 Nov 2017 14:54:37 +0300 Subject: [PATCH 0005/1165] Small enhancements. [#CLICKHOUSE-3452] --- .../MergeTree/MergeTreeDataMerger.cpp | 2 +- .../Storages/System/StorageSystemParts.cpp | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataMerger.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataMerger.cpp index cc8094b8ee5..280e1cc30a6 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataMerger.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataMerger.cpp @@ -187,7 +187,7 @@ bool MergeTreeDataMerger::selectPartsToMerge( if (prev_part && part->info.partition_id == (*prev_part)->info.partition_id && part->info.min_block < (*prev_part)->info.max_block) { - LOG_ERROR(log, "Part " << part->getNameWithState() << " intersects previous part " << (*prev_part)->getNameWithState()); + LOG_ERROR(log, "Part " << part->name << " intersects previous part " << (*prev_part)->name); } prev_part = ∂ diff --git a/dbms/src/Storages/System/StorageSystemParts.cpp b/dbms/src/Storages/System/StorageSystemParts.cpp index 02cad078f02..91c03f58b4b 100644 --- a/dbms/src/Storages/System/StorageSystemParts.cpp +++ b/dbms/src/Storages/System/StorageSystemParts.cpp @@ -53,11 +53,22 @@ BlockInputStreams StorageSystemParts::read( const size_t max_block_size, const unsigned num_streams) { - //check(column_names); - processed_stage = QueryProcessingStage::FetchColumns; + bool has_state_column = false; + Names real_column_names; - auto it_state_column = std::find(column_names.begin(), column_names.end(), "_state"); - bool has_state_column = it_state_column != column_names.end(); + for (const String & column_name : column_names) + { + if (column_name == "_state") + has_state_column = true; + else + real_column_names.emplace_back(column_name); + } + + /// Do not check if only _state column is requested + if (!(has_state_column && real_column_names.empty())) + check(real_column_names); + + processed_stage = QueryProcessingStage::FetchColumns; /// Will apply WHERE to subset of columns and then add more columns. /// This is kind of complicated, but we use WHERE to do less work. From 616697f14f404e119aff317680ed57d144aed741 Mon Sep 17 00:00:00 2001 From: proller Date: Tue, 21 Nov 2017 19:18:18 +0300 Subject: [PATCH 0006/1165] Zlib-ng: enable zlib compat mode (this fixes log compression) (#CLICKHOUSE-3447) --- cmake/find_zlib.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/find_zlib.cmake b/cmake/find_zlib.cmake index bbfc75e5e24..93e62497c25 100644 --- a/cmake/find_zlib.cmake +++ b/cmake/find_zlib.cmake @@ -6,6 +6,7 @@ endif () if (NOT ZLIB_FOUND) set (USE_INTERNAL_ZLIB_LIBRARY 1) + set (ZLIB_COMPAT 1) # for zlib-ng, also enables WITH_GZFILEOP set (ZLIB_INCLUDE_DIR "${ClickHouse_SOURCE_DIR}/contrib/libzlib-ng" "${ClickHouse_BINARY_DIR}/contrib/libzlib-ng") # generated zconf.h set (ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR}) # for poco set (ZLIB_FOUND 1) # for poco From 8d3bc22fed080e20474df0e65c75fd0cad6deaa0 Mon Sep 17 00:00:00 2001 From: proller Date: Tue, 21 Nov 2017 20:46:28 +0300 Subject: [PATCH 0007/1165] Zlib: as submodule, fix compile options; config: add logger options: logger.flush logger.rotateOnOpen Conflicts: .gitmodules dbms/src/Common/BackgroundSchedulePool.h --- .gitmodules | 3 +++ contrib/CMakeLists.txt | 6 +++++- contrib/zlib-ng | 1 + libs/libdaemon/src/BaseDaemon.cpp | 24 ++++++++++++++---------- 4 files changed, 23 insertions(+), 11 deletions(-) create mode 160000 contrib/zlib-ng diff --git a/.gitmodules b/.gitmodules index 87f07998f35..fc08ca60275 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "contrib/librdkafka"] path = contrib/librdkafka url = https://github.com/edenhill/librdkafka.git +[submodule "contrib/zlib-ng"] + path = contrib/zlib-ng + url = https://github.com/Dead2/zlib-ng.git diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index f21bee5d979..137eea988bc 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -45,7 +45,11 @@ if (USE_INTERNAL_UNWIND_LIBRARY) endif () if (USE_INTERNAL_ZLIB_LIBRARY) - add_subdirectory (libzlib-ng) + add_subdirectory (zlib-ng) + # todo: make pull to Dead2/zlib-ng and remove: + # We should use same defines when including zlib.h as used when zlib compiled + target_compile_definitions (zlib PUBLIC ZLIB_COMPAT WITH_GZFILEOP) + target_compile_definitions (zlibstatic PUBLIC ZLIB_COMPAT WITH_GZFILEOP) endif () if (USE_INTERNAL_CCTZ_LIBRARY) diff --git a/contrib/zlib-ng b/contrib/zlib-ng new file mode 160000 index 00000000000..e07a52dbaa3 --- /dev/null +++ b/contrib/zlib-ng @@ -0,0 +1 @@ +Subproject commit e07a52dbaa35d003f5659b221b29d220c091667b diff --git a/libs/libdaemon/src/BaseDaemon.cpp b/libs/libdaemon/src/BaseDaemon.cpp index bf6a0a778de..4b8f1e8d766 100644 --- a/libs/libdaemon/src/BaseDaemon.cpp +++ b/libs/libdaemon/src/BaseDaemon.cpp @@ -604,11 +604,13 @@ void BaseDaemon::buildLoggers() pf->setProperty("times", "local"); Poco::AutoPtr log = new FormattingChannel(pf); log_file = new FileChannel; - log_file->setProperty("path", Poco::Path(config().getString("logger.log")).absolute().toString()); - log_file->setProperty("rotation", config().getRawString("logger.size", "100M")); - log_file->setProperty("archive", "number"); - log_file->setProperty("compress", config().getRawString("logger.compress", "true")); - log_file->setProperty("purgeCount", config().getRawString("logger.count", "1")); + log_file->setProperty(Poco::FileChannel::PROP_PATH, Poco::Path(config().getString("logger.log")).absolute().toString()); + log_file->setProperty(Poco::FileChannel::PROP_ROTATION, config().getRawString("logger.size", "100M")); + log_file->setProperty(Poco::FileChannel::PROP_ARCHIVE, "number"); + log_file->setProperty(Poco::FileChannel::PROP_COMPRESS, config().getRawString("logger.compress", "true")); + log_file->setProperty(Poco::FileChannel::PROP_PURGECOUNT, config().getRawString("logger.count", "1")); + log_file->setProperty(Poco::FileChannel::PROP_FLUSH, config().getRawString("logger.flush", "true")); + log_file->setProperty(Poco::FileChannel::PROP_ROTATEONOPEN, config().getRawString("logger.rotateOnOpen", "false")); log->setChannel(log_file); split->addChannel(log); log_file->open(); @@ -622,11 +624,13 @@ void BaseDaemon::buildLoggers() pf->setProperty("times", "local"); Poco::AutoPtr errorlog = new FormattingChannel(pf); error_log_file = new FileChannel; - error_log_file->setProperty("path", Poco::Path(config().getString("logger.errorlog")).absolute().toString()); - error_log_file->setProperty("rotation", config().getRawString("logger.size", "100M")); - error_log_file->setProperty("archive", "number"); - error_log_file->setProperty("compress", config().getRawString("logger.compress", "true")); - error_log_file->setProperty("purgeCount", config().getRawString("logger.count", "1")); + error_log_file->setProperty(Poco::FileChannel::PROP_PATH, Poco::Path(config().getString("logger.errorlog")).absolute().toString()); + error_log_file->setProperty(Poco::FileChannel::PROP_ROTATION, config().getRawString("logger.size", "100M")); + error_log_file->setProperty(Poco::FileChannel::PROP_ARCHIVE, "number"); + error_log_file->setProperty(Poco::FileChannel::PROP_COMPRESS, config().getRawString("logger.compress", "true")); + error_log_file->setProperty(Poco::FileChannel::PROP_PURGECOUNT, config().getRawString("logger.count", "1")); + error_log_file->setProperty(Poco::FileChannel::PROP_FLUSH, config().getRawString("logger.flush", "true")); + error_log_file->setProperty(Poco::FileChannel::PROP_ROTATEONOPEN, config().getRawString("logger.rotateOnOpen", "false")); errorlog->setChannel(error_log_file); level->setChannel(errorlog); split->addChannel(level); From 00d8ff3ced8d4f723ae1196b36f95b7dd16ecada Mon Sep 17 00:00:00 2001 From: proller Date: Wed, 22 Nov 2017 00:21:22 +0300 Subject: [PATCH 0008/1165] Remove old contrib/libzlib-ng --- contrib/libzlib-ng/.gitignore | 52 - contrib/libzlib-ng/.travis.yml | 12 - contrib/libzlib-ng/CMakeLists.txt | 563 ---- contrib/libzlib-ng/ChangeLog.zlib | 1478 ---------- contrib/libzlib-ng/FAQ.zlib | 374 --- contrib/libzlib-ng/INDEX | 55 - contrib/libzlib-ng/LICENSE.md | 19 - contrib/libzlib-ng/Makefile.in | 329 --- contrib/libzlib-ng/README | 63 - contrib/libzlib-ng/README.clickhouse | 12 - contrib/libzlib-ng/README.md | 65 - contrib/libzlib-ng/README.zlib | 121 - contrib/libzlib-ng/adler32.c | 177 -- contrib/libzlib-ng/arch/.gitignore | 2 - contrib/libzlib-ng/arch/arm/Makefile.in | 20 - contrib/libzlib-ng/arch/generic/Makefile.in | 20 - contrib/libzlib-ng/arch/x86/INDEX | 3 - contrib/libzlib-ng/arch/x86/Makefile.in | 53 - contrib/libzlib-ng/arch/x86/crc_folding.c | 465 ---- contrib/libzlib-ng/arch/x86/deflate_quick.c | 2371 ----------------- contrib/libzlib-ng/arch/x86/fill_window_sse.c | 165 -- .../libzlib-ng/arch/x86/insert_string_sse.c | 50 - contrib/libzlib-ng/arch/x86/x86.c | 53 - contrib/libzlib-ng/arch/x86/x86.h | 23 - contrib/libzlib-ng/compress.c | 74 - contrib/libzlib-ng/configure | 923 ------- contrib/libzlib-ng/crc32.c | 458 ---- contrib/libzlib-ng/crc32.h | 444 --- contrib/libzlib-ng/deflate.c | 1407 ---------- contrib/libzlib-ng/deflate.h | 459 ---- contrib/libzlib-ng/deflate_fast.c | 114 - contrib/libzlib-ng/deflate_medium.c | 322 --- contrib/libzlib-ng/deflate_p.h | 96 - contrib/libzlib-ng/deflate_slow.c | 160 -- contrib/libzlib-ng/doc/algorithm.txt | 209 -- contrib/libzlib-ng/doc/rfc1950.txt | 619 ----- contrib/libzlib-ng/doc/rfc1951.txt | 955 ------- contrib/libzlib-ng/doc/rfc1952.txt | 675 ----- contrib/libzlib-ng/doc/txtvsbin.txt | 107 - contrib/libzlib-ng/gzclose.c | 23 - contrib/libzlib-ng/gzguts.h | 158 -- contrib/libzlib-ng/gzlib.c | 518 ---- contrib/libzlib-ng/gzread.c | 538 ---- contrib/libzlib-ng/gzwrite.c | 457 ---- contrib/libzlib-ng/infback.c | 612 ----- contrib/libzlib-ng/inffast.c | 328 --- contrib/libzlib-ng/inffast.h | 15 - contrib/libzlib-ng/inffixed.h | 94 - contrib/libzlib-ng/inflate.c | 1467 ---------- contrib/libzlib-ng/inflate.h | 127 - contrib/libzlib-ng/inftrees.c | 298 --- contrib/libzlib-ng/inftrees.h | 66 - contrib/libzlib-ng/match.c | 471 ---- contrib/libzlib-ng/match.h | 6 - contrib/libzlib-ng/test/.gitignore | 2 - contrib/libzlib-ng/test/CVE-2002-0059/test.gz | Bin 4610 -> 0 bytes contrib/libzlib-ng/test/CVE-2003-0107.c | 20 - contrib/libzlib-ng/test/CVE-2004-0797/test.gz | Bin 52 -> 0 bytes contrib/libzlib-ng/test/CVE-2005-1849/test.gz | Bin 52 -> 0 bytes contrib/libzlib-ng/test/CVE-2005-2096/test.gz | Bin 52 -> 0 bytes contrib/libzlib-ng/test/INDEX | 10 - contrib/libzlib-ng/test/Makefile.in | 77 - contrib/libzlib-ng/test/example.c | 544 ---- contrib/libzlib-ng/test/infcover.c | 668 ----- contrib/libzlib-ng/test/minigzip.c | 530 ---- contrib/libzlib-ng/test/testCVEinputs.sh | 22 - contrib/libzlib-ng/treebuild.xml | 116 - contrib/libzlib-ng/trees.c | 1119 -------- contrib/libzlib-ng/trees.h | 132 - contrib/libzlib-ng/uncompr.c | 75 - contrib/libzlib-ng/win32/DLL_FAQ.txt | 397 --- contrib/libzlib-ng/win32/Makefile.msc | 154 -- contrib/libzlib-ng/win32/README-WIN32.txt | 103 - contrib/libzlib-ng/win32/VisualC.txt | 3 - contrib/libzlib-ng/win32/zlib.def | 55 - contrib/libzlib-ng/win32/zlib1.rc | 40 - contrib/libzlib-ng/win32/zlibcompat.def | 86 - contrib/libzlib-ng/zconf.h.in | 176 -- contrib/libzlib-ng/zlib.3 | 169 -- contrib/libzlib-ng/zlib.3.pdf | Bin 8734 -> 0 bytes contrib/libzlib-ng/zlib.h | 1728 ------------ contrib/libzlib-ng/zlib.map | 83 - contrib/libzlib-ng/zlib.pc.cmakein | 13 - contrib/libzlib-ng/zlib.pc.in | 13 - contrib/libzlib-ng/zutil.c | 124 - contrib/libzlib-ng/zutil.h | 185 -- 86 files changed, 25389 deletions(-) delete mode 100644 contrib/libzlib-ng/.gitignore delete mode 100644 contrib/libzlib-ng/.travis.yml delete mode 100644 contrib/libzlib-ng/CMakeLists.txt delete mode 100644 contrib/libzlib-ng/ChangeLog.zlib delete mode 100644 contrib/libzlib-ng/FAQ.zlib delete mode 100644 contrib/libzlib-ng/INDEX delete mode 100644 contrib/libzlib-ng/LICENSE.md delete mode 100644 contrib/libzlib-ng/Makefile.in delete mode 100644 contrib/libzlib-ng/README delete mode 100644 contrib/libzlib-ng/README.clickhouse delete mode 100644 contrib/libzlib-ng/README.md delete mode 100644 contrib/libzlib-ng/README.zlib delete mode 100644 contrib/libzlib-ng/adler32.c delete mode 100644 contrib/libzlib-ng/arch/.gitignore delete mode 100644 contrib/libzlib-ng/arch/arm/Makefile.in delete mode 100644 contrib/libzlib-ng/arch/generic/Makefile.in delete mode 100644 contrib/libzlib-ng/arch/x86/INDEX delete mode 100644 contrib/libzlib-ng/arch/x86/Makefile.in delete mode 100644 contrib/libzlib-ng/arch/x86/crc_folding.c delete mode 100644 contrib/libzlib-ng/arch/x86/deflate_quick.c delete mode 100644 contrib/libzlib-ng/arch/x86/fill_window_sse.c delete mode 100644 contrib/libzlib-ng/arch/x86/insert_string_sse.c delete mode 100644 contrib/libzlib-ng/arch/x86/x86.c delete mode 100644 contrib/libzlib-ng/arch/x86/x86.h delete mode 100644 contrib/libzlib-ng/compress.c delete mode 100755 contrib/libzlib-ng/configure delete mode 100644 contrib/libzlib-ng/crc32.c delete mode 100644 contrib/libzlib-ng/crc32.h delete mode 100644 contrib/libzlib-ng/deflate.c delete mode 100644 contrib/libzlib-ng/deflate.h delete mode 100644 contrib/libzlib-ng/deflate_fast.c delete mode 100644 contrib/libzlib-ng/deflate_medium.c delete mode 100644 contrib/libzlib-ng/deflate_p.h delete mode 100644 contrib/libzlib-ng/deflate_slow.c delete mode 100644 contrib/libzlib-ng/doc/algorithm.txt delete mode 100644 contrib/libzlib-ng/doc/rfc1950.txt delete mode 100644 contrib/libzlib-ng/doc/rfc1951.txt delete mode 100644 contrib/libzlib-ng/doc/rfc1952.txt delete mode 100644 contrib/libzlib-ng/doc/txtvsbin.txt delete mode 100644 contrib/libzlib-ng/gzclose.c delete mode 100644 contrib/libzlib-ng/gzguts.h delete mode 100644 contrib/libzlib-ng/gzlib.c delete mode 100644 contrib/libzlib-ng/gzread.c delete mode 100644 contrib/libzlib-ng/gzwrite.c delete mode 100644 contrib/libzlib-ng/infback.c delete mode 100644 contrib/libzlib-ng/inffast.c delete mode 100644 contrib/libzlib-ng/inffast.h delete mode 100644 contrib/libzlib-ng/inffixed.h delete mode 100644 contrib/libzlib-ng/inflate.c delete mode 100644 contrib/libzlib-ng/inflate.h delete mode 100644 contrib/libzlib-ng/inftrees.c delete mode 100644 contrib/libzlib-ng/inftrees.h delete mode 100644 contrib/libzlib-ng/match.c delete mode 100644 contrib/libzlib-ng/match.h delete mode 100644 contrib/libzlib-ng/test/.gitignore delete mode 100644 contrib/libzlib-ng/test/CVE-2002-0059/test.gz delete mode 100644 contrib/libzlib-ng/test/CVE-2003-0107.c delete mode 100644 contrib/libzlib-ng/test/CVE-2004-0797/test.gz delete mode 100644 contrib/libzlib-ng/test/CVE-2005-1849/test.gz delete mode 100644 contrib/libzlib-ng/test/CVE-2005-2096/test.gz delete mode 100644 contrib/libzlib-ng/test/INDEX delete mode 100644 contrib/libzlib-ng/test/Makefile.in delete mode 100644 contrib/libzlib-ng/test/example.c delete mode 100644 contrib/libzlib-ng/test/infcover.c delete mode 100644 contrib/libzlib-ng/test/minigzip.c delete mode 100755 contrib/libzlib-ng/test/testCVEinputs.sh delete mode 100644 contrib/libzlib-ng/treebuild.xml delete mode 100644 contrib/libzlib-ng/trees.c delete mode 100644 contrib/libzlib-ng/trees.h delete mode 100644 contrib/libzlib-ng/uncompr.c delete mode 100644 contrib/libzlib-ng/win32/DLL_FAQ.txt delete mode 100644 contrib/libzlib-ng/win32/Makefile.msc delete mode 100644 contrib/libzlib-ng/win32/README-WIN32.txt delete mode 100644 contrib/libzlib-ng/win32/VisualC.txt delete mode 100644 contrib/libzlib-ng/win32/zlib.def delete mode 100644 contrib/libzlib-ng/win32/zlib1.rc delete mode 100644 contrib/libzlib-ng/win32/zlibcompat.def delete mode 100644 contrib/libzlib-ng/zconf.h.in delete mode 100644 contrib/libzlib-ng/zlib.3 delete mode 100644 contrib/libzlib-ng/zlib.3.pdf delete mode 100644 contrib/libzlib-ng/zlib.h delete mode 100644 contrib/libzlib-ng/zlib.map delete mode 100644 contrib/libzlib-ng/zlib.pc.cmakein delete mode 100644 contrib/libzlib-ng/zlib.pc.in delete mode 100644 contrib/libzlib-ng/zutil.c delete mode 100644 contrib/libzlib-ng/zutil.h diff --git a/contrib/libzlib-ng/.gitignore b/contrib/libzlib-ng/.gitignore deleted file mode 100644 index 0beb44b722a..00000000000 --- a/contrib/libzlib-ng/.gitignore +++ /dev/null @@ -1,52 +0,0 @@ -*.diff -*.patch -*.orig -*.rej - -*~ -*.a -*.lo -*.o -*.dylib - -*.gcda -*.gcno -*.gcov - -/example -/example64 -/examplesh -/libz.so* -/minigzip -/minigzip64 -/minigzipsh -/zlib.pc -/CVE-2003-0107 - -.DS_Store -*.obj -*.exe -*.pdb -*.exp -*.lib -*.dll -*.res -foo.gz -*.manifest - -CMakeCache.txt -CMakeFiles -Testing -*.cmake -*.stackdump -zconf.h -zconf.h.cmakein -zconf.h.included -ztest* - -configure.log -a.out - -/arch/arm/Makefile -/arch/generic/Makefile -/arch/x86/Makefile diff --git a/contrib/libzlib-ng/.travis.yml b/contrib/libzlib-ng/.travis.yml deleted file mode 100644 index 6080169cf68..00000000000 --- a/contrib/libzlib-ng/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: c -compiler: - - gcc - - clang -env: - - BUILDDIR=. TOOL="./configure --zlib-compat" - - BUILDDIR=../build TOOL="../zlib-ng/configure --zlib-compat" - - BUILDDIR=. TOOL="./configure --zlib-compat --without-optimizations --without-new-strategies" - - BUILDDIR=. TOOL="cmake ." - - BUILDDIR=../build TOOL="cmake ../zlib-ng" -script: mkdir -p $BUILDDIR && cd $BUILDDIR && - $TOOL && make && make test diff --git a/contrib/libzlib-ng/CMakeLists.txt b/contrib/libzlib-ng/CMakeLists.txt deleted file mode 100644 index 3d5be9eabf2..00000000000 --- a/contrib/libzlib-ng/CMakeLists.txt +++ /dev/null @@ -1,563 +0,0 @@ -cmake_minimum_required(VERSION 2.8.4) -set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) - -project(zlib C) - -set(VERSION "1.2.8") - -set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables") -set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries") -set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers") -set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages") -set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files") - -include(CheckTypeSize) -include(CheckSymbolExists) -include(CheckFunctionExists) -include(CheckIncludeFile) -include(CheckCSourceCompiles) -include(CheckCSourceRuns) -include(CheckLibraryExists) -include(FeatureSummary) - -# make sure we use an appropriate BUILD_TYPE by default, "Release" to be exact -# this should select the maximum generic optimisation on the current platform (i.e. -O3 for gcc/clang) -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE "Release" CACHE STRING - "Choose the type of build, standard options are: Debug Release RelWithDebInfo MinSizeRel." - FORCE) - add_feature_info(CMAKE_BUILD_TYPE 1 "Build type: ${CMAKE_BUILD_TYPE} (default)") -else() - add_feature_info(CMAKE_BUILD_TYPE 1 "Build type: ${CMAKE_BUILD_TYPE} (selected)") -endif() - -enable_testing() - -check_include_file(sys/types.h HAVE_SYS_TYPES_H) -check_include_file(stdint.h HAVE_STDINT_H) -check_include_file(stddef.h HAVE_STDDEF_H) - -# -# Options parsing -# -set(ARCH ${CMAKE_HOST_SYSTEM_PROCESSOR}) -message(STATUS "Architecture: ${ARCH}") - -option (ZLIB_COMPAT "Compile with zlib compatible API" OFF) -if (ZLIB_COMPAT) - add_definitions(-DZLIB_COMPAT) - set (WITH_GZFILEOP ON) -endif (ZLIB_COMPAT) - -option (WITH_GZFILEOP "Compile with support for gzFile related functions" OFF) -if (WITH_GZFILEOP) - add_definitions(-DWITH_GZFILEOP) -endif (WITH_GZFILEOP) - -option(WITH_OPTIM "Build with optimisation" ON) -option(WITH_NEW_QUICK_STRATEGY "Use new quick strategy for compression level 1" OFF) # this option produces corrupt gzip stream so turn it off for now. -option(WITH_NEW_MEDIUM_STRATEGY "Use new medium strategy for compression levels 4-6" ON) -option(WITH_NATIVE_INSTRUCTIONS - "Instruct the compiler to use the full instruction set on this host (gcc/clang -march=native)" OFF) - -if(${CMAKE_C_COMPILER} MATCHES "icc" OR ${CMAKE_C_COMPILER} MATCHES "icpc" OR ${CMAKE_C_COMPILER} MATCHES "icl") - if(WITH_NATIVE_INSTRUCTIONS) - message(STATUS "Ignoring WITH_NATIVE_INSTRUCTIONS; not supported on this configuration") - endif() - if(CMAKE_HOST_UNIX) - if(NOT SSE2FLAG) - set(SSE2FLAG "-msse2") - endif() - if(NOT SSE4FLAG) - set(SSE4FLAG "-msse4.2") - endif() - else() - if(NOT SSE2FLAG) - set(SSE2FLAG "/arch:SSE2") - endif() - if(NOT SSE4FLAG) - set(SSE4FLAG "/arch:SSE4.2") - endif() - endif() -elseif(MSVC) - # TODO. ICC can be used through MSVC. I'm not sure if we'd ever see that combination - # (who'd use cmake from an IDE...) but checking for ICC before checking for MSVC should - # avoid mistakes. - # /Oi ? - if(NOT ${ARCH} MATCHES "AMD64") - set(SSE2FLAG "/arch:SSE2") - endif() - if(WITH_NATIVE_INSTRUCTIONS) - message(STATUS "Ignoring WITH_NATIVE_INSTRUCTIONS; not supported on this configuration") - endif() -else() - execute_process(COMMAND ${CMAKE_C_COMPILER} --version OUTPUT_VARIABLE COMPILER_VERSION) - if("${COMPILER_VERSION}" MATCHES "gcc" OR "${COMPILER_VERSION}" MATCHES "clang") - set(__GNUC__ ON) - endif() - if(WITH_NATIVE_INSTRUCTIONS) - if(__GNUC__) - set(NATIVEFLAG "-march=native") - else() - message(STATUS "Ignoring WITH_NATIVE_INSTRUCTIONS; not implemented yet on this configuration") - endif() - endif() - if(NOT NATIVEFLAG) - if(NOT SSE2FLAG) - if(__GNUC__) - set(SSE2FLAG "-msse2") - endif() - endif() - if(NOT SSE4FLAG) - if(__GNUC__) - set(SSE4FLAG "-msse4") - endif() - endif() - if(NOT PCLMULFLAG) - if(__GNUC__) - set(PCLMULFLAG "-mpclmul") - endif() - endif() - else(NOT NATIVEFLAG) - set(SSE2FLAG ${NATIVEFLAG}) - set(SSE4FLAG ${NATIVEFLAG}) - set(PCLMULFLAG ${NATIVEFLAG}) - endif(NOT NATIVEFLAG) -endif() - -add_feature_info(ZLIB_COMPAT ZLIB_COMPAT "Provide a zlib-compatible API") -add_feature_info(WITH_GZFILEOP WITH_GZFILEOP "Compile with support for gzFile-related functions") -add_feature_info(WITH_OPTIM WITH_OPTIM "Build with optimisation") -add_feature_info(WITH_NEW_QUICK_STRATEGY WITH_NEW_QUICK_STRATEGY "Use new quick strategy for compression level 1") -add_feature_info(WITH_NEW_MEDIUM_STRATEGY WITH_NEW_MEDIUM_STRATEGY "Use new medium strategy for compression levels 4-6") - -# -# Check to see if we have large file support -# -set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1) -# We add these other definitions here because CheckTypeSize.cmake -# in CMake 2.4.x does not automatically do so and we want -# compatibility with CMake 2.4.x. -if(HAVE_SYS_TYPES_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H) -endif() -if(HAVE_STDINT_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H) -endif() -if(HAVE_STDDEF_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H) -endif() -check_type_size(off64_t OFF64_T) -if(HAVE_OFF64_T) - add_definitions(-D_LARGEFILE64_SOURCE=1) -else() - check_type_size(_off64_t _OFF64_T) - if (HAVE__OFF64_T) - add_definitions(-D_LARGEFILE64_SOURCE=1) - endif() -endif() -set(CMAKE_REQUIRED_DEFINITIONS) # clear variable - -# -# Check for fseeko and other optional functions -# -check_function_exists(fseeko HAVE_FSEEKO) -if(NOT HAVE_FSEEKO) - add_definitions(-DNO_FSEEKO) -endif() -check_function_exists(strerror HAVE_STRERROR) -if(NOT HAVE_STRERROR) - add_definitions(-DNO_STRERROR) -endif() - -# -# Check for unistd.h and stdarg.h -# -check_include_file(unistd.h Z_HAVE_UNISTD_H) -check_include_file(stdarg.h Z_HAVE_STDARG_H) - -# -# Check if we can hide zlib internal symbols that are linked between separate source files using hidden -# -check_c_source_compiles( - "#define ZLIB_INTERNAL __attribute__((visibility (\"hidden\"))) - int ZLIB_INTERNAL foo; - int main() - { - return 0; - }" - HAVE_ATTRIBUTE_VISIBILITY_HIDDEN FAIL_REGEX "not supported") -if(HAVE_ATTRIBUTE_VISIBILITY_HIDDEN) - add_definitions(-DHAVE_HIDDEN) -endif() - -# -# Check if we can hide zlib internal symbols that are linked between separate source files using internal -# -check_c_source_compiles( - "#define ZLIB_INTERNAL __attribute__((visibility (\"internal\"))) - int ZLIB_INTERNAL foo; - int main() - { - return 0; - }" - HAVE_ATTRIBUTE_VISIBILITY_INTERNAL FAIL_REGEX "not supported") -if(HAVE_ATTRIBUTE_VISIBILITY_INTERNAL) - add_definitions(-DHAVE_INTERNAL) -endif() - -# -# check for __builtin_ctzl() support in the compiler -# -check_c_source_compiles( - "int main(void) - { - unsigned int zero = 0; - long test = __builtin_ctzl(zero); - (void)test; - return 0; - }" - HAVE_BUILTIN_CTZL -) -if(HAVE_BUILTIN_CTZL) - add_definitions(-DHAVE_BUILTIN_CTZL) -endif() - -# Macro to check if source compiles when cross-compiling -# or runs when compiling natively -macro(check_c_source_compile_or_run source flag) - if(CMAKE_CROSSCOMPILING) - check_c_source_compiles("${source}" ${flag}) - else() - check_c_source_runs("${source}" ${flag}) - endif() -endmacro(check_c_source_compile_or_run) -if(MSVC) - set(CMAKE_DEBUG_POSTFIX "d") - add_definitions(-D_CRT_SECURE_NO_DEPRECATE) - add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -else() - # - # not MSVC, so we need to check if we have the MS-style SSE etc. intrinsics - # - if(WITH_NATIVE_INSTRUCTIONS) - set(CMAKE_REQUIRED_FLAGS "${NATIVEFLAG}") - else() - set(CMAKE_REQUIRED_FLAGS "${SSE2FLAG}") - endif() - check_c_source_compile_or_run( - "#include - int main(void) - { - __m128i zero = _mm_setzero_si128(); - (void)zero; - return 0; - }" - HAVE_SSE2_INTRIN - ) - if(WITH_NATIVE_INSTRUCTIONS) - set(CMAKE_REQUIRED_FLAGS "${NATIVEFLAG}") - else() - # use the generic SSE4 enabler option to check for the SSE4.2 instruction we require: - set(CMAKE_REQUIRED_FLAGS "${SSE4FLAG}") - endif() - check_c_source_compile_or_run( - "int main(void) - { - unsigned val = 0, h = 0; - __asm__ __volatile__ ( \"crc32 %1,%0\" : \"+r\" (h) : \"r\" (val) ); - return (int) h; - }" - HAVE_SSE42_INTRIN - ) - if(WITH_NATIVE_INSTRUCTIONS) - set(CMAKE_REQUIRED_FLAGS "${NATIVEFLAG}") - else() - # the PCLMUL instruction we use also requires an SSE4.1 instruction check for both - set(CMAKE_REQUIRED_FLAGS "${SSE4FLAG} ${PCLMULFLAG}") - endif() - check_c_source_compile_or_run( - "#include - #include - #include - int main(void) - { - __m128i a = _mm_setzero_si128(); - __m128i b = _mm_setzero_si128(); - __m128i c = _mm_clmulepi64_si128(a, b, 0x10); - int d = _mm_extract_epi32(c, 2); - return d; - }" - HAVE_PCLMULQDQ_INTRIN - ) -endif() - -# -# Enable deflate_medium at level 4-6 -# -if(WITH_NEW_MEDIUM_STRATEGY) - add_definitions(-DMEDIUM_STRATEGY) -endif() - -# -# macro to add either the given intrinsics option to the global compiler options, -# or ${NATIVEFLAG} (-march=native) if that is appropriate and possible. -# An alternative version of this macro would take a file argument, and set ${flag} -# only for that file as opposed to ${NATIVEFLAG} globally, to limit side-effect of -# using ${flag} globally. -# -macro(add_intrinsics_option flag) - if(WITH_NATIVE_INSTRUCTIONS AND NATIVEFLAG) - if (NOT "${CMAKE_C_FLAGS} " MATCHES ".*${NATIVEFLAG} .*") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${NATIVEFLAG}") - endif() - else() - if (NOT "${CMAKE_C_FLAGS} " MATCHES ".*${flag} .*") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}") - endif() - endif() -endmacro(add_intrinsics_option) - -set(ZLIB_ARCH_SRCS) -set(ARCHDIR "arch/generic") -if("${ARCH}" MATCHES "x86_64" OR "${ARCH}" MATCHES "AMD64") - set(ARCHDIR "arch/x86") - add_definitions(-DX86_64 -DX86_NOCHECK_SSE2 -DUNALIGNED_OK -DUNROLL_LESS -DX86_CPUID) - add_feature_info(SSE2 1 "Use the SSE2 instruction set, using \"${SSE2FLAG}\"") -elseif("${ARCH}" MATCHES "arm" OR "${ARCH}" MATCHES "aarch64") - set(ARCHDIR "arch/arm") - add_definitions(-DUNALIGNED_OK -DUNROLL_LESS) -else() - set(ARCHDIR "arch/x86") - add_definitions(-DX86 -DUNALIGNED_OK -DUNROLL_LESS -DX86_CPUID) - add_feature_info(SSE2 1 "Support the SSE2 instruction set, using \"${SSE2FLAG}\"") -endif() -if(WITH_OPTIM) - if(NOT CMAKE_SYSTEM_PROCESSOR MATCHES "arm" AND NOT CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") - set(ZLIB_ARCH_SRCS ${ZLIB_ARCH_SRCS} ${ARCHDIR}/x86.c) - endif() - if(HAVE_SSE42_INTRIN) - add_definitions(-DX86_SSE4_2_CRC_HASH) - set(ZLIB_ARCH_SRCS ${ZLIB_ARCH_SRCS} ${ARCHDIR}/insert_string_sse.c) - add_feature_info(SSE4_CRC 1 "Support CRC hash generation using the SSE4.2 instruction set, using \"${SSE4FLAG}\"") - add_intrinsics_option("${SSE4FLAG}") - if(WITH_NEW_QUICK_STRATEGY) - add_definitions(-DX86_QUICK_STRATEGY) - set(ZLIB_ARCH_SRCS ${ZLIB_ARCH_SRCS} ${ARCHDIR}/deflate_quick.c) - add_feature_info(SSE4DEFLATE 1 "Support SSE4.2-accelerated quick decompression") - endif() - endif() - if(HAVE_SSE2_INTRIN) - add_definitions(-DX86_SSE2_FILL_WINDOW) - set(ZLIB_ARCH_SRCS ${ZLIB_ARCH_SRCS} ${ARCHDIR}/fill_window_sse.c) - if(NOT ${ARCH} MATCHES "x86_64") - add_intrinsics_option("${SSE2FLAG}") - endif() - endif() - if(HAVE_PCLMULQDQ_INTRIN) - if (CMAKE_SYSTEM_PROCESSOR MATCHES "^x86") - add_definitions(-DX86_PCLMULQDQ_CRC) - endif() - set(ZLIB_ARCH_SRCS ${ZLIB_ARCH_SRCS} ${ARCHDIR}/crc_folding.c) - add_feature_info(PCLMUL_CRC 1 "Support CRC hash generation using PCLMULQDQ, using \"${SSE4FLAG} ${PCLMULFLAG}\"") - add_intrinsics_option("${PCLMULFLAG}") - if(NOT HAVE_SSE42_INTRIN) - add_intrinsics_option("${SSE4FLAG}") - endif() - endif() -endif() -message(STATUS "Architecture-specific source files: ${ZLIB_ARCH_SRCS}") - -#============================================================================ -# zconf.h -#============================================================================ - -macro(generate_cmakein input output) - execute_process(COMMAND sed "/#define ZCONF_H/ a\\\n#cmakedefine Z_HAVE_UNISTD_H\\\n#cmakedefine Z_HAVE_STDARG_H\n" - INPUT_FILE ${input} - OUTPUT_FILE ${output} -) - -endmacro(generate_cmakein) - -generate_cmakein( ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.in ${CMAKE_CURRENT_BINARY_DIR}/zconf.h.cmakein ) - -if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) - # If we're doing an out of source build and the user has a zconf.h - # in their source tree... - if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h) - message(STATUS "Renaming") - message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h") - message(STATUS "to 'zconf.h.included' because this file is included with zlib") - message(STATUS "but CMake generates it automatically in the build directory.") - file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included) - endif() - - # If we're doing an out of source build and the user has a zconf.h.cmakein - # in their source tree... - if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein) - message(STATUS "Renaming") - message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein") - message(STATUS "to 'zconf.h.cmakeincluded' because this file is included with zlib") - message(STATUS "but CMake generates it automatically in the build directory.") - file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakeincluded) - endif() -endif() - -set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc) -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein - ${ZLIB_PC} @ONLY) -configure_file( ${CMAKE_CURRENT_BINARY_DIR}/zconf.h.cmakein - ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY) -include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) - - -#============================================================================ -# zlib -#============================================================================ - -set(ZLIB_PUBLIC_HDRS - ${CMAKE_CURRENT_BINARY_DIR}/zconf.h - zlib.h -) -set(ZLIB_PRIVATE_HDRS - crc32.h - deflate.h - gzguts.h - inffast.h - inffixed.h - inflate.h - inftrees.h - trees.h - zutil.h -) -set(ZLIB_SRCS - adler32.c - compress.c - crc32.c - deflate.c - deflate_fast.c - deflate_medium.c - deflate_slow.c - inflate.c - infback.c - inftrees.c - inffast.c - match.c - trees.c - uncompr.c - zutil.c -) -if (WITH_GZFILEOP) - set(ZLIB_GZFILE_SRCS - gzclose.c - gzlib.c - gzread.c - gzwrite.c - ) -else (WITH_GZFILEOP) - set(ZLIB_GZFILE_SRCS - ) -endif (WITH_GZFILEOP) - - -if(NOT MINGW AND NOT MSYS) - set(ZLIB_DLL_SRCS - win32/zlib1.rc # If present will override custom build rule below. - ) -endif() - -# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION -file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) -string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" - "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents}) - -if(MINGW OR MSYS) - # This gets us DLL resource information when compiling on MinGW. - if(NOT CMAKE_RC_COMPILER) - set(CMAKE_RC_COMPILER windres.exe) - endif() - - add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj - COMMAND ${CMAKE_RC_COMPILER} - -D GCC_WINDRES - -I ${CMAKE_CURRENT_SOURCE_DIR} - -I ${CMAKE_CURRENT_BINARY_DIR} - -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj - -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc) - set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj) -endif(MINGW OR MSYS) - -add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_GZFILE_SRCS} ${ZLIB_ARCH_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) -add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_GZFILE_SRCS} ${ZLIB_ARCH_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) - -set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL) -set_target_properties(zlib PROPERTIES SOVERSION 1) - -if(NOT CYGWIN) - # This property causes shared libraries on Linux to have the full version - # encoded into their final filename. We disable this on Cygwin because - # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll - # seems to be the default. - # - # This has no effect with MSVC, on that platform the version info for - # the DLL comes from the resource file win32/zlib1.rc - set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION}) -endif() - -if(UNIX) - # On unix-like platforms the library is almost always called libz - set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z) - if(NOT APPLE) - set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"") - endif() -elseif(MSYS) - # Suppress version number from shared library name - set(CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION 0) -elseif(BUILD_SHARED_LIBS AND WIN32) - # Creates zlib1.dll when building shared library version - set_target_properties(zlib PROPERTIES SUFFIX "1.dll") -endif() - -if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL ) - install(TARGETS zlib zlibstatic - RUNTIME DESTINATION "${INSTALL_BIN_DIR}" - ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" - LIBRARY DESTINATION "${INSTALL_LIB_DIR}" ) -endif() -if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL ) - install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION "${INSTALL_INC_DIR}") -endif() -if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) - install(FILES zlib.3 DESTINATION "${INSTALL_MAN_DIR}/man3") -endif() -if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) - install(FILES ${ZLIB_PC} DESTINATION "${INSTALL_PKGCONFIG_DIR}") -endif() - -#============================================================================ -# Example binaries -#============================================================================ - -if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - set (CMAKE_EXE_LINKER_FLAGS "") -endif () - -add_executable(example test/example.c) -target_link_libraries(example zlib) -add_test(example example) - -add_executable(minigzip test/minigzip.c) -target_link_libraries(minigzip zlib) - -if(HAVE_OFF64_T) - add_executable(example64 test/example.c) - target_link_libraries(example64 zlib) - set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") - add_test(example64 example64) - - add_executable(minigzip64 test/minigzip.c) - target_link_libraries(minigzip64 zlib) - set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") -endif() diff --git a/contrib/libzlib-ng/ChangeLog.zlib b/contrib/libzlib-ng/ChangeLog.zlib deleted file mode 100644 index 909d11f9b47..00000000000 --- a/contrib/libzlib-ng/ChangeLog.zlib +++ /dev/null @@ -1,1478 +0,0 @@ -## -# THIS IS AN UNMAINTAINED COPY OF THE ORIGINAL FILE DISTRIBUTED WITH ZLIB 1.2.8 -## - - - - - ChangeLog file for zlib - -Changes in 1.2.8 (28 Apr 2013) -- Update contrib/minizip/iowin32.c for Windows RT [Vollant] -- Do not force Z_CONST for C++ -- Clean up contrib/vstudio [Roß] -- Correct spelling error in zlib.h -- Fix mixed line endings in contrib/vstudio - -Changes in 1.2.7.3 (13 Apr 2013) -- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc - -Changes in 1.2.7.2 (13 Apr 2013) -- Change check for a four-byte type back to hexadecimal -- Fix typo in win32/Makefile.msc -- Add casts in gzwrite.c for pointer differences - -Changes in 1.2.7.1 (24 Mar 2013) -- Replace use of unsafe string functions with snprintf if available -- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink] -- Fix gzgetc undefine when Z_PREFIX set [Turk] -- Eliminate use of mktemp in Makefile (not always available) -- Fix bug in 'F' mode for gzopen() -- Add inflateGetDictionary() function -- Correct comment in deflate.h -- Use _snprintf for snprintf in Microsoft C -- On Darwin, only use /usr/bin/libtool if libtool is not Apple -- Delete "--version" file if created by "ar --version" [Richard G.] -- Fix configure check for veracity of compiler error return codes -- Fix CMake compilation of static lib for MSVC2010 x64 -- Remove unused variable in infback9.c -- Fix argument checks in gzlog_compress() and gzlog_write() -- Clean up the usage of z_const and respect const usage within zlib -- Clean up examples/gzlog.[ch] comparisons of different types -- Avoid shift equal to bits in type (caused endless loop) -- Fix uninitialized value bug in gzputc() introduced by const patches -- Fix memory allocation error in examples/zran.c [Nor] -- Fix bug where gzopen(), gzclose() would write an empty file -- Fix bug in gzclose() when gzwrite() runs out of memory -- Check for input buffer malloc failure in examples/gzappend.c -- Add note to contrib/blast to use binary mode in stdio -- Fix comparisons of differently signed integers in contrib/blast -- Check for invalid code length codes in contrib/puff -- Fix serious but very rare decompression bug in inftrees.c -- Update inflateBack() comments, since inflate() can be faster -- Use underscored I/O function names for WINAPI_FAMILY -- Add _tr_flush_bits to the external symbols prefixed by --zprefix -- Add contrib/vstudio/vc10 pre-build step for static only -- Quote --version-script argument in CMakeLists.txt -- Don't specify --version-script on Apple platforms in CMakeLists.txt -- Fix casting error in contrib/testzlib/testzlib.c -- Fix types in contrib/minizip to match result of get_crc_table() -- Simplify contrib/vstudio/vc10 with 'd' suffix -- Add TOP support to win32/Makefile.msc -- Suport i686 and amd64 assembler builds in CMakeLists.txt -- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h -- Add vc11 and vc12 build files to contrib/vstudio -- Add gzvprintf() as an undocumented function in zlib -- Fix configure for Sun shell -- Remove runtime check in configure for four-byte integer type -- Add casts and consts to ease user conversion to C++ -- Add man pages for minizip and miniunzip -- In Makefile uninstall, don't rm if preceding cd fails -- Do not return Z_BUF_ERROR if deflateParam() has nothing to write - -Changes in 1.2.7 (2 May 2012) -- Replace use of memmove() with a simple copy for portability -- Test for existence of strerror -- Restore gzgetc_ for backward compatibility with 1.2.6 -- Fix build with non-GNU make on Solaris -- Require gcc 4.0 or later on Mac OS X to use the hidden attribute -- Include unistd.h for Watcom C -- Use __WATCOMC__ instead of __WATCOM__ -- Do not use the visibility attribute if NO_VIZ defined -- Improve the detection of no hidden visibility attribute -- Avoid using __int64 for gcc or solo compilation -- Cast to char * in gzprintf to avoid warnings [Zinser] -- Fix make_vms.com for VAX [Zinser] -- Don't use library or built-in byte swaps -- Simplify test and use of gcc hidden attribute -- Fix bug in gzclose_w() when gzwrite() fails to allocate memory -- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen() -- Fix bug in test/minigzip.c for configure --solo -- Fix contrib/vstudio project link errors [Mohanathas] -- Add ability to choose the builder in make_vms.com [Schweda] -- Add DESTDIR support to mingw32 win32/Makefile.gcc -- Fix comments in win32/Makefile.gcc for proper usage -- Allow overriding the default install locations for cmake -- Generate and install the pkg-config file with cmake -- Build both a static and a shared version of zlib with cmake -- Include version symbols for cmake builds -- If using cmake with MSVC, add the source directory to the includes -- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta] -- Move obsolete emx makefile to old [Truta] -- Allow the use of -Wundef when compiling or using zlib -- Avoid the use of the -u option with mktemp -- Improve inflate() documentation on the use of Z_FINISH -- Recognize clang as gcc -- Add gzopen_w() in Windows for wide character path names -- Rename zconf.h in CMakeLists.txt to move it out of the way -- Add source directory in CMakeLists.txt for building examples -- Look in build directory for zlib.pc in CMakeLists.txt -- Remove gzflags from zlibvc.def in vc9 and vc10 -- Fix contrib/minizip compilation in the MinGW environment -- Update ./configure for Solaris, support --64 [Mooney] -- Remove -R. from Solaris shared build (possible security issue) -- Avoid race condition for parallel make (-j) running example -- Fix type mismatch between get_crc_table() and crc_table -- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler] -- Fix the path to zlib.map in CMakeLists.txt -- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe] -- Add instructions to win32/Makefile.gcc for shared install [Torri] - -Changes in 1.2.6.1 (12 Feb 2012) -- Avoid the use of the Objective-C reserved name "id" -- Include io.h in gzguts.h for Microsoft compilers -- Fix problem with ./configure --prefix and gzgetc macro -- Include gz_header definition when compiling zlib solo -- Put gzflags() functionality back in zutil.c -- Avoid library header include in crc32.c for Z_SOLO -- Use name in GCC_CLASSIC as C compiler for coverage testing, if set -- Minor cleanup in contrib/minizip/zip.c [Vollant] -- Update make_vms.com [Zinser] -- Remove unnecessary gzgetc_ function -- Use optimized byte swap operations for Microsoft and GNU [Snyder] -- Fix minor typo in zlib.h comments [Rzesniowiecki] - -Changes in 1.2.6 (29 Jan 2012) -- Update the Pascal interface in contrib/pascal -- Fix function numbers for gzgetc_ in zlibvc.def files -- Fix configure.ac for contrib/minizip [Schiffer] -- Fix large-entry detection in minizip on 64-bit systems [Schiffer] -- Have ./configure use the compiler return code for error indication -- Fix CMakeLists.txt for cross compilation [McClure] -- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes] -- Fix compilation of contrib/minizip on FreeBSD [Marquez] -- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath] -- Include io.h for Turbo C / Borland C on all platforms [Truta] -- Make version explicit in contrib/minizip/configure.ac [Bosmans] -- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant] -- Minor cleanup up contrib/minizip/unzip.c [Vollant] -- Fix bug when compiling minizip with C++ [Vollant] -- Protect for long name and extra fields in contrib/minizip [Vollant] -- Avoid some warnings in contrib/minizip [Vollant] -- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip -- Add missing libs to minizip linker command -- Add support for VPATH builds in contrib/minizip -- Add an --enable-demos option to contrib/minizip/configure -- Add the generation of configure.log by ./configure -- Exit when required parameters not provided to win32/Makefile.gcc -- Have gzputc return the character written instead of the argument -- Use the -m option on ldconfig for BSD systems [Tobias] -- Correct in zlib.map when deflateResetKeep was added - -Changes in 1.2.5.3 (15 Jan 2012) -- Restore gzgetc function for binary compatibility -- Do not use _lseeki64 under Borland C++ [Truta] -- Update win32/Makefile.msc to build test/*.c [Truta] -- Remove old/visualc6 given CMakefile and other alternatives -- Update AS400 build files and documentation [Monnerat] -- Update win32/Makefile.gcc to build test/*.c [Truta] -- Permit stronger flushes after Z_BLOCK flushes -- Avoid extraneous empty blocks when doing empty flushes -- Permit Z_NULL arguments to deflatePending -- Allow deflatePrime() to insert bits in the middle of a stream -- Remove second empty static block for Z_PARTIAL_FLUSH -- Write out all of the available bits when using Z_BLOCK -- Insert the first two strings in the hash table after a flush - -Changes in 1.2.5.2 (17 Dec 2011) -- fix ld error: unable to find version dependency 'ZLIB_1.2.5' -- use relative symlinks for shared libs -- Avoid searching past window for Z_RLE strategy -- Assure that high-water mark initialization is always applied in deflate -- Add assertions to fill_window() in deflate.c to match comments -- Update python link in README -- Correct spelling error in gzread.c -- Fix bug in gzgets() for a concatenated empty gzip stream -- Correct error in comment for gz_make() -- Change gzread() and related to ignore junk after gzip streams -- Allow gzread() and related to continue after gzclearerr() -- Allow gzrewind() and gzseek() after a premature end-of-file -- Simplify gzseek() now that raw after gzip is ignored -- Change gzgetc() to a macro for speed (~40% speedup in testing) -- Fix gzclose() to return the actual error last encountered -- Always add large file support for windows -- Include zconf.h for windows large file support -- Include zconf.h.cmakein for windows large file support -- Update zconf.h.cmakein on make distclean -- Merge vestigial vsnprintf determination from zutil.h to gzguts.h -- Clarify how gzopen() appends in zlib.h comments -- Correct documentation of gzdirect() since junk at end now ignored -- Add a transparent write mode to gzopen() when 'T' is in the mode -- Update python link in zlib man page -- Get inffixed.h and MAKEFIXED result to match -- Add a ./config --solo option to make zlib subset with no libary use -- Add undocumented inflateResetKeep() function for CAB file decoding -- Add --cover option to ./configure for gcc coverage testing -- Add #define ZLIB_CONST option to use const in the z_stream interface -- Add comment to gzdopen() in zlib.h to use dup() when using fileno() -- Note behavior of uncompress() to provide as much data as it can -- Add files in contrib/minizip to aid in building libminizip -- Split off AR options in Makefile.in and configure -- Change ON macro to Z_ARG to avoid application conflicts -- Facilitate compilation with Borland C++ for pragmas and vsnprintf -- Include io.h for Turbo C / Borland C++ -- Move example.c and minigzip.c to test/ -- Simplify incomplete code table filling in inflate_table() -- Remove code from inflate.c and infback.c that is impossible to execute -- Test the inflate code with full coverage -- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw) -- Add deflateResetKeep and fix inflateResetKeep to retain dictionary -- Fix gzwrite.c to accommodate reduced memory zlib compilation -- Have inflate() with Z_FINISH avoid the allocation of a window -- Do not set strm->adler when doing raw inflate -- Fix gzeof() to behave just like feof() when read is not past end of file -- Fix bug in gzread.c when end-of-file is reached -- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF -- Document gzread() capability to read concurrently written files -- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo] - -Changes in 1.2.5.1 (10 Sep 2011) -- Update FAQ entry on shared builds (#13) -- Avoid symbolic argument to chmod in Makefile.in -- Fix bug and add consts in contrib/puff [Oberhumer] -- Update contrib/puff/zeros.raw test file to have all block types -- Add full coverage test for puff in contrib/puff/Makefile -- Fix static-only-build install in Makefile.in -- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno] -- Add libz.a dependency to shared in Makefile.in for parallel builds -- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out -- Replace $(...) with `...` in configure for non-bash sh [Bowler] -- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen] -- Add solaris* to Linux* in configure to allow gcc use [Groffen] -- Add *bsd* to Linux* case in configure [Bar-Lev] -- Add inffast.obj to dependencies in win32/Makefile.msc -- Correct spelling error in deflate.h [Kohler] -- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc -- Add test to configure for GNU C looking for gcc in output of $cc -v -- Add zlib.pc generation to win32/Makefile.gcc [Weigelt] -- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not -- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense -- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser) -- Make stronger test in zconf.h to include unistd.h for LFS -- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack] -- Fix zlib.h LFS support when Z_PREFIX used -- Add updated as400 support (removed from old) [Monnerat] -- Avoid deflate sensitivity to volatile input data -- Avoid division in adler32_combine for NO_DIVIDE -- Clarify the use of Z_FINISH with deflateBound() amount of space -- Set binary for output file in puff.c -- Use u4 type for crc_table to avoid conversion warnings -- Apply casts in zlib.h to avoid conversion warnings -- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller] -- Improve inflateSync() documentation to note indeterminancy -- Add deflatePending() function to return the amount of pending output -- Correct the spelling of "specification" in FAQ [Randers-Pehrson] -- Add a check in configure for stdarg.h, use for gzprintf() -- Check that pointers fit in ints when gzprint() compiled old style -- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler] -- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt] -- Add debug records in assmebler code [Londer] -- Update RFC references to use http://tools.ietf.org/html/... [Li] -- Add --archs option, use of libtool to configure for Mac OS X [Borstel] - -Changes in 1.2.5 (19 Apr 2010) -- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev] -- Default to libdir as sharedlibdir in configure [Nieder] -- Update copyright dates on modified source files -- Update trees.c to be able to generate modified trees.h -- Exit configure for MinGW, suggesting win32/Makefile.gcc -- Check for NULL path in gz_open [Homurlu] - -Changes in 1.2.4.5 (18 Apr 2010) -- Set sharedlibdir in configure [Torok] -- Set LDFLAGS in Makefile.in [Bar-Lev] -- Avoid mkdir objs race condition in Makefile.in [Bowler] -- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays -- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C -- Don't use hidden attribute when it is a warning generator (e.g. Solaris) - -Changes in 1.2.4.4 (18 Apr 2010) -- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok] -- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty -- Try to use bash or ksh regardless of functionality of /bin/sh -- Fix configure incompatibility with NetBSD sh -- Remove attempt to run under bash or ksh since have better NetBSD fix -- Fix win32/Makefile.gcc for MinGW [Bar-Lev] -- Add diagnostic messages when using CROSS_PREFIX in configure -- Added --sharedlibdir option to configure [Weigelt] -- Use hidden visibility attribute when available [Frysinger] - -Changes in 1.2.4.3 (10 Apr 2010) -- Only use CROSS_PREFIX in configure for ar and ranlib if they exist -- Use CROSS_PREFIX for nm [Bar-Lev] -- Assume _LARGEFILE64_SOURCE defined is equivalent to true -- Avoid use of undefined symbols in #if with && and || -- Make *64 prototypes in gzguts.h consistent with functions -- Add -shared load option for MinGW in configure [Bowler] -- Move z_off64_t to public interface, use instead of off64_t -- Remove ! from shell test in configure (not portable to Solaris) -- Change +0 macro tests to -0 for possibly increased portability - -Changes in 1.2.4.2 (9 Apr 2010) -- Add consistent carriage returns to readme.txt's in masmx86 and masmx64 -- Really provide prototypes for *64 functions when building without LFS -- Only define unlink() in minigzip.c if unistd.h not included -- Update README to point to contrib/vstudio project files -- Move projects/vc6 to old/ and remove projects/ -- Include stdlib.h in minigzip.c for setmode() definition under WinCE -- Clean up assembler builds in win32/Makefile.msc [Rowe] -- Include sys/types.h for Microsoft for off_t definition -- Fix memory leak on error in gz_open() -- Symbolize nm as $NM in configure [Weigelt] -- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt] -- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined -- Fix bug in gzeof() to take into account unused input data -- Avoid initialization of structures with variables in puff.c -- Updated win32/README-WIN32.txt [Rowe] - -Changes in 1.2.4.1 (28 Mar 2010) -- Remove the use of [a-z] constructs for sed in configure [gentoo 310225] -- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech] -- Restore "for debugging" comment on sprintf() in gzlib.c -- Remove fdopen for MVS from gzguts.h -- Put new README-WIN32.txt in win32 [Rowe] -- Add check for shell to configure and invoke another shell if needed -- Fix big fat stinking bug in gzseek() on uncompressed files -- Remove vestigial F_OPEN64 define in zutil.h -- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE -- Avoid errors on non-LFS systems when applications define LFS macros -- Set EXE to ".exe" in configure for MINGW [Kahle] -- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill] -- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev] -- Add DLL install in win32/makefile.gcc [Bar-Lev] -- Allow Linux* or linux* from uname in configure [Bar-Lev] -- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev] -- Add cross-compilation prefixes to configure [Bar-Lev] -- Match type exactly in gz_load() invocation in gzread.c -- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func -- Provide prototypes for *64 functions when building zlib without LFS -- Don't use -lc when linking shared library on MinGW -- Remove errno.h check in configure and vestigial errno code in zutil.h - -Changes in 1.2.4 (14 Mar 2010) -- Fix VER3 extraction in configure for no fourth subversion -- Update zlib.3, add docs to Makefile.in to make .pdf out of it -- Add zlib.3.pdf to distribution -- Don't set error code in gzerror() if passed pointer is NULL -- Apply destination directory fixes to CMakeLists.txt [Lowman] -- Move #cmakedefine's to a new zconf.in.cmakein -- Restore zconf.h for builds that don't use configure or cmake -- Add distclean to dummy Makefile for convenience -- Update and improve INDEX, README, and FAQ -- Update CMakeLists.txt for the return of zconf.h [Lowman] -- Update contrib/vstudio/vc9 and vc10 [Vollant] -- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc -- Apply license and readme changes to contrib/asm686 [Raiter] -- Check file name lengths and add -c option in minigzip.c [Li] -- Update contrib/amd64 and contrib/masmx86/ [Vollant] -- Avoid use of "eof" parameter in trees.c to not shadow library variable -- Update make_vms.com for removal of zlibdefs.h [Zinser] -- Update assembler code and vstudio projects in contrib [Vollant] -- Remove outdated assembler code contrib/masm686 and contrib/asm586 -- Remove old vc7 and vc8 from contrib/vstudio -- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe] -- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open() -- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant] -- Remove *64 functions from win32/zlib.def (they're not 64-bit yet) -- Fix bug in void-returning vsprintf() case in gzwrite.c -- Fix name change from inflate.h in contrib/inflate86/inffas86.c -- Check if temporary file exists before removing in make_vms.com [Zinser] -- Fix make install and uninstall for --static option -- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta] -- Update readme.txt in contrib/masmx64 and masmx86 to assemble - -Changes in 1.2.3.9 (21 Feb 2010) -- Expunge gzio.c -- Move as400 build information to old -- Fix updates in contrib/minizip and contrib/vstudio -- Add const to vsnprintf test in configure to avoid warnings [Weigelt] -- Delete zconf.h (made by configure) [Weigelt] -- Change zconf.in.h to zconf.h.in per convention [Weigelt] -- Check for NULL buf in gzgets() -- Return empty string for gzgets() with len == 1 (like fgets()) -- Fix description of gzgets() in zlib.h for end-of-file, NULL return -- Update minizip to 1.1 [Vollant] -- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c -- Note in zlib.h that gzerror() should be used to distinguish from EOF -- Remove use of snprintf() from gzlib.c -- Fix bug in gzseek() -- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant] -- Fix zconf.h generation in CMakeLists.txt [Lowman] -- Improve comments in zconf.h where modified by configure - -Changes in 1.2.3.8 (13 Feb 2010) -- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer] -- Use z_off64_t in gz_zero() and gz_skip() to match state->skip -- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t) -- Revert to Makefile.in from 1.2.3.6 (live with the clutter) -- Fix missing error return in gzflush(), add zlib.h note -- Add *64 functions to zlib.map [Levin] -- Fix signed/unsigned comparison in gz_comp() -- Use SFLAGS when testing shared linking in configure -- Add --64 option to ./configure to use -m64 with gcc -- Fix ./configure --help to correctly name options -- Have make fail if a test fails [Levin] -- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson] -- Remove assembler object files from contrib - -Changes in 1.2.3.7 (24 Jan 2010) -- Always gzopen() with O_LARGEFILE if available -- Fix gzdirect() to work immediately after gzopen() or gzdopen() -- Make gzdirect() more precise when the state changes while reading -- Improve zlib.h documentation in many places -- Catch memory allocation failure in gz_open() -- Complete close operation if seek forward in gzclose_w() fails -- Return Z_ERRNO from gzclose_r() if close() fails -- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL -- Return zero for gzwrite() errors to match zlib.h description -- Return -1 on gzputs() error to match zlib.h description -- Add zconf.in.h to allow recovery from configure modification [Weigelt] -- Fix static library permissions in Makefile.in [Weigelt] -- Avoid warnings in configure tests that hide functionality [Weigelt] -- Add *BSD and DragonFly to Linux case in configure [gentoo 123571] -- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212] -- Avoid access of uninitialized data for first inflateReset2 call [Gomes] -- Keep object files in subdirectories to reduce the clutter somewhat -- Remove default Makefile and zlibdefs.h, add dummy Makefile -- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_ -- Remove zlibdefs.h completely -- modify zconf.h instead - -Changes in 1.2.3.6 (17 Jan 2010) -- Avoid void * arithmetic in gzread.c and gzwrite.c -- Make compilers happier with const char * for gz_error message -- Avoid unused parameter warning in inflate.c -- Avoid signed-unsigned comparison warning in inflate.c -- Indent #pragma's for traditional C -- Fix usage of strwinerror() in glib.c, change to gz_strwinerror() -- Correct email address in configure for system options -- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser] -- Update zlib.map [Brown] -- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok] -- Apply various fixes to CMakeLists.txt [Lowman] -- Add checks on len in gzread() and gzwrite() -- Add error message for no more room for gzungetc() -- Remove zlib version check in gzwrite() -- Defer compression of gzprintf() result until need to -- Use snprintf() in gzdopen() if available -- Remove USE_MMAP configuration determination (only used by minigzip) -- Remove examples/pigz.c (available separately) -- Update examples/gun.c to 1.6 - -Changes in 1.2.3.5 (8 Jan 2010) -- Add space after #if in zutil.h for some compilers -- Fix relatively harmless bug in deflate_fast() [Exarevsky] -- Fix same problem in deflate_slow() -- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown] -- Add deflate_rle() for faster Z_RLE strategy run-length encoding -- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding -- Change name of "write" variable in inffast.c to avoid library collisions -- Fix premature EOF from gzread() in gzio.c [Brown] -- Use zlib header window size if windowBits is 0 in inflateInit2() -- Remove compressBound() call in deflate.c to avoid linking compress.o -- Replace use of errno in gz* with functions, support WinCE [Alves] -- Provide alternative to perror() in minigzip.c for WinCE [Alves] -- Don't use _vsnprintf on later versions of MSVC [Lowman] -- Add CMake build script and input file [Lowman] -- Update contrib/minizip to 1.1 [Svensson, Vollant] -- Moved nintendods directory from contrib to . -- Replace gzio.c with a new set of routines with the same functionality -- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above -- Update contrib/minizip to 1.1b -- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h - -Changes in 1.2.3.4 (21 Dec 2009) -- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility -- Update comments in configure and Makefile.in for default --shared -- Fix test -z's in configure [Marquess] -- Build examplesh and minigzipsh when not testing -- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h -- Import LDFLAGS from the environment in configure -- Fix configure to populate SFLAGS with discovered CFLAGS options -- Adapt make_vms.com to the new Makefile.in [Zinser] -- Add zlib2ansi script for C++ compilation [Marquess] -- Add _FILE_OFFSET_BITS=64 test to make test (when applicable) -- Add AMD64 assembler code for longest match to contrib [Teterin] -- Include options from $SFLAGS when doing $LDSHARED -- Simplify 64-bit file support by introducing z_off64_t type -- Make shared object files in objs directory to work around old Sun cc -- Use only three-part version number for Darwin shared compiles -- Add rc option to ar in Makefile.in for when ./configure not run -- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4* -- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile -- Protect against _FILE_OFFSET_BITS being defined when compiling zlib -- Rename Makefile.in targets allstatic to static and allshared to shared -- Fix static and shared Makefile.in targets to be independent -- Correct error return bug in gz_open() by setting state [Brown] -- Put spaces before ;;'s in configure for better sh compatibility -- Add pigz.c (parallel implementation of gzip) to examples/ -- Correct constant in crc32.c to UL [Leventhal] -- Reject negative lengths in crc32_combine() -- Add inflateReset2() function to work like inflateEnd()/inflateInit2() -- Include sys/types.h for _LARGEFILE64_SOURCE [Brown] -- Correct typo in doc/algorithm.txt [Janik] -- Fix bug in adler32_combine() [Zhu] -- Catch missing-end-of-block-code error in all inflates and in puff - Assures that random input to inflate eventually results in an error -- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/ -- Update ENOUGH and its usage to reflect discovered bounds -- Fix gzerror() error report on empty input file [Brown] -- Add ush casts in trees.c to avoid pedantic runtime errors -- Fix typo in zlib.h uncompress() description [Reiss] -- Correct inflate() comments with regard to automatic header detection -- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays) -- Put new version of gzlog (2.0) in examples with interruption recovery -- Add puff compile option to permit invalid distance-too-far streams -- Add puff TEST command options, ability to read piped input -- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but - _LARGEFILE64_SOURCE not defined -- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart -- Fix deflateSetDictionary() to use all 32K for output consistency -- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h) -- Clear bytes after deflate lookahead to avoid use of uninitialized data -- Change a limit in inftrees.c to be more transparent to Coverity Prevent -- Update win32/zlib.def with exported symbols from zlib.h -- Correct spelling errors in zlib.h [Willem, Sobrado] -- Allow Z_BLOCK for deflate() to force a new block -- Allow negative bits in inflatePrime() to delete existing bit buffer -- Add Z_TREES flush option to inflate() to return at end of trees -- Add inflateMark() to return current state information for random access -- Add Makefile for NintendoDS to contrib [Costa] -- Add -w in configure compile tests to avoid spurious warnings [Beucler] -- Fix typos in zlib.h comments for deflateSetDictionary() -- Fix EOF detection in transparent gzread() [Maier] - -Changes in 1.2.3.3 (2 October 2006) -- Make --shared the default for configure, add a --static option -- Add compile option to permit invalid distance-too-far streams -- Add inflateUndermine() function which is required to enable above -- Remove use of "this" variable name for C++ compatibility [Marquess] -- Add testing of shared library in make test, if shared library built -- Use ftello() and fseeko() if available instead of ftell() and fseek() -- Provide two versions of all functions that use the z_off_t type for - binary compatibility -- a normal version and a 64-bit offset version, - per the Large File Support Extension when _LARGEFILE64_SOURCE is - defined; use the 64-bit versions by default when _FILE_OFFSET_BITS - is defined to be 64 -- Add a --uname= option to configure to perhaps help with cross-compiling - -Changes in 1.2.3.2 (3 September 2006) -- Turn off silly Borland warnings [Hay] -- Use off64_t and define _LARGEFILE64_SOURCE when present -- Fix missing dependency on inffixed.h in Makefile.in -- Rig configure --shared to build both shared and static [Teredesai, Truta] -- Remove zconf.in.h and instead create a new zlibdefs.h file -- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant] -- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt] - -Changes in 1.2.3.1 (16 August 2006) -- Add watcom directory with OpenWatcom make files [Daniel] -- Remove #undef of FAR in zconf.in.h for MVS [Fedtke] -- Update make_vms.com [Zinser] -- Use -fPIC for shared build in configure [Teredesai, Nicholson] -- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen] -- Use fdopen() (not _fdopen()) for Interix in zutil.h [Bäck] -- Add some FAQ entries about the contrib directory -- Update the MVS question in the FAQ -- Avoid extraneous reads after EOF in gzio.c [Brown] -- Correct spelling of "successfully" in gzio.c [Randers-Pehrson] -- Add comments to zlib.h about gzerror() usage [Brown] -- Set extra flags in gzip header in gzopen() like deflate() does -- Make configure options more compatible with double-dash conventions - [Weigelt] -- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen] -- Fix uninstall target in Makefile.in [Truta] -- Add pkgconfig support [Weigelt] -- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt] -- Replace set_data_type() with a more accurate detect_data_type() in - trees.c, according to the txtvsbin.txt document [Truta] -- Swap the order of #include and #include "zlib.h" in - gzio.c, example.c and minigzip.c [Truta] -- Shut up annoying VS2005 warnings about standard C deprecation [Rowe, - Truta] (where?) -- Fix target "clean" from win32/Makefile.bor [Truta] -- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe] -- Update zlib www home address in win32/DLL_FAQ.txt [Truta] -- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove] -- Enable browse info in the "Debug" and "ASM Debug" configurations in - the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta] -- Add pkgconfig support [Weigelt] -- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h, - for use in win32/zlib1.rc [Polushin, Rowe, Truta] -- Add a document that explains the new text detection scheme to - doc/txtvsbin.txt [Truta] -- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta] -- Move algorithm.txt into doc/ [Truta] -- Synchronize FAQ with website -- Fix compressBound(), was low for some pathological cases [Fearnley] -- Take into account wrapper variations in deflateBound() -- Set examples/zpipe.c input and output to binary mode for Windows -- Update examples/zlib_how.html with new zpipe.c (also web site) -- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems - that gcc became pickier in 4.0) -- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain - un-versioned, the patch adds versioning only for symbols introduced in - zlib-1.2.0 or later. It also declares as local those symbols which are - not designed to be exported." [Levin] -- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure -- Do not initialize global static by default in trees.c, add a response - NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess] -- Don't use strerror() in gzio.c under WinCE [Yakimov] -- Don't use errno.h in zutil.h under WinCE [Yakimov] -- Move arguments for AR to its usage to allow replacing ar [Marot] -- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson] -- Improve inflateInit() and inflateInit2() documentation -- Fix structure size comment in inflate.h -- Change configure help option from --h* to --help [Santos] - -Changes in 1.2.3 (18 July 2005) -- Apply security vulnerability fixes to contrib/infback9 as well -- Clean up some text files (carriage returns, trailing space) -- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] - -Changes in 1.2.2.4 (11 July 2005) -- Add inflatePrime() function for starting inflation at bit boundary -- Avoid some Visual C warnings in deflate.c -- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit - compile -- Fix some spelling errors in comments [Betts] -- Correct inflateInit2() error return documentation in zlib.h -- Add zran.c example of compressed data random access to examples - directory, shows use of inflatePrime() -- Fix cast for assignments to strm->state in inflate.c and infback.c -- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] -- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] -- Add cast in trees.c t avoid a warning [Oberhumer] -- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] -- Update make_vms.com [Zinser] -- Initialize state->write in inflateReset() since copied in inflate_fast() -- Be more strict on incomplete code sets in inflate_table() and increase - ENOUGH and MAXD -- this repairs a possible security vulnerability for - invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for - discovering the vulnerability and providing test cases. -- Add ia64 support to configure for HP-UX [Smith] -- Add error return to gzread() for format or i/o error [Levin] -- Use malloc.h for OS/2 [Necasek] - -Changes in 1.2.2.3 (27 May 2005) -- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile -- Typecast fread() return values in gzio.c [Vollant] -- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) -- Fix crc check bug in gzread() after gzungetc() [Heiner] -- Add the deflateTune() function to adjust internal compression parameters -- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) -- Remove an incorrect assertion in examples/zpipe.c -- Add C++ wrapper in infback9.h [Donais] -- Fix bug in inflateCopy() when decoding fixed codes -- Note in zlib.h how much deflateSetDictionary() actually uses -- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) -- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] -- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] -- Add gzdirect() function to indicate transparent reads -- Update contrib/minizip [Vollant] -- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] -- Add casts in crc32.c to avoid warnings [Oberhumer] -- Add contrib/masmx64 [Vollant] -- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] - -Changes in 1.2.2.2 (30 December 2004) -- Replace structure assignments in deflate.c and inflate.c with zmemcpy to - avoid implicit memcpy calls (portability for no-library compilation) -- Increase sprintf() buffer size in gzdopen() to allow for large numbers -- Add INFLATE_STRICT to check distances against zlib header -- Improve WinCE errno handling and comments [Chang] -- Remove comment about no gzip header processing in FAQ -- Add Z_FIXED strategy option to deflateInit2() to force fixed trees -- Add updated make_vms.com [Coghlan], update README -- Create a new "examples" directory, move gzappend.c there, add zpipe.c, - fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. -- Add FAQ entry and comments in deflate.c on uninitialized memory access -- Add Solaris 9 make options in configure [Gilbert] -- Allow strerror() usage in gzio.c for STDC -- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] -- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] -- Use z_off_t for adler32_combine() and crc32_combine() lengths -- Make adler32() much faster for small len -- Use OS_CODE in deflate() default gzip header - -Changes in 1.2.2.1 (31 October 2004) -- Allow inflateSetDictionary() call for raw inflate -- Fix inflate header crc check bug for file names and comments -- Add deflateSetHeader() and gz_header structure for custom gzip headers -- Add inflateGetheader() to retrieve gzip headers -- Add crc32_combine() and adler32_combine() functions -- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list -- Use zstreamp consistently in zlib.h (inflate_back functions) -- Remove GUNZIP condition from definition of inflate_mode in inflate.h - and in contrib/inflate86/inffast.S [Truta, Anderson] -- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] -- Update projects/README.projects and projects/visualc6 [Truta] -- Update win32/DLL_FAQ.txt [Truta] -- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] -- Deprecate Z_ASCII; use Z_TEXT instead [Truta] -- Use a new algorithm for setting strm->data_type in trees.c [Truta] -- Do not define an exit() prototype in zutil.c unless DEBUG defined -- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] -- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() -- Fix Darwin build version identification [Peterson] - -Changes in 1.2.2 (3 October 2004) -- Update zlib.h comments on gzip in-memory processing -- Set adler to 1 in inflateReset() to support Java test suite [Walles] -- Add contrib/dotzlib [Ravn] -- Update win32/DLL_FAQ.txt [Truta] -- Update contrib/minizip [Vollant] -- Move contrib/visual-basic.txt to old/ [Truta] -- Fix assembler builds in projects/visualc6/ [Truta] - -Changes in 1.2.1.2 (9 September 2004) -- Update INDEX file -- Fix trees.c to update strm->data_type (no one ever noticed!) -- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] -- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) -- Add limited multitasking protection to DYNAMIC_CRC_TABLE -- Add NO_vsnprintf for VMS in zutil.h [Mozilla] -- Don't declare strerror() under VMS [Mozilla] -- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize -- Update contrib/ada [Anisimkov] -- Update contrib/minizip [Vollant] -- Fix configure to not hardcode directories for Darwin [Peterson] -- Fix gzio.c to not return error on empty files [Brown] -- Fix indentation; update version in contrib/delphi/ZLib.pas and - contrib/pascal/zlibpas.pas [Truta] -- Update mkasm.bat in contrib/masmx86 [Truta] -- Update contrib/untgz [Truta] -- Add projects/README.projects [Truta] -- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] -- Update win32/DLL_FAQ.txt [Truta] -- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] -- Remove an unnecessary assignment to curr in inftrees.c [Truta] -- Add OS/2 to exe builds in configure [Poltorak] -- Remove err dummy parameter in zlib.h [Kientzle] - -Changes in 1.2.1.1 (9 January 2004) -- Update email address in README -- Several FAQ updates -- Fix a big fat bug in inftrees.c that prevented decoding valid - dynamic blocks with only literals and no distance codes -- - Thanks to "Hot Emu" for the bug report and sample file -- Add a note to puff.c on no distance codes case. - -Changes in 1.2.1 (17 November 2003) -- Remove a tab in contrib/gzappend/gzappend.c -- Update some interfaces in contrib for new zlib functions -- Update zlib version number in some contrib entries -- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] -- Support shared libraries on Hurd and KFreeBSD [Brown] -- Fix error in NO_DIVIDE option of adler32.c - -Changes in 1.2.0.8 (4 November 2003) -- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas -- Add experimental NO_DIVIDE #define in adler32.c - - Possibly faster on some processors (let me know if it is) -- Correct Z_BLOCK to not return on first inflate call if no wrap -- Fix strm->data_type on inflate() return to correctly indicate EOB -- Add deflatePrime() function for appending in the middle of a byte -- Add contrib/gzappend for an example of appending to a stream -- Update win32/DLL_FAQ.txt [Truta] -- Delete Turbo C comment in README [Truta] -- Improve some indentation in zconf.h [Truta] -- Fix infinite loop on bad input in configure script [Church] -- Fix gzeof() for concatenated gzip files [Johnson] -- Add example to contrib/visual-basic.txt [Michael B.] -- Add -p to mkdir's in Makefile.in [vda] -- Fix configure to properly detect presence or lack of printf functions -- Add AS400 support [Monnerat] -- Add a little Cygwin support [Wilson] - -Changes in 1.2.0.7 (21 September 2003) -- Correct some debug formats in contrib/infback9 -- Cast a type in a debug statement in trees.c -- Change search and replace delimiter in configure from % to # [Beebe] -- Update contrib/untgz to 0.2 with various fixes [Truta] -- Add build support for Amiga [Nikl] -- Remove some directories in old that have been updated to 1.2 -- Add dylib building for Mac OS X in configure and Makefile.in -- Remove old distribution stuff from Makefile -- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X -- Update links in README - -Changes in 1.2.0.6 (13 September 2003) -- Minor FAQ updates -- Update contrib/minizip to 1.00 [Vollant] -- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] -- Update POSTINC comment for 68060 [Nikl] -- Add contrib/infback9 with deflate64 decoding (unsupported) -- For MVS define NO_vsnprintf and undefine FAR [van Burik] -- Add pragma for fdopen on MVS [van Burik] - -Changes in 1.2.0.5 (8 September 2003) -- Add OF to inflateBackEnd() declaration in zlib.h -- Remember start when using gzdopen in the middle of a file -- Use internal off_t counters in gz* functions to properly handle seeks -- Perform more rigorous check for distance-too-far in inffast.c -- Add Z_BLOCK flush option to return from inflate at block boundary -- Set strm->data_type on return from inflate - - Indicate bits unused, if at block boundary, and if in last block -- Replace size_t with ptrdiff_t in crc32.c, and check for correct size -- Add condition so old NO_DEFLATE define still works for compatibility -- FAQ update regarding the Windows DLL [Truta] -- INDEX update: add qnx entry, remove aix entry [Truta] -- Install zlib.3 into mandir [Wilson] -- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] -- Adapt the zlib interface to the new DLL convention guidelines [Truta] -- Introduce ZLIB_WINAPI macro to allow the export of functions using - the WINAPI calling convention, for Visual Basic [Vollant, Truta] -- Update msdos and win32 scripts and makefiles [Truta] -- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] -- Add contrib/ada [Anisimkov] -- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] -- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] -- Add contrib/masm686 [Truta] -- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm - [Truta, Vollant] -- Update contrib/delphi; rename to contrib/pascal; add example [Truta] -- Remove contrib/delphi2; add a new contrib/delphi [Truta] -- Avoid inclusion of the nonstandard in contrib/iostream, - and fix some method prototypes [Truta] -- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip - [Truta] -- Avoid the use of backslash (\) in contrib/minizip [Vollant] -- Fix file time handling in contrib/untgz; update makefiles [Truta] -- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines - [Vollant] -- Remove contrib/vstudio/vc15_16 [Vollant] -- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] -- Update README.contrib [Truta] -- Invert the assignment order of match_head and s->prev[...] in - INSERT_STRING [Truta] -- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings - [Truta] -- Compare function pointers with 0, not with NULL or Z_NULL [Truta] -- Fix prototype of syncsearch in inflate.c [Truta] -- Introduce ASMINF macro to be enabled when using an ASM implementation - of inflate_fast [Truta] -- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] -- Modify test_gzio in example.c to take a single file name as a - parameter [Truta] -- Exit the example.c program if gzopen fails [Truta] -- Add type casts around strlen in example.c [Truta] -- Remove casting to sizeof in minigzip.c; give a proper type - to the variable compared with SUFFIX_LEN [Truta] -- Update definitions of STDC and STDC99 in zconf.h [Truta] -- Synchronize zconf.h with the new Windows DLL interface [Truta] -- Use SYS16BIT instead of __32BIT__ to distinguish between - 16- and 32-bit platforms [Truta] -- Use far memory allocators in small 16-bit memory models for - Turbo C [Truta] -- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in - zlibCompileFlags [Truta] -- Cygwin has vsnprintf [Wilson] -- In Windows16, OS_CODE is 0, as in MSDOS [Truta] -- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] - -Changes in 1.2.0.4 (10 August 2003) -- Minor FAQ updates -- Be more strict when checking inflateInit2's windowBits parameter -- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well -- Add gzip wrapper option to deflateInit2 using windowBits -- Add updated QNX rule in configure and qnx directory [Bonnefoy] -- Make inflate distance-too-far checks more rigorous -- Clean up FAR usage in inflate -- Add casting to sizeof() in gzio.c and minigzip.c - -Changes in 1.2.0.3 (19 July 2003) -- Fix silly error in gzungetc() implementation [Vollant] -- Update contrib/minizip and contrib/vstudio [Vollant] -- Fix printf format in example.c -- Correct cdecl support in zconf.in.h [Anisimkov] -- Minor FAQ updates - -Changes in 1.2.0.2 (13 July 2003) -- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons -- Attempt to avoid warnings in crc32.c for pointer-int conversion -- Add AIX to configure, remove aix directory [Bakker] -- Add some casts to minigzip.c -- Improve checking after insecure sprintf() or vsprintf() calls -- Remove #elif's from crc32.c -- Change leave label to inf_leave in inflate.c and infback.c to avoid - library conflicts -- Remove inflate gzip decoding by default--only enable gzip decoding by - special request for stricter backward compatibility -- Add zlibCompileFlags() function to return compilation information -- More typecasting in deflate.c to avoid warnings -- Remove leading underscore from _Capital #defines [Truta] -- Fix configure to link shared library when testing -- Add some Windows CE target adjustments [Mai] -- Remove #define ZLIB_DLL in zconf.h [Vollant] -- Add zlib.3 [Rodgers] -- Update RFC URL in deflate.c and algorithm.txt [Mai] -- Add zlib_dll_FAQ.txt to contrib [Truta] -- Add UL to some constants [Truta] -- Update minizip and vstudio [Vollant] -- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h -- Expand use of NO_DUMMY_DECL to avoid all dummy structures -- Added iostream3 to contrib [Schwardt] -- Replace rewind() with fseek() for WinCE [Truta] -- Improve setting of zlib format compression level flags - - Report 0 for huffman and rle strategies and for level == 0 or 1 - - Report 2 only for level == 6 -- Only deal with 64K limit when necessary at compile time [Truta] -- Allow TOO_FAR check to be turned off at compile time [Truta] -- Add gzclearerr() function [Souza] -- Add gzungetc() function - -Changes in 1.2.0.1 (17 March 2003) -- Add Z_RLE strategy for run-length encoding [Truta] - - When Z_RLE requested, restrict matches to distance one - - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE -- Correct FASTEST compilation to allow level == 0 -- Clean up what gets compiled for FASTEST -- Incorporate changes to zconf.in.h [Vollant] - - Refine detection of Turbo C need for dummy returns - - Refine ZLIB_DLL compilation - - Include additional header file on VMS for off_t typedef -- Try to use _vsnprintf where it supplants vsprintf [Vollant] -- Add some casts in inffast.c -- Enchance comments in zlib.h on what happens if gzprintf() tries to - write more than 4095 bytes before compression -- Remove unused state from inflateBackEnd() -- Remove exit(0) from minigzip.c, example.c -- Get rid of all those darn tabs -- Add "check" target to Makefile.in that does the same thing as "test" -- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in -- Update contrib/inflate86 [Anderson] -- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] -- Add msdos and win32 directories with makefiles [Truta] -- More additions and improvements to the FAQ - -Changes in 1.2.0 (9 March 2003) -- New and improved inflate code - - About 20% faster - - Does not allocate 32K window unless and until needed - - Automatically detects and decompresses gzip streams - - Raw inflate no longer needs an extra dummy byte at end - - Added inflateBack functions using a callback interface--even faster - than inflate, useful for file utilities (gzip, zip) - - Added inflateCopy() function to record state for random access on - externally generated deflate streams (e.g. in gzip files) - - More readable code (I hope) -- New and improved crc32() - - About 50% faster, thanks to suggestions from Rodney Brown -- Add deflateBound() and compressBound() functions -- Fix memory leak in deflateInit2() -- Permit setting dictionary for raw deflate (for parallel deflate) -- Fix const declaration for gzwrite() -- Check for some malloc() failures in gzio.c -- Fix bug in gzopen() on single-byte file 0x1f -- Fix bug in gzread() on concatenated file with 0x1f at end of buffer - and next buffer doesn't start with 0x8b -- Fix uncompress() to return Z_DATA_ERROR on truncated input -- Free memory at end of example.c -- Remove MAX #define in trees.c (conflicted with some libraries) -- Fix static const's in deflate.c, gzio.c, and zutil.[ch] -- Declare malloc() and free() in gzio.c if STDC not defined -- Use malloc() instead of calloc() in zutil.c if int big enough -- Define STDC for AIX -- Add aix/ with approach for compiling shared library on AIX -- Add HP-UX support for shared libraries in configure -- Add OpenUNIX support for shared libraries in configure -- Use $cc instead of gcc to build shared library -- Make prefix directory if needed when installing -- Correct Macintosh avoidance of typedef Byte in zconf.h -- Correct Turbo C memory allocation when under Linux -- Use libz.a instead of -lz in Makefile (assure use of compiled library) -- Update configure to check for snprintf or vsnprintf functions and their - return value, warn during make if using an insecure function -- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that - is lost when library is used--resolution is to build new zconf.h -- Documentation improvements (in zlib.h): - - Document raw deflate and inflate - - Update RFCs URL - - Point out that zlib and gzip formats are different - - Note that Z_BUF_ERROR is not fatal - - Document string limit for gzprintf() and possible buffer overflow - - Note requirement on avail_out when flushing - - Note permitted values of flush parameter of inflate() -- Add some FAQs (and even answers) to the FAQ -- Add contrib/inflate86/ for x86 faster inflate -- Add contrib/blast/ for PKWare Data Compression Library decompression -- Add contrib/puff/ simple inflate for deflate format description - -Changes in 1.1.4 (11 March 2002) -- ZFREE was repeated on same allocation on some error conditions. - This creates a security problem described in - http://www.zlib.org/advisory-2002-03-11.txt -- Returned incorrect error (Z_MEM_ERROR) on some invalid data -- Avoid accesses before window for invalid distances with inflate window - less than 32K. -- force windowBits > 8 to avoid a bug in the encoder for a window size - of 256 bytes. (A complete fix will be available in 1.1.5). - -Changes in 1.1.3 (9 July 1998) -- fix "an inflate input buffer bug that shows up on rare but persistent - occasions" (Mark) -- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) -- fix gzseek(..., SEEK_SET) in write mode -- fix crc check after a gzeek (Frank Faubert) -- fix miniunzip when the last entry in a zip file is itself a zip file - (J Lillge) -- add contrib/asm586 and contrib/asm686 (Brian Raiter) - See http://www.muppetlabs.com/~breadbox/software/assembly.html -- add support for Delphi 3 in contrib/delphi (Bob Dellaca) -- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) -- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) -- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) -- added a FAQ file - -- Support gzdopen on Mac with Metrowerks (Jason Linhart) -- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) -- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) -- avoid some warnings with Borland C (Tom Tanner) -- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) -- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) -- allow several arguments to configure (Tim Mooney, Frodo Looijaard) -- use libdir and includedir in Makefile.in (Tim Mooney) -- support shared libraries on OSF1 V4 (Tim Mooney) -- remove so_locations in "make clean" (Tim Mooney) -- fix maketree.c compilation error (Glenn, Mark) -- Python interface to zlib now in Python 1.5 (Jeremy Hylton) -- new Makefile.riscos (Rich Walker) -- initialize static descriptors in trees.c for embedded targets (Nick Smith) -- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) -- add the OS/2 files in Makefile.in too (Andrew Zabolotny) -- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) -- fix maketree.c to allow clean compilation of inffixed.h (Mark) -- fix parameter check in deflateCopy (Gunther Nikl) -- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) -- Many portability patches by Christian Spieler: - . zutil.c, zutil.h: added "const" for zmem* - . Make_vms.com: fixed some typos - . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists - . msdos/Makefile.msc: remove "default rtl link library" info from obj files - . msdos/Makefile.*: use model-dependent name for the built zlib library - . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: - new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) -- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) -- replace __far with _far for better portability (Christian Spieler, Tom Lane) -- fix test for errno.h in configure (Tim Newsham) - -Changes in 1.1.2 (19 March 98) -- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) - See http://www.winimage.com/zLibDll/unzip.html -- preinitialize the inflate tables for fixed codes, to make the code - completely thread safe (Mark) -- some simplifications and slight speed-up to the inflate code (Mark) -- fix gzeof on non-compressed files (Allan Schrum) -- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) -- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) -- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) -- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) -- do not wrap extern "C" around system includes (Tom Lane) -- mention zlib binding for TCL in README (Andreas Kupries) -- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) -- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) -- allow "configure --prefix $HOME" (Tim Mooney) -- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) -- move Makefile.sas to amiga/Makefile.sas - -Changes in 1.1.1 (27 Feb 98) -- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) -- remove block truncation heuristic which had very marginal effect for zlib - (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the - compression ratio on some files. This also allows inlining _tr_tally for - matches in deflate_slow. -- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) - -Changes in 1.1.0 (24 Feb 98) -- do not return STREAM_END prematurely in inflate (John Bowler) -- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) -- compile with -DFASTEST to get compression code optimized for speed only -- in minigzip, try mmap'ing the input file first (Miguel Albrecht) -- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain - on Sun but significant on HP) - -- add a pointer to experimental unzip library in README (Gilles Vollant) -- initialize variable gcc in configure (Chris Herborth) - -Changes in 1.0.9 (17 Feb 1998) -- added gzputs and gzgets functions -- do not clear eof flag in gzseek (Mark Diekhans) -- fix gzseek for files in transparent mode (Mark Diekhans) -- do not assume that vsprintf returns the number of bytes written (Jens Krinke) -- replace EXPORT with ZEXPORT to avoid conflict with other programs -- added compress2 in zconf.h, zlib.def, zlib.dnt -- new asm code from Gilles Vollant in contrib/asm386 -- simplify the inflate code (Mark): - . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() - . ZALLOC the length list in inflate_trees_fixed() instead of using stack - . ZALLOC the value area for huft_build() instead of using stack - . Simplify Z_FINISH check in inflate() - -- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 -- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) -- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with - the declaration of FAR (Gilles VOllant) -- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) -- read_buf buf parameter of type Bytef* instead of charf* -- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) -- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) -- fix check for presence of directories in "make install" (Ian Willis) - -Changes in 1.0.8 (27 Jan 1998) -- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) -- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) -- added compress2() to allow setting the compression level -- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) -- use constant arrays for the static trees in trees.c instead of computing - them at run time (thanks to Ken Raeburn for this suggestion). To create - trees.h, compile with GEN_TREES_H and run "make test". -- check return code of example in "make test" and display result -- pass minigzip command line options to file_compress -- simplifying code of inflateSync to avoid gcc 2.8 bug - -- support CC="gcc -Wall" in configure -s (QingLong) -- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) -- fix test for shared library support to avoid compiler warnings -- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) -- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) -- do not use fdopen for Metrowerks on Mac (Brad Pettit)) -- add checks for gzputc and gzputc in example.c -- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) -- use const for the CRC table (Ken Raeburn) -- fixed "make uninstall" for shared libraries -- use Tracev instead of Trace in infblock.c -- in example.c use correct compressed length for test_sync -- suppress +vnocompatwarnings in configure for HPUX (not always supported) - -Changes in 1.0.7 (20 Jan 1998) -- fix gzseek which was broken in write mode -- return error for gzseek to negative absolute position -- fix configure for Linux (Chun-Chung Chen) -- increase stack space for MSC (Tim Wegner) -- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) -- define EXPORTVA for gzprintf (Gilles Vollant) -- added man page zlib.3 (Rick Rodgers) -- for contrib/untgz, fix makedir() and improve Makefile - -- check gzseek in write mode in example.c -- allocate extra buffer for seeks only if gzseek is actually called -- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) -- add inflateSyncPoint in zconf.h -- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def - -Changes in 1.0.6 (19 Jan 1998) -- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and - gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) -- Fix a deflate bug occurring only with compression level 0 (thanks to - Andy Buckler for finding this one). -- In minigzip, pass transparently also the first byte for .Z files. -- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() -- check Z_FINISH in inflate (thanks to Marc Schluper) -- Implement deflateCopy (thanks to Adam Costello) -- make static libraries by default in configure, add --shared option. -- move MSDOS or Windows specific files to directory msdos -- suppress the notion of partial flush to simplify the interface - (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) -- suppress history buffer provided by application to simplify the interface - (this feature was not implemented anyway in 1.0.4) -- next_in and avail_in must be initialized before calling inflateInit or - inflateInit2 -- add EXPORT in all exported functions (for Windows DLL) -- added Makefile.nt (thanks to Stephen Williams) -- added the unsupported "contrib" directory: - contrib/asm386/ by Gilles Vollant - 386 asm code replacing longest_match(). - contrib/iostream/ by Kevin Ruland - A C++ I/O streams interface to the zlib gz* functions - contrib/iostream2/ by Tyge Løvset - Another C++ I/O streams interface - contrib/untgz/ by "Pedro A. Aranda Guti\irrez" - A very simple tar.gz file extractor using zlib - contrib/visual-basic.txt by Carlos Rios - How to use compress(), uncompress() and the gz* functions from VB. -- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression - level) in minigzip (thanks to Tom Lane) - -- use const for rommable constants in deflate -- added test for gzseek and gztell in example.c -- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) -- add undocumented function zError to convert error code to string - (for Tim Smithers) -- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. -- Use default memcpy for Symantec MSDOS compiler. -- Add EXPORT keyword for check_func (needed for Windows DLL) -- add current directory to LD_LIBRARY_PATH for "make test" -- create also a link for libz.so.1 -- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) -- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) -- added -soname for Linux in configure (Chun-Chung Chen, -- assign numbers to the exported functions in zlib.def (for Windows DLL) -- add advice in zlib.h for best usage of deflateSetDictionary -- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) -- allow compilation with ANSI keywords only enabled for TurboC in large model -- avoid "versionString"[0] (Borland bug) -- add NEED_DUMMY_RETURN for Borland -- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). -- allow compilation with CC -- defined STDC for OS/2 (David Charlap) -- limit external names to 8 chars for MVS (Thomas Lund) -- in minigzip.c, use static buffers only for 16-bit systems -- fix suffix check for "minigzip -d foo.gz" -- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) -- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) -- added makelcc.bat for lcc-win32 (Tom St Denis) -- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) -- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. -- check for unistd.h in configure (for off_t) -- remove useless check parameter in inflate_blocks_free -- avoid useless assignment of s->check to itself in inflate_blocks_new -- do not flush twice in gzclose (thanks to Ken Raeburn) -- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h -- use NO_ERRNO_H instead of enumeration of operating systems with errno.h -- work around buggy fclose on pipes for HP/UX -- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) -- fix configure if CC is already equal to gcc - -Changes in 1.0.5 (3 Jan 98) -- Fix inflate to terminate gracefully when fed corrupted or invalid data -- Use const for rommable constants in inflate -- Eliminate memory leaks on error conditions in inflate -- Removed some vestigial code in inflate -- Update web address in README - -Changes in 1.0.4 (24 Jul 96) -- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF - bit, so the decompressor could decompress all the correct data but went - on to attempt decompressing extra garbage data. This affected minigzip too. -- zlibVersion and gzerror return const char* (needed for DLL) -- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) -- use z_error only for DEBUG (avoid problem with DLLs) - -Changes in 1.0.3 (2 Jul 96) -- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS - small and medium models; this makes the library incompatible with previous - versions for these models. (No effect in large model or on other systems.) -- return OK instead of BUF_ERROR if previous deflate call returned with - avail_out as zero but there is nothing to do -- added memcmp for non STDC compilers -- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) -- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) -- better check for 16-bit mode MSC (avoids problem with Symantec) - -Changes in 1.0.2 (23 May 96) -- added Windows DLL support -- added a function zlibVersion (for the DLL support) -- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) -- Bytef is define's instead of typedef'd only for Borland C -- avoid reading uninitialized memory in example.c -- mention in README that the zlib format is now RFC1950 -- updated Makefile.dj2 -- added algorithm.doc - -Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] -- fix array overlay in deflate.c which sometimes caused bad compressed data -- fix inflate bug with empty stored block -- fix MSDOS medium model which was broken in 0.99 -- fix deflateParams() which could generated bad compressed data. -- Bytef is define'd instead of typedef'ed (work around Borland bug) -- added an INDEX file -- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), - Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) -- speed up adler32 for modern machines without auto-increment -- added -ansi for IRIX in configure -- static_init_done in trees.c is an int -- define unlink as delete for VMS -- fix configure for QNX -- add configure branch for SCO and HPUX -- avoid many warnings (unused variables, dead assignments, etc...) -- no fdopen for BeOS -- fix the Watcom fix for 32 bit mode (define FAR as empty) -- removed redefinition of Byte for MKWERKS -- work around an MWKERKS bug (incorrect merge of all .h files) - -Changes in 0.99 (27 Jan 96) -- allow preset dictionary shared between compressor and decompressor -- allow compression level 0 (no compression) -- add deflateParams in zlib.h: allow dynamic change of compression level - and compression strategy. -- test large buffers and deflateParams in example.c -- add optional "configure" to build zlib as a shared library -- suppress Makefile.qnx, use configure instead -- fixed deflate for 64-bit systems (detected on Cray) -- fixed inflate_blocks for 64-bit systems (detected on Alpha) -- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) -- always return Z_BUF_ERROR when deflate() has nothing to do -- deflateInit and inflateInit are now macros to allow version checking -- prefix all global functions and types with z_ with -DZ_PREFIX -- make falloc completely reentrant (inftrees.c) -- fixed very unlikely race condition in ct_static_init -- free in reverse order of allocation to help memory manager -- use zlib-1.0/* instead of zlib/* inside the tar.gz -- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith - -Wconversion -Wstrict-prototypes -Wmissing-prototypes" -- allow gzread on concatenated .gz files -- deflateEnd now returns Z_DATA_ERROR if it was premature -- deflate is finally (?) fully deterministic (no matches beyond end of input) -- Document Z_SYNC_FLUSH -- add uninstall in Makefile -- Check for __cpluplus in zlib.h -- Better test in ct_align for partial flush -- avoid harmless warnings for Borland C++ -- initialize hash_head in deflate.c -- avoid warning on fdopen (gzio.c) for HP cc -Aa -- include stdlib.h for STDC compilers -- include errno.h for Cray -- ignore error if ranlib doesn't exist -- call ranlib twice for NeXTSTEP -- use exec_prefix instead of prefix for libz.a -- renamed ct_* as _tr_* to avoid conflict with applications -- clear z->msg in inflateInit2 before any error return -- initialize opaque in example.c, gzio.c, deflate.c and inflate.c -- fixed typo in zconf.h (_GNUC__ => __GNUC__) -- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) -- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) -- in fcalloc, normalize pointer if size > 65520 bytes -- don't use special fcalloc for 32 bit Borland C++ -- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... -- use Z_BINARY instead of BINARY -- document that gzclose after gzdopen will close the file -- allow "a" as mode in gzopen. -- fix error checking in gzread -- allow skipping .gz extra-field on pipes -- added reference to Perl interface in README -- put the crc table in FAR data (I dislike more and more the medium model :) -- added get_crc_table -- added a dimension to all arrays (Borland C can't count). -- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast -- guard against multiple inclusion of *.h (for precompiled header on Mac) -- Watcom C pretends to be Microsoft C small model even in 32 bit mode. -- don't use unsized arrays to avoid silly warnings by Visual C++: - warning C4746: 'inflate_mask' : unsized array treated as '__far' - (what's wrong with far data in far model?). -- define enum out of inflate_blocks_state to allow compilation with C++ - -Changes in 0.95 (16 Aug 95) -- fix MSDOS small and medium model (now easier to adapt to any compiler) -- inlined send_bits -- fix the final (:-) bug for deflate with flush (output was correct but - not completely flushed in rare occasions). -- default window size is same for compression and decompression - (it's now sufficient to set MAX_WBITS in zconf.h). -- voidp -> voidpf and voidnp -> voidp (for consistency with other - typedefs and because voidnp was not near in large model). - -Changes in 0.94 (13 Aug 95) -- support MSDOS medium model -- fix deflate with flush (could sometimes generate bad output) -- fix deflateReset (zlib header was incorrectly suppressed) -- added support for VMS -- allow a compression level in gzopen() -- gzflush now calls fflush -- For deflate with flush, flush even if no more input is provided. -- rename libgz.a as libz.a -- avoid complex expression in infcodes.c triggering Turbo C bug -- work around a problem with gcc on Alpha (in INSERT_STRING) -- don't use inline functions (problem with some gcc versions) -- allow renaming of Byte, uInt, etc... with #define. -- avoid warning about (unused) pointer before start of array in deflate.c -- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c -- avoid reserved word 'new' in trees.c - -Changes in 0.93 (25 June 95) -- temporarily disable inline functions -- make deflate deterministic -- give enough lookahead for PARTIAL_FLUSH -- Set binary mode for stdin/stdout in minigzip.c for OS/2 -- don't even use signed char in inflate (not portable enough) -- fix inflate memory leak for segmented architectures - -Changes in 0.92 (3 May 95) -- don't assume that char is signed (problem on SGI) -- Clear bit buffer when starting a stored block -- no memcpy on Pyramid -- suppressed inftest.c -- optimized fill_window, put longest_match inline for gcc -- optimized inflate on stored blocks. -- untabify all sources to simplify patches - -Changes in 0.91 (2 May 95) -- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h -- Document the memory requirements in zconf.h -- added "make install" -- fix sync search logic in inflateSync -- deflate(Z_FULL_FLUSH) now works even if output buffer too short -- after inflateSync, don't scare people with just "lo world" -- added support for DJGPP - -Changes in 0.9 (1 May 95) -- don't assume that zalloc clears the allocated memory (the TurboC bug - was Mark's bug after all :) -- let again gzread copy uncompressed data unchanged (was working in 0.71) -- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented -- added a test of inflateSync in example.c -- moved MAX_WBITS to zconf.h because users might want to change that. -- document explicitly that zalloc(64K) on MSDOS must return a normalized - pointer (zero offset) -- added Makefiles for Microsoft C, Turbo C, Borland C++ -- faster crc32() - -Changes in 0.8 (29 April 95) -- added fast inflate (inffast.c) -- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this - is incompatible with previous versions of zlib which returned Z_OK. -- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) - (actually that was not a compiler bug, see 0.81 above) -- gzread no longer reads one extra byte in certain cases -- In gzio destroy(), don't reference a freed structure -- avoid many warnings for MSDOS -- avoid the ERROR symbol which is used by MS Windows - -Changes in 0.71 (14 April 95) -- Fixed more MSDOS compilation problems :( There is still a bug with - TurboC large model. - -Changes in 0.7 (14 April 95) -- Added full inflate support. -- Simplified the crc32() interface. The pre- and post-conditioning - (one's complement) is now done inside crc32(). WARNING: this is - incompatible with previous versions; see zlib.h for the new usage. - -Changes in 0.61 (12 April 95) -- workaround for a bug in TurboC. example and minigzip now work on MSDOS. - -Changes in 0.6 (11 April 95) -- added minigzip.c -- added gzdopen to reopen a file descriptor as gzFile -- added transparent reading of non-gziped files in gzread. -- fixed bug in gzread (don't read crc as data) -- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). -- don't allocate big arrays in the stack (for MSDOS) -- fix some MSDOS compilation problems - -Changes in 0.5: -- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but - not yet Z_FULL_FLUSH. -- support decompression but only in a single step (forced Z_FINISH) -- added opaque object for zalloc and zfree. -- added deflateReset and inflateReset -- added a variable zlib_version for consistency checking. -- renamed the 'filter' parameter of deflateInit2 as 'strategy'. - Added Z_FILTERED and Z_HUFFMAN_ONLY constants. - -Changes in 0.4: -- avoid "zip" everywhere, use zlib instead of ziplib. -- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush - if compression method == 8. -- added adler32 and crc32 -- renamed deflateOptions as deflateInit2, call one or the other but not both -- added the method parameter for deflateInit2. -- added inflateInit2 -- simplied considerably deflateInit and inflateInit by not supporting - user-provided history buffer. This is supported only in deflateInit2 - and inflateInit2. - -Changes in 0.3: -- prefix all macro names with Z_ -- use Z_FINISH instead of deflateEnd to finish compression. -- added Z_HUFFMAN_ONLY -- added gzerror() diff --git a/contrib/libzlib-ng/FAQ.zlib b/contrib/libzlib-ng/FAQ.zlib deleted file mode 100644 index 8da63b40767..00000000000 --- a/contrib/libzlib-ng/FAQ.zlib +++ /dev/null @@ -1,374 +0,0 @@ -## -# THIS IS AN UNMAINTAINED COPY OF THE ORIGINAL FILE DISTRIBUTED WITH ZLIB 1.2.8 -## - - - - - Frequently Asked Questions about zlib - - -If your question is not there, please check the zlib home page -http://zlib.net/ which may have more recent information. -The lastest zlib FAQ is at http://zlib.net/zlib_faq.html - - - 1. Is zlib Y2K-compliant? - - Yes. zlib doesn't handle dates. - - 2. Where can I get a Windows DLL version? - - The zlib sources can be compiled without change to produce a DLL. See the - file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the - precompiled DLL are found in the zlib web site at http://zlib.net/ . - - 3. Where can I get a Visual Basic interface to zlib? - - See - * http://marknelson.us/1997/01/01/zlib-engine/ - * win32/DLL_FAQ.txt in the zlib distribution - - 4. compress() returns Z_BUF_ERROR. - - Make sure that before the call of compress(), the length of the compressed - buffer is equal to the available size of the compressed buffer and not - zero. For Visual Basic, check that this parameter is passed by reference - ("as any"), not by value ("as long"). - - 5. deflate() or inflate() returns Z_BUF_ERROR. - - Before making the call, make sure that avail_in and avail_out are not zero. - When setting the parameter flush equal to Z_FINISH, also make sure that - avail_out is big enough to allow processing all pending input. Note that a - Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be - made with more input or output space. A Z_BUF_ERROR may in fact be - unavoidable depending on how the functions are used, since it is not - possible to tell whether or not there is more output pending when - strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a - heavily annotated example. - - 6. Where's the zlib documentation (man pages, etc.)? - - It's in zlib.h . Examples of zlib usage are in the files test/example.c - and test/minigzip.c, with more in examples/ . - - 7. Why don't you use GNU autoconf or libtool or ...? - - Because we would like to keep zlib as a very small and simple package. - zlib is rather portable and doesn't need much configuration. - - 8. I found a bug in zlib. - - Most of the time, such problems are due to an incorrect usage of zlib. - Please try to reproduce the problem with a small program and send the - corresponding source to us at zlib@gzip.org . Do not send multi-megabyte - data files without prior agreement. - - 9. Why do I get "undefined reference to gzputc"? - - If "make test" produces something like - - example.o(.text+0x154): undefined reference to `gzputc' - - check that you don't have old files libz.* in /usr/lib, /usr/local/lib or - /usr/X11R6/lib. Remove any old versions, then do "make install". - -10. I need a Delphi interface to zlib. - - See the contrib/delphi directory in the zlib distribution. - -11. Can zlib handle .zip archives? - - Not by itself, no. See the directory contrib/minizip in the zlib - distribution. - -12. Can zlib handle .Z files? - - No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt - the code of uncompress on your own. - -13. How can I make a Unix shared library? - - By default a shared (and a static) library is built for Unix. So: - - make distclean - ./configure - make - -14. How do I install a shared zlib library on Unix? - - After the above, then: - - make install - - However, many flavors of Unix come with a shared zlib already installed. - Before going to the trouble of compiling a shared version of zlib and - trying to install it, you may want to check if it's already there! If you - can #include , it's there. The -lz option will probably link to - it. You can check the version at the top of zlib.h or with the - ZLIB_VERSION symbol defined in zlib.h . - -15. I have a question about OttoPDF. - - We are not the authors of OttoPDF. The real author is on the OttoPDF web - site: Joel Hainley, jhainley@myndkryme.com. - -16. Can zlib decode Flate data in an Adobe PDF file? - - Yes. See http://www.pdflib.com/ . To modify PDF forms, see - http://sourceforge.net/projects/acroformtool/ . - -17. Why am I getting this "register_frame_info not found" error on Solaris? - - After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib - generates an error such as: - - ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so: - symbol __register_frame_info: referenced symbol not found - - The symbol __register_frame_info is not part of zlib, it is generated by - the C compiler (cc or gcc). You must recompile applications using zlib - which have this problem. This problem is specific to Solaris. See - http://www.sunfreeware.com for Solaris versions of zlib and applications - using zlib. - -18. Why does gzip give an error on a file I make with compress/deflate? - - The compress and deflate functions produce data in the zlib format, which - is different and incompatible with the gzip format. The gz* functions in - zlib on the other hand use the gzip format. Both the zlib and gzip formats - use the same compressed data format internally, but have different headers - and trailers around the compressed data. - -19. Ok, so why are there two different formats? - - The gzip format was designed to retain the directory information about a - single file, such as the name and last modification date. The zlib format - on the other hand was designed for in-memory and communication channel - applications, and has a much more compact header and trailer and uses a - faster integrity check than gzip. - -20. Well that's nice, but how do I make a gzip file in memory? - - You can request that deflate write the gzip format instead of the zlib - format using deflateInit2(). You can also request that inflate decode the - gzip format using inflateInit2(). Read zlib.h for more details. - -21. Is zlib thread-safe? - - Yes. However any library routines that zlib uses and any application- - provided memory allocation routines must also be thread-safe. zlib's gz* - functions use stdio library routines, and most of zlib's functions use the - library memory allocation routines by default. zlib's *Init* functions - allow for the application to provide custom memory allocation routines. - - Of course, you should only operate on any given zlib or gzip stream from a - single thread at a time. - -22. Can I use zlib in my commercial application? - - Yes. Please read the license in zlib.h. - -23. Is zlib under the GNU license? - - No. Please read the license in zlib.h. - -24. The license says that altered source versions must be "plainly marked". So - what exactly do I need to do to meet that requirement? - - You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In - particular, the final version number needs to be changed to "f", and an - identification string should be appended to ZLIB_VERSION. Version numbers - x.x.x.f are reserved for modifications to zlib by others than the zlib - maintainers. For example, if the version of the base zlib you are altering - is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and - ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also - update the version strings in deflate.c and inftrees.c. - - For altered source distributions, you should also note the origin and - nature of the changes in zlib.h, as well as in ChangeLog and README, along - with the dates of the alterations. The origin should include at least your - name (or your company's name), and an email address to contact for help or - issues with the library. - - Note that distributing a compiled zlib library along with zlib.h and - zconf.h is also a source distribution, and so you should change - ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes - in zlib.h as you would for a full source distribution. - -25. Will zlib work on a big-endian or little-endian architecture, and can I - exchange compressed data between them? - - Yes and yes. - -26. Will zlib work on a 64-bit machine? - - Yes. It has been tested on 64-bit machines, and has no dependence on any - data types being limited to 32-bits in length. If you have any - difficulties, please provide a complete problem report to zlib@gzip.org - -27. Will zlib decompress data from the PKWare Data Compression Library? - - No. The PKWare DCL uses a completely different compressed data format than - does PKZIP and zlib. However, you can look in zlib's contrib/blast - directory for a possible solution to your problem. - -28. Can I access data randomly in a compressed stream? - - No, not without some preparation. If when compressing you periodically use - Z_FULL_FLUSH, carefully write all the pending data at those points, and - keep an index of those locations, then you can start decompression at those - points. You have to be careful to not use Z_FULL_FLUSH too often, since it - can significantly degrade compression. Alternatively, you can scan a - deflate stream once to generate an index, and then use that index for - random access. See examples/zran.c . - -29. Does zlib work on MVS, OS/390, CICS, etc.? - - It has in the past, but we have not heard of any recent evidence. There - were working ports of zlib 1.1.4 to MVS, but those links no longer work. - If you know of recent, successful applications of zlib on these operating - systems, please let us know. Thanks. - -30. Is there some simpler, easier to read version of inflate I can look at to - understand the deflate format? - - First off, you should read RFC 1951. Second, yes. Look in zlib's - contrib/puff directory. - -31. Does zlib infringe on any patents? - - As far as we know, no. In fact, that was originally the whole point behind - zlib. Look here for some more information: - - http://www.gzip.org/#faq11 - -32. Can zlib work with greater than 4 GB of data? - - Yes. inflate() and deflate() will process any amount of data correctly. - Each call of inflate() or deflate() is limited to input and output chunks - of the maximum value that can be stored in the compiler's "unsigned int" - type, but there is no limit to the number of chunks. Note however that the - strm.total_in and strm_total_out counters may be limited to 4 GB. These - counters are provided as a convenience and are not used internally by - inflate() or deflate(). The application can easily set up its own counters - updated after each call of inflate() or deflate() to count beyond 4 GB. - compress() and uncompress() may be limited to 4 GB, since they operate in a - single call. gzseek() and gztell() may be limited to 4 GB depending on how - zlib is compiled. See the zlibCompileFlags() function in zlib.h. - - The word "may" appears several times above since there is a 4 GB limit only - if the compiler's "long" type is 32 bits. If the compiler's "long" type is - 64 bits, then the limit is 16 exabytes. - -33. Does zlib have any security vulnerabilities? - - The only one that we are aware of is potentially in gzprintf(). If zlib is - compiled to use sprintf() or vsprintf(), then there is no protection - against a buffer overflow of an 8K string space (or other value as set by - gzbuffer()), other than the caller of gzprintf() assuring that the output - will not exceed 8K. On the other hand, if zlib is compiled to use - snprintf() or vsnprintf(), which should normally be the case, then there is - no vulnerability. The ./configure script will display warnings if an - insecure variation of sprintf() will be used by gzprintf(). Also the - zlibCompileFlags() function will return information on what variant of - sprintf() is used by gzprintf(). - - If you don't have snprintf() or vsnprintf() and would like one, you can - find a portable implementation here: - - http://www.ijs.si/software/snprintf/ - - Note that you should be using the most recent version of zlib. Versions - 1.1.3 and before were subject to a double-free vulnerability, and versions - 1.2.1 and 1.2.2 were subject to an access exception when decompressing - invalid compressed data. - -34. Is there a Java version of zlib? - - Probably what you want is to use zlib in Java. zlib is already included - as part of the Java SDK in the java.util.zip package. If you really want - a version of zlib written in the Java language, look on the zlib home - page for links: http://zlib.net/ . - -35. I get this or that compiler or source-code scanner warning when I crank it - up to maximally-pedantic. Can't you guys write proper code? - - Many years ago, we gave up attempting to avoid warnings on every compiler - in the universe. It just got to be a waste of time, and some compilers - were downright silly as well as contradicted each other. So now, we simply - make sure that the code always works. - -36. Valgrind (or some similar memory access checker) says that deflate is - performing a conditional jump that depends on an uninitialized value. - Isn't that a bug? - - No. That is intentional for performance reasons, and the output of deflate - is not affected. This only started showing up recently since zlib 1.2.x - uses malloc() by default for allocations, whereas earlier versions used - calloc(), which zeros out the allocated memory. Even though the code was - correct, versions 1.2.4 and later was changed to not stimulate these - checkers. - -37. Will zlib read the (insert any ancient or arcane format here) compressed - data format? - - Probably not. Look in the comp.compression FAQ for pointers to various - formats and associated software. - -38. How can I encrypt/decrypt zip files with zlib? - - zlib doesn't support encryption. The original PKZIP encryption is very - weak and can be broken with freely available programs. To get strong - encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib - compression. For PKZIP compatible "encryption", look at - http://www.info-zip.org/ - -39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? - - "gzip" is the gzip format, and "deflate" is the zlib format. They should - probably have called the second one "zlib" instead to avoid confusion with - the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 - correctly points to the zlib specification in RFC 1950 for the "deflate" - transfer encoding, there have been reports of servers and browsers that - incorrectly produce or expect raw deflate data per the deflate - specification in RFC 1951, most notably Microsoft. So even though the - "deflate" transfer encoding using the zlib format would be the more - efficient approach (and in fact exactly what the zlib format was designed - for), using the "gzip" transfer encoding is probably more reliable due to - an unfortunate choice of name on the part of the HTTP 1.1 authors. - - Bottom line: use the gzip format for HTTP 1.1 encoding. - -40. Does zlib support the new "Deflate64" format introduced by PKWare? - - No. PKWare has apparently decided to keep that format proprietary, since - they have not documented it as they have previous compression formats. In - any case, the compression improvements are so modest compared to other more - modern approaches, that it's not worth the effort to implement. - -41. I'm having a problem with the zip functions in zlib, can you help? - - There are no zip functions in zlib. You are probably using minizip by - Giles Vollant, which is found in the contrib directory of zlib. It is not - part of zlib. In fact none of the stuff in contrib is part of zlib. The - files in there are not supported by the zlib authors. You need to contact - the authors of the respective contribution for help. - -42. The match.asm code in contrib is under the GNU General Public License. - Since it's part of zlib, doesn't that mean that all of zlib falls under the - GNU GPL? - - No. The files in contrib are not part of zlib. They were contributed by - other authors and are provided as a convenience to the user within the zlib - distribution. Each item in contrib has its own license. - -43. Is zlib subject to export controls? What is its ECCN? - - zlib is not subject to export controls, and so is classified as EAR99. - -44. Can you please sign these lengthy legal documents and fax them back to us - so that we can use your software in our product? - - No. Go away. Shoo. diff --git a/contrib/libzlib-ng/INDEX b/contrib/libzlib-ng/INDEX deleted file mode 100644 index acb9aba64c3..00000000000 --- a/contrib/libzlib-ng/INDEX +++ /dev/null @@ -1,55 +0,0 @@ -CMakeLists.txt cmake build file -ChangeLog.zlib history of changes up to the fork from zlib 1.2.8 -FAQ.zlib Frequently Asked Questions about zlib, as distributed in zlib 1.2.8 -INDEX this file -Makefile dummy Makefile that tells you to ./configure -Makefile.in template for Unix Makefile -README guess what -README.zlib Copy of the original README file distributed in zlib 1.2.8 -configure configure script for Unix -test/example.c zlib usages examples for build testing -test/minigzip.c minimal gzip-like functionality for build testing -test/infcover.c inf*.c code coverage for build coverage testing -treebuild.xml XML description of source file dependencies -zconf.h.cmakein zconf.h template for cmake -zconf.h.in zconf.h template for configure -zlib.3 Man page for zlib -zlib.3.pdf Man page in PDF format -zlib.map Linux symbol information -zlib.pc.in Template for pkg-config descriptor -zlib.pc.cmakein zlib.pc template for cmake -zlib2ansi perl script to convert source files for C++ compilation - -arch/ architecture-specific code -doc/ documentation for formats and algorithms -win32/ makefiles for Windows - - zlib public header files (required for library use): -zconf.h -zlib.h - - private source files used to build the zlib library: -adler32.c -compress.c -crc32.c -crc32.h -deflate.c -deflate.h -gzclose.c -gzguts.h -gzlib.c -gzread.c -gzwrite.c -infback.c -inffast.c -inffast.h -inffixed.h -inflate.c -inflate.h -inftrees.c -inftrees.h -trees.c -trees.h -uncompr.c -zutil.c -zutil.h diff --git a/contrib/libzlib-ng/LICENSE.md b/contrib/libzlib-ng/LICENSE.md deleted file mode 100644 index adb48d47296..00000000000 --- a/contrib/libzlib-ng/LICENSE.md +++ /dev/null @@ -1,19 +0,0 @@ -(C) 1995-2013 Jean-loup Gailly and Mark Adler - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - -3. This notice may not be removed or altered from any source distribution. diff --git a/contrib/libzlib-ng/Makefile.in b/contrib/libzlib-ng/Makefile.in deleted file mode 100644 index c69175e2d9a..00000000000 --- a/contrib/libzlib-ng/Makefile.in +++ /dev/null @@ -1,329 +0,0 @@ -# Makefile for zlib -# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler -# For conditions of distribution and use, see copyright notice in zlib.h - -# To compile and test, type: -# ./configure; make test -# Normally configure builds both a static and a shared library. -# If you want to build just a static library, use: ./configure --static - -# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: -# make install -# To install in $HOME instead of /usr/local, use: -# make install prefix=$HOME - -CC=cc - -CFLAGS=-O -#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 -#CFLAGS=-g -DDEBUG -#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ -# -Wstrict-prototypes -Wmissing-prototypes - -SFLAGS=-O -LDFLAGS= -TEST_LDFLAGS=-L. libz.a -LDSHARED=$(CC) - -STATICLIB=libz.a -SHAREDLIB=libz.so -SHAREDLIBV=libz.so.1.2.8 -SHAREDLIBM=libz.so.1 -IMPORTLIB= -SHAREDTARGET=libz.so.1.2.8 - -LIBS=$(STATICLIB) $(SHAREDTARGET) - -AR=ar -ARFLAGS=rc -DEFFILE= -RC= -RCFLAGS= -RCOBJS= -STRIP= -RANLIB=ranlib -LDCONFIG=ldconfig -LDSHAREDLIBC=-lc -TAR=tar -SHELL=/bin/sh -EXE= - -SRCDIR=. -INCLUDES=-I$(SRCDIR) - -ARCHDIR=arch/generic -ARCH_STATIC_OBJS= -ARCH_SHARED_OBJS= - -prefix = /usr/local -exec_prefix = ${prefix} -bindir = ${exec_prefix}/bin -libdir = ${exec_prefix}/lib -sharedlibdir = ${libdir} -includedir = ${prefix}/include -mandir = ${prefix}/share/man -man3dir = ${mandir}/man3 -pkgconfigdir = ${libdir}/pkgconfig - -OBJZ = adler32.o compress.o crc32.o deflate.o deflate_fast.o deflate_medium.o deflate_slow.o match.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o $(ARCH_STATIC_OBJS) -OBJG = gzclose.o gzlib.o gzread.o gzwrite.o -OBJC = $(OBJZ) $(OBJG) - -PIC_OBJZ = adler32.lo compress.lo crc32.lo deflate.lo deflate_fast.lo deflate_medium.lo deflate_slow.lo match.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo uncompr.lo zutil.lo $(ARCH_SHARED_OBJS) -PIC_OBJG = gzclose.lo gzlib.lo gzread.lo gzwrite.lo -PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG) - -OBJS = $(OBJC) - -PIC_OBJS = $(PIC_OBJC) - -all: static shared - -static: example$(EXE) minigzip$(EXE) - -shared: examplesh$(EXE) minigzipsh$(EXE) - -all64: example64$(EXE) minigzip64$(EXE) - -check: test - -$(ARCHDIR)/%.o: $(SRCDIR)/$(ARCHDIR)/%.c - $(MAKE) -C $(ARCHDIR) $(notdir $@) - -$(ARCHDIR)/%.lo: $(SRCDIR)/$(ARCHDIR)/%.c - $(MAKE) -C $(ARCHDIR) $(notdir $@) - -%.o: $(ARCHDIR)/%.o - -cp $< $@ - -%.lo: $(ARCHDIR)/%.lo - -cp $< $@ - -test: all - $(MAKE) -C test - -infcover.o: $(SRCDIR)/test/infcover.c $(SRCDIR)/zlib.h zconf.h - $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/test/infcover.c - -infcover$(EXE): infcover.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ infcover.o $(STATICLIB) -ifneq ($(STRIP),) - $(STRIP) $@ -endif - -cover: infcover$(EXE) - rm -f *.gcda - ./infcover - gcov inf*.c - -$(STATICLIB): $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 - -example.o: $(SRCDIR)/test/example.c $(SRCDIR)/zlib.h zconf.h - $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/test/example.c - -minigzip.o: $(SRCDIR)/test/minigzip.c $(SRCDIR)/zlib.h zconf.h - $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/test/minigzip.c - -example64.o: $(SRCDIR)/test/example.c $(SRCDIR)/zlib.h zconf.h - $(CC) $(CFLAGS) $(INCLUDES) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)/test/example.c - -minigzip64.o: $(SRCDIR)/test/minigzip.c $(SRCDIR)/zlib.h zconf.h - $(CC) $(CFLAGS) $(INCLUDES) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)/test/minigzip.c - -zlibrc.o: win32/zlib1.rc - $(RC) $(RCFLAGS) -o $@ win32/zlib1.rc - -.SUFFIXES: .lo - -%.o: $(SRCDIR)/%.c - $(CC) $(INCLUDES) $(CFLAGS) -c -o $@ $< - -%.lo: $(SRCDIR)/%.c - $(CC) $(INCLUDES) $(SFLAGS) -DPIC -c -o $@ $< - -$(SHAREDTARGET): $(PIC_OBJS) $(DEFFILE) $(RCOBJS) -ifneq ($(SHAREDTARGET),) - $(LDSHARED) $(SFLAGS) -o $@ $(DEFFILE) $(PIC_OBJS) $(RCOBJS) $(LDSHAREDLIBC) $(LDFLAGS) -ifneq ($(STRIP),) - $(STRIP) $@ -endif -ifneq ($(SHAREDLIB),$(SHAREDTARGET)) - rm -f $(SHAREDLIB) $(SHAREDLIBM) - ln -s $@ $(SHAREDLIB) - ln -s $@ $(SHAREDLIBM) -endif -endif - -example$(EXE): example.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS) -ifneq ($(STRIP),) - $(STRIP) $@ -endif - -minigzip$(EXE): minigzip.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS) -ifneq ($(STRIP),) - $(STRIP) $@ -endif - -examplesh$(EXE): example.o $(SHAREDTARGET) - $(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDTARGET) -ifneq ($(STRIP),) - $(STRIP) $@ -endif - -minigzipsh$(EXE): minigzip.o $(SHAREDTARGET) - $(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDTARGET) -ifneq ($(STRIP),) - $(STRIP) $@ -endif - -example64$(EXE): example64.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS) -ifneq ($(STRIP),) - $(STRIP) $@ -endif - -minigzip64$(EXE): minigzip64.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ minigzip64.o $(TEST_LDFLAGS) -ifneq ($(STRIP),) - $(STRIP) $@ -endif - -install-shared: $(SHAREDTARGET) -ifneq ($(SHAREDTARGET),) - -@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi - cp $(SHAREDTARGET) $(DESTDIR)$(sharedlibdir) - chmod 644 $(DESTDIR)$(sharedlibdir)/$(SHAREDTARGET) -ifneq ($(SHAREDLIB),$(SHAREDTARGET)) - rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM) - ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) - ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM) - ($(LDCONFIG) || true) >/dev/null 2>&1 -# ldconfig is for Linux -endif -ifneq ($(IMPORTLIB),) - cp $(IMPORTLIB) $(DESTDIR)$(sharedlibdir) - chmod 644 $(DESTDIR)$(sharedlibdir)/$(IMPORTLIB) -endif -endif - -install-static: $(STATICLIB) - -@if [ ! -d $(DESTDIR)$(libdir) ]; then mkdir -p $(DESTDIR)$(libdir); fi - cp $(STATICLIB) $(DESTDIR)$(libdir) - chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB) - -@($(RANLIB) $(DESTDIR)$(libdir)/$(STATICLIB) || true) >/dev/null 2>&1 -# The ranlib in install-static is needed on NeXTSTEP which checks file times - -install-libs: install-shared install-static - -@if [ ! -d $(DESTDIR)$(man3dir) ]; then mkdir -p $(DESTDIR)$(man3dir); fi - -@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi - cp $(SRCDIR)/zlib.3 $(DESTDIR)$(man3dir) - chmod 644 $(DESTDIR)$(man3dir)/zlib.3 - cp zlib.pc $(DESTDIR)$(pkgconfigdir) - chmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc - -install: install-libs - -@if [ ! -d $(DESTDIR)$(includedir) ]; then mkdir -p $(DESTDIR)$(includedir); fi - cp $(SRCDIR)/zlib.h zconf.h $(DESTDIR)$(includedir) - chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h - -uninstall-static: - cd $(DESTDIR)$(libdir) && rm -f $(STATICLIB) - -uninstall-shared: -ifneq ($(SHAREDLIB),) - cd $(DESTDIR)$(sharedlibdir) && rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM) -endif -ifneq ($(IMPORTLIB),) - cd $(DESTDIR)$(sharedlibdir) && rm -f $(IMPORTLIB) -endif - -uninstall: uninstall-static uninstall-shared - cd $(DESTDIR)$(includedir) && rm -f zlib.h zconf.h - cd $(DESTDIR)$(man3dir) && rm -f zlib.3 - cd $(DESTDIR)$(pkgconfigdir) && rm -f zlib.pc - -docs: zlib.3.pdf - -zlib.3.pdf: $(SRCDIR)/zlib.3 - groff -mandoc -f H -T ps $(SRCDIR)/zlib.3 | ps2pdf - zlib.3.pdf - -mostlyclean: clean -clean: - @if [ -f $(ARCHDIR)/Makefile ]; then $(MAKE) -C $(ARCHDIR) clean; fi - @if [ -f test/Makefile ]; then $(MAKE) -C test clean; fi - rm -f *.o *.lo *~ \ - example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \ - example64$(EXE) minigzip64$(EXE) \ - infcover \ - $(STATICLIB) $(IMPORTLIB) $(SHAREDLIB) $(SHAREDLIBV) $(SHAREDLIBM) \ - foo.gz so_locations \ - _match.s maketree - rm -rf objs - rm -f *.gcda *.gcno *.gcov - rm -f a.out - -maintainer-clean: distclean -distclean: clean - @if [ -f $(ARCHDIR)/Makefile ]; then $(MAKE) -C $(ARCHDIR) distclean; fi - @if [ -f test/Makefile ]; then $(MAKE) -C test distclean; fi - rm -f zlib.pc configure.log zconf.h zconf.h.cmakein - -@rm -f .DS_Store -# Reset Makefile if building inside source tree - @if [ -f Makefile.in ]; then \ - printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile ; \ - printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile ; \ - touch -r $(SRCDIR)/Makefile.in Makefile ; fi -# Reset zconf.h and zconf.h.cmakein if building inside source tree - @if [ -f zconf.h.in ]; then \ - cp -p $(SRCDIR)/zconf.h.in zconf.h ; \ - TEMPFILE=zconfh_$$ ; \ - echo "/#define ZCONF_H/ a\\\\\n#cmakedefine Z_HAVE_UNISTD_H\n" >> $$TEMPFILE &&\ - sed -f $$TEMPFILE $(SRCDIR)/zconf.h.in > zconf.h.cmakein &&\ - touch -r $(SRCDIR)/zconf.h.in zconf.h.cmakein &&\ - rm $$TEMPFILE ; fi -# Cleanup these files if building outside source tree - @if [ ! -f zlib.3 ]; then rm -f zlib.3.pdf Makefile; fi -# Remove arch and test directory if building outside source tree - @if [ ! -f $(ARCHDIR)/Makefile.in ]; then rm -rf arch; fi - @if [ ! -f test/Makefile.in ]; then rm -rf test; fi - -tags: - etags $(SRCDIR)/*.[ch] - -depend: - makedepend -- $(CFLAGS) -- $(SRCDIR)/*.[ch] - makedepend -a -o.lo -- $(SFLAGS) -- $(SRCDIR)/*.[ch] - @sed "s=^$(SRCDIR)/\([a-zA-Z0-9_]*\.\(lo\|o\):\)=\1=g" < Makefile > Makefile.tmp - @mv -f Makefile.tmp Makefile - -# DO NOT DELETE THIS LINE -- make depend depends on it. - -adler32.o zutil.o: $(SRCDIR)/zutil.h $(SRCDIR)/zlib.h zconf.h -gzclose.o gzlib.o gzread.o gzwrite.o: $(SRCDIR)/zlib.h zconf.h $(SRCDIR)/gzguts.h -compress.o example.o minigzip.o uncompr.o: $(SRCDIR)/zlib.h zconf.h -crc32.o: $(SRCDIR)/zutil.h $(SRCDIR)/zlib.h zconf.h $(SRCDIR)/crc32.h -deflate.o: $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/match.h $(SRCDIR)/zutil.h $(SRCDIR)/zlib.h zconf.h -deflate_fast.o: $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/match.h -deflate_medium.o: $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/match.h -deflate_slow.o: $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/match.h -infback.o inflate.o: $(SRCDIR)/zutil.h $(SRCDIR)/zlib.h zconf.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inffast.h $(SRCDIR)/inffixed.h -inffast.o: $(SRCDIR)/zutil.h $(SRCDIR)/zlib.h zconf.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inffast.h -inftrees.o: $(SRCDIR)/zutil.h $(SRCDIR)/zlib.h zconf.h $(SRCDIR)/inftrees.h -trees.o: $(SRCDIR)/deflate.h $(SRCDIR)/zutil.h $(SRCDIR)/zlib.h zconf.h $(SRCDIR)/trees.h - -adler32.lo zutil.lo: $(SRCDIR)/zutil.h $(SRCDIR)/zlib.h zconf.h -gzclose.lo gzlib.lo gzread.lo gzwrite.lo: $(SRCDIR)/zlib.h zconf.h $(SRCDIR)/gzguts.h -compress.lo example.lo minigzip.lo uncompr.lo: $(SRCDIR)/zlib.h zconf.h -crc32.lo: $(SRCDIR)/zutil.h $(SRCDIR)/zlib.h zconf.h $(SRCDIR)/crc32.h -deflate.lo: $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/match.h $(SRCDIR)/zutil.h $(SRCDIR)/zlib.h zconf.h -deflate_fast.lo: $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/match.h -deflate_medium.lo: $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/match.h -deflate_slow.lo: $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/match.h -infback.lo inflate.lo: $(SRCDIR)/zutil.h $(SRCDIR)/zlib.h zconf.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inffast.h $(SRCDIR)/inffixed.h -inffast.lo: $(SRCDIR)/zutil.h $(SRCDIR)/zlib.h zconf.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inffast.h -inftrees.lo: $(SRCDIR)/zutil.h $(SRCDIR)/zlib.h zconf.h $(SRCDIR)/inftrees.h -trees.lo: $(SRCDIR)/deflate.h $(SRCDIR)/zutil.h $(SRCDIR)/zlib.h zconf.h $(SRCDIR)/trees.h diff --git a/contrib/libzlib-ng/README b/contrib/libzlib-ng/README deleted file mode 100644 index db98f1112fb..00000000000 --- a/contrib/libzlib-ng/README +++ /dev/null @@ -1,63 +0,0 @@ -zlib-ng - zlib for the next generation systems - -Maintained by Hans Kristian Rosbach - aka Dead2 (zlib-ng àt circlestorm dót org) - - -Fork Motivation and History ---------------------------- - -The motivation for this fork was due to seeing several 3rd party -contributions containing new optimizations not getting implemented -into the official zlib repository. - -Mark Adler has been maintaining zlib for a very long time, and he has -done a great job and hopefully he will continue for a long time yet. -The idea of zlib-ng is not to replace zlib, but to co-exist as a -drop-in replacement with a lower threshold for code change. - -zlib has a long history and is incredibly portable, even supporting -lots of systems that predate the Internet. This is great, but it does -complicate further development and maintainability. -The zlib code has to make numerous workarounds for old compilers that -do not understand ANSI-C or to accommodate systems with limitations -such as operating in a 16-bit environment. - -Many of these workarounds are only maintenance burdens, some of them -are pretty huge code-wise. For example, the [v]s[n]printf workaround -code has a whopping 8 different implementations just to cater to -various old compilers. With this many workarounds cluttered throughout -the code, new programmers with an idea/interest for zlib will need -to take some time to figure out why all of these seemingly strange -things are used, and how to work within those confines. - -So I decided to make a fork, merge all the Intel optimizations, merge -the Cloudflare optimizations that did not conflict, plus a couple -of other smaller patches. Then I started cleaning out workarounds, -various dead code, all contrib and example code as there is little -point in having those in this fork for different reasons. - -Lastly I have been cleaning up the handling of different arches, -so that it will be easier to implement arch-specific code without -cluttering up the main code too much. - -Now, there is still a lot to do and I am sure there are better ways -of doing several of the changes I have done. And I would be delighted -to receive patches, preferably as pull requests on github. -Just remember that any code you submit must be your own and it must -be zlib licensed. - -Please read LICENSE.md, it is very simple and very liberal. - - -Acknowledgments ----------------- - -Big thanks to Raske Sider AS / raskesider.no for sponsoring my -maintainership of zlib-ng. - -The deflate format used by zlib was defined by Phil Katz. -The deflate and zlib specifications were written by L. Peter Deutsch. - -zlib was originally created by Jean-loup Gailly (compression) -and Mark Adler (decompression). diff --git a/contrib/libzlib-ng/README.clickhouse b/contrib/libzlib-ng/README.clickhouse deleted file mode 100644 index 82f318a88ee..00000000000 --- a/contrib/libzlib-ng/README.clickhouse +++ /dev/null @@ -1,12 +0,0 @@ -Sources imported from https://github.com/Dead2/zlib-ng/tree/343c4c549107d31f6eeabfb4b31bec4502a2ea0e -CMakeLists.txt taken from https://github.com/mtl1979/zlib-ng/tree/ad8868ab0e78a87fb0485d4bc67b8cfe96e00891 - -Zlib with CloudFlare patches provides slightly better performance for decompression and compression -with level > 1. Unfortunately, we can't use that version due to GPL-licensed code. If you still -want to use it, replace contents of this directory with contents of https://github.com/cloudflare/zlib -and add the following lines at the beginning of CMakeLists.txt: - -set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-variable -DHAS_PCLMUL") -set (ZLIB_ASMS - contrib/amd64/crc32-pclmul_asm.S -) diff --git a/contrib/libzlib-ng/README.md b/contrib/libzlib-ng/README.md deleted file mode 100644 index 35ea0545568..00000000000 --- a/contrib/libzlib-ng/README.md +++ /dev/null @@ -1,65 +0,0 @@ -Travis CI: [![build status](https://api.travis-ci.org/Dead2/zlib-ng.svg)](https://travis-ci.org/Dead2/zlib-ng/) - -zlib-ng - zlib for the next generation systems - -Maintained by Hans Kristian Rosbach - aka Dead2 (zlib-ng àt circlestorm dót org) - - -Fork Motivation and History ---------------------------- - -The motivation for this fork was due to seeing several 3rd party -contributions containing new optimizations not getting implemented -into the official zlib repository. - -Mark Adler has been maintaining zlib for a very long time, and he has -done a great job and hopefully he will continue for a long time yet. -The idea of zlib-ng is not to replace zlib, but to co-exist as a -drop-in replacement with a lower threshold for code change. - -zlib has a long history and is incredibly portable, even supporting -lots of systems that predate the Internet. This is great, but it does -complicate further development and maintainability. -The zlib code has to make numerous workarounds for old compilers that -do not understand ANSI-C or to accommodate systems with limitations -such as operating in a 16-bit environment. - -Many of these workarounds are only maintenance burdens, some of them -are pretty huge code-wise. For example, the [v]s[n]printf workaround -code has a whopping 8 different implementations just to cater to -various old compilers. With this many workarounds cluttered throughout -the code, new programmers with an idea/interest for zlib will need -to take some time to figure out why all of these seemingly strange -things are used, and how to work within those confines. - -So I decided to make a fork, merge all the Intel optimizations, merge -the Cloudflare optimizations that did not conflict, plus a couple -of other smaller patches. Then I started cleaning out workarounds, -various dead code, all contrib and example code as there is little -point in having those in this fork for different reasons. - -Lastly I have been cleaning up the handling of different arches, -so that it will be easier to implement arch-specific code without -cluttering up the main code too much. - -Now, there is still a lot to do and I am sure there are better ways -of doing several of the changes I have done. And I would be delighted -to receive patches, preferably as pull requests on github. -Just remember that any code you submit must be your own and it must -be zlib licensed. - -Please read LICENSE.md, it is very simple and very liberal. - - -Acknowledgments ----------------- - -Big thanks to Raske Sider AS / raskesider.no for sponsoring my -maintainership of zlib-ng. - -The deflate format used by zlib was defined by Phil Katz. -The deflate and zlib specifications were written by L. Peter Deutsch. - -zlib was originally created by Jean-loup Gailly (compression) -and Mark Adler (decompression). diff --git a/contrib/libzlib-ng/README.zlib b/contrib/libzlib-ng/README.zlib deleted file mode 100644 index 200579260ac..00000000000 --- a/contrib/libzlib-ng/README.zlib +++ /dev/null @@ -1,121 +0,0 @@ -## -# THIS IS AN UNMAINTAINED COPY OF THE ORIGINAL FILE DISTRIBUTED WITH ZLIB 1.2.8 -## - - - -ZLIB DATA COMPRESSION LIBRARY - -zlib 1.2.8 is a general purpose data compression library. All the code is -thread safe. The data format used by the zlib library is described by RFCs -(Request for Comments) 1950 to 1952 in the files -http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and -rfc1952 (gzip format). - -All functions of the compression library are documented in the file zlib.h -(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example -of the library is given in the file test/example.c which also tests that -the library is working correctly. Another example is given in the file -test/minigzip.c. The compression library itself is composed of all source -files in the root directory. - -To compile all files and run the test program, follow the instructions given at -the top of Makefile.in. In short "./configure; make test", and if that goes -well, "make install" should work for most flavors of Unix. For Windows, use -one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use -make_vms.com. - -Questions about zlib should be sent to , or to Gilles Vollant - for the Windows DLL version. The zlib home page is -http://zlib.net/ . Before reporting a problem, please check this site to -verify that you have the latest version of zlib; otherwise get the latest -version and check whether the problem still exists or not. - -PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. - -Mark Nelson wrote an article about zlib for the Jan. 1997 -issue of Dr. Dobb's Journal; a copy of the article is available at -http://marknelson.us/1997/01/01/zlib-engine/ . - -The changes made in version 1.2.8 are documented in the file ChangeLog. - -Unsupported third party contributions are provided in directory contrib/ . - -zlib is available in Java using the java.util.zip package, documented at -http://java.sun.com/developer/technicalArticles/Programming/compression/ . - -A Perl interface to zlib written by Paul Marquess is available -at CPAN (Comprehensive Perl Archive Network) sites, including -http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . - -A Python interface to zlib written by A.M. Kuchling is -available in Python 1.5 and later versions, see -http://docs.python.org/library/zlib.html . - -zlib is built into tcl: http://wiki.tcl.tk/4610 . - -An experimental package to read and write files in .zip format, written on top -of zlib by Gilles Vollant , is available in the -contrib/minizip directory of zlib. - - -Notes for some targets: - -- For Windows DLL versions, please see win32/DLL_FAQ.txt - -- For 64-bit Irix, deflate.c must be compiled without any optimization. With - -O, one libpng test fails. The test works in 32 bit mode (with the -n32 - compiler flag). The compiler bug has been reported to SGI. - -- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works - when compiled with cc. - -- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is - necessary to get gzprintf working correctly. This is done by configure. - -- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with - other compilers. Use "make test" to check your compiler. - -- gzdopen is not supported on RISCOS or BEOS. - -- For PalmOs, see http://palmzlib.sourceforge.net/ - - -Acknowledgments: - - The deflate format used by zlib was defined by Phil Katz. The deflate and - zlib specifications were written by L. Peter Deutsch. Thanks to all the - people who reported problems and suggested various improvements in zlib; they - are too numerous to cite here. - -Copyright notice: - - (C) 1995-2013 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - -If you use the zlib library in a product, we would appreciate *not* receiving -lengthy legal documents to sign. The sources are provided for free but without -warranty of any kind. The library has been entirely written by Jean-loup -Gailly and Mark Adler; it does not include third-party code. - -If you redistribute modified sources, we would appreciate that you include in -the file ChangeLog history information documenting your changes. Please read -the FAQ for more information on the distribution of modified source versions. diff --git a/contrib/libzlib-ng/adler32.c b/contrib/libzlib-ng/adler32.c deleted file mode 100644 index 495101dd5d0..00000000000 --- a/contrib/libzlib-ng/adler32.c +++ /dev/null @@ -1,177 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2011 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -static uint32_t adler32_combine_(uint32_t adler1, uint32_t adler2, z_off64_t len2); - -#define BASE 65521U /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf, i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf, i) DO1(buf, i); DO1(buf, i+1); -#define DO4(buf, i) DO2(buf, i); DO2(buf, i+2); -#define DO8(buf, i) DO4(buf, i); DO4(buf, i+4); -#define DO16(buf) DO8(buf, 0); DO8(buf, 8); - -/* use NO_DIVIDE if your processor does not do division in hardware -- - try it both ways to see which is faster */ -#ifdef NO_DIVIDE -/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 - (thank you to John Reiser for pointing this out) */ -# define CHOP(a) \ - do { \ - uint32_t tmp = a >> 16; \ - a &= 0xffff; \ - a += (tmp << 4) - tmp; \ - } while (0) -# define MOD28(a) \ - do { \ - CHOP(a); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD(a) \ - do { \ - CHOP(a); \ - MOD28(a); \ - } while (0) -# define MOD63(a) \ - do { /* this assumes a is not negative */ \ - z_off64_t tmp = a >> 32; \ - a &= 0xffffffffL; \ - a += (tmp << 8) - (tmp << 5) + tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD28(a) a %= BASE -# define MOD63(a) a %= BASE -#endif - -/* ========================================================================= */ -uint32_t ZEXPORT adler32(uint32_t adler, const unsigned char *buf, uint32_t len) { - uint32_t sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD28(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; -#ifndef UNROLL_LESS - n = NMAX / 16; /* NMAX is divisible by 16 */ -#else - n = NMAX / 8; /* NMAX is divisible by 8 */ -#endif - do { -#ifndef UNROLL_LESS - DO16(buf); /* 16 sums unrolled */ - buf += 16; -#else - DO8(buf, 0); /* 8 sums unrolled */ - buf += 8; -#endif - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ -#ifndef UNROLL_LESS - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; -#else - while (len >= 8) { - len -= 8; - DO8(buf, 0); - buf += 8; -#endif - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -static uint32_t adler32_combine_(uint32_t adler1, uint32_t adler2, z_off64_t len2) { - uint32_t sum1; - uint32_t sum2; - unsigned rem; - - /* for negative len, return invalid adler32 as a clue for debugging */ - if (len2 < 0) - return 0xffffffff; - - /* the derivation of this formula is left as an exercise for the reader */ - MOD63(len2); /* assumes len2 >= 0 */ - rem = (unsigned)len2; - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 >= BASE) sum1 -= BASE; - if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); - if (sum2 >= BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} - -/* ========================================================================= */ -uint32_t ZEXPORT adler32_combine(uint32_t adler1, uint32_t adler2, z_off_t len2) { - return adler32_combine_(adler1, adler2, len2); -} - -uint32_t ZEXPORT adler32_combine64(uint32_t adler1, uint32_t adler2, z_off64_t len2) { - return adler32_combine_(adler1, adler2, len2); -} diff --git a/contrib/libzlib-ng/arch/.gitignore b/contrib/libzlib-ng/arch/.gitignore deleted file mode 100644 index 2c3af0a08cb..00000000000 --- a/contrib/libzlib-ng/arch/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# ignore Makefiles; they're all automatically generated -Makefile diff --git a/contrib/libzlib-ng/arch/arm/Makefile.in b/contrib/libzlib-ng/arch/arm/Makefile.in deleted file mode 100644 index 759a1213ba8..00000000000 --- a/contrib/libzlib-ng/arch/arm/Makefile.in +++ /dev/null @@ -1,20 +0,0 @@ -# Makefile for zlib -# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler -# For conditions of distribution and use, see copyright notice in zlib.h - -CC= -CFLAGS= -SFLAGS= -INCLUDES= - -SRCDIR= -SRCTOP= - -all: - - -mostlyclean: clean -clean: - rm -f *.o *.lo *~ \ - rm -rf objs - rm -f *.gcda *.gcno *.gcov diff --git a/contrib/libzlib-ng/arch/generic/Makefile.in b/contrib/libzlib-ng/arch/generic/Makefile.in deleted file mode 100644 index 759a1213ba8..00000000000 --- a/contrib/libzlib-ng/arch/generic/Makefile.in +++ /dev/null @@ -1,20 +0,0 @@ -# Makefile for zlib -# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler -# For conditions of distribution and use, see copyright notice in zlib.h - -CC= -CFLAGS= -SFLAGS= -INCLUDES= - -SRCDIR= -SRCTOP= - -all: - - -mostlyclean: clean -clean: - rm -f *.o *.lo *~ \ - rm -rf objs - rm -f *.gcda *.gcno *.gcov diff --git a/contrib/libzlib-ng/arch/x86/INDEX b/contrib/libzlib-ng/arch/x86/INDEX deleted file mode 100644 index 9ee3802a2cd..00000000000 --- a/contrib/libzlib-ng/arch/x86/INDEX +++ /dev/null @@ -1,3 +0,0 @@ -fill_window_sse.c SSE2 optimized fill_window -deflate_quick.c SSE4 optimized deflate strategy for use as level 1 -crc_folding.c SSE4 + PCLMULQDQ optimized CRC folding implementation diff --git a/contrib/libzlib-ng/arch/x86/Makefile.in b/contrib/libzlib-ng/arch/x86/Makefile.in deleted file mode 100644 index 3604ba85226..00000000000 --- a/contrib/libzlib-ng/arch/x86/Makefile.in +++ /dev/null @@ -1,53 +0,0 @@ -# Makefile for zlib -# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler -# For conditions of distribution and use, see copyright notice in zlib.h - -CC= -CFLAGS= -SFLAGS= -INCLUDES= - -SRCDIR= -SRCTOP= - -all: x86.o x86.lo fill_window_sse.o fill_window_sse.lo deflate_quick.o deflate_quick.lo insert_string_sse.o insert_string_sse.lo crc_folding.o crc_folding.lo - -x86.o: - $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/x86.c - -x86.lo: - $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/x86.c - -fill_window_sse.o: - $(CC) $(CFLAGS) -msse2 $(INCLUDES) -c -o $@ $(SRCDIR)/fill_window_sse.c - -fill_window_sse.lo: - $(CC) $(SFLAGS) -msse2 -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/fill_window_sse.c - -deflate_quick.o: - $(CC) $(CFLAGS) -msse4 $(INCLUDES) -c -o $@ $(SRCDIR)/deflate_quick.c - -deflate_quick.lo: - $(CC) $(SFLAGS) -msse4 -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/deflate_quick.c - -insert_string_sse.o: - $(CC) $(CFLAGS) -msse4 $(INCLUDES) -c -o $@ $(SRCDIR)/insert_string_sse.c - -insert_string_sse.lo: - $(CC) $(SFLAGS) -msse4 -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/insert_string_sse.c - -crc_folding.o: - $(CC) $(CFLAGS) -mpclmul -msse4 $(INCLUDES) -c -o $@ $(SRCDIR)/crc_folding.c - -crc_folding.lo: - $(CC) $(SFLAGS) -mpclmul -msse4 -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/crc_folding.c - - -mostlyclean: clean -clean: - rm -f *.o *.lo *~ \ - rm -rf objs - rm -f *.gcda *.gcno *.gcov - -distclean: - rm -f Makefile diff --git a/contrib/libzlib-ng/arch/x86/crc_folding.c b/contrib/libzlib-ng/arch/x86/crc_folding.c deleted file mode 100644 index b1fb6ec3a35..00000000000 --- a/contrib/libzlib-ng/arch/x86/crc_folding.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Compute the CRC32 using a parallelized folding approach with the PCLMULQDQ - * instruction. - * - * A white paper describing this algorithm can be found at: - * http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf - * - * Copyright (C) 2013 Intel Corporation. All rights reserved. - * Authors: - * Wajdi Feghali - * Jim Guilford - * Vinodh Gopal - * Erdinc Ozturk - * Jim Kukunas - * - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#ifdef X86_PCLMULQDQ_CRC - -#include -#include -#include - -#include "deflate.h" - - -#define CRC_LOAD(s) \ - do { \ - __m128i xmm_crc0 = _mm_loadu_si128((__m128i *)s->crc0 + 0);\ - __m128i xmm_crc1 = _mm_loadu_si128((__m128i *)s->crc0 + 1);\ - __m128i xmm_crc2 = _mm_loadu_si128((__m128i *)s->crc0 + 2);\ - __m128i xmm_crc3 = _mm_loadu_si128((__m128i *)s->crc0 + 3);\ - __m128i xmm_crc_part = _mm_loadu_si128((__m128i *)s->crc0 + 4); - -#define CRC_SAVE(s) \ - _mm_storeu_si128((__m128i *)s->crc0 + 0, xmm_crc0);\ - _mm_storeu_si128((__m128i *)s->crc0 + 1, xmm_crc1);\ - _mm_storeu_si128((__m128i *)s->crc0 + 2, xmm_crc2);\ - _mm_storeu_si128((__m128i *)s->crc0 + 3, xmm_crc3);\ - _mm_storeu_si128((__m128i *)s->crc0 + 4, xmm_crc_part);\ - } while (0); - -ZLIB_INTERNAL void crc_fold_init(deflate_state *const s) { - CRC_LOAD(s) - - xmm_crc0 = _mm_cvtsi32_si128(0x9db42487); - xmm_crc1 = _mm_setzero_si128(); - xmm_crc2 = _mm_setzero_si128(); - xmm_crc3 = _mm_setzero_si128(); - - CRC_SAVE(s) - - s->strm->adler = 0; -} - -local void fold_1(deflate_state *const s, __m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, __m128i *xmm_crc3) { - const __m128i xmm_fold4 = _mm_set_epi32( - 0x00000001, 0x54442bd4, - 0x00000001, 0xc6e41596); - - __m128i x_tmp3; - __m128 ps_crc0, ps_crc3, ps_res; - - x_tmp3 = *xmm_crc3; - - *xmm_crc3 = *xmm_crc0; - *xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01); - *xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x10); - ps_crc0 = _mm_castsi128_ps(*xmm_crc0); - ps_crc3 = _mm_castsi128_ps(*xmm_crc3); - ps_res = _mm_xor_ps(ps_crc0, ps_crc3); - - *xmm_crc0 = *xmm_crc1; - *xmm_crc1 = *xmm_crc2; - *xmm_crc2 = x_tmp3; - *xmm_crc3 = _mm_castps_si128(ps_res); -} - -local void fold_2(deflate_state *const s, __m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, __m128i *xmm_crc3) { - const __m128i xmm_fold4 = _mm_set_epi32( - 0x00000001, 0x54442bd4, - 0x00000001, 0xc6e41596); - - __m128i x_tmp3, x_tmp2; - __m128 ps_crc0, ps_crc1, ps_crc2, ps_crc3, ps_res31, ps_res20; - - x_tmp3 = *xmm_crc3; - x_tmp2 = *xmm_crc2; - - *xmm_crc3 = *xmm_crc1; - *xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x01); - *xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x10); - ps_crc3 = _mm_castsi128_ps(*xmm_crc3); - ps_crc1 = _mm_castsi128_ps(*xmm_crc1); - ps_res31 = _mm_xor_ps(ps_crc3, ps_crc1); - - *xmm_crc2 = *xmm_crc0; - *xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01); - *xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x10); - ps_crc0 = _mm_castsi128_ps(*xmm_crc0); - ps_crc2 = _mm_castsi128_ps(*xmm_crc2); - ps_res20 = _mm_xor_ps(ps_crc0, ps_crc2); - - *xmm_crc0 = x_tmp2; - *xmm_crc1 = x_tmp3; - *xmm_crc2 = _mm_castps_si128(ps_res20); - *xmm_crc3 = _mm_castps_si128(ps_res31); -} - -local void fold_3(deflate_state *const s, __m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, __m128i *xmm_crc3) { - const __m128i xmm_fold4 = _mm_set_epi32( - 0x00000001, 0x54442bd4, - 0x00000001, 0xc6e41596); - - __m128i x_tmp3; - __m128 ps_crc0, ps_crc1, ps_crc2, ps_crc3, ps_res32, ps_res21, ps_res10; - - x_tmp3 = *xmm_crc3; - - *xmm_crc3 = *xmm_crc2; - *xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x01); - *xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x10); - ps_crc2 = _mm_castsi128_ps(*xmm_crc2); - ps_crc3 = _mm_castsi128_ps(*xmm_crc3); - ps_res32 = _mm_xor_ps(ps_crc2, ps_crc3); - - *xmm_crc2 = *xmm_crc1; - *xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x01); - *xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x10); - ps_crc1 = _mm_castsi128_ps(*xmm_crc1); - ps_crc2 = _mm_castsi128_ps(*xmm_crc2); - ps_res21 = _mm_xor_ps(ps_crc1, ps_crc2); - - *xmm_crc1 = *xmm_crc0; - *xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01); - *xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x10); - ps_crc0 = _mm_castsi128_ps(*xmm_crc0); - ps_crc1 = _mm_castsi128_ps(*xmm_crc1); - ps_res10 = _mm_xor_ps(ps_crc0, ps_crc1); - - *xmm_crc0 = x_tmp3; - *xmm_crc1 = _mm_castps_si128(ps_res10); - *xmm_crc2 = _mm_castps_si128(ps_res21); - *xmm_crc3 = _mm_castps_si128(ps_res32); -} - -local void fold_4(deflate_state *const s, __m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, __m128i *xmm_crc3) { - const __m128i xmm_fold4 = _mm_set_epi32( - 0x00000001, 0x54442bd4, - 0x00000001, 0xc6e41596); - - __m128i x_tmp0, x_tmp1, x_tmp2, x_tmp3; - __m128 ps_crc0, ps_crc1, ps_crc2, ps_crc3; - __m128 ps_t0, ps_t1, ps_t2, ps_t3; - __m128 ps_res0, ps_res1, ps_res2, ps_res3; - - x_tmp0 = *xmm_crc0; - x_tmp1 = *xmm_crc1; - x_tmp2 = *xmm_crc2; - x_tmp3 = *xmm_crc3; - - *xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01); - x_tmp0 = _mm_clmulepi64_si128(x_tmp0, xmm_fold4, 0x10); - ps_crc0 = _mm_castsi128_ps(*xmm_crc0); - ps_t0 = _mm_castsi128_ps(x_tmp0); - ps_res0 = _mm_xor_ps(ps_crc0, ps_t0); - - *xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x01); - x_tmp1 = _mm_clmulepi64_si128(x_tmp1, xmm_fold4, 0x10); - ps_crc1 = _mm_castsi128_ps(*xmm_crc1); - ps_t1 = _mm_castsi128_ps(x_tmp1); - ps_res1 = _mm_xor_ps(ps_crc1, ps_t1); - - *xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x01); - x_tmp2 = _mm_clmulepi64_si128(x_tmp2, xmm_fold4, 0x10); - ps_crc2 = _mm_castsi128_ps(*xmm_crc2); - ps_t2 = _mm_castsi128_ps(x_tmp2); - ps_res2 = _mm_xor_ps(ps_crc2, ps_t2); - - *xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x01); - x_tmp3 = _mm_clmulepi64_si128(x_tmp3, xmm_fold4, 0x10); - ps_crc3 = _mm_castsi128_ps(*xmm_crc3); - ps_t3 = _mm_castsi128_ps(x_tmp3); - ps_res3 = _mm_xor_ps(ps_crc3, ps_t3); - - *xmm_crc0 = _mm_castps_si128(ps_res0); - *xmm_crc1 = _mm_castps_si128(ps_res1); - *xmm_crc2 = _mm_castps_si128(ps_res2); - *xmm_crc3 = _mm_castps_si128(ps_res3); -} - -local const unsigned ALIGNED_(32) pshufb_shf_table[60] = { - 0x84838281, 0x88878685, 0x8c8b8a89, 0x008f8e8d, /* shl 15 (16 - 1)/shr1 */ - 0x85848382, 0x89888786, 0x8d8c8b8a, 0x01008f8e, /* shl 14 (16 - 3)/shr2 */ - 0x86858483, 0x8a898887, 0x8e8d8c8b, 0x0201008f, /* shl 13 (16 - 4)/shr3 */ - 0x87868584, 0x8b8a8988, 0x8f8e8d8c, 0x03020100, /* shl 12 (16 - 4)/shr4 */ - 0x88878685, 0x8c8b8a89, 0x008f8e8d, 0x04030201, /* shl 11 (16 - 5)/shr5 */ - 0x89888786, 0x8d8c8b8a, 0x01008f8e, 0x05040302, /* shl 10 (16 - 6)/shr6 */ - 0x8a898887, 0x8e8d8c8b, 0x0201008f, 0x06050403, /* shl 9 (16 - 7)/shr7 */ - 0x8b8a8988, 0x8f8e8d8c, 0x03020100, 0x07060504, /* shl 8 (16 - 8)/shr8 */ - 0x8c8b8a89, 0x008f8e8d, 0x04030201, 0x08070605, /* shl 7 (16 - 9)/shr9 */ - 0x8d8c8b8a, 0x01008f8e, 0x05040302, 0x09080706, /* shl 6 (16 -10)/shr10*/ - 0x8e8d8c8b, 0x0201008f, 0x06050403, 0x0a090807, /* shl 5 (16 -11)/shr11*/ - 0x8f8e8d8c, 0x03020100, 0x07060504, 0x0b0a0908, /* shl 4 (16 -12)/shr12*/ - 0x008f8e8d, 0x04030201, 0x08070605, 0x0c0b0a09, /* shl 3 (16 -13)/shr13*/ - 0x01008f8e, 0x05040302, 0x09080706, 0x0d0c0b0a, /* shl 2 (16 -14)/shr14*/ - 0x0201008f, 0x06050403, 0x0a090807, 0x0e0d0c0b /* shl 1 (16 -15)/shr15*/ -}; - -local void partial_fold(deflate_state *const s, const size_t len, __m128i *xmm_crc0, __m128i *xmm_crc1, - __m128i *xmm_crc2, __m128i *xmm_crc3, __m128i *xmm_crc_part) { - - const __m128i xmm_fold4 = _mm_set_epi32( - 0x00000001, 0x54442bd4, - 0x00000001, 0xc6e41596); - const __m128i xmm_mask3 = _mm_set1_epi32(0x80808080); - - __m128i xmm_shl, xmm_shr, xmm_tmp1, xmm_tmp2, xmm_tmp3; - __m128i xmm_a0_0, xmm_a0_1; - __m128 ps_crc3, psa0_0, psa0_1, ps_res; - - xmm_shl = _mm_load_si128((__m128i *)pshufb_shf_table + (len - 1)); - xmm_shr = xmm_shl; - xmm_shr = _mm_xor_si128(xmm_shr, xmm_mask3); - - xmm_a0_0 = _mm_shuffle_epi8(*xmm_crc0, xmm_shl); - - *xmm_crc0 = _mm_shuffle_epi8(*xmm_crc0, xmm_shr); - xmm_tmp1 = _mm_shuffle_epi8(*xmm_crc1, xmm_shl); - *xmm_crc0 = _mm_or_si128(*xmm_crc0, xmm_tmp1); - - *xmm_crc1 = _mm_shuffle_epi8(*xmm_crc1, xmm_shr); - xmm_tmp2 = _mm_shuffle_epi8(*xmm_crc2, xmm_shl); - *xmm_crc1 = _mm_or_si128(*xmm_crc1, xmm_tmp2); - - *xmm_crc2 = _mm_shuffle_epi8(*xmm_crc2, xmm_shr); - xmm_tmp3 = _mm_shuffle_epi8(*xmm_crc3, xmm_shl); - *xmm_crc2 = _mm_or_si128(*xmm_crc2, xmm_tmp3); - - *xmm_crc3 = _mm_shuffle_epi8(*xmm_crc3, xmm_shr); - *xmm_crc_part = _mm_shuffle_epi8(*xmm_crc_part, xmm_shl); - *xmm_crc3 = _mm_or_si128(*xmm_crc3, *xmm_crc_part); - - xmm_a0_1 = _mm_clmulepi64_si128(xmm_a0_0, xmm_fold4, 0x10); - xmm_a0_0 = _mm_clmulepi64_si128(xmm_a0_0, xmm_fold4, 0x01); - - ps_crc3 = _mm_castsi128_ps(*xmm_crc3); - psa0_0 = _mm_castsi128_ps(xmm_a0_0); - psa0_1 = _mm_castsi128_ps(xmm_a0_1); - - ps_res = _mm_xor_ps(ps_crc3, psa0_0); - ps_res = _mm_xor_ps(ps_res, psa0_1); - - *xmm_crc3 = _mm_castps_si128(ps_res); -} - -ZLIB_INTERNAL void crc_fold_copy(deflate_state *const s, unsigned char *dst, const unsigned char *src, long len) { - unsigned long algn_diff; - __m128i xmm_t0, xmm_t1, xmm_t2, xmm_t3; - - CRC_LOAD(s) - - if (len < 16) { - if (len == 0) - return; - xmm_crc_part = _mm_loadu_si128((__m128i *)src); - goto partial; - } - - algn_diff = (0 - (uintptr_t)src) & 0xF; - if (algn_diff) { - xmm_crc_part = _mm_loadu_si128((__m128i *)src); - _mm_storeu_si128((__m128i *)dst, xmm_crc_part); - - dst += algn_diff; - src += algn_diff; - len -= algn_diff; - - partial_fold(s, algn_diff, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, - &xmm_crc_part); - } - - while ((len -= 64) >= 0) { - xmm_t0 = _mm_load_si128((__m128i *)src); - xmm_t1 = _mm_load_si128((__m128i *)src + 1); - xmm_t2 = _mm_load_si128((__m128i *)src + 2); - xmm_t3 = _mm_load_si128((__m128i *)src + 3); - - fold_4(s, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); - - _mm_storeu_si128((__m128i *)dst, xmm_t0); - _mm_storeu_si128((__m128i *)dst + 1, xmm_t1); - _mm_storeu_si128((__m128i *)dst + 2, xmm_t2); - _mm_storeu_si128((__m128i *)dst + 3, xmm_t3); - - xmm_crc0 = _mm_xor_si128(xmm_crc0, xmm_t0); - xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_t1); - xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t2); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t3); - - src += 64; - dst += 64; - } - - /* - * len = num bytes left - 64 - */ - if (len + 16 >= 0) { - len += 16; - - xmm_t0 = _mm_load_si128((__m128i *)src); - xmm_t1 = _mm_load_si128((__m128i *)src + 1); - xmm_t2 = _mm_load_si128((__m128i *)src + 2); - - fold_3(s, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); - - _mm_storeu_si128((__m128i *)dst, xmm_t0); - _mm_storeu_si128((__m128i *)dst + 1, xmm_t1); - _mm_storeu_si128((__m128i *)dst + 2, xmm_t2); - - xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_t0); - xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t1); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t2); - - if (len == 0) - goto done; - - dst += 48; - xmm_crc_part = _mm_load_si128((__m128i *)src + 3); - } else if (len + 32 >= 0) { - len += 32; - - xmm_t0 = _mm_load_si128((__m128i *)src); - xmm_t1 = _mm_load_si128((__m128i *)src + 1); - - fold_2(s, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); - - _mm_storeu_si128((__m128i *)dst, xmm_t0); - _mm_storeu_si128((__m128i *)dst + 1, xmm_t1); - - xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t0); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t1); - - if (len == 0) - goto done; - - dst += 32; - xmm_crc_part = _mm_load_si128((__m128i *)src + 2); - } else if (len + 48 >= 0) { - len += 48; - - xmm_t0 = _mm_load_si128((__m128i *)src); - - fold_1(s, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); - - _mm_storeu_si128((__m128i *)dst, xmm_t0); - - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t0); - - if (len == 0) - goto done; - - dst += 16; - xmm_crc_part = _mm_load_si128((__m128i *)src + 1); - } else { - len += 64; - if (len == 0) - goto done; - xmm_crc_part = _mm_load_si128((__m128i *)src); - } - -partial: - _mm_storeu_si128((__m128i *)dst, xmm_crc_part); - partial_fold(s, len, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, - &xmm_crc_part); -done: - CRC_SAVE(s) -} - -local const unsigned ALIGNED_(16) crc_k[] = { - 0xccaa009e, 0x00000000, /* rk1 */ - 0x751997d0, 0x00000001, /* rk2 */ - 0xccaa009e, 0x00000000, /* rk5 */ - 0x63cd6124, 0x00000001, /* rk6 */ - 0xf7011640, 0x00000001, /* rk7 */ - 0xdb710640, 0x00000001 /* rk8 */ -}; - -local const unsigned ALIGNED_(16) crc_mask[4] = { - 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000 -}; - -local const unsigned ALIGNED_(16) crc_mask2[4] = { - 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF -}; - -uint32_t ZLIB_INTERNAL crc_fold_512to32(deflate_state *const s) { - const __m128i xmm_mask = _mm_load_si128((__m128i *)crc_mask); - const __m128i xmm_mask2 = _mm_load_si128((__m128i *)crc_mask2); - - uint32_t crc; - __m128i x_tmp0, x_tmp1, x_tmp2, crc_fold; - - CRC_LOAD(s) - - /* - * k1 - */ - crc_fold = _mm_load_si128((__m128i *)crc_k); - - x_tmp0 = _mm_clmulepi64_si128(xmm_crc0, crc_fold, 0x10); - xmm_crc0 = _mm_clmulepi64_si128(xmm_crc0, crc_fold, 0x01); - xmm_crc1 = _mm_xor_si128(xmm_crc1, x_tmp0); - xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_crc0); - - x_tmp1 = _mm_clmulepi64_si128(xmm_crc1, crc_fold, 0x10); - xmm_crc1 = _mm_clmulepi64_si128(xmm_crc1, crc_fold, 0x01); - xmm_crc2 = _mm_xor_si128(xmm_crc2, x_tmp1); - xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_crc1); - - x_tmp2 = _mm_clmulepi64_si128(xmm_crc2, crc_fold, 0x10); - xmm_crc2 = _mm_clmulepi64_si128(xmm_crc2, crc_fold, 0x01); - xmm_crc3 = _mm_xor_si128(xmm_crc3, x_tmp2); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); - - /* - * k5 - */ - crc_fold = _mm_load_si128((__m128i *)crc_k + 1); - - xmm_crc0 = xmm_crc3; - xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0); - xmm_crc0 = _mm_srli_si128(xmm_crc0, 8); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc0); - - xmm_crc0 = xmm_crc3; - xmm_crc3 = _mm_slli_si128(xmm_crc3, 4); - xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0x10); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc0); - xmm_crc3 = _mm_and_si128(xmm_crc3, xmm_mask2); - - /* - * k7 - */ - xmm_crc1 = xmm_crc3; - xmm_crc2 = xmm_crc3; - crc_fold = _mm_load_si128((__m128i *)crc_k + 2); - - xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); - xmm_crc3 = _mm_and_si128(xmm_crc3, xmm_mask); - - xmm_crc2 = xmm_crc3; - xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0x10); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); - xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc1); - - crc = _mm_extract_epi32(xmm_crc3, 2); - return ~crc; - CRC_SAVE(s) -} - -#endif - diff --git a/contrib/libzlib-ng/arch/x86/deflate_quick.c b/contrib/libzlib-ng/arch/x86/deflate_quick.c deleted file mode 100644 index b5190d59898..00000000000 --- a/contrib/libzlib-ng/arch/x86/deflate_quick.c +++ /dev/null @@ -1,2371 +0,0 @@ -/* - * The deflate_quick deflate strategy, designed to be used when cycles are - * at a premium. - * - * Copyright (C) 2013 Intel Corporation. All rights reserved. - * Authors: - * Wajdi Feghali - * Jim Guilford - * Vinodh Gopal - * Erdinc Ozturk - * Jim Kukunas - * - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include -#ifdef _MSC_VER -# include -#endif -#include "deflate.h" - -extern void fill_window_sse(deflate_state *s); -extern void flush_pending(z_stream *strm); - -local inline long compare258(const unsigned char *const src0, const unsigned char *const src1) { -#ifdef _MSC_VER - long cnt; - - cnt = 0; - do { -#define mode _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_EACH | _SIDD_NEGATIVE_POLARITY - - int ret; - __m128i xmm_src0, xmm_src1; - - xmm_src0 = _mm_loadu_si128((__m128i *)(src0 + cnt)); - xmm_src1 = _mm_loadu_si128((__m128i *)(src1 + cnt)); - ret = _mm_cmpestri(xmm_src0, 16, xmm_src1, 16, mode); - if (_mm_cmpestrc(xmm_src0, 16, xmm_src1, 16, mode)) { - cnt += ret; - break; - } - cnt += 16; - - xmm_src0 = _mm_loadu_si128((__m128i *)(src0 + cnt)); - xmm_src1 = _mm_loadu_si128((__m128i *)(src1 + cnt)); - ret = _mm_cmpestri(xmm_src0, 16, xmm_src1, 16, mode); - if (_mm_cmpestrc(xmm_src0, 16, xmm_src1, 16, mode)) { - cnt += ret; - break; - } - cnt += 16; - } while (cnt < 256); - - if (*(unsigned short *)(src0 + cnt) == *(unsigned short *)(src1 + cnt)) { - cnt += 2; - } else if (*(src0 + cnt) == *(src1 + cnt)) { - cnt++; - } - return cnt; -#else - uintptr_t ax, dx, cx; - __m128i xmm_src0; - - ax = 16; - dx = 16; - /* set cx to something, otherwise gcc thinks it's used - uninitalised */ - cx = 0; - - __asm__ __volatile__ ( - "1:" - "movdqu -16(%[src0], %[ax]), %[xmm_src0]\n\t" - "pcmpestri $0x18, -16(%[src1], %[ax]), %[xmm_src0]\n\t" - "jc 2f\n\t" - "add $16, %[ax]\n\t" - - "movdqu -16(%[src0], %[ax]), %[xmm_src0]\n\t" - "pcmpestri $0x18, -16(%[src1], %[ax]), %[xmm_src0]\n\t" - "jc 2f\n\t" - "add $16, %[ax]\n\t" - - "cmp $256 + 16, %[ax]\n\t" - "jb 1b\n\t" - -#ifdef X86 - "movzwl -16(%[src0], %[ax]), %[dx]\n\t" -#else - "movzwq -16(%[src0], %[ax]), %[dx]\n\t" -#endif - "xorw -16(%[src1], %[ax]), %%dx\n\t" - "jnz 3f\n\t" - - "add $2, %[ax]\n\t" - "jmp 4f\n\t" - "3:\n\t" - "rep; bsf %[dx], %[cx]\n\t" - "shr $3, %[cx]\n\t" - "2:" - "add %[cx], %[ax]\n\t" - "4:" - : [ax] "+a" (ax), - [cx] "+c" (cx), - [dx] "+d" (dx), - [xmm_src0] "=x" (xmm_src0) - : [src0] "r" (src0), - [src1] "r" (src1) - : "cc" - ); - return ax - 16; -#endif -} - -local const unsigned quick_len_codes[MAX_MATCH-MIN_MATCH+1]; -local const unsigned quick_dist_codes[8192]; - -local inline void quick_send_bits(deflate_state *const s, const int value, const int length) { - unsigned code, out, w, b; - - out = s->bi_buf; - w = s->bi_valid; - - code = value << s->bi_valid; - out |= code; - w += length; - - if (s->pending + 4 >= s->pending_buf_size) - flush_pending(s->strm); - - *(unsigned *)(s->pending_buf + s->pending) = out; - - b = w >> 3; - s->pending += b; - s->bi_buf = out >> (b << 3); - s->bi_valid = w - (b << 3); -} - -local inline void static_emit_ptr(deflate_state *const s, const int lc, const unsigned dist) { - unsigned code, len; - - code = quick_len_codes[lc] >> 8; - len = quick_len_codes[lc] & 0xFF; - quick_send_bits(s, code, len); - - code = quick_dist_codes[dist-1] >> 8; - len = quick_dist_codes[dist-1] & 0xFF; - quick_send_bits(s, code, len); -} - -const ct_data static_ltree[L_CODES+2]; - -local inline void static_emit_lit(deflate_state *const s, const int lit) { - quick_send_bits(s, static_ltree[lit].Code, static_ltree[lit].Len); - Tracecv(isgraph(lit), (stderr, " '%c' ", lit)); -} - -local void static_emit_tree(deflate_state *const s, const int flush) { - unsigned last; - - last = flush == Z_FINISH ? 1 : 0; - send_bits(s, (STATIC_TREES << 1)+ last, 3); -} - - -local void static_emit_end_block(deflate_state *const s, int last) { - send_code(s, END_BLOCK, static_ltree); - - if (last) - bi_windup(s); - - s->block_start = s->strstart; - flush_pending(s->strm); -} - -local inline Pos quick_insert_string(deflate_state *const s, const Pos str) { - Pos ret; - unsigned h = 0; - -#ifdef _MSC_VER - h = _mm_crc32_u32(h, *(unsigned *)(s->window + str)); -#else - __asm__ __volatile__ ( - "crc32l (%[window], %[str], 1), %0\n\t" - : "+r" (h) - : [window] "r" (s->window), - [str] "r" ((uintptr_t)str) - ); -#endif - - ret = s->head[h & s->hash_mask]; - s->head[h & s->hash_mask] = str; - return ret; -} - -ZLIB_INTERNAL block_state deflate_quick(deflate_state *s, int flush) { - IPos hash_head; - unsigned dist, match_len; - - static_emit_tree(s, flush); - - do { - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window_sse(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - static_emit_end_block(s, 0); - return need_more; - } - if (s->lookahead == 0) - break; - } - - if (s->lookahead >= MIN_MATCH) { - hash_head = quick_insert_string(s, s->strstart); - dist = s->strstart - hash_head; - - if ((dist-1) < (s->w_size - 1)) { - match_len = compare258(s->window + s->strstart, s->window + s->strstart - dist); - - if (match_len >= MIN_MATCH) { - if (match_len > s->lookahead) - match_len = s->lookahead; - - if (match_len > MAX_MATCH) - match_len = MAX_MATCH; - - static_emit_ptr(s, match_len - MIN_MATCH, s->strstart - hash_head); - s->lookahead -= match_len; - s->strstart += match_len; - continue; - } - } - } - - static_emit_lit(s, s->window[s->strstart]); - s->strstart++; - s->lookahead--; - } while (s->strm->avail_out != 0); - - if (s->strm->avail_out == 0 && flush != Z_FINISH) - return need_more; - - s->insert = s->strstart < MIN_MATCH - 1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - static_emit_end_block(s, 1); - if (s->strm->avail_out == 0) - return s->strm->avail_in == 0 ? finish_started : need_more; - else - return finish_done; - } - - static_emit_end_block(s, 0); - return block_done; -} - -local const unsigned quick_len_codes[MAX_MATCH-MIN_MATCH+1] = { - 0x00004007, 0x00002007, 0x00006007, 0x00001007, - 0x00005007, 0x00003007, 0x00007007, 0x00000807, - 0x00004808, 0x0000c808, 0x00002808, 0x0000a808, - 0x00006808, 0x0000e808, 0x00001808, 0x00009808, - 0x00005809, 0x0000d809, 0x00015809, 0x0001d809, - 0x00003809, 0x0000b809, 0x00013809, 0x0001b809, - 0x00007809, 0x0000f809, 0x00017809, 0x0001f809, - 0x00000409, 0x00008409, 0x00010409, 0x00018409, - 0x0000440a, 0x0000c40a, 0x0001440a, 0x0001c40a, - 0x0002440a, 0x0002c40a, 0x0003440a, 0x0003c40a, - 0x0000240a, 0x0000a40a, 0x0001240a, 0x0001a40a, - 0x0002240a, 0x0002a40a, 0x0003240a, 0x0003a40a, - 0x0000640a, 0x0000e40a, 0x0001640a, 0x0001e40a, - 0x0002640a, 0x0002e40a, 0x0003640a, 0x0003e40a, - 0x0000140a, 0x0000940a, 0x0001140a, 0x0001940a, - 0x0002140a, 0x0002940a, 0x0003140a, 0x0003940a, - 0x0000540b, 0x0000d40b, 0x0001540b, 0x0001d40b, - 0x0002540b, 0x0002d40b, 0x0003540b, 0x0003d40b, - 0x0004540b, 0x0004d40b, 0x0005540b, 0x0005d40b, - 0x0006540b, 0x0006d40b, 0x0007540b, 0x0007d40b, - 0x0000340b, 0x0000b40b, 0x0001340b, 0x0001b40b, - 0x0002340b, 0x0002b40b, 0x0003340b, 0x0003b40b, - 0x0004340b, 0x0004b40b, 0x0005340b, 0x0005b40b, - 0x0006340b, 0x0006b40b, 0x0007340b, 0x0007b40b, - 0x0000740b, 0x0000f40b, 0x0001740b, 0x0001f40b, - 0x0002740b, 0x0002f40b, 0x0003740b, 0x0003f40b, - 0x0004740b, 0x0004f40b, 0x0005740b, 0x0005f40b, - 0x0006740b, 0x0006f40b, 0x0007740b, 0x0007f40b, - 0x0000030c, 0x0001030c, 0x0002030c, 0x0003030c, - 0x0004030c, 0x0005030c, 0x0006030c, 0x0007030c, - 0x0008030c, 0x0009030c, 0x000a030c, 0x000b030c, - 0x000c030c, 0x000d030c, 0x000e030c, 0x000f030c, - 0x0000830d, 0x0001830d, 0x0002830d, 0x0003830d, - 0x0004830d, 0x0005830d, 0x0006830d, 0x0007830d, - 0x0008830d, 0x0009830d, 0x000a830d, 0x000b830d, - 0x000c830d, 0x000d830d, 0x000e830d, 0x000f830d, - 0x0010830d, 0x0011830d, 0x0012830d, 0x0013830d, - 0x0014830d, 0x0015830d, 0x0016830d, 0x0017830d, - 0x0018830d, 0x0019830d, 0x001a830d, 0x001b830d, - 0x001c830d, 0x001d830d, 0x001e830d, 0x001f830d, - 0x0000430d, 0x0001430d, 0x0002430d, 0x0003430d, - 0x0004430d, 0x0005430d, 0x0006430d, 0x0007430d, - 0x0008430d, 0x0009430d, 0x000a430d, 0x000b430d, - 0x000c430d, 0x000d430d, 0x000e430d, 0x000f430d, - 0x0010430d, 0x0011430d, 0x0012430d, 0x0013430d, - 0x0014430d, 0x0015430d, 0x0016430d, 0x0017430d, - 0x0018430d, 0x0019430d, 0x001a430d, 0x001b430d, - 0x001c430d, 0x001d430d, 0x001e430d, 0x001f430d, - 0x0000c30d, 0x0001c30d, 0x0002c30d, 0x0003c30d, - 0x0004c30d, 0x0005c30d, 0x0006c30d, 0x0007c30d, - 0x0008c30d, 0x0009c30d, 0x000ac30d, 0x000bc30d, - 0x000cc30d, 0x000dc30d, 0x000ec30d, 0x000fc30d, - 0x0010c30d, 0x0011c30d, 0x0012c30d, 0x0013c30d, - 0x0014c30d, 0x0015c30d, 0x0016c30d, 0x0017c30d, - 0x0018c30d, 0x0019c30d, 0x001ac30d, 0x001bc30d, - 0x001cc30d, 0x001dc30d, 0x001ec30d, 0x001fc30d, - 0x0000230d, 0x0001230d, 0x0002230d, 0x0003230d, - 0x0004230d, 0x0005230d, 0x0006230d, 0x0007230d, - 0x0008230d, 0x0009230d, 0x000a230d, 0x000b230d, - 0x000c230d, 0x000d230d, 0x000e230d, 0x000f230d, - 0x0010230d, 0x0011230d, 0x0012230d, 0x0013230d, - 0x0014230d, 0x0015230d, 0x0016230d, 0x0017230d, - 0x0018230d, 0x0019230d, 0x001a230d, 0x001b230d, - 0x001c230d, 0x001d230d, 0x001e230d, 0x0000a308, -}; - -local const unsigned quick_dist_codes[8192] = { - 0x00000005, 0x00001005, 0x00000805, 0x00001805, - 0x00000406, 0x00002406, 0x00001406, 0x00003406, - 0x00000c07, 0x00002c07, 0x00004c07, 0x00006c07, - 0x00001c07, 0x00003c07, 0x00005c07, 0x00007c07, - 0x00000208, 0x00002208, 0x00004208, 0x00006208, - 0x00008208, 0x0000a208, 0x0000c208, 0x0000e208, - 0x00001208, 0x00003208, 0x00005208, 0x00007208, - 0x00009208, 0x0000b208, 0x0000d208, 0x0000f208, - 0x00000a09, 0x00002a09, 0x00004a09, 0x00006a09, - 0x00008a09, 0x0000aa09, 0x0000ca09, 0x0000ea09, - 0x00010a09, 0x00012a09, 0x00014a09, 0x00016a09, - 0x00018a09, 0x0001aa09, 0x0001ca09, 0x0001ea09, - 0x00001a09, 0x00003a09, 0x00005a09, 0x00007a09, - 0x00009a09, 0x0000ba09, 0x0000da09, 0x0000fa09, - 0x00011a09, 0x00013a09, 0x00015a09, 0x00017a09, - 0x00019a09, 0x0001ba09, 0x0001da09, 0x0001fa09, - 0x0000060a, 0x0000260a, 0x0000460a, 0x0000660a, - 0x0000860a, 0x0000a60a, 0x0000c60a, 0x0000e60a, - 0x0001060a, 0x0001260a, 0x0001460a, 0x0001660a, - 0x0001860a, 0x0001a60a, 0x0001c60a, 0x0001e60a, - 0x0002060a, 0x0002260a, 0x0002460a, 0x0002660a, - 0x0002860a, 0x0002a60a, 0x0002c60a, 0x0002e60a, - 0x0003060a, 0x0003260a, 0x0003460a, 0x0003660a, - 0x0003860a, 0x0003a60a, 0x0003c60a, 0x0003e60a, - 0x0000160a, 0x0000360a, 0x0000560a, 0x0000760a, - 0x0000960a, 0x0000b60a, 0x0000d60a, 0x0000f60a, - 0x0001160a, 0x0001360a, 0x0001560a, 0x0001760a, - 0x0001960a, 0x0001b60a, 0x0001d60a, 0x0001f60a, - 0x0002160a, 0x0002360a, 0x0002560a, 0x0002760a, - 0x0002960a, 0x0002b60a, 0x0002d60a, 0x0002f60a, - 0x0003160a, 0x0003360a, 0x0003560a, 0x0003760a, - 0x0003960a, 0x0003b60a, 0x0003d60a, 0x0003f60a, - 0x00000e0b, 0x00002e0b, 0x00004e0b, 0x00006e0b, - 0x00008e0b, 0x0000ae0b, 0x0000ce0b, 0x0000ee0b, - 0x00010e0b, 0x00012e0b, 0x00014e0b, 0x00016e0b, - 0x00018e0b, 0x0001ae0b, 0x0001ce0b, 0x0001ee0b, - 0x00020e0b, 0x00022e0b, 0x00024e0b, 0x00026e0b, - 0x00028e0b, 0x0002ae0b, 0x0002ce0b, 0x0002ee0b, - 0x00030e0b, 0x00032e0b, 0x00034e0b, 0x00036e0b, - 0x00038e0b, 0x0003ae0b, 0x0003ce0b, 0x0003ee0b, - 0x00040e0b, 0x00042e0b, 0x00044e0b, 0x00046e0b, - 0x00048e0b, 0x0004ae0b, 0x0004ce0b, 0x0004ee0b, - 0x00050e0b, 0x00052e0b, 0x00054e0b, 0x00056e0b, - 0x00058e0b, 0x0005ae0b, 0x0005ce0b, 0x0005ee0b, - 0x00060e0b, 0x00062e0b, 0x00064e0b, 0x00066e0b, - 0x00068e0b, 0x0006ae0b, 0x0006ce0b, 0x0006ee0b, - 0x00070e0b, 0x00072e0b, 0x00074e0b, 0x00076e0b, - 0x00078e0b, 0x0007ae0b, 0x0007ce0b, 0x0007ee0b, - 0x00001e0b, 0x00003e0b, 0x00005e0b, 0x00007e0b, - 0x00009e0b, 0x0000be0b, 0x0000de0b, 0x0000fe0b, - 0x00011e0b, 0x00013e0b, 0x00015e0b, 0x00017e0b, - 0x00019e0b, 0x0001be0b, 0x0001de0b, 0x0001fe0b, - 0x00021e0b, 0x00023e0b, 0x00025e0b, 0x00027e0b, - 0x00029e0b, 0x0002be0b, 0x0002de0b, 0x0002fe0b, - 0x00031e0b, 0x00033e0b, 0x00035e0b, 0x00037e0b, - 0x00039e0b, 0x0003be0b, 0x0003de0b, 0x0003fe0b, - 0x00041e0b, 0x00043e0b, 0x00045e0b, 0x00047e0b, - 0x00049e0b, 0x0004be0b, 0x0004de0b, 0x0004fe0b, - 0x00051e0b, 0x00053e0b, 0x00055e0b, 0x00057e0b, - 0x00059e0b, 0x0005be0b, 0x0005de0b, 0x0005fe0b, - 0x00061e0b, 0x00063e0b, 0x00065e0b, 0x00067e0b, - 0x00069e0b, 0x0006be0b, 0x0006de0b, 0x0006fe0b, - 0x00071e0b, 0x00073e0b, 0x00075e0b, 0x00077e0b, - 0x00079e0b, 0x0007be0b, 0x0007de0b, 0x0007fe0b, - 0x0000010c, 0x0000210c, 0x0000410c, 0x0000610c, - 0x0000810c, 0x0000a10c, 0x0000c10c, 0x0000e10c, - 0x0001010c, 0x0001210c, 0x0001410c, 0x0001610c, - 0x0001810c, 0x0001a10c, 0x0001c10c, 0x0001e10c, - 0x0002010c, 0x0002210c, 0x0002410c, 0x0002610c, - 0x0002810c, 0x0002a10c, 0x0002c10c, 0x0002e10c, - 0x0003010c, 0x0003210c, 0x0003410c, 0x0003610c, - 0x0003810c, 0x0003a10c, 0x0003c10c, 0x0003e10c, - 0x0004010c, 0x0004210c, 0x0004410c, 0x0004610c, - 0x0004810c, 0x0004a10c, 0x0004c10c, 0x0004e10c, - 0x0005010c, 0x0005210c, 0x0005410c, 0x0005610c, - 0x0005810c, 0x0005a10c, 0x0005c10c, 0x0005e10c, - 0x0006010c, 0x0006210c, 0x0006410c, 0x0006610c, - 0x0006810c, 0x0006a10c, 0x0006c10c, 0x0006e10c, - 0x0007010c, 0x0007210c, 0x0007410c, 0x0007610c, - 0x0007810c, 0x0007a10c, 0x0007c10c, 0x0007e10c, - 0x0008010c, 0x0008210c, 0x0008410c, 0x0008610c, - 0x0008810c, 0x0008a10c, 0x0008c10c, 0x0008e10c, - 0x0009010c, 0x0009210c, 0x0009410c, 0x0009610c, - 0x0009810c, 0x0009a10c, 0x0009c10c, 0x0009e10c, - 0x000a010c, 0x000a210c, 0x000a410c, 0x000a610c, - 0x000a810c, 0x000aa10c, 0x000ac10c, 0x000ae10c, - 0x000b010c, 0x000b210c, 0x000b410c, 0x000b610c, - 0x000b810c, 0x000ba10c, 0x000bc10c, 0x000be10c, - 0x000c010c, 0x000c210c, 0x000c410c, 0x000c610c, - 0x000c810c, 0x000ca10c, 0x000cc10c, 0x000ce10c, - 0x000d010c, 0x000d210c, 0x000d410c, 0x000d610c, - 0x000d810c, 0x000da10c, 0x000dc10c, 0x000de10c, - 0x000e010c, 0x000e210c, 0x000e410c, 0x000e610c, - 0x000e810c, 0x000ea10c, 0x000ec10c, 0x000ee10c, - 0x000f010c, 0x000f210c, 0x000f410c, 0x000f610c, - 0x000f810c, 0x000fa10c, 0x000fc10c, 0x000fe10c, - 0x0000110c, 0x0000310c, 0x0000510c, 0x0000710c, - 0x0000910c, 0x0000b10c, 0x0000d10c, 0x0000f10c, - 0x0001110c, 0x0001310c, 0x0001510c, 0x0001710c, - 0x0001910c, 0x0001b10c, 0x0001d10c, 0x0001f10c, - 0x0002110c, 0x0002310c, 0x0002510c, 0x0002710c, - 0x0002910c, 0x0002b10c, 0x0002d10c, 0x0002f10c, - 0x0003110c, 0x0003310c, 0x0003510c, 0x0003710c, - 0x0003910c, 0x0003b10c, 0x0003d10c, 0x0003f10c, - 0x0004110c, 0x0004310c, 0x0004510c, 0x0004710c, - 0x0004910c, 0x0004b10c, 0x0004d10c, 0x0004f10c, - 0x0005110c, 0x0005310c, 0x0005510c, 0x0005710c, - 0x0005910c, 0x0005b10c, 0x0005d10c, 0x0005f10c, - 0x0006110c, 0x0006310c, 0x0006510c, 0x0006710c, - 0x0006910c, 0x0006b10c, 0x0006d10c, 0x0006f10c, - 0x0007110c, 0x0007310c, 0x0007510c, 0x0007710c, - 0x0007910c, 0x0007b10c, 0x0007d10c, 0x0007f10c, - 0x0008110c, 0x0008310c, 0x0008510c, 0x0008710c, - 0x0008910c, 0x0008b10c, 0x0008d10c, 0x0008f10c, - 0x0009110c, 0x0009310c, 0x0009510c, 0x0009710c, - 0x0009910c, 0x0009b10c, 0x0009d10c, 0x0009f10c, - 0x000a110c, 0x000a310c, 0x000a510c, 0x000a710c, - 0x000a910c, 0x000ab10c, 0x000ad10c, 0x000af10c, - 0x000b110c, 0x000b310c, 0x000b510c, 0x000b710c, - 0x000b910c, 0x000bb10c, 0x000bd10c, 0x000bf10c, - 0x000c110c, 0x000c310c, 0x000c510c, 0x000c710c, - 0x000c910c, 0x000cb10c, 0x000cd10c, 0x000cf10c, - 0x000d110c, 0x000d310c, 0x000d510c, 0x000d710c, - 0x000d910c, 0x000db10c, 0x000dd10c, 0x000df10c, - 0x000e110c, 0x000e310c, 0x000e510c, 0x000e710c, - 0x000e910c, 0x000eb10c, 0x000ed10c, 0x000ef10c, - 0x000f110c, 0x000f310c, 0x000f510c, 0x000f710c, - 0x000f910c, 0x000fb10c, 0x000fd10c, 0x000ff10c, - 0x0000090d, 0x0000290d, 0x0000490d, 0x0000690d, - 0x0000890d, 0x0000a90d, 0x0000c90d, 0x0000e90d, - 0x0001090d, 0x0001290d, 0x0001490d, 0x0001690d, - 0x0001890d, 0x0001a90d, 0x0001c90d, 0x0001e90d, - 0x0002090d, 0x0002290d, 0x0002490d, 0x0002690d, - 0x0002890d, 0x0002a90d, 0x0002c90d, 0x0002e90d, - 0x0003090d, 0x0003290d, 0x0003490d, 0x0003690d, - 0x0003890d, 0x0003a90d, 0x0003c90d, 0x0003e90d, - 0x0004090d, 0x0004290d, 0x0004490d, 0x0004690d, - 0x0004890d, 0x0004a90d, 0x0004c90d, 0x0004e90d, - 0x0005090d, 0x0005290d, 0x0005490d, 0x0005690d, - 0x0005890d, 0x0005a90d, 0x0005c90d, 0x0005e90d, - 0x0006090d, 0x0006290d, 0x0006490d, 0x0006690d, - 0x0006890d, 0x0006a90d, 0x0006c90d, 0x0006e90d, - 0x0007090d, 0x0007290d, 0x0007490d, 0x0007690d, - 0x0007890d, 0x0007a90d, 0x0007c90d, 0x0007e90d, - 0x0008090d, 0x0008290d, 0x0008490d, 0x0008690d, - 0x0008890d, 0x0008a90d, 0x0008c90d, 0x0008e90d, - 0x0009090d, 0x0009290d, 0x0009490d, 0x0009690d, - 0x0009890d, 0x0009a90d, 0x0009c90d, 0x0009e90d, - 0x000a090d, 0x000a290d, 0x000a490d, 0x000a690d, - 0x000a890d, 0x000aa90d, 0x000ac90d, 0x000ae90d, - 0x000b090d, 0x000b290d, 0x000b490d, 0x000b690d, - 0x000b890d, 0x000ba90d, 0x000bc90d, 0x000be90d, - 0x000c090d, 0x000c290d, 0x000c490d, 0x000c690d, - 0x000c890d, 0x000ca90d, 0x000cc90d, 0x000ce90d, - 0x000d090d, 0x000d290d, 0x000d490d, 0x000d690d, - 0x000d890d, 0x000da90d, 0x000dc90d, 0x000de90d, - 0x000e090d, 0x000e290d, 0x000e490d, 0x000e690d, - 0x000e890d, 0x000ea90d, 0x000ec90d, 0x000ee90d, - 0x000f090d, 0x000f290d, 0x000f490d, 0x000f690d, - 0x000f890d, 0x000fa90d, 0x000fc90d, 0x000fe90d, - 0x0010090d, 0x0010290d, 0x0010490d, 0x0010690d, - 0x0010890d, 0x0010a90d, 0x0010c90d, 0x0010e90d, - 0x0011090d, 0x0011290d, 0x0011490d, 0x0011690d, - 0x0011890d, 0x0011a90d, 0x0011c90d, 0x0011e90d, - 0x0012090d, 0x0012290d, 0x0012490d, 0x0012690d, - 0x0012890d, 0x0012a90d, 0x0012c90d, 0x0012e90d, - 0x0013090d, 0x0013290d, 0x0013490d, 0x0013690d, - 0x0013890d, 0x0013a90d, 0x0013c90d, 0x0013e90d, - 0x0014090d, 0x0014290d, 0x0014490d, 0x0014690d, - 0x0014890d, 0x0014a90d, 0x0014c90d, 0x0014e90d, - 0x0015090d, 0x0015290d, 0x0015490d, 0x0015690d, - 0x0015890d, 0x0015a90d, 0x0015c90d, 0x0015e90d, - 0x0016090d, 0x0016290d, 0x0016490d, 0x0016690d, - 0x0016890d, 0x0016a90d, 0x0016c90d, 0x0016e90d, - 0x0017090d, 0x0017290d, 0x0017490d, 0x0017690d, - 0x0017890d, 0x0017a90d, 0x0017c90d, 0x0017e90d, - 0x0018090d, 0x0018290d, 0x0018490d, 0x0018690d, - 0x0018890d, 0x0018a90d, 0x0018c90d, 0x0018e90d, - 0x0019090d, 0x0019290d, 0x0019490d, 0x0019690d, - 0x0019890d, 0x0019a90d, 0x0019c90d, 0x0019e90d, - 0x001a090d, 0x001a290d, 0x001a490d, 0x001a690d, - 0x001a890d, 0x001aa90d, 0x001ac90d, 0x001ae90d, - 0x001b090d, 0x001b290d, 0x001b490d, 0x001b690d, - 0x001b890d, 0x001ba90d, 0x001bc90d, 0x001be90d, - 0x001c090d, 0x001c290d, 0x001c490d, 0x001c690d, - 0x001c890d, 0x001ca90d, 0x001cc90d, 0x001ce90d, - 0x001d090d, 0x001d290d, 0x001d490d, 0x001d690d, - 0x001d890d, 0x001da90d, 0x001dc90d, 0x001de90d, - 0x001e090d, 0x001e290d, 0x001e490d, 0x001e690d, - 0x001e890d, 0x001ea90d, 0x001ec90d, 0x001ee90d, - 0x001f090d, 0x001f290d, 0x001f490d, 0x001f690d, - 0x001f890d, 0x001fa90d, 0x001fc90d, 0x001fe90d, - 0x0000190d, 0x0000390d, 0x0000590d, 0x0000790d, - 0x0000990d, 0x0000b90d, 0x0000d90d, 0x0000f90d, - 0x0001190d, 0x0001390d, 0x0001590d, 0x0001790d, - 0x0001990d, 0x0001b90d, 0x0001d90d, 0x0001f90d, - 0x0002190d, 0x0002390d, 0x0002590d, 0x0002790d, - 0x0002990d, 0x0002b90d, 0x0002d90d, 0x0002f90d, - 0x0003190d, 0x0003390d, 0x0003590d, 0x0003790d, - 0x0003990d, 0x0003b90d, 0x0003d90d, 0x0003f90d, - 0x0004190d, 0x0004390d, 0x0004590d, 0x0004790d, - 0x0004990d, 0x0004b90d, 0x0004d90d, 0x0004f90d, - 0x0005190d, 0x0005390d, 0x0005590d, 0x0005790d, - 0x0005990d, 0x0005b90d, 0x0005d90d, 0x0005f90d, - 0x0006190d, 0x0006390d, 0x0006590d, 0x0006790d, - 0x0006990d, 0x0006b90d, 0x0006d90d, 0x0006f90d, - 0x0007190d, 0x0007390d, 0x0007590d, 0x0007790d, - 0x0007990d, 0x0007b90d, 0x0007d90d, 0x0007f90d, - 0x0008190d, 0x0008390d, 0x0008590d, 0x0008790d, - 0x0008990d, 0x0008b90d, 0x0008d90d, 0x0008f90d, - 0x0009190d, 0x0009390d, 0x0009590d, 0x0009790d, - 0x0009990d, 0x0009b90d, 0x0009d90d, 0x0009f90d, - 0x000a190d, 0x000a390d, 0x000a590d, 0x000a790d, - 0x000a990d, 0x000ab90d, 0x000ad90d, 0x000af90d, - 0x000b190d, 0x000b390d, 0x000b590d, 0x000b790d, - 0x000b990d, 0x000bb90d, 0x000bd90d, 0x000bf90d, - 0x000c190d, 0x000c390d, 0x000c590d, 0x000c790d, - 0x000c990d, 0x000cb90d, 0x000cd90d, 0x000cf90d, - 0x000d190d, 0x000d390d, 0x000d590d, 0x000d790d, - 0x000d990d, 0x000db90d, 0x000dd90d, 0x000df90d, - 0x000e190d, 0x000e390d, 0x000e590d, 0x000e790d, - 0x000e990d, 0x000eb90d, 0x000ed90d, 0x000ef90d, - 0x000f190d, 0x000f390d, 0x000f590d, 0x000f790d, - 0x000f990d, 0x000fb90d, 0x000fd90d, 0x000ff90d, - 0x0010190d, 0x0010390d, 0x0010590d, 0x0010790d, - 0x0010990d, 0x0010b90d, 0x0010d90d, 0x0010f90d, - 0x0011190d, 0x0011390d, 0x0011590d, 0x0011790d, - 0x0011990d, 0x0011b90d, 0x0011d90d, 0x0011f90d, - 0x0012190d, 0x0012390d, 0x0012590d, 0x0012790d, - 0x0012990d, 0x0012b90d, 0x0012d90d, 0x0012f90d, - 0x0013190d, 0x0013390d, 0x0013590d, 0x0013790d, - 0x0013990d, 0x0013b90d, 0x0013d90d, 0x0013f90d, - 0x0014190d, 0x0014390d, 0x0014590d, 0x0014790d, - 0x0014990d, 0x0014b90d, 0x0014d90d, 0x0014f90d, - 0x0015190d, 0x0015390d, 0x0015590d, 0x0015790d, - 0x0015990d, 0x0015b90d, 0x0015d90d, 0x0015f90d, - 0x0016190d, 0x0016390d, 0x0016590d, 0x0016790d, - 0x0016990d, 0x0016b90d, 0x0016d90d, 0x0016f90d, - 0x0017190d, 0x0017390d, 0x0017590d, 0x0017790d, - 0x0017990d, 0x0017b90d, 0x0017d90d, 0x0017f90d, - 0x0018190d, 0x0018390d, 0x0018590d, 0x0018790d, - 0x0018990d, 0x0018b90d, 0x0018d90d, 0x0018f90d, - 0x0019190d, 0x0019390d, 0x0019590d, 0x0019790d, - 0x0019990d, 0x0019b90d, 0x0019d90d, 0x0019f90d, - 0x001a190d, 0x001a390d, 0x001a590d, 0x001a790d, - 0x001a990d, 0x001ab90d, 0x001ad90d, 0x001af90d, - 0x001b190d, 0x001b390d, 0x001b590d, 0x001b790d, - 0x001b990d, 0x001bb90d, 0x001bd90d, 0x001bf90d, - 0x001c190d, 0x001c390d, 0x001c590d, 0x001c790d, - 0x001c990d, 0x001cb90d, 0x001cd90d, 0x001cf90d, - 0x001d190d, 0x001d390d, 0x001d590d, 0x001d790d, - 0x001d990d, 0x001db90d, 0x001dd90d, 0x001df90d, - 0x001e190d, 0x001e390d, 0x001e590d, 0x001e790d, - 0x001e990d, 0x001eb90d, 0x001ed90d, 0x001ef90d, - 0x001f190d, 0x001f390d, 0x001f590d, 0x001f790d, - 0x001f990d, 0x001fb90d, 0x001fd90d, 0x001ff90d, - 0x0000050e, 0x0000250e, 0x0000450e, 0x0000650e, - 0x0000850e, 0x0000a50e, 0x0000c50e, 0x0000e50e, - 0x0001050e, 0x0001250e, 0x0001450e, 0x0001650e, - 0x0001850e, 0x0001a50e, 0x0001c50e, 0x0001e50e, - 0x0002050e, 0x0002250e, 0x0002450e, 0x0002650e, - 0x0002850e, 0x0002a50e, 0x0002c50e, 0x0002e50e, - 0x0003050e, 0x0003250e, 0x0003450e, 0x0003650e, - 0x0003850e, 0x0003a50e, 0x0003c50e, 0x0003e50e, - 0x0004050e, 0x0004250e, 0x0004450e, 0x0004650e, - 0x0004850e, 0x0004a50e, 0x0004c50e, 0x0004e50e, - 0x0005050e, 0x0005250e, 0x0005450e, 0x0005650e, - 0x0005850e, 0x0005a50e, 0x0005c50e, 0x0005e50e, - 0x0006050e, 0x0006250e, 0x0006450e, 0x0006650e, - 0x0006850e, 0x0006a50e, 0x0006c50e, 0x0006e50e, - 0x0007050e, 0x0007250e, 0x0007450e, 0x0007650e, - 0x0007850e, 0x0007a50e, 0x0007c50e, 0x0007e50e, - 0x0008050e, 0x0008250e, 0x0008450e, 0x0008650e, - 0x0008850e, 0x0008a50e, 0x0008c50e, 0x0008e50e, - 0x0009050e, 0x0009250e, 0x0009450e, 0x0009650e, - 0x0009850e, 0x0009a50e, 0x0009c50e, 0x0009e50e, - 0x000a050e, 0x000a250e, 0x000a450e, 0x000a650e, - 0x000a850e, 0x000aa50e, 0x000ac50e, 0x000ae50e, - 0x000b050e, 0x000b250e, 0x000b450e, 0x000b650e, - 0x000b850e, 0x000ba50e, 0x000bc50e, 0x000be50e, - 0x000c050e, 0x000c250e, 0x000c450e, 0x000c650e, - 0x000c850e, 0x000ca50e, 0x000cc50e, 0x000ce50e, - 0x000d050e, 0x000d250e, 0x000d450e, 0x000d650e, - 0x000d850e, 0x000da50e, 0x000dc50e, 0x000de50e, - 0x000e050e, 0x000e250e, 0x000e450e, 0x000e650e, - 0x000e850e, 0x000ea50e, 0x000ec50e, 0x000ee50e, - 0x000f050e, 0x000f250e, 0x000f450e, 0x000f650e, - 0x000f850e, 0x000fa50e, 0x000fc50e, 0x000fe50e, - 0x0010050e, 0x0010250e, 0x0010450e, 0x0010650e, - 0x0010850e, 0x0010a50e, 0x0010c50e, 0x0010e50e, - 0x0011050e, 0x0011250e, 0x0011450e, 0x0011650e, - 0x0011850e, 0x0011a50e, 0x0011c50e, 0x0011e50e, - 0x0012050e, 0x0012250e, 0x0012450e, 0x0012650e, - 0x0012850e, 0x0012a50e, 0x0012c50e, 0x0012e50e, - 0x0013050e, 0x0013250e, 0x0013450e, 0x0013650e, - 0x0013850e, 0x0013a50e, 0x0013c50e, 0x0013e50e, - 0x0014050e, 0x0014250e, 0x0014450e, 0x0014650e, - 0x0014850e, 0x0014a50e, 0x0014c50e, 0x0014e50e, - 0x0015050e, 0x0015250e, 0x0015450e, 0x0015650e, - 0x0015850e, 0x0015a50e, 0x0015c50e, 0x0015e50e, - 0x0016050e, 0x0016250e, 0x0016450e, 0x0016650e, - 0x0016850e, 0x0016a50e, 0x0016c50e, 0x0016e50e, - 0x0017050e, 0x0017250e, 0x0017450e, 0x0017650e, - 0x0017850e, 0x0017a50e, 0x0017c50e, 0x0017e50e, - 0x0018050e, 0x0018250e, 0x0018450e, 0x0018650e, - 0x0018850e, 0x0018a50e, 0x0018c50e, 0x0018e50e, - 0x0019050e, 0x0019250e, 0x0019450e, 0x0019650e, - 0x0019850e, 0x0019a50e, 0x0019c50e, 0x0019e50e, - 0x001a050e, 0x001a250e, 0x001a450e, 0x001a650e, - 0x001a850e, 0x001aa50e, 0x001ac50e, 0x001ae50e, - 0x001b050e, 0x001b250e, 0x001b450e, 0x001b650e, - 0x001b850e, 0x001ba50e, 0x001bc50e, 0x001be50e, - 0x001c050e, 0x001c250e, 0x001c450e, 0x001c650e, - 0x001c850e, 0x001ca50e, 0x001cc50e, 0x001ce50e, - 0x001d050e, 0x001d250e, 0x001d450e, 0x001d650e, - 0x001d850e, 0x001da50e, 0x001dc50e, 0x001de50e, - 0x001e050e, 0x001e250e, 0x001e450e, 0x001e650e, - 0x001e850e, 0x001ea50e, 0x001ec50e, 0x001ee50e, - 0x001f050e, 0x001f250e, 0x001f450e, 0x001f650e, - 0x001f850e, 0x001fa50e, 0x001fc50e, 0x001fe50e, - 0x0020050e, 0x0020250e, 0x0020450e, 0x0020650e, - 0x0020850e, 0x0020a50e, 0x0020c50e, 0x0020e50e, - 0x0021050e, 0x0021250e, 0x0021450e, 0x0021650e, - 0x0021850e, 0x0021a50e, 0x0021c50e, 0x0021e50e, - 0x0022050e, 0x0022250e, 0x0022450e, 0x0022650e, - 0x0022850e, 0x0022a50e, 0x0022c50e, 0x0022e50e, - 0x0023050e, 0x0023250e, 0x0023450e, 0x0023650e, - 0x0023850e, 0x0023a50e, 0x0023c50e, 0x0023e50e, - 0x0024050e, 0x0024250e, 0x0024450e, 0x0024650e, - 0x0024850e, 0x0024a50e, 0x0024c50e, 0x0024e50e, - 0x0025050e, 0x0025250e, 0x0025450e, 0x0025650e, - 0x0025850e, 0x0025a50e, 0x0025c50e, 0x0025e50e, - 0x0026050e, 0x0026250e, 0x0026450e, 0x0026650e, - 0x0026850e, 0x0026a50e, 0x0026c50e, 0x0026e50e, - 0x0027050e, 0x0027250e, 0x0027450e, 0x0027650e, - 0x0027850e, 0x0027a50e, 0x0027c50e, 0x0027e50e, - 0x0028050e, 0x0028250e, 0x0028450e, 0x0028650e, - 0x0028850e, 0x0028a50e, 0x0028c50e, 0x0028e50e, - 0x0029050e, 0x0029250e, 0x0029450e, 0x0029650e, - 0x0029850e, 0x0029a50e, 0x0029c50e, 0x0029e50e, - 0x002a050e, 0x002a250e, 0x002a450e, 0x002a650e, - 0x002a850e, 0x002aa50e, 0x002ac50e, 0x002ae50e, - 0x002b050e, 0x002b250e, 0x002b450e, 0x002b650e, - 0x002b850e, 0x002ba50e, 0x002bc50e, 0x002be50e, - 0x002c050e, 0x002c250e, 0x002c450e, 0x002c650e, - 0x002c850e, 0x002ca50e, 0x002cc50e, 0x002ce50e, - 0x002d050e, 0x002d250e, 0x002d450e, 0x002d650e, - 0x002d850e, 0x002da50e, 0x002dc50e, 0x002de50e, - 0x002e050e, 0x002e250e, 0x002e450e, 0x002e650e, - 0x002e850e, 0x002ea50e, 0x002ec50e, 0x002ee50e, - 0x002f050e, 0x002f250e, 0x002f450e, 0x002f650e, - 0x002f850e, 0x002fa50e, 0x002fc50e, 0x002fe50e, - 0x0030050e, 0x0030250e, 0x0030450e, 0x0030650e, - 0x0030850e, 0x0030a50e, 0x0030c50e, 0x0030e50e, - 0x0031050e, 0x0031250e, 0x0031450e, 0x0031650e, - 0x0031850e, 0x0031a50e, 0x0031c50e, 0x0031e50e, - 0x0032050e, 0x0032250e, 0x0032450e, 0x0032650e, - 0x0032850e, 0x0032a50e, 0x0032c50e, 0x0032e50e, - 0x0033050e, 0x0033250e, 0x0033450e, 0x0033650e, - 0x0033850e, 0x0033a50e, 0x0033c50e, 0x0033e50e, - 0x0034050e, 0x0034250e, 0x0034450e, 0x0034650e, - 0x0034850e, 0x0034a50e, 0x0034c50e, 0x0034e50e, - 0x0035050e, 0x0035250e, 0x0035450e, 0x0035650e, - 0x0035850e, 0x0035a50e, 0x0035c50e, 0x0035e50e, - 0x0036050e, 0x0036250e, 0x0036450e, 0x0036650e, - 0x0036850e, 0x0036a50e, 0x0036c50e, 0x0036e50e, - 0x0037050e, 0x0037250e, 0x0037450e, 0x0037650e, - 0x0037850e, 0x0037a50e, 0x0037c50e, 0x0037e50e, - 0x0038050e, 0x0038250e, 0x0038450e, 0x0038650e, - 0x0038850e, 0x0038a50e, 0x0038c50e, 0x0038e50e, - 0x0039050e, 0x0039250e, 0x0039450e, 0x0039650e, - 0x0039850e, 0x0039a50e, 0x0039c50e, 0x0039e50e, - 0x003a050e, 0x003a250e, 0x003a450e, 0x003a650e, - 0x003a850e, 0x003aa50e, 0x003ac50e, 0x003ae50e, - 0x003b050e, 0x003b250e, 0x003b450e, 0x003b650e, - 0x003b850e, 0x003ba50e, 0x003bc50e, 0x003be50e, - 0x003c050e, 0x003c250e, 0x003c450e, 0x003c650e, - 0x003c850e, 0x003ca50e, 0x003cc50e, 0x003ce50e, - 0x003d050e, 0x003d250e, 0x003d450e, 0x003d650e, - 0x003d850e, 0x003da50e, 0x003dc50e, 0x003de50e, - 0x003e050e, 0x003e250e, 0x003e450e, 0x003e650e, - 0x003e850e, 0x003ea50e, 0x003ec50e, 0x003ee50e, - 0x003f050e, 0x003f250e, 0x003f450e, 0x003f650e, - 0x003f850e, 0x003fa50e, 0x003fc50e, 0x003fe50e, - 0x0000150e, 0x0000350e, 0x0000550e, 0x0000750e, - 0x0000950e, 0x0000b50e, 0x0000d50e, 0x0000f50e, - 0x0001150e, 0x0001350e, 0x0001550e, 0x0001750e, - 0x0001950e, 0x0001b50e, 0x0001d50e, 0x0001f50e, - 0x0002150e, 0x0002350e, 0x0002550e, 0x0002750e, - 0x0002950e, 0x0002b50e, 0x0002d50e, 0x0002f50e, - 0x0003150e, 0x0003350e, 0x0003550e, 0x0003750e, - 0x0003950e, 0x0003b50e, 0x0003d50e, 0x0003f50e, - 0x0004150e, 0x0004350e, 0x0004550e, 0x0004750e, - 0x0004950e, 0x0004b50e, 0x0004d50e, 0x0004f50e, - 0x0005150e, 0x0005350e, 0x0005550e, 0x0005750e, - 0x0005950e, 0x0005b50e, 0x0005d50e, 0x0005f50e, - 0x0006150e, 0x0006350e, 0x0006550e, 0x0006750e, - 0x0006950e, 0x0006b50e, 0x0006d50e, 0x0006f50e, - 0x0007150e, 0x0007350e, 0x0007550e, 0x0007750e, - 0x0007950e, 0x0007b50e, 0x0007d50e, 0x0007f50e, - 0x0008150e, 0x0008350e, 0x0008550e, 0x0008750e, - 0x0008950e, 0x0008b50e, 0x0008d50e, 0x0008f50e, - 0x0009150e, 0x0009350e, 0x0009550e, 0x0009750e, - 0x0009950e, 0x0009b50e, 0x0009d50e, 0x0009f50e, - 0x000a150e, 0x000a350e, 0x000a550e, 0x000a750e, - 0x000a950e, 0x000ab50e, 0x000ad50e, 0x000af50e, - 0x000b150e, 0x000b350e, 0x000b550e, 0x000b750e, - 0x000b950e, 0x000bb50e, 0x000bd50e, 0x000bf50e, - 0x000c150e, 0x000c350e, 0x000c550e, 0x000c750e, - 0x000c950e, 0x000cb50e, 0x000cd50e, 0x000cf50e, - 0x000d150e, 0x000d350e, 0x000d550e, 0x000d750e, - 0x000d950e, 0x000db50e, 0x000dd50e, 0x000df50e, - 0x000e150e, 0x000e350e, 0x000e550e, 0x000e750e, - 0x000e950e, 0x000eb50e, 0x000ed50e, 0x000ef50e, - 0x000f150e, 0x000f350e, 0x000f550e, 0x000f750e, - 0x000f950e, 0x000fb50e, 0x000fd50e, 0x000ff50e, - 0x0010150e, 0x0010350e, 0x0010550e, 0x0010750e, - 0x0010950e, 0x0010b50e, 0x0010d50e, 0x0010f50e, - 0x0011150e, 0x0011350e, 0x0011550e, 0x0011750e, - 0x0011950e, 0x0011b50e, 0x0011d50e, 0x0011f50e, - 0x0012150e, 0x0012350e, 0x0012550e, 0x0012750e, - 0x0012950e, 0x0012b50e, 0x0012d50e, 0x0012f50e, - 0x0013150e, 0x0013350e, 0x0013550e, 0x0013750e, - 0x0013950e, 0x0013b50e, 0x0013d50e, 0x0013f50e, - 0x0014150e, 0x0014350e, 0x0014550e, 0x0014750e, - 0x0014950e, 0x0014b50e, 0x0014d50e, 0x0014f50e, - 0x0015150e, 0x0015350e, 0x0015550e, 0x0015750e, - 0x0015950e, 0x0015b50e, 0x0015d50e, 0x0015f50e, - 0x0016150e, 0x0016350e, 0x0016550e, 0x0016750e, - 0x0016950e, 0x0016b50e, 0x0016d50e, 0x0016f50e, - 0x0017150e, 0x0017350e, 0x0017550e, 0x0017750e, - 0x0017950e, 0x0017b50e, 0x0017d50e, 0x0017f50e, - 0x0018150e, 0x0018350e, 0x0018550e, 0x0018750e, - 0x0018950e, 0x0018b50e, 0x0018d50e, 0x0018f50e, - 0x0019150e, 0x0019350e, 0x0019550e, 0x0019750e, - 0x0019950e, 0x0019b50e, 0x0019d50e, 0x0019f50e, - 0x001a150e, 0x001a350e, 0x001a550e, 0x001a750e, - 0x001a950e, 0x001ab50e, 0x001ad50e, 0x001af50e, - 0x001b150e, 0x001b350e, 0x001b550e, 0x001b750e, - 0x001b950e, 0x001bb50e, 0x001bd50e, 0x001bf50e, - 0x001c150e, 0x001c350e, 0x001c550e, 0x001c750e, - 0x001c950e, 0x001cb50e, 0x001cd50e, 0x001cf50e, - 0x001d150e, 0x001d350e, 0x001d550e, 0x001d750e, - 0x001d950e, 0x001db50e, 0x001dd50e, 0x001df50e, - 0x001e150e, 0x001e350e, 0x001e550e, 0x001e750e, - 0x001e950e, 0x001eb50e, 0x001ed50e, 0x001ef50e, - 0x001f150e, 0x001f350e, 0x001f550e, 0x001f750e, - 0x001f950e, 0x001fb50e, 0x001fd50e, 0x001ff50e, - 0x0020150e, 0x0020350e, 0x0020550e, 0x0020750e, - 0x0020950e, 0x0020b50e, 0x0020d50e, 0x0020f50e, - 0x0021150e, 0x0021350e, 0x0021550e, 0x0021750e, - 0x0021950e, 0x0021b50e, 0x0021d50e, 0x0021f50e, - 0x0022150e, 0x0022350e, 0x0022550e, 0x0022750e, - 0x0022950e, 0x0022b50e, 0x0022d50e, 0x0022f50e, - 0x0023150e, 0x0023350e, 0x0023550e, 0x0023750e, - 0x0023950e, 0x0023b50e, 0x0023d50e, 0x0023f50e, - 0x0024150e, 0x0024350e, 0x0024550e, 0x0024750e, - 0x0024950e, 0x0024b50e, 0x0024d50e, 0x0024f50e, - 0x0025150e, 0x0025350e, 0x0025550e, 0x0025750e, - 0x0025950e, 0x0025b50e, 0x0025d50e, 0x0025f50e, - 0x0026150e, 0x0026350e, 0x0026550e, 0x0026750e, - 0x0026950e, 0x0026b50e, 0x0026d50e, 0x0026f50e, - 0x0027150e, 0x0027350e, 0x0027550e, 0x0027750e, - 0x0027950e, 0x0027b50e, 0x0027d50e, 0x0027f50e, - 0x0028150e, 0x0028350e, 0x0028550e, 0x0028750e, - 0x0028950e, 0x0028b50e, 0x0028d50e, 0x0028f50e, - 0x0029150e, 0x0029350e, 0x0029550e, 0x0029750e, - 0x0029950e, 0x0029b50e, 0x0029d50e, 0x0029f50e, - 0x002a150e, 0x002a350e, 0x002a550e, 0x002a750e, - 0x002a950e, 0x002ab50e, 0x002ad50e, 0x002af50e, - 0x002b150e, 0x002b350e, 0x002b550e, 0x002b750e, - 0x002b950e, 0x002bb50e, 0x002bd50e, 0x002bf50e, - 0x002c150e, 0x002c350e, 0x002c550e, 0x002c750e, - 0x002c950e, 0x002cb50e, 0x002cd50e, 0x002cf50e, - 0x002d150e, 0x002d350e, 0x002d550e, 0x002d750e, - 0x002d950e, 0x002db50e, 0x002dd50e, 0x002df50e, - 0x002e150e, 0x002e350e, 0x002e550e, 0x002e750e, - 0x002e950e, 0x002eb50e, 0x002ed50e, 0x002ef50e, - 0x002f150e, 0x002f350e, 0x002f550e, 0x002f750e, - 0x002f950e, 0x002fb50e, 0x002fd50e, 0x002ff50e, - 0x0030150e, 0x0030350e, 0x0030550e, 0x0030750e, - 0x0030950e, 0x0030b50e, 0x0030d50e, 0x0030f50e, - 0x0031150e, 0x0031350e, 0x0031550e, 0x0031750e, - 0x0031950e, 0x0031b50e, 0x0031d50e, 0x0031f50e, - 0x0032150e, 0x0032350e, 0x0032550e, 0x0032750e, - 0x0032950e, 0x0032b50e, 0x0032d50e, 0x0032f50e, - 0x0033150e, 0x0033350e, 0x0033550e, 0x0033750e, - 0x0033950e, 0x0033b50e, 0x0033d50e, 0x0033f50e, - 0x0034150e, 0x0034350e, 0x0034550e, 0x0034750e, - 0x0034950e, 0x0034b50e, 0x0034d50e, 0x0034f50e, - 0x0035150e, 0x0035350e, 0x0035550e, 0x0035750e, - 0x0035950e, 0x0035b50e, 0x0035d50e, 0x0035f50e, - 0x0036150e, 0x0036350e, 0x0036550e, 0x0036750e, - 0x0036950e, 0x0036b50e, 0x0036d50e, 0x0036f50e, - 0x0037150e, 0x0037350e, 0x0037550e, 0x0037750e, - 0x0037950e, 0x0037b50e, 0x0037d50e, 0x0037f50e, - 0x0038150e, 0x0038350e, 0x0038550e, 0x0038750e, - 0x0038950e, 0x0038b50e, 0x0038d50e, 0x0038f50e, - 0x0039150e, 0x0039350e, 0x0039550e, 0x0039750e, - 0x0039950e, 0x0039b50e, 0x0039d50e, 0x0039f50e, - 0x003a150e, 0x003a350e, 0x003a550e, 0x003a750e, - 0x003a950e, 0x003ab50e, 0x003ad50e, 0x003af50e, - 0x003b150e, 0x003b350e, 0x003b550e, 0x003b750e, - 0x003b950e, 0x003bb50e, 0x003bd50e, 0x003bf50e, - 0x003c150e, 0x003c350e, 0x003c550e, 0x003c750e, - 0x003c950e, 0x003cb50e, 0x003cd50e, 0x003cf50e, - 0x003d150e, 0x003d350e, 0x003d550e, 0x003d750e, - 0x003d950e, 0x003db50e, 0x003dd50e, 0x003df50e, - 0x003e150e, 0x003e350e, 0x003e550e, 0x003e750e, - 0x003e950e, 0x003eb50e, 0x003ed50e, 0x003ef50e, - 0x003f150e, 0x003f350e, 0x003f550e, 0x003f750e, - 0x003f950e, 0x003fb50e, 0x003fd50e, 0x003ff50e, - 0x00000d0f, 0x00002d0f, 0x00004d0f, 0x00006d0f, - 0x00008d0f, 0x0000ad0f, 0x0000cd0f, 0x0000ed0f, - 0x00010d0f, 0x00012d0f, 0x00014d0f, 0x00016d0f, - 0x00018d0f, 0x0001ad0f, 0x0001cd0f, 0x0001ed0f, - 0x00020d0f, 0x00022d0f, 0x00024d0f, 0x00026d0f, - 0x00028d0f, 0x0002ad0f, 0x0002cd0f, 0x0002ed0f, - 0x00030d0f, 0x00032d0f, 0x00034d0f, 0x00036d0f, - 0x00038d0f, 0x0003ad0f, 0x0003cd0f, 0x0003ed0f, - 0x00040d0f, 0x00042d0f, 0x00044d0f, 0x00046d0f, - 0x00048d0f, 0x0004ad0f, 0x0004cd0f, 0x0004ed0f, - 0x00050d0f, 0x00052d0f, 0x00054d0f, 0x00056d0f, - 0x00058d0f, 0x0005ad0f, 0x0005cd0f, 0x0005ed0f, - 0x00060d0f, 0x00062d0f, 0x00064d0f, 0x00066d0f, - 0x00068d0f, 0x0006ad0f, 0x0006cd0f, 0x0006ed0f, - 0x00070d0f, 0x00072d0f, 0x00074d0f, 0x00076d0f, - 0x00078d0f, 0x0007ad0f, 0x0007cd0f, 0x0007ed0f, - 0x00080d0f, 0x00082d0f, 0x00084d0f, 0x00086d0f, - 0x00088d0f, 0x0008ad0f, 0x0008cd0f, 0x0008ed0f, - 0x00090d0f, 0x00092d0f, 0x00094d0f, 0x00096d0f, - 0x00098d0f, 0x0009ad0f, 0x0009cd0f, 0x0009ed0f, - 0x000a0d0f, 0x000a2d0f, 0x000a4d0f, 0x000a6d0f, - 0x000a8d0f, 0x000aad0f, 0x000acd0f, 0x000aed0f, - 0x000b0d0f, 0x000b2d0f, 0x000b4d0f, 0x000b6d0f, - 0x000b8d0f, 0x000bad0f, 0x000bcd0f, 0x000bed0f, - 0x000c0d0f, 0x000c2d0f, 0x000c4d0f, 0x000c6d0f, - 0x000c8d0f, 0x000cad0f, 0x000ccd0f, 0x000ced0f, - 0x000d0d0f, 0x000d2d0f, 0x000d4d0f, 0x000d6d0f, - 0x000d8d0f, 0x000dad0f, 0x000dcd0f, 0x000ded0f, - 0x000e0d0f, 0x000e2d0f, 0x000e4d0f, 0x000e6d0f, - 0x000e8d0f, 0x000ead0f, 0x000ecd0f, 0x000eed0f, - 0x000f0d0f, 0x000f2d0f, 0x000f4d0f, 0x000f6d0f, - 0x000f8d0f, 0x000fad0f, 0x000fcd0f, 0x000fed0f, - 0x00100d0f, 0x00102d0f, 0x00104d0f, 0x00106d0f, - 0x00108d0f, 0x0010ad0f, 0x0010cd0f, 0x0010ed0f, - 0x00110d0f, 0x00112d0f, 0x00114d0f, 0x00116d0f, - 0x00118d0f, 0x0011ad0f, 0x0011cd0f, 0x0011ed0f, - 0x00120d0f, 0x00122d0f, 0x00124d0f, 0x00126d0f, - 0x00128d0f, 0x0012ad0f, 0x0012cd0f, 0x0012ed0f, - 0x00130d0f, 0x00132d0f, 0x00134d0f, 0x00136d0f, - 0x00138d0f, 0x0013ad0f, 0x0013cd0f, 0x0013ed0f, - 0x00140d0f, 0x00142d0f, 0x00144d0f, 0x00146d0f, - 0x00148d0f, 0x0014ad0f, 0x0014cd0f, 0x0014ed0f, - 0x00150d0f, 0x00152d0f, 0x00154d0f, 0x00156d0f, - 0x00158d0f, 0x0015ad0f, 0x0015cd0f, 0x0015ed0f, - 0x00160d0f, 0x00162d0f, 0x00164d0f, 0x00166d0f, - 0x00168d0f, 0x0016ad0f, 0x0016cd0f, 0x0016ed0f, - 0x00170d0f, 0x00172d0f, 0x00174d0f, 0x00176d0f, - 0x00178d0f, 0x0017ad0f, 0x0017cd0f, 0x0017ed0f, - 0x00180d0f, 0x00182d0f, 0x00184d0f, 0x00186d0f, - 0x00188d0f, 0x0018ad0f, 0x0018cd0f, 0x0018ed0f, - 0x00190d0f, 0x00192d0f, 0x00194d0f, 0x00196d0f, - 0x00198d0f, 0x0019ad0f, 0x0019cd0f, 0x0019ed0f, - 0x001a0d0f, 0x001a2d0f, 0x001a4d0f, 0x001a6d0f, - 0x001a8d0f, 0x001aad0f, 0x001acd0f, 0x001aed0f, - 0x001b0d0f, 0x001b2d0f, 0x001b4d0f, 0x001b6d0f, - 0x001b8d0f, 0x001bad0f, 0x001bcd0f, 0x001bed0f, - 0x001c0d0f, 0x001c2d0f, 0x001c4d0f, 0x001c6d0f, - 0x001c8d0f, 0x001cad0f, 0x001ccd0f, 0x001ced0f, - 0x001d0d0f, 0x001d2d0f, 0x001d4d0f, 0x001d6d0f, - 0x001d8d0f, 0x001dad0f, 0x001dcd0f, 0x001ded0f, - 0x001e0d0f, 0x001e2d0f, 0x001e4d0f, 0x001e6d0f, - 0x001e8d0f, 0x001ead0f, 0x001ecd0f, 0x001eed0f, - 0x001f0d0f, 0x001f2d0f, 0x001f4d0f, 0x001f6d0f, - 0x001f8d0f, 0x001fad0f, 0x001fcd0f, 0x001fed0f, - 0x00200d0f, 0x00202d0f, 0x00204d0f, 0x00206d0f, - 0x00208d0f, 0x0020ad0f, 0x0020cd0f, 0x0020ed0f, - 0x00210d0f, 0x00212d0f, 0x00214d0f, 0x00216d0f, - 0x00218d0f, 0x0021ad0f, 0x0021cd0f, 0x0021ed0f, - 0x00220d0f, 0x00222d0f, 0x00224d0f, 0x00226d0f, - 0x00228d0f, 0x0022ad0f, 0x0022cd0f, 0x0022ed0f, - 0x00230d0f, 0x00232d0f, 0x00234d0f, 0x00236d0f, - 0x00238d0f, 0x0023ad0f, 0x0023cd0f, 0x0023ed0f, - 0x00240d0f, 0x00242d0f, 0x00244d0f, 0x00246d0f, - 0x00248d0f, 0x0024ad0f, 0x0024cd0f, 0x0024ed0f, - 0x00250d0f, 0x00252d0f, 0x00254d0f, 0x00256d0f, - 0x00258d0f, 0x0025ad0f, 0x0025cd0f, 0x0025ed0f, - 0x00260d0f, 0x00262d0f, 0x00264d0f, 0x00266d0f, - 0x00268d0f, 0x0026ad0f, 0x0026cd0f, 0x0026ed0f, - 0x00270d0f, 0x00272d0f, 0x00274d0f, 0x00276d0f, - 0x00278d0f, 0x0027ad0f, 0x0027cd0f, 0x0027ed0f, - 0x00280d0f, 0x00282d0f, 0x00284d0f, 0x00286d0f, - 0x00288d0f, 0x0028ad0f, 0x0028cd0f, 0x0028ed0f, - 0x00290d0f, 0x00292d0f, 0x00294d0f, 0x00296d0f, - 0x00298d0f, 0x0029ad0f, 0x0029cd0f, 0x0029ed0f, - 0x002a0d0f, 0x002a2d0f, 0x002a4d0f, 0x002a6d0f, - 0x002a8d0f, 0x002aad0f, 0x002acd0f, 0x002aed0f, - 0x002b0d0f, 0x002b2d0f, 0x002b4d0f, 0x002b6d0f, - 0x002b8d0f, 0x002bad0f, 0x002bcd0f, 0x002bed0f, - 0x002c0d0f, 0x002c2d0f, 0x002c4d0f, 0x002c6d0f, - 0x002c8d0f, 0x002cad0f, 0x002ccd0f, 0x002ced0f, - 0x002d0d0f, 0x002d2d0f, 0x002d4d0f, 0x002d6d0f, - 0x002d8d0f, 0x002dad0f, 0x002dcd0f, 0x002ded0f, - 0x002e0d0f, 0x002e2d0f, 0x002e4d0f, 0x002e6d0f, - 0x002e8d0f, 0x002ead0f, 0x002ecd0f, 0x002eed0f, - 0x002f0d0f, 0x002f2d0f, 0x002f4d0f, 0x002f6d0f, - 0x002f8d0f, 0x002fad0f, 0x002fcd0f, 0x002fed0f, - 0x00300d0f, 0x00302d0f, 0x00304d0f, 0x00306d0f, - 0x00308d0f, 0x0030ad0f, 0x0030cd0f, 0x0030ed0f, - 0x00310d0f, 0x00312d0f, 0x00314d0f, 0x00316d0f, - 0x00318d0f, 0x0031ad0f, 0x0031cd0f, 0x0031ed0f, - 0x00320d0f, 0x00322d0f, 0x00324d0f, 0x00326d0f, - 0x00328d0f, 0x0032ad0f, 0x0032cd0f, 0x0032ed0f, - 0x00330d0f, 0x00332d0f, 0x00334d0f, 0x00336d0f, - 0x00338d0f, 0x0033ad0f, 0x0033cd0f, 0x0033ed0f, - 0x00340d0f, 0x00342d0f, 0x00344d0f, 0x00346d0f, - 0x00348d0f, 0x0034ad0f, 0x0034cd0f, 0x0034ed0f, - 0x00350d0f, 0x00352d0f, 0x00354d0f, 0x00356d0f, - 0x00358d0f, 0x0035ad0f, 0x0035cd0f, 0x0035ed0f, - 0x00360d0f, 0x00362d0f, 0x00364d0f, 0x00366d0f, - 0x00368d0f, 0x0036ad0f, 0x0036cd0f, 0x0036ed0f, - 0x00370d0f, 0x00372d0f, 0x00374d0f, 0x00376d0f, - 0x00378d0f, 0x0037ad0f, 0x0037cd0f, 0x0037ed0f, - 0x00380d0f, 0x00382d0f, 0x00384d0f, 0x00386d0f, - 0x00388d0f, 0x0038ad0f, 0x0038cd0f, 0x0038ed0f, - 0x00390d0f, 0x00392d0f, 0x00394d0f, 0x00396d0f, - 0x00398d0f, 0x0039ad0f, 0x0039cd0f, 0x0039ed0f, - 0x003a0d0f, 0x003a2d0f, 0x003a4d0f, 0x003a6d0f, - 0x003a8d0f, 0x003aad0f, 0x003acd0f, 0x003aed0f, - 0x003b0d0f, 0x003b2d0f, 0x003b4d0f, 0x003b6d0f, - 0x003b8d0f, 0x003bad0f, 0x003bcd0f, 0x003bed0f, - 0x003c0d0f, 0x003c2d0f, 0x003c4d0f, 0x003c6d0f, - 0x003c8d0f, 0x003cad0f, 0x003ccd0f, 0x003ced0f, - 0x003d0d0f, 0x003d2d0f, 0x003d4d0f, 0x003d6d0f, - 0x003d8d0f, 0x003dad0f, 0x003dcd0f, 0x003ded0f, - 0x003e0d0f, 0x003e2d0f, 0x003e4d0f, 0x003e6d0f, - 0x003e8d0f, 0x003ead0f, 0x003ecd0f, 0x003eed0f, - 0x003f0d0f, 0x003f2d0f, 0x003f4d0f, 0x003f6d0f, - 0x003f8d0f, 0x003fad0f, 0x003fcd0f, 0x003fed0f, - 0x00400d0f, 0x00402d0f, 0x00404d0f, 0x00406d0f, - 0x00408d0f, 0x0040ad0f, 0x0040cd0f, 0x0040ed0f, - 0x00410d0f, 0x00412d0f, 0x00414d0f, 0x00416d0f, - 0x00418d0f, 0x0041ad0f, 0x0041cd0f, 0x0041ed0f, - 0x00420d0f, 0x00422d0f, 0x00424d0f, 0x00426d0f, - 0x00428d0f, 0x0042ad0f, 0x0042cd0f, 0x0042ed0f, - 0x00430d0f, 0x00432d0f, 0x00434d0f, 0x00436d0f, - 0x00438d0f, 0x0043ad0f, 0x0043cd0f, 0x0043ed0f, - 0x00440d0f, 0x00442d0f, 0x00444d0f, 0x00446d0f, - 0x00448d0f, 0x0044ad0f, 0x0044cd0f, 0x0044ed0f, - 0x00450d0f, 0x00452d0f, 0x00454d0f, 0x00456d0f, - 0x00458d0f, 0x0045ad0f, 0x0045cd0f, 0x0045ed0f, - 0x00460d0f, 0x00462d0f, 0x00464d0f, 0x00466d0f, - 0x00468d0f, 0x0046ad0f, 0x0046cd0f, 0x0046ed0f, - 0x00470d0f, 0x00472d0f, 0x00474d0f, 0x00476d0f, - 0x00478d0f, 0x0047ad0f, 0x0047cd0f, 0x0047ed0f, - 0x00480d0f, 0x00482d0f, 0x00484d0f, 0x00486d0f, - 0x00488d0f, 0x0048ad0f, 0x0048cd0f, 0x0048ed0f, - 0x00490d0f, 0x00492d0f, 0x00494d0f, 0x00496d0f, - 0x00498d0f, 0x0049ad0f, 0x0049cd0f, 0x0049ed0f, - 0x004a0d0f, 0x004a2d0f, 0x004a4d0f, 0x004a6d0f, - 0x004a8d0f, 0x004aad0f, 0x004acd0f, 0x004aed0f, - 0x004b0d0f, 0x004b2d0f, 0x004b4d0f, 0x004b6d0f, - 0x004b8d0f, 0x004bad0f, 0x004bcd0f, 0x004bed0f, - 0x004c0d0f, 0x004c2d0f, 0x004c4d0f, 0x004c6d0f, - 0x004c8d0f, 0x004cad0f, 0x004ccd0f, 0x004ced0f, - 0x004d0d0f, 0x004d2d0f, 0x004d4d0f, 0x004d6d0f, - 0x004d8d0f, 0x004dad0f, 0x004dcd0f, 0x004ded0f, - 0x004e0d0f, 0x004e2d0f, 0x004e4d0f, 0x004e6d0f, - 0x004e8d0f, 0x004ead0f, 0x004ecd0f, 0x004eed0f, - 0x004f0d0f, 0x004f2d0f, 0x004f4d0f, 0x004f6d0f, - 0x004f8d0f, 0x004fad0f, 0x004fcd0f, 0x004fed0f, - 0x00500d0f, 0x00502d0f, 0x00504d0f, 0x00506d0f, - 0x00508d0f, 0x0050ad0f, 0x0050cd0f, 0x0050ed0f, - 0x00510d0f, 0x00512d0f, 0x00514d0f, 0x00516d0f, - 0x00518d0f, 0x0051ad0f, 0x0051cd0f, 0x0051ed0f, - 0x00520d0f, 0x00522d0f, 0x00524d0f, 0x00526d0f, - 0x00528d0f, 0x0052ad0f, 0x0052cd0f, 0x0052ed0f, - 0x00530d0f, 0x00532d0f, 0x00534d0f, 0x00536d0f, - 0x00538d0f, 0x0053ad0f, 0x0053cd0f, 0x0053ed0f, - 0x00540d0f, 0x00542d0f, 0x00544d0f, 0x00546d0f, - 0x00548d0f, 0x0054ad0f, 0x0054cd0f, 0x0054ed0f, - 0x00550d0f, 0x00552d0f, 0x00554d0f, 0x00556d0f, - 0x00558d0f, 0x0055ad0f, 0x0055cd0f, 0x0055ed0f, - 0x00560d0f, 0x00562d0f, 0x00564d0f, 0x00566d0f, - 0x00568d0f, 0x0056ad0f, 0x0056cd0f, 0x0056ed0f, - 0x00570d0f, 0x00572d0f, 0x00574d0f, 0x00576d0f, - 0x00578d0f, 0x0057ad0f, 0x0057cd0f, 0x0057ed0f, - 0x00580d0f, 0x00582d0f, 0x00584d0f, 0x00586d0f, - 0x00588d0f, 0x0058ad0f, 0x0058cd0f, 0x0058ed0f, - 0x00590d0f, 0x00592d0f, 0x00594d0f, 0x00596d0f, - 0x00598d0f, 0x0059ad0f, 0x0059cd0f, 0x0059ed0f, - 0x005a0d0f, 0x005a2d0f, 0x005a4d0f, 0x005a6d0f, - 0x005a8d0f, 0x005aad0f, 0x005acd0f, 0x005aed0f, - 0x005b0d0f, 0x005b2d0f, 0x005b4d0f, 0x005b6d0f, - 0x005b8d0f, 0x005bad0f, 0x005bcd0f, 0x005bed0f, - 0x005c0d0f, 0x005c2d0f, 0x005c4d0f, 0x005c6d0f, - 0x005c8d0f, 0x005cad0f, 0x005ccd0f, 0x005ced0f, - 0x005d0d0f, 0x005d2d0f, 0x005d4d0f, 0x005d6d0f, - 0x005d8d0f, 0x005dad0f, 0x005dcd0f, 0x005ded0f, - 0x005e0d0f, 0x005e2d0f, 0x005e4d0f, 0x005e6d0f, - 0x005e8d0f, 0x005ead0f, 0x005ecd0f, 0x005eed0f, - 0x005f0d0f, 0x005f2d0f, 0x005f4d0f, 0x005f6d0f, - 0x005f8d0f, 0x005fad0f, 0x005fcd0f, 0x005fed0f, - 0x00600d0f, 0x00602d0f, 0x00604d0f, 0x00606d0f, - 0x00608d0f, 0x0060ad0f, 0x0060cd0f, 0x0060ed0f, - 0x00610d0f, 0x00612d0f, 0x00614d0f, 0x00616d0f, - 0x00618d0f, 0x0061ad0f, 0x0061cd0f, 0x0061ed0f, - 0x00620d0f, 0x00622d0f, 0x00624d0f, 0x00626d0f, - 0x00628d0f, 0x0062ad0f, 0x0062cd0f, 0x0062ed0f, - 0x00630d0f, 0x00632d0f, 0x00634d0f, 0x00636d0f, - 0x00638d0f, 0x0063ad0f, 0x0063cd0f, 0x0063ed0f, - 0x00640d0f, 0x00642d0f, 0x00644d0f, 0x00646d0f, - 0x00648d0f, 0x0064ad0f, 0x0064cd0f, 0x0064ed0f, - 0x00650d0f, 0x00652d0f, 0x00654d0f, 0x00656d0f, - 0x00658d0f, 0x0065ad0f, 0x0065cd0f, 0x0065ed0f, - 0x00660d0f, 0x00662d0f, 0x00664d0f, 0x00666d0f, - 0x00668d0f, 0x0066ad0f, 0x0066cd0f, 0x0066ed0f, - 0x00670d0f, 0x00672d0f, 0x00674d0f, 0x00676d0f, - 0x00678d0f, 0x0067ad0f, 0x0067cd0f, 0x0067ed0f, - 0x00680d0f, 0x00682d0f, 0x00684d0f, 0x00686d0f, - 0x00688d0f, 0x0068ad0f, 0x0068cd0f, 0x0068ed0f, - 0x00690d0f, 0x00692d0f, 0x00694d0f, 0x00696d0f, - 0x00698d0f, 0x0069ad0f, 0x0069cd0f, 0x0069ed0f, - 0x006a0d0f, 0x006a2d0f, 0x006a4d0f, 0x006a6d0f, - 0x006a8d0f, 0x006aad0f, 0x006acd0f, 0x006aed0f, - 0x006b0d0f, 0x006b2d0f, 0x006b4d0f, 0x006b6d0f, - 0x006b8d0f, 0x006bad0f, 0x006bcd0f, 0x006bed0f, - 0x006c0d0f, 0x006c2d0f, 0x006c4d0f, 0x006c6d0f, - 0x006c8d0f, 0x006cad0f, 0x006ccd0f, 0x006ced0f, - 0x006d0d0f, 0x006d2d0f, 0x006d4d0f, 0x006d6d0f, - 0x006d8d0f, 0x006dad0f, 0x006dcd0f, 0x006ded0f, - 0x006e0d0f, 0x006e2d0f, 0x006e4d0f, 0x006e6d0f, - 0x006e8d0f, 0x006ead0f, 0x006ecd0f, 0x006eed0f, - 0x006f0d0f, 0x006f2d0f, 0x006f4d0f, 0x006f6d0f, - 0x006f8d0f, 0x006fad0f, 0x006fcd0f, 0x006fed0f, - 0x00700d0f, 0x00702d0f, 0x00704d0f, 0x00706d0f, - 0x00708d0f, 0x0070ad0f, 0x0070cd0f, 0x0070ed0f, - 0x00710d0f, 0x00712d0f, 0x00714d0f, 0x00716d0f, - 0x00718d0f, 0x0071ad0f, 0x0071cd0f, 0x0071ed0f, - 0x00720d0f, 0x00722d0f, 0x00724d0f, 0x00726d0f, - 0x00728d0f, 0x0072ad0f, 0x0072cd0f, 0x0072ed0f, - 0x00730d0f, 0x00732d0f, 0x00734d0f, 0x00736d0f, - 0x00738d0f, 0x0073ad0f, 0x0073cd0f, 0x0073ed0f, - 0x00740d0f, 0x00742d0f, 0x00744d0f, 0x00746d0f, - 0x00748d0f, 0x0074ad0f, 0x0074cd0f, 0x0074ed0f, - 0x00750d0f, 0x00752d0f, 0x00754d0f, 0x00756d0f, - 0x00758d0f, 0x0075ad0f, 0x0075cd0f, 0x0075ed0f, - 0x00760d0f, 0x00762d0f, 0x00764d0f, 0x00766d0f, - 0x00768d0f, 0x0076ad0f, 0x0076cd0f, 0x0076ed0f, - 0x00770d0f, 0x00772d0f, 0x00774d0f, 0x00776d0f, - 0x00778d0f, 0x0077ad0f, 0x0077cd0f, 0x0077ed0f, - 0x00780d0f, 0x00782d0f, 0x00784d0f, 0x00786d0f, - 0x00788d0f, 0x0078ad0f, 0x0078cd0f, 0x0078ed0f, - 0x00790d0f, 0x00792d0f, 0x00794d0f, 0x00796d0f, - 0x00798d0f, 0x0079ad0f, 0x0079cd0f, 0x0079ed0f, - 0x007a0d0f, 0x007a2d0f, 0x007a4d0f, 0x007a6d0f, - 0x007a8d0f, 0x007aad0f, 0x007acd0f, 0x007aed0f, - 0x007b0d0f, 0x007b2d0f, 0x007b4d0f, 0x007b6d0f, - 0x007b8d0f, 0x007bad0f, 0x007bcd0f, 0x007bed0f, - 0x007c0d0f, 0x007c2d0f, 0x007c4d0f, 0x007c6d0f, - 0x007c8d0f, 0x007cad0f, 0x007ccd0f, 0x007ced0f, - 0x007d0d0f, 0x007d2d0f, 0x007d4d0f, 0x007d6d0f, - 0x007d8d0f, 0x007dad0f, 0x007dcd0f, 0x007ded0f, - 0x007e0d0f, 0x007e2d0f, 0x007e4d0f, 0x007e6d0f, - 0x007e8d0f, 0x007ead0f, 0x007ecd0f, 0x007eed0f, - 0x007f0d0f, 0x007f2d0f, 0x007f4d0f, 0x007f6d0f, - 0x007f8d0f, 0x007fad0f, 0x007fcd0f, 0x007fed0f, - 0x00001d0f, 0x00003d0f, 0x00005d0f, 0x00007d0f, - 0x00009d0f, 0x0000bd0f, 0x0000dd0f, 0x0000fd0f, - 0x00011d0f, 0x00013d0f, 0x00015d0f, 0x00017d0f, - 0x00019d0f, 0x0001bd0f, 0x0001dd0f, 0x0001fd0f, - 0x00021d0f, 0x00023d0f, 0x00025d0f, 0x00027d0f, - 0x00029d0f, 0x0002bd0f, 0x0002dd0f, 0x0002fd0f, - 0x00031d0f, 0x00033d0f, 0x00035d0f, 0x00037d0f, - 0x00039d0f, 0x0003bd0f, 0x0003dd0f, 0x0003fd0f, - 0x00041d0f, 0x00043d0f, 0x00045d0f, 0x00047d0f, - 0x00049d0f, 0x0004bd0f, 0x0004dd0f, 0x0004fd0f, - 0x00051d0f, 0x00053d0f, 0x00055d0f, 0x00057d0f, - 0x00059d0f, 0x0005bd0f, 0x0005dd0f, 0x0005fd0f, - 0x00061d0f, 0x00063d0f, 0x00065d0f, 0x00067d0f, - 0x00069d0f, 0x0006bd0f, 0x0006dd0f, 0x0006fd0f, - 0x00071d0f, 0x00073d0f, 0x00075d0f, 0x00077d0f, - 0x00079d0f, 0x0007bd0f, 0x0007dd0f, 0x0007fd0f, - 0x00081d0f, 0x00083d0f, 0x00085d0f, 0x00087d0f, - 0x00089d0f, 0x0008bd0f, 0x0008dd0f, 0x0008fd0f, - 0x00091d0f, 0x00093d0f, 0x00095d0f, 0x00097d0f, - 0x00099d0f, 0x0009bd0f, 0x0009dd0f, 0x0009fd0f, - 0x000a1d0f, 0x000a3d0f, 0x000a5d0f, 0x000a7d0f, - 0x000a9d0f, 0x000abd0f, 0x000add0f, 0x000afd0f, - 0x000b1d0f, 0x000b3d0f, 0x000b5d0f, 0x000b7d0f, - 0x000b9d0f, 0x000bbd0f, 0x000bdd0f, 0x000bfd0f, - 0x000c1d0f, 0x000c3d0f, 0x000c5d0f, 0x000c7d0f, - 0x000c9d0f, 0x000cbd0f, 0x000cdd0f, 0x000cfd0f, - 0x000d1d0f, 0x000d3d0f, 0x000d5d0f, 0x000d7d0f, - 0x000d9d0f, 0x000dbd0f, 0x000ddd0f, 0x000dfd0f, - 0x000e1d0f, 0x000e3d0f, 0x000e5d0f, 0x000e7d0f, - 0x000e9d0f, 0x000ebd0f, 0x000edd0f, 0x000efd0f, - 0x000f1d0f, 0x000f3d0f, 0x000f5d0f, 0x000f7d0f, - 0x000f9d0f, 0x000fbd0f, 0x000fdd0f, 0x000ffd0f, - 0x00101d0f, 0x00103d0f, 0x00105d0f, 0x00107d0f, - 0x00109d0f, 0x0010bd0f, 0x0010dd0f, 0x0010fd0f, - 0x00111d0f, 0x00113d0f, 0x00115d0f, 0x00117d0f, - 0x00119d0f, 0x0011bd0f, 0x0011dd0f, 0x0011fd0f, - 0x00121d0f, 0x00123d0f, 0x00125d0f, 0x00127d0f, - 0x00129d0f, 0x0012bd0f, 0x0012dd0f, 0x0012fd0f, - 0x00131d0f, 0x00133d0f, 0x00135d0f, 0x00137d0f, - 0x00139d0f, 0x0013bd0f, 0x0013dd0f, 0x0013fd0f, - 0x00141d0f, 0x00143d0f, 0x00145d0f, 0x00147d0f, - 0x00149d0f, 0x0014bd0f, 0x0014dd0f, 0x0014fd0f, - 0x00151d0f, 0x00153d0f, 0x00155d0f, 0x00157d0f, - 0x00159d0f, 0x0015bd0f, 0x0015dd0f, 0x0015fd0f, - 0x00161d0f, 0x00163d0f, 0x00165d0f, 0x00167d0f, - 0x00169d0f, 0x0016bd0f, 0x0016dd0f, 0x0016fd0f, - 0x00171d0f, 0x00173d0f, 0x00175d0f, 0x00177d0f, - 0x00179d0f, 0x0017bd0f, 0x0017dd0f, 0x0017fd0f, - 0x00181d0f, 0x00183d0f, 0x00185d0f, 0x00187d0f, - 0x00189d0f, 0x0018bd0f, 0x0018dd0f, 0x0018fd0f, - 0x00191d0f, 0x00193d0f, 0x00195d0f, 0x00197d0f, - 0x00199d0f, 0x0019bd0f, 0x0019dd0f, 0x0019fd0f, - 0x001a1d0f, 0x001a3d0f, 0x001a5d0f, 0x001a7d0f, - 0x001a9d0f, 0x001abd0f, 0x001add0f, 0x001afd0f, - 0x001b1d0f, 0x001b3d0f, 0x001b5d0f, 0x001b7d0f, - 0x001b9d0f, 0x001bbd0f, 0x001bdd0f, 0x001bfd0f, - 0x001c1d0f, 0x001c3d0f, 0x001c5d0f, 0x001c7d0f, - 0x001c9d0f, 0x001cbd0f, 0x001cdd0f, 0x001cfd0f, - 0x001d1d0f, 0x001d3d0f, 0x001d5d0f, 0x001d7d0f, - 0x001d9d0f, 0x001dbd0f, 0x001ddd0f, 0x001dfd0f, - 0x001e1d0f, 0x001e3d0f, 0x001e5d0f, 0x001e7d0f, - 0x001e9d0f, 0x001ebd0f, 0x001edd0f, 0x001efd0f, - 0x001f1d0f, 0x001f3d0f, 0x001f5d0f, 0x001f7d0f, - 0x001f9d0f, 0x001fbd0f, 0x001fdd0f, 0x001ffd0f, - 0x00201d0f, 0x00203d0f, 0x00205d0f, 0x00207d0f, - 0x00209d0f, 0x0020bd0f, 0x0020dd0f, 0x0020fd0f, - 0x00211d0f, 0x00213d0f, 0x00215d0f, 0x00217d0f, - 0x00219d0f, 0x0021bd0f, 0x0021dd0f, 0x0021fd0f, - 0x00221d0f, 0x00223d0f, 0x00225d0f, 0x00227d0f, - 0x00229d0f, 0x0022bd0f, 0x0022dd0f, 0x0022fd0f, - 0x00231d0f, 0x00233d0f, 0x00235d0f, 0x00237d0f, - 0x00239d0f, 0x0023bd0f, 0x0023dd0f, 0x0023fd0f, - 0x00241d0f, 0x00243d0f, 0x00245d0f, 0x00247d0f, - 0x00249d0f, 0x0024bd0f, 0x0024dd0f, 0x0024fd0f, - 0x00251d0f, 0x00253d0f, 0x00255d0f, 0x00257d0f, - 0x00259d0f, 0x0025bd0f, 0x0025dd0f, 0x0025fd0f, - 0x00261d0f, 0x00263d0f, 0x00265d0f, 0x00267d0f, - 0x00269d0f, 0x0026bd0f, 0x0026dd0f, 0x0026fd0f, - 0x00271d0f, 0x00273d0f, 0x00275d0f, 0x00277d0f, - 0x00279d0f, 0x0027bd0f, 0x0027dd0f, 0x0027fd0f, - 0x00281d0f, 0x00283d0f, 0x00285d0f, 0x00287d0f, - 0x00289d0f, 0x0028bd0f, 0x0028dd0f, 0x0028fd0f, - 0x00291d0f, 0x00293d0f, 0x00295d0f, 0x00297d0f, - 0x00299d0f, 0x0029bd0f, 0x0029dd0f, 0x0029fd0f, - 0x002a1d0f, 0x002a3d0f, 0x002a5d0f, 0x002a7d0f, - 0x002a9d0f, 0x002abd0f, 0x002add0f, 0x002afd0f, - 0x002b1d0f, 0x002b3d0f, 0x002b5d0f, 0x002b7d0f, - 0x002b9d0f, 0x002bbd0f, 0x002bdd0f, 0x002bfd0f, - 0x002c1d0f, 0x002c3d0f, 0x002c5d0f, 0x002c7d0f, - 0x002c9d0f, 0x002cbd0f, 0x002cdd0f, 0x002cfd0f, - 0x002d1d0f, 0x002d3d0f, 0x002d5d0f, 0x002d7d0f, - 0x002d9d0f, 0x002dbd0f, 0x002ddd0f, 0x002dfd0f, - 0x002e1d0f, 0x002e3d0f, 0x002e5d0f, 0x002e7d0f, - 0x002e9d0f, 0x002ebd0f, 0x002edd0f, 0x002efd0f, - 0x002f1d0f, 0x002f3d0f, 0x002f5d0f, 0x002f7d0f, - 0x002f9d0f, 0x002fbd0f, 0x002fdd0f, 0x002ffd0f, - 0x00301d0f, 0x00303d0f, 0x00305d0f, 0x00307d0f, - 0x00309d0f, 0x0030bd0f, 0x0030dd0f, 0x0030fd0f, - 0x00311d0f, 0x00313d0f, 0x00315d0f, 0x00317d0f, - 0x00319d0f, 0x0031bd0f, 0x0031dd0f, 0x0031fd0f, - 0x00321d0f, 0x00323d0f, 0x00325d0f, 0x00327d0f, - 0x00329d0f, 0x0032bd0f, 0x0032dd0f, 0x0032fd0f, - 0x00331d0f, 0x00333d0f, 0x00335d0f, 0x00337d0f, - 0x00339d0f, 0x0033bd0f, 0x0033dd0f, 0x0033fd0f, - 0x00341d0f, 0x00343d0f, 0x00345d0f, 0x00347d0f, - 0x00349d0f, 0x0034bd0f, 0x0034dd0f, 0x0034fd0f, - 0x00351d0f, 0x00353d0f, 0x00355d0f, 0x00357d0f, - 0x00359d0f, 0x0035bd0f, 0x0035dd0f, 0x0035fd0f, - 0x00361d0f, 0x00363d0f, 0x00365d0f, 0x00367d0f, - 0x00369d0f, 0x0036bd0f, 0x0036dd0f, 0x0036fd0f, - 0x00371d0f, 0x00373d0f, 0x00375d0f, 0x00377d0f, - 0x00379d0f, 0x0037bd0f, 0x0037dd0f, 0x0037fd0f, - 0x00381d0f, 0x00383d0f, 0x00385d0f, 0x00387d0f, - 0x00389d0f, 0x0038bd0f, 0x0038dd0f, 0x0038fd0f, - 0x00391d0f, 0x00393d0f, 0x00395d0f, 0x00397d0f, - 0x00399d0f, 0x0039bd0f, 0x0039dd0f, 0x0039fd0f, - 0x003a1d0f, 0x003a3d0f, 0x003a5d0f, 0x003a7d0f, - 0x003a9d0f, 0x003abd0f, 0x003add0f, 0x003afd0f, - 0x003b1d0f, 0x003b3d0f, 0x003b5d0f, 0x003b7d0f, - 0x003b9d0f, 0x003bbd0f, 0x003bdd0f, 0x003bfd0f, - 0x003c1d0f, 0x003c3d0f, 0x003c5d0f, 0x003c7d0f, - 0x003c9d0f, 0x003cbd0f, 0x003cdd0f, 0x003cfd0f, - 0x003d1d0f, 0x003d3d0f, 0x003d5d0f, 0x003d7d0f, - 0x003d9d0f, 0x003dbd0f, 0x003ddd0f, 0x003dfd0f, - 0x003e1d0f, 0x003e3d0f, 0x003e5d0f, 0x003e7d0f, - 0x003e9d0f, 0x003ebd0f, 0x003edd0f, 0x003efd0f, - 0x003f1d0f, 0x003f3d0f, 0x003f5d0f, 0x003f7d0f, - 0x003f9d0f, 0x003fbd0f, 0x003fdd0f, 0x003ffd0f, - 0x00401d0f, 0x00403d0f, 0x00405d0f, 0x00407d0f, - 0x00409d0f, 0x0040bd0f, 0x0040dd0f, 0x0040fd0f, - 0x00411d0f, 0x00413d0f, 0x00415d0f, 0x00417d0f, - 0x00419d0f, 0x0041bd0f, 0x0041dd0f, 0x0041fd0f, - 0x00421d0f, 0x00423d0f, 0x00425d0f, 0x00427d0f, - 0x00429d0f, 0x0042bd0f, 0x0042dd0f, 0x0042fd0f, - 0x00431d0f, 0x00433d0f, 0x00435d0f, 0x00437d0f, - 0x00439d0f, 0x0043bd0f, 0x0043dd0f, 0x0043fd0f, - 0x00441d0f, 0x00443d0f, 0x00445d0f, 0x00447d0f, - 0x00449d0f, 0x0044bd0f, 0x0044dd0f, 0x0044fd0f, - 0x00451d0f, 0x00453d0f, 0x00455d0f, 0x00457d0f, - 0x00459d0f, 0x0045bd0f, 0x0045dd0f, 0x0045fd0f, - 0x00461d0f, 0x00463d0f, 0x00465d0f, 0x00467d0f, - 0x00469d0f, 0x0046bd0f, 0x0046dd0f, 0x0046fd0f, - 0x00471d0f, 0x00473d0f, 0x00475d0f, 0x00477d0f, - 0x00479d0f, 0x0047bd0f, 0x0047dd0f, 0x0047fd0f, - 0x00481d0f, 0x00483d0f, 0x00485d0f, 0x00487d0f, - 0x00489d0f, 0x0048bd0f, 0x0048dd0f, 0x0048fd0f, - 0x00491d0f, 0x00493d0f, 0x00495d0f, 0x00497d0f, - 0x00499d0f, 0x0049bd0f, 0x0049dd0f, 0x0049fd0f, - 0x004a1d0f, 0x004a3d0f, 0x004a5d0f, 0x004a7d0f, - 0x004a9d0f, 0x004abd0f, 0x004add0f, 0x004afd0f, - 0x004b1d0f, 0x004b3d0f, 0x004b5d0f, 0x004b7d0f, - 0x004b9d0f, 0x004bbd0f, 0x004bdd0f, 0x004bfd0f, - 0x004c1d0f, 0x004c3d0f, 0x004c5d0f, 0x004c7d0f, - 0x004c9d0f, 0x004cbd0f, 0x004cdd0f, 0x004cfd0f, - 0x004d1d0f, 0x004d3d0f, 0x004d5d0f, 0x004d7d0f, - 0x004d9d0f, 0x004dbd0f, 0x004ddd0f, 0x004dfd0f, - 0x004e1d0f, 0x004e3d0f, 0x004e5d0f, 0x004e7d0f, - 0x004e9d0f, 0x004ebd0f, 0x004edd0f, 0x004efd0f, - 0x004f1d0f, 0x004f3d0f, 0x004f5d0f, 0x004f7d0f, - 0x004f9d0f, 0x004fbd0f, 0x004fdd0f, 0x004ffd0f, - 0x00501d0f, 0x00503d0f, 0x00505d0f, 0x00507d0f, - 0x00509d0f, 0x0050bd0f, 0x0050dd0f, 0x0050fd0f, - 0x00511d0f, 0x00513d0f, 0x00515d0f, 0x00517d0f, - 0x00519d0f, 0x0051bd0f, 0x0051dd0f, 0x0051fd0f, - 0x00521d0f, 0x00523d0f, 0x00525d0f, 0x00527d0f, - 0x00529d0f, 0x0052bd0f, 0x0052dd0f, 0x0052fd0f, - 0x00531d0f, 0x00533d0f, 0x00535d0f, 0x00537d0f, - 0x00539d0f, 0x0053bd0f, 0x0053dd0f, 0x0053fd0f, - 0x00541d0f, 0x00543d0f, 0x00545d0f, 0x00547d0f, - 0x00549d0f, 0x0054bd0f, 0x0054dd0f, 0x0054fd0f, - 0x00551d0f, 0x00553d0f, 0x00555d0f, 0x00557d0f, - 0x00559d0f, 0x0055bd0f, 0x0055dd0f, 0x0055fd0f, - 0x00561d0f, 0x00563d0f, 0x00565d0f, 0x00567d0f, - 0x00569d0f, 0x0056bd0f, 0x0056dd0f, 0x0056fd0f, - 0x00571d0f, 0x00573d0f, 0x00575d0f, 0x00577d0f, - 0x00579d0f, 0x0057bd0f, 0x0057dd0f, 0x0057fd0f, - 0x00581d0f, 0x00583d0f, 0x00585d0f, 0x00587d0f, - 0x00589d0f, 0x0058bd0f, 0x0058dd0f, 0x0058fd0f, - 0x00591d0f, 0x00593d0f, 0x00595d0f, 0x00597d0f, - 0x00599d0f, 0x0059bd0f, 0x0059dd0f, 0x0059fd0f, - 0x005a1d0f, 0x005a3d0f, 0x005a5d0f, 0x005a7d0f, - 0x005a9d0f, 0x005abd0f, 0x005add0f, 0x005afd0f, - 0x005b1d0f, 0x005b3d0f, 0x005b5d0f, 0x005b7d0f, - 0x005b9d0f, 0x005bbd0f, 0x005bdd0f, 0x005bfd0f, - 0x005c1d0f, 0x005c3d0f, 0x005c5d0f, 0x005c7d0f, - 0x005c9d0f, 0x005cbd0f, 0x005cdd0f, 0x005cfd0f, - 0x005d1d0f, 0x005d3d0f, 0x005d5d0f, 0x005d7d0f, - 0x005d9d0f, 0x005dbd0f, 0x005ddd0f, 0x005dfd0f, - 0x005e1d0f, 0x005e3d0f, 0x005e5d0f, 0x005e7d0f, - 0x005e9d0f, 0x005ebd0f, 0x005edd0f, 0x005efd0f, - 0x005f1d0f, 0x005f3d0f, 0x005f5d0f, 0x005f7d0f, - 0x005f9d0f, 0x005fbd0f, 0x005fdd0f, 0x005ffd0f, - 0x00601d0f, 0x00603d0f, 0x00605d0f, 0x00607d0f, - 0x00609d0f, 0x0060bd0f, 0x0060dd0f, 0x0060fd0f, - 0x00611d0f, 0x00613d0f, 0x00615d0f, 0x00617d0f, - 0x00619d0f, 0x0061bd0f, 0x0061dd0f, 0x0061fd0f, - 0x00621d0f, 0x00623d0f, 0x00625d0f, 0x00627d0f, - 0x00629d0f, 0x0062bd0f, 0x0062dd0f, 0x0062fd0f, - 0x00631d0f, 0x00633d0f, 0x00635d0f, 0x00637d0f, - 0x00639d0f, 0x0063bd0f, 0x0063dd0f, 0x0063fd0f, - 0x00641d0f, 0x00643d0f, 0x00645d0f, 0x00647d0f, - 0x00649d0f, 0x0064bd0f, 0x0064dd0f, 0x0064fd0f, - 0x00651d0f, 0x00653d0f, 0x00655d0f, 0x00657d0f, - 0x00659d0f, 0x0065bd0f, 0x0065dd0f, 0x0065fd0f, - 0x00661d0f, 0x00663d0f, 0x00665d0f, 0x00667d0f, - 0x00669d0f, 0x0066bd0f, 0x0066dd0f, 0x0066fd0f, - 0x00671d0f, 0x00673d0f, 0x00675d0f, 0x00677d0f, - 0x00679d0f, 0x0067bd0f, 0x0067dd0f, 0x0067fd0f, - 0x00681d0f, 0x00683d0f, 0x00685d0f, 0x00687d0f, - 0x00689d0f, 0x0068bd0f, 0x0068dd0f, 0x0068fd0f, - 0x00691d0f, 0x00693d0f, 0x00695d0f, 0x00697d0f, - 0x00699d0f, 0x0069bd0f, 0x0069dd0f, 0x0069fd0f, - 0x006a1d0f, 0x006a3d0f, 0x006a5d0f, 0x006a7d0f, - 0x006a9d0f, 0x006abd0f, 0x006add0f, 0x006afd0f, - 0x006b1d0f, 0x006b3d0f, 0x006b5d0f, 0x006b7d0f, - 0x006b9d0f, 0x006bbd0f, 0x006bdd0f, 0x006bfd0f, - 0x006c1d0f, 0x006c3d0f, 0x006c5d0f, 0x006c7d0f, - 0x006c9d0f, 0x006cbd0f, 0x006cdd0f, 0x006cfd0f, - 0x006d1d0f, 0x006d3d0f, 0x006d5d0f, 0x006d7d0f, - 0x006d9d0f, 0x006dbd0f, 0x006ddd0f, 0x006dfd0f, - 0x006e1d0f, 0x006e3d0f, 0x006e5d0f, 0x006e7d0f, - 0x006e9d0f, 0x006ebd0f, 0x006edd0f, 0x006efd0f, - 0x006f1d0f, 0x006f3d0f, 0x006f5d0f, 0x006f7d0f, - 0x006f9d0f, 0x006fbd0f, 0x006fdd0f, 0x006ffd0f, - 0x00701d0f, 0x00703d0f, 0x00705d0f, 0x00707d0f, - 0x00709d0f, 0x0070bd0f, 0x0070dd0f, 0x0070fd0f, - 0x00711d0f, 0x00713d0f, 0x00715d0f, 0x00717d0f, - 0x00719d0f, 0x0071bd0f, 0x0071dd0f, 0x0071fd0f, - 0x00721d0f, 0x00723d0f, 0x00725d0f, 0x00727d0f, - 0x00729d0f, 0x0072bd0f, 0x0072dd0f, 0x0072fd0f, - 0x00731d0f, 0x00733d0f, 0x00735d0f, 0x00737d0f, - 0x00739d0f, 0x0073bd0f, 0x0073dd0f, 0x0073fd0f, - 0x00741d0f, 0x00743d0f, 0x00745d0f, 0x00747d0f, - 0x00749d0f, 0x0074bd0f, 0x0074dd0f, 0x0074fd0f, - 0x00751d0f, 0x00753d0f, 0x00755d0f, 0x00757d0f, - 0x00759d0f, 0x0075bd0f, 0x0075dd0f, 0x0075fd0f, - 0x00761d0f, 0x00763d0f, 0x00765d0f, 0x00767d0f, - 0x00769d0f, 0x0076bd0f, 0x0076dd0f, 0x0076fd0f, - 0x00771d0f, 0x00773d0f, 0x00775d0f, 0x00777d0f, - 0x00779d0f, 0x0077bd0f, 0x0077dd0f, 0x0077fd0f, - 0x00781d0f, 0x00783d0f, 0x00785d0f, 0x00787d0f, - 0x00789d0f, 0x0078bd0f, 0x0078dd0f, 0x0078fd0f, - 0x00791d0f, 0x00793d0f, 0x00795d0f, 0x00797d0f, - 0x00799d0f, 0x0079bd0f, 0x0079dd0f, 0x0079fd0f, - 0x007a1d0f, 0x007a3d0f, 0x007a5d0f, 0x007a7d0f, - 0x007a9d0f, 0x007abd0f, 0x007add0f, 0x007afd0f, - 0x007b1d0f, 0x007b3d0f, 0x007b5d0f, 0x007b7d0f, - 0x007b9d0f, 0x007bbd0f, 0x007bdd0f, 0x007bfd0f, - 0x007c1d0f, 0x007c3d0f, 0x007c5d0f, 0x007c7d0f, - 0x007c9d0f, 0x007cbd0f, 0x007cdd0f, 0x007cfd0f, - 0x007d1d0f, 0x007d3d0f, 0x007d5d0f, 0x007d7d0f, - 0x007d9d0f, 0x007dbd0f, 0x007ddd0f, 0x007dfd0f, - 0x007e1d0f, 0x007e3d0f, 0x007e5d0f, 0x007e7d0f, - 0x007e9d0f, 0x007ebd0f, 0x007edd0f, 0x007efd0f, - 0x007f1d0f, 0x007f3d0f, 0x007f5d0f, 0x007f7d0f, - 0x007f9d0f, 0x007fbd0f, 0x007fdd0f, 0x007ffd0f, - 0x00000310, 0x00002310, 0x00004310, 0x00006310, - 0x00008310, 0x0000a310, 0x0000c310, 0x0000e310, - 0x00010310, 0x00012310, 0x00014310, 0x00016310, - 0x00018310, 0x0001a310, 0x0001c310, 0x0001e310, - 0x00020310, 0x00022310, 0x00024310, 0x00026310, - 0x00028310, 0x0002a310, 0x0002c310, 0x0002e310, - 0x00030310, 0x00032310, 0x00034310, 0x00036310, - 0x00038310, 0x0003a310, 0x0003c310, 0x0003e310, - 0x00040310, 0x00042310, 0x00044310, 0x00046310, - 0x00048310, 0x0004a310, 0x0004c310, 0x0004e310, - 0x00050310, 0x00052310, 0x00054310, 0x00056310, - 0x00058310, 0x0005a310, 0x0005c310, 0x0005e310, - 0x00060310, 0x00062310, 0x00064310, 0x00066310, - 0x00068310, 0x0006a310, 0x0006c310, 0x0006e310, - 0x00070310, 0x00072310, 0x00074310, 0x00076310, - 0x00078310, 0x0007a310, 0x0007c310, 0x0007e310, - 0x00080310, 0x00082310, 0x00084310, 0x00086310, - 0x00088310, 0x0008a310, 0x0008c310, 0x0008e310, - 0x00090310, 0x00092310, 0x00094310, 0x00096310, - 0x00098310, 0x0009a310, 0x0009c310, 0x0009e310, - 0x000a0310, 0x000a2310, 0x000a4310, 0x000a6310, - 0x000a8310, 0x000aa310, 0x000ac310, 0x000ae310, - 0x000b0310, 0x000b2310, 0x000b4310, 0x000b6310, - 0x000b8310, 0x000ba310, 0x000bc310, 0x000be310, - 0x000c0310, 0x000c2310, 0x000c4310, 0x000c6310, - 0x000c8310, 0x000ca310, 0x000cc310, 0x000ce310, - 0x000d0310, 0x000d2310, 0x000d4310, 0x000d6310, - 0x000d8310, 0x000da310, 0x000dc310, 0x000de310, - 0x000e0310, 0x000e2310, 0x000e4310, 0x000e6310, - 0x000e8310, 0x000ea310, 0x000ec310, 0x000ee310, - 0x000f0310, 0x000f2310, 0x000f4310, 0x000f6310, - 0x000f8310, 0x000fa310, 0x000fc310, 0x000fe310, - 0x00100310, 0x00102310, 0x00104310, 0x00106310, - 0x00108310, 0x0010a310, 0x0010c310, 0x0010e310, - 0x00110310, 0x00112310, 0x00114310, 0x00116310, - 0x00118310, 0x0011a310, 0x0011c310, 0x0011e310, - 0x00120310, 0x00122310, 0x00124310, 0x00126310, - 0x00128310, 0x0012a310, 0x0012c310, 0x0012e310, - 0x00130310, 0x00132310, 0x00134310, 0x00136310, - 0x00138310, 0x0013a310, 0x0013c310, 0x0013e310, - 0x00140310, 0x00142310, 0x00144310, 0x00146310, - 0x00148310, 0x0014a310, 0x0014c310, 0x0014e310, - 0x00150310, 0x00152310, 0x00154310, 0x00156310, - 0x00158310, 0x0015a310, 0x0015c310, 0x0015e310, - 0x00160310, 0x00162310, 0x00164310, 0x00166310, - 0x00168310, 0x0016a310, 0x0016c310, 0x0016e310, - 0x00170310, 0x00172310, 0x00174310, 0x00176310, - 0x00178310, 0x0017a310, 0x0017c310, 0x0017e310, - 0x00180310, 0x00182310, 0x00184310, 0x00186310, - 0x00188310, 0x0018a310, 0x0018c310, 0x0018e310, - 0x00190310, 0x00192310, 0x00194310, 0x00196310, - 0x00198310, 0x0019a310, 0x0019c310, 0x0019e310, - 0x001a0310, 0x001a2310, 0x001a4310, 0x001a6310, - 0x001a8310, 0x001aa310, 0x001ac310, 0x001ae310, - 0x001b0310, 0x001b2310, 0x001b4310, 0x001b6310, - 0x001b8310, 0x001ba310, 0x001bc310, 0x001be310, - 0x001c0310, 0x001c2310, 0x001c4310, 0x001c6310, - 0x001c8310, 0x001ca310, 0x001cc310, 0x001ce310, - 0x001d0310, 0x001d2310, 0x001d4310, 0x001d6310, - 0x001d8310, 0x001da310, 0x001dc310, 0x001de310, - 0x001e0310, 0x001e2310, 0x001e4310, 0x001e6310, - 0x001e8310, 0x001ea310, 0x001ec310, 0x001ee310, - 0x001f0310, 0x001f2310, 0x001f4310, 0x001f6310, - 0x001f8310, 0x001fa310, 0x001fc310, 0x001fe310, - 0x00200310, 0x00202310, 0x00204310, 0x00206310, - 0x00208310, 0x0020a310, 0x0020c310, 0x0020e310, - 0x00210310, 0x00212310, 0x00214310, 0x00216310, - 0x00218310, 0x0021a310, 0x0021c310, 0x0021e310, - 0x00220310, 0x00222310, 0x00224310, 0x00226310, - 0x00228310, 0x0022a310, 0x0022c310, 0x0022e310, - 0x00230310, 0x00232310, 0x00234310, 0x00236310, - 0x00238310, 0x0023a310, 0x0023c310, 0x0023e310, - 0x00240310, 0x00242310, 0x00244310, 0x00246310, - 0x00248310, 0x0024a310, 0x0024c310, 0x0024e310, - 0x00250310, 0x00252310, 0x00254310, 0x00256310, - 0x00258310, 0x0025a310, 0x0025c310, 0x0025e310, - 0x00260310, 0x00262310, 0x00264310, 0x00266310, - 0x00268310, 0x0026a310, 0x0026c310, 0x0026e310, - 0x00270310, 0x00272310, 0x00274310, 0x00276310, - 0x00278310, 0x0027a310, 0x0027c310, 0x0027e310, - 0x00280310, 0x00282310, 0x00284310, 0x00286310, - 0x00288310, 0x0028a310, 0x0028c310, 0x0028e310, - 0x00290310, 0x00292310, 0x00294310, 0x00296310, - 0x00298310, 0x0029a310, 0x0029c310, 0x0029e310, - 0x002a0310, 0x002a2310, 0x002a4310, 0x002a6310, - 0x002a8310, 0x002aa310, 0x002ac310, 0x002ae310, - 0x002b0310, 0x002b2310, 0x002b4310, 0x002b6310, - 0x002b8310, 0x002ba310, 0x002bc310, 0x002be310, - 0x002c0310, 0x002c2310, 0x002c4310, 0x002c6310, - 0x002c8310, 0x002ca310, 0x002cc310, 0x002ce310, - 0x002d0310, 0x002d2310, 0x002d4310, 0x002d6310, - 0x002d8310, 0x002da310, 0x002dc310, 0x002de310, - 0x002e0310, 0x002e2310, 0x002e4310, 0x002e6310, - 0x002e8310, 0x002ea310, 0x002ec310, 0x002ee310, - 0x002f0310, 0x002f2310, 0x002f4310, 0x002f6310, - 0x002f8310, 0x002fa310, 0x002fc310, 0x002fe310, - 0x00300310, 0x00302310, 0x00304310, 0x00306310, - 0x00308310, 0x0030a310, 0x0030c310, 0x0030e310, - 0x00310310, 0x00312310, 0x00314310, 0x00316310, - 0x00318310, 0x0031a310, 0x0031c310, 0x0031e310, - 0x00320310, 0x00322310, 0x00324310, 0x00326310, - 0x00328310, 0x0032a310, 0x0032c310, 0x0032e310, - 0x00330310, 0x00332310, 0x00334310, 0x00336310, - 0x00338310, 0x0033a310, 0x0033c310, 0x0033e310, - 0x00340310, 0x00342310, 0x00344310, 0x00346310, - 0x00348310, 0x0034a310, 0x0034c310, 0x0034e310, - 0x00350310, 0x00352310, 0x00354310, 0x00356310, - 0x00358310, 0x0035a310, 0x0035c310, 0x0035e310, - 0x00360310, 0x00362310, 0x00364310, 0x00366310, - 0x00368310, 0x0036a310, 0x0036c310, 0x0036e310, - 0x00370310, 0x00372310, 0x00374310, 0x00376310, - 0x00378310, 0x0037a310, 0x0037c310, 0x0037e310, - 0x00380310, 0x00382310, 0x00384310, 0x00386310, - 0x00388310, 0x0038a310, 0x0038c310, 0x0038e310, - 0x00390310, 0x00392310, 0x00394310, 0x00396310, - 0x00398310, 0x0039a310, 0x0039c310, 0x0039e310, - 0x003a0310, 0x003a2310, 0x003a4310, 0x003a6310, - 0x003a8310, 0x003aa310, 0x003ac310, 0x003ae310, - 0x003b0310, 0x003b2310, 0x003b4310, 0x003b6310, - 0x003b8310, 0x003ba310, 0x003bc310, 0x003be310, - 0x003c0310, 0x003c2310, 0x003c4310, 0x003c6310, - 0x003c8310, 0x003ca310, 0x003cc310, 0x003ce310, - 0x003d0310, 0x003d2310, 0x003d4310, 0x003d6310, - 0x003d8310, 0x003da310, 0x003dc310, 0x003de310, - 0x003e0310, 0x003e2310, 0x003e4310, 0x003e6310, - 0x003e8310, 0x003ea310, 0x003ec310, 0x003ee310, - 0x003f0310, 0x003f2310, 0x003f4310, 0x003f6310, - 0x003f8310, 0x003fa310, 0x003fc310, 0x003fe310, - 0x00400310, 0x00402310, 0x00404310, 0x00406310, - 0x00408310, 0x0040a310, 0x0040c310, 0x0040e310, - 0x00410310, 0x00412310, 0x00414310, 0x00416310, - 0x00418310, 0x0041a310, 0x0041c310, 0x0041e310, - 0x00420310, 0x00422310, 0x00424310, 0x00426310, - 0x00428310, 0x0042a310, 0x0042c310, 0x0042e310, - 0x00430310, 0x00432310, 0x00434310, 0x00436310, - 0x00438310, 0x0043a310, 0x0043c310, 0x0043e310, - 0x00440310, 0x00442310, 0x00444310, 0x00446310, - 0x00448310, 0x0044a310, 0x0044c310, 0x0044e310, - 0x00450310, 0x00452310, 0x00454310, 0x00456310, - 0x00458310, 0x0045a310, 0x0045c310, 0x0045e310, - 0x00460310, 0x00462310, 0x00464310, 0x00466310, - 0x00468310, 0x0046a310, 0x0046c310, 0x0046e310, - 0x00470310, 0x00472310, 0x00474310, 0x00476310, - 0x00478310, 0x0047a310, 0x0047c310, 0x0047e310, - 0x00480310, 0x00482310, 0x00484310, 0x00486310, - 0x00488310, 0x0048a310, 0x0048c310, 0x0048e310, - 0x00490310, 0x00492310, 0x00494310, 0x00496310, - 0x00498310, 0x0049a310, 0x0049c310, 0x0049e310, - 0x004a0310, 0x004a2310, 0x004a4310, 0x004a6310, - 0x004a8310, 0x004aa310, 0x004ac310, 0x004ae310, - 0x004b0310, 0x004b2310, 0x004b4310, 0x004b6310, - 0x004b8310, 0x004ba310, 0x004bc310, 0x004be310, - 0x004c0310, 0x004c2310, 0x004c4310, 0x004c6310, - 0x004c8310, 0x004ca310, 0x004cc310, 0x004ce310, - 0x004d0310, 0x004d2310, 0x004d4310, 0x004d6310, - 0x004d8310, 0x004da310, 0x004dc310, 0x004de310, - 0x004e0310, 0x004e2310, 0x004e4310, 0x004e6310, - 0x004e8310, 0x004ea310, 0x004ec310, 0x004ee310, - 0x004f0310, 0x004f2310, 0x004f4310, 0x004f6310, - 0x004f8310, 0x004fa310, 0x004fc310, 0x004fe310, - 0x00500310, 0x00502310, 0x00504310, 0x00506310, - 0x00508310, 0x0050a310, 0x0050c310, 0x0050e310, - 0x00510310, 0x00512310, 0x00514310, 0x00516310, - 0x00518310, 0x0051a310, 0x0051c310, 0x0051e310, - 0x00520310, 0x00522310, 0x00524310, 0x00526310, - 0x00528310, 0x0052a310, 0x0052c310, 0x0052e310, - 0x00530310, 0x00532310, 0x00534310, 0x00536310, - 0x00538310, 0x0053a310, 0x0053c310, 0x0053e310, - 0x00540310, 0x00542310, 0x00544310, 0x00546310, - 0x00548310, 0x0054a310, 0x0054c310, 0x0054e310, - 0x00550310, 0x00552310, 0x00554310, 0x00556310, - 0x00558310, 0x0055a310, 0x0055c310, 0x0055e310, - 0x00560310, 0x00562310, 0x00564310, 0x00566310, - 0x00568310, 0x0056a310, 0x0056c310, 0x0056e310, - 0x00570310, 0x00572310, 0x00574310, 0x00576310, - 0x00578310, 0x0057a310, 0x0057c310, 0x0057e310, - 0x00580310, 0x00582310, 0x00584310, 0x00586310, - 0x00588310, 0x0058a310, 0x0058c310, 0x0058e310, - 0x00590310, 0x00592310, 0x00594310, 0x00596310, - 0x00598310, 0x0059a310, 0x0059c310, 0x0059e310, - 0x005a0310, 0x005a2310, 0x005a4310, 0x005a6310, - 0x005a8310, 0x005aa310, 0x005ac310, 0x005ae310, - 0x005b0310, 0x005b2310, 0x005b4310, 0x005b6310, - 0x005b8310, 0x005ba310, 0x005bc310, 0x005be310, - 0x005c0310, 0x005c2310, 0x005c4310, 0x005c6310, - 0x005c8310, 0x005ca310, 0x005cc310, 0x005ce310, - 0x005d0310, 0x005d2310, 0x005d4310, 0x005d6310, - 0x005d8310, 0x005da310, 0x005dc310, 0x005de310, - 0x005e0310, 0x005e2310, 0x005e4310, 0x005e6310, - 0x005e8310, 0x005ea310, 0x005ec310, 0x005ee310, - 0x005f0310, 0x005f2310, 0x005f4310, 0x005f6310, - 0x005f8310, 0x005fa310, 0x005fc310, 0x005fe310, - 0x00600310, 0x00602310, 0x00604310, 0x00606310, - 0x00608310, 0x0060a310, 0x0060c310, 0x0060e310, - 0x00610310, 0x00612310, 0x00614310, 0x00616310, - 0x00618310, 0x0061a310, 0x0061c310, 0x0061e310, - 0x00620310, 0x00622310, 0x00624310, 0x00626310, - 0x00628310, 0x0062a310, 0x0062c310, 0x0062e310, - 0x00630310, 0x00632310, 0x00634310, 0x00636310, - 0x00638310, 0x0063a310, 0x0063c310, 0x0063e310, - 0x00640310, 0x00642310, 0x00644310, 0x00646310, - 0x00648310, 0x0064a310, 0x0064c310, 0x0064e310, - 0x00650310, 0x00652310, 0x00654310, 0x00656310, - 0x00658310, 0x0065a310, 0x0065c310, 0x0065e310, - 0x00660310, 0x00662310, 0x00664310, 0x00666310, - 0x00668310, 0x0066a310, 0x0066c310, 0x0066e310, - 0x00670310, 0x00672310, 0x00674310, 0x00676310, - 0x00678310, 0x0067a310, 0x0067c310, 0x0067e310, - 0x00680310, 0x00682310, 0x00684310, 0x00686310, - 0x00688310, 0x0068a310, 0x0068c310, 0x0068e310, - 0x00690310, 0x00692310, 0x00694310, 0x00696310, - 0x00698310, 0x0069a310, 0x0069c310, 0x0069e310, - 0x006a0310, 0x006a2310, 0x006a4310, 0x006a6310, - 0x006a8310, 0x006aa310, 0x006ac310, 0x006ae310, - 0x006b0310, 0x006b2310, 0x006b4310, 0x006b6310, - 0x006b8310, 0x006ba310, 0x006bc310, 0x006be310, - 0x006c0310, 0x006c2310, 0x006c4310, 0x006c6310, - 0x006c8310, 0x006ca310, 0x006cc310, 0x006ce310, - 0x006d0310, 0x006d2310, 0x006d4310, 0x006d6310, - 0x006d8310, 0x006da310, 0x006dc310, 0x006de310, - 0x006e0310, 0x006e2310, 0x006e4310, 0x006e6310, - 0x006e8310, 0x006ea310, 0x006ec310, 0x006ee310, - 0x006f0310, 0x006f2310, 0x006f4310, 0x006f6310, - 0x006f8310, 0x006fa310, 0x006fc310, 0x006fe310, - 0x00700310, 0x00702310, 0x00704310, 0x00706310, - 0x00708310, 0x0070a310, 0x0070c310, 0x0070e310, - 0x00710310, 0x00712310, 0x00714310, 0x00716310, - 0x00718310, 0x0071a310, 0x0071c310, 0x0071e310, - 0x00720310, 0x00722310, 0x00724310, 0x00726310, - 0x00728310, 0x0072a310, 0x0072c310, 0x0072e310, - 0x00730310, 0x00732310, 0x00734310, 0x00736310, - 0x00738310, 0x0073a310, 0x0073c310, 0x0073e310, - 0x00740310, 0x00742310, 0x00744310, 0x00746310, - 0x00748310, 0x0074a310, 0x0074c310, 0x0074e310, - 0x00750310, 0x00752310, 0x00754310, 0x00756310, - 0x00758310, 0x0075a310, 0x0075c310, 0x0075e310, - 0x00760310, 0x00762310, 0x00764310, 0x00766310, - 0x00768310, 0x0076a310, 0x0076c310, 0x0076e310, - 0x00770310, 0x00772310, 0x00774310, 0x00776310, - 0x00778310, 0x0077a310, 0x0077c310, 0x0077e310, - 0x00780310, 0x00782310, 0x00784310, 0x00786310, - 0x00788310, 0x0078a310, 0x0078c310, 0x0078e310, - 0x00790310, 0x00792310, 0x00794310, 0x00796310, - 0x00798310, 0x0079a310, 0x0079c310, 0x0079e310, - 0x007a0310, 0x007a2310, 0x007a4310, 0x007a6310, - 0x007a8310, 0x007aa310, 0x007ac310, 0x007ae310, - 0x007b0310, 0x007b2310, 0x007b4310, 0x007b6310, - 0x007b8310, 0x007ba310, 0x007bc310, 0x007be310, - 0x007c0310, 0x007c2310, 0x007c4310, 0x007c6310, - 0x007c8310, 0x007ca310, 0x007cc310, 0x007ce310, - 0x007d0310, 0x007d2310, 0x007d4310, 0x007d6310, - 0x007d8310, 0x007da310, 0x007dc310, 0x007de310, - 0x007e0310, 0x007e2310, 0x007e4310, 0x007e6310, - 0x007e8310, 0x007ea310, 0x007ec310, 0x007ee310, - 0x007f0310, 0x007f2310, 0x007f4310, 0x007f6310, - 0x007f8310, 0x007fa310, 0x007fc310, 0x007fe310, - 0x00800310, 0x00802310, 0x00804310, 0x00806310, - 0x00808310, 0x0080a310, 0x0080c310, 0x0080e310, - 0x00810310, 0x00812310, 0x00814310, 0x00816310, - 0x00818310, 0x0081a310, 0x0081c310, 0x0081e310, - 0x00820310, 0x00822310, 0x00824310, 0x00826310, - 0x00828310, 0x0082a310, 0x0082c310, 0x0082e310, - 0x00830310, 0x00832310, 0x00834310, 0x00836310, - 0x00838310, 0x0083a310, 0x0083c310, 0x0083e310, - 0x00840310, 0x00842310, 0x00844310, 0x00846310, - 0x00848310, 0x0084a310, 0x0084c310, 0x0084e310, - 0x00850310, 0x00852310, 0x00854310, 0x00856310, - 0x00858310, 0x0085a310, 0x0085c310, 0x0085e310, - 0x00860310, 0x00862310, 0x00864310, 0x00866310, - 0x00868310, 0x0086a310, 0x0086c310, 0x0086e310, - 0x00870310, 0x00872310, 0x00874310, 0x00876310, - 0x00878310, 0x0087a310, 0x0087c310, 0x0087e310, - 0x00880310, 0x00882310, 0x00884310, 0x00886310, - 0x00888310, 0x0088a310, 0x0088c310, 0x0088e310, - 0x00890310, 0x00892310, 0x00894310, 0x00896310, - 0x00898310, 0x0089a310, 0x0089c310, 0x0089e310, - 0x008a0310, 0x008a2310, 0x008a4310, 0x008a6310, - 0x008a8310, 0x008aa310, 0x008ac310, 0x008ae310, - 0x008b0310, 0x008b2310, 0x008b4310, 0x008b6310, - 0x008b8310, 0x008ba310, 0x008bc310, 0x008be310, - 0x008c0310, 0x008c2310, 0x008c4310, 0x008c6310, - 0x008c8310, 0x008ca310, 0x008cc310, 0x008ce310, - 0x008d0310, 0x008d2310, 0x008d4310, 0x008d6310, - 0x008d8310, 0x008da310, 0x008dc310, 0x008de310, - 0x008e0310, 0x008e2310, 0x008e4310, 0x008e6310, - 0x008e8310, 0x008ea310, 0x008ec310, 0x008ee310, - 0x008f0310, 0x008f2310, 0x008f4310, 0x008f6310, - 0x008f8310, 0x008fa310, 0x008fc310, 0x008fe310, - 0x00900310, 0x00902310, 0x00904310, 0x00906310, - 0x00908310, 0x0090a310, 0x0090c310, 0x0090e310, - 0x00910310, 0x00912310, 0x00914310, 0x00916310, - 0x00918310, 0x0091a310, 0x0091c310, 0x0091e310, - 0x00920310, 0x00922310, 0x00924310, 0x00926310, - 0x00928310, 0x0092a310, 0x0092c310, 0x0092e310, - 0x00930310, 0x00932310, 0x00934310, 0x00936310, - 0x00938310, 0x0093a310, 0x0093c310, 0x0093e310, - 0x00940310, 0x00942310, 0x00944310, 0x00946310, - 0x00948310, 0x0094a310, 0x0094c310, 0x0094e310, - 0x00950310, 0x00952310, 0x00954310, 0x00956310, - 0x00958310, 0x0095a310, 0x0095c310, 0x0095e310, - 0x00960310, 0x00962310, 0x00964310, 0x00966310, - 0x00968310, 0x0096a310, 0x0096c310, 0x0096e310, - 0x00970310, 0x00972310, 0x00974310, 0x00976310, - 0x00978310, 0x0097a310, 0x0097c310, 0x0097e310, - 0x00980310, 0x00982310, 0x00984310, 0x00986310, - 0x00988310, 0x0098a310, 0x0098c310, 0x0098e310, - 0x00990310, 0x00992310, 0x00994310, 0x00996310, - 0x00998310, 0x0099a310, 0x0099c310, 0x0099e310, - 0x009a0310, 0x009a2310, 0x009a4310, 0x009a6310, - 0x009a8310, 0x009aa310, 0x009ac310, 0x009ae310, - 0x009b0310, 0x009b2310, 0x009b4310, 0x009b6310, - 0x009b8310, 0x009ba310, 0x009bc310, 0x009be310, - 0x009c0310, 0x009c2310, 0x009c4310, 0x009c6310, - 0x009c8310, 0x009ca310, 0x009cc310, 0x009ce310, - 0x009d0310, 0x009d2310, 0x009d4310, 0x009d6310, - 0x009d8310, 0x009da310, 0x009dc310, 0x009de310, - 0x009e0310, 0x009e2310, 0x009e4310, 0x009e6310, - 0x009e8310, 0x009ea310, 0x009ec310, 0x009ee310, - 0x009f0310, 0x009f2310, 0x009f4310, 0x009f6310, - 0x009f8310, 0x009fa310, 0x009fc310, 0x009fe310, - 0x00a00310, 0x00a02310, 0x00a04310, 0x00a06310, - 0x00a08310, 0x00a0a310, 0x00a0c310, 0x00a0e310, - 0x00a10310, 0x00a12310, 0x00a14310, 0x00a16310, - 0x00a18310, 0x00a1a310, 0x00a1c310, 0x00a1e310, - 0x00a20310, 0x00a22310, 0x00a24310, 0x00a26310, - 0x00a28310, 0x00a2a310, 0x00a2c310, 0x00a2e310, - 0x00a30310, 0x00a32310, 0x00a34310, 0x00a36310, - 0x00a38310, 0x00a3a310, 0x00a3c310, 0x00a3e310, - 0x00a40310, 0x00a42310, 0x00a44310, 0x00a46310, - 0x00a48310, 0x00a4a310, 0x00a4c310, 0x00a4e310, - 0x00a50310, 0x00a52310, 0x00a54310, 0x00a56310, - 0x00a58310, 0x00a5a310, 0x00a5c310, 0x00a5e310, - 0x00a60310, 0x00a62310, 0x00a64310, 0x00a66310, - 0x00a68310, 0x00a6a310, 0x00a6c310, 0x00a6e310, - 0x00a70310, 0x00a72310, 0x00a74310, 0x00a76310, - 0x00a78310, 0x00a7a310, 0x00a7c310, 0x00a7e310, - 0x00a80310, 0x00a82310, 0x00a84310, 0x00a86310, - 0x00a88310, 0x00a8a310, 0x00a8c310, 0x00a8e310, - 0x00a90310, 0x00a92310, 0x00a94310, 0x00a96310, - 0x00a98310, 0x00a9a310, 0x00a9c310, 0x00a9e310, - 0x00aa0310, 0x00aa2310, 0x00aa4310, 0x00aa6310, - 0x00aa8310, 0x00aaa310, 0x00aac310, 0x00aae310, - 0x00ab0310, 0x00ab2310, 0x00ab4310, 0x00ab6310, - 0x00ab8310, 0x00aba310, 0x00abc310, 0x00abe310, - 0x00ac0310, 0x00ac2310, 0x00ac4310, 0x00ac6310, - 0x00ac8310, 0x00aca310, 0x00acc310, 0x00ace310, - 0x00ad0310, 0x00ad2310, 0x00ad4310, 0x00ad6310, - 0x00ad8310, 0x00ada310, 0x00adc310, 0x00ade310, - 0x00ae0310, 0x00ae2310, 0x00ae4310, 0x00ae6310, - 0x00ae8310, 0x00aea310, 0x00aec310, 0x00aee310, - 0x00af0310, 0x00af2310, 0x00af4310, 0x00af6310, - 0x00af8310, 0x00afa310, 0x00afc310, 0x00afe310, - 0x00b00310, 0x00b02310, 0x00b04310, 0x00b06310, - 0x00b08310, 0x00b0a310, 0x00b0c310, 0x00b0e310, - 0x00b10310, 0x00b12310, 0x00b14310, 0x00b16310, - 0x00b18310, 0x00b1a310, 0x00b1c310, 0x00b1e310, - 0x00b20310, 0x00b22310, 0x00b24310, 0x00b26310, - 0x00b28310, 0x00b2a310, 0x00b2c310, 0x00b2e310, - 0x00b30310, 0x00b32310, 0x00b34310, 0x00b36310, - 0x00b38310, 0x00b3a310, 0x00b3c310, 0x00b3e310, - 0x00b40310, 0x00b42310, 0x00b44310, 0x00b46310, - 0x00b48310, 0x00b4a310, 0x00b4c310, 0x00b4e310, - 0x00b50310, 0x00b52310, 0x00b54310, 0x00b56310, - 0x00b58310, 0x00b5a310, 0x00b5c310, 0x00b5e310, - 0x00b60310, 0x00b62310, 0x00b64310, 0x00b66310, - 0x00b68310, 0x00b6a310, 0x00b6c310, 0x00b6e310, - 0x00b70310, 0x00b72310, 0x00b74310, 0x00b76310, - 0x00b78310, 0x00b7a310, 0x00b7c310, 0x00b7e310, - 0x00b80310, 0x00b82310, 0x00b84310, 0x00b86310, - 0x00b88310, 0x00b8a310, 0x00b8c310, 0x00b8e310, - 0x00b90310, 0x00b92310, 0x00b94310, 0x00b96310, - 0x00b98310, 0x00b9a310, 0x00b9c310, 0x00b9e310, - 0x00ba0310, 0x00ba2310, 0x00ba4310, 0x00ba6310, - 0x00ba8310, 0x00baa310, 0x00bac310, 0x00bae310, - 0x00bb0310, 0x00bb2310, 0x00bb4310, 0x00bb6310, - 0x00bb8310, 0x00bba310, 0x00bbc310, 0x00bbe310, - 0x00bc0310, 0x00bc2310, 0x00bc4310, 0x00bc6310, - 0x00bc8310, 0x00bca310, 0x00bcc310, 0x00bce310, - 0x00bd0310, 0x00bd2310, 0x00bd4310, 0x00bd6310, - 0x00bd8310, 0x00bda310, 0x00bdc310, 0x00bde310, - 0x00be0310, 0x00be2310, 0x00be4310, 0x00be6310, - 0x00be8310, 0x00bea310, 0x00bec310, 0x00bee310, - 0x00bf0310, 0x00bf2310, 0x00bf4310, 0x00bf6310, - 0x00bf8310, 0x00bfa310, 0x00bfc310, 0x00bfe310, - 0x00c00310, 0x00c02310, 0x00c04310, 0x00c06310, - 0x00c08310, 0x00c0a310, 0x00c0c310, 0x00c0e310, - 0x00c10310, 0x00c12310, 0x00c14310, 0x00c16310, - 0x00c18310, 0x00c1a310, 0x00c1c310, 0x00c1e310, - 0x00c20310, 0x00c22310, 0x00c24310, 0x00c26310, - 0x00c28310, 0x00c2a310, 0x00c2c310, 0x00c2e310, - 0x00c30310, 0x00c32310, 0x00c34310, 0x00c36310, - 0x00c38310, 0x00c3a310, 0x00c3c310, 0x00c3e310, - 0x00c40310, 0x00c42310, 0x00c44310, 0x00c46310, - 0x00c48310, 0x00c4a310, 0x00c4c310, 0x00c4e310, - 0x00c50310, 0x00c52310, 0x00c54310, 0x00c56310, - 0x00c58310, 0x00c5a310, 0x00c5c310, 0x00c5e310, - 0x00c60310, 0x00c62310, 0x00c64310, 0x00c66310, - 0x00c68310, 0x00c6a310, 0x00c6c310, 0x00c6e310, - 0x00c70310, 0x00c72310, 0x00c74310, 0x00c76310, - 0x00c78310, 0x00c7a310, 0x00c7c310, 0x00c7e310, - 0x00c80310, 0x00c82310, 0x00c84310, 0x00c86310, - 0x00c88310, 0x00c8a310, 0x00c8c310, 0x00c8e310, - 0x00c90310, 0x00c92310, 0x00c94310, 0x00c96310, - 0x00c98310, 0x00c9a310, 0x00c9c310, 0x00c9e310, - 0x00ca0310, 0x00ca2310, 0x00ca4310, 0x00ca6310, - 0x00ca8310, 0x00caa310, 0x00cac310, 0x00cae310, - 0x00cb0310, 0x00cb2310, 0x00cb4310, 0x00cb6310, - 0x00cb8310, 0x00cba310, 0x00cbc310, 0x00cbe310, - 0x00cc0310, 0x00cc2310, 0x00cc4310, 0x00cc6310, - 0x00cc8310, 0x00cca310, 0x00ccc310, 0x00cce310, - 0x00cd0310, 0x00cd2310, 0x00cd4310, 0x00cd6310, - 0x00cd8310, 0x00cda310, 0x00cdc310, 0x00cde310, - 0x00ce0310, 0x00ce2310, 0x00ce4310, 0x00ce6310, - 0x00ce8310, 0x00cea310, 0x00cec310, 0x00cee310, - 0x00cf0310, 0x00cf2310, 0x00cf4310, 0x00cf6310, - 0x00cf8310, 0x00cfa310, 0x00cfc310, 0x00cfe310, - 0x00d00310, 0x00d02310, 0x00d04310, 0x00d06310, - 0x00d08310, 0x00d0a310, 0x00d0c310, 0x00d0e310, - 0x00d10310, 0x00d12310, 0x00d14310, 0x00d16310, - 0x00d18310, 0x00d1a310, 0x00d1c310, 0x00d1e310, - 0x00d20310, 0x00d22310, 0x00d24310, 0x00d26310, - 0x00d28310, 0x00d2a310, 0x00d2c310, 0x00d2e310, - 0x00d30310, 0x00d32310, 0x00d34310, 0x00d36310, - 0x00d38310, 0x00d3a310, 0x00d3c310, 0x00d3e310, - 0x00d40310, 0x00d42310, 0x00d44310, 0x00d46310, - 0x00d48310, 0x00d4a310, 0x00d4c310, 0x00d4e310, - 0x00d50310, 0x00d52310, 0x00d54310, 0x00d56310, - 0x00d58310, 0x00d5a310, 0x00d5c310, 0x00d5e310, - 0x00d60310, 0x00d62310, 0x00d64310, 0x00d66310, - 0x00d68310, 0x00d6a310, 0x00d6c310, 0x00d6e310, - 0x00d70310, 0x00d72310, 0x00d74310, 0x00d76310, - 0x00d78310, 0x00d7a310, 0x00d7c310, 0x00d7e310, - 0x00d80310, 0x00d82310, 0x00d84310, 0x00d86310, - 0x00d88310, 0x00d8a310, 0x00d8c310, 0x00d8e310, - 0x00d90310, 0x00d92310, 0x00d94310, 0x00d96310, - 0x00d98310, 0x00d9a310, 0x00d9c310, 0x00d9e310, - 0x00da0310, 0x00da2310, 0x00da4310, 0x00da6310, - 0x00da8310, 0x00daa310, 0x00dac310, 0x00dae310, - 0x00db0310, 0x00db2310, 0x00db4310, 0x00db6310, - 0x00db8310, 0x00dba310, 0x00dbc310, 0x00dbe310, - 0x00dc0310, 0x00dc2310, 0x00dc4310, 0x00dc6310, - 0x00dc8310, 0x00dca310, 0x00dcc310, 0x00dce310, - 0x00dd0310, 0x00dd2310, 0x00dd4310, 0x00dd6310, - 0x00dd8310, 0x00dda310, 0x00ddc310, 0x00dde310, - 0x00de0310, 0x00de2310, 0x00de4310, 0x00de6310, - 0x00de8310, 0x00dea310, 0x00dec310, 0x00dee310, - 0x00df0310, 0x00df2310, 0x00df4310, 0x00df6310, - 0x00df8310, 0x00dfa310, 0x00dfc310, 0x00dfe310, - 0x00e00310, 0x00e02310, 0x00e04310, 0x00e06310, - 0x00e08310, 0x00e0a310, 0x00e0c310, 0x00e0e310, - 0x00e10310, 0x00e12310, 0x00e14310, 0x00e16310, - 0x00e18310, 0x00e1a310, 0x00e1c310, 0x00e1e310, - 0x00e20310, 0x00e22310, 0x00e24310, 0x00e26310, - 0x00e28310, 0x00e2a310, 0x00e2c310, 0x00e2e310, - 0x00e30310, 0x00e32310, 0x00e34310, 0x00e36310, - 0x00e38310, 0x00e3a310, 0x00e3c310, 0x00e3e310, - 0x00e40310, 0x00e42310, 0x00e44310, 0x00e46310, - 0x00e48310, 0x00e4a310, 0x00e4c310, 0x00e4e310, - 0x00e50310, 0x00e52310, 0x00e54310, 0x00e56310, - 0x00e58310, 0x00e5a310, 0x00e5c310, 0x00e5e310, - 0x00e60310, 0x00e62310, 0x00e64310, 0x00e66310, - 0x00e68310, 0x00e6a310, 0x00e6c310, 0x00e6e310, - 0x00e70310, 0x00e72310, 0x00e74310, 0x00e76310, - 0x00e78310, 0x00e7a310, 0x00e7c310, 0x00e7e310, - 0x00e80310, 0x00e82310, 0x00e84310, 0x00e86310, - 0x00e88310, 0x00e8a310, 0x00e8c310, 0x00e8e310, - 0x00e90310, 0x00e92310, 0x00e94310, 0x00e96310, - 0x00e98310, 0x00e9a310, 0x00e9c310, 0x00e9e310, - 0x00ea0310, 0x00ea2310, 0x00ea4310, 0x00ea6310, - 0x00ea8310, 0x00eaa310, 0x00eac310, 0x00eae310, - 0x00eb0310, 0x00eb2310, 0x00eb4310, 0x00eb6310, - 0x00eb8310, 0x00eba310, 0x00ebc310, 0x00ebe310, - 0x00ec0310, 0x00ec2310, 0x00ec4310, 0x00ec6310, - 0x00ec8310, 0x00eca310, 0x00ecc310, 0x00ece310, - 0x00ed0310, 0x00ed2310, 0x00ed4310, 0x00ed6310, - 0x00ed8310, 0x00eda310, 0x00edc310, 0x00ede310, - 0x00ee0310, 0x00ee2310, 0x00ee4310, 0x00ee6310, - 0x00ee8310, 0x00eea310, 0x00eec310, 0x00eee310, - 0x00ef0310, 0x00ef2310, 0x00ef4310, 0x00ef6310, - 0x00ef8310, 0x00efa310, 0x00efc310, 0x00efe310, - 0x00f00310, 0x00f02310, 0x00f04310, 0x00f06310, - 0x00f08310, 0x00f0a310, 0x00f0c310, 0x00f0e310, - 0x00f10310, 0x00f12310, 0x00f14310, 0x00f16310, - 0x00f18310, 0x00f1a310, 0x00f1c310, 0x00f1e310, - 0x00f20310, 0x00f22310, 0x00f24310, 0x00f26310, - 0x00f28310, 0x00f2a310, 0x00f2c310, 0x00f2e310, - 0x00f30310, 0x00f32310, 0x00f34310, 0x00f36310, - 0x00f38310, 0x00f3a310, 0x00f3c310, 0x00f3e310, - 0x00f40310, 0x00f42310, 0x00f44310, 0x00f46310, - 0x00f48310, 0x00f4a310, 0x00f4c310, 0x00f4e310, - 0x00f50310, 0x00f52310, 0x00f54310, 0x00f56310, - 0x00f58310, 0x00f5a310, 0x00f5c310, 0x00f5e310, - 0x00f60310, 0x00f62310, 0x00f64310, 0x00f66310, - 0x00f68310, 0x00f6a310, 0x00f6c310, 0x00f6e310, - 0x00f70310, 0x00f72310, 0x00f74310, 0x00f76310, - 0x00f78310, 0x00f7a310, 0x00f7c310, 0x00f7e310, - 0x00f80310, 0x00f82310, 0x00f84310, 0x00f86310, - 0x00f88310, 0x00f8a310, 0x00f8c310, 0x00f8e310, - 0x00f90310, 0x00f92310, 0x00f94310, 0x00f96310, - 0x00f98310, 0x00f9a310, 0x00f9c310, 0x00f9e310, - 0x00fa0310, 0x00fa2310, 0x00fa4310, 0x00fa6310, - 0x00fa8310, 0x00faa310, 0x00fac310, 0x00fae310, - 0x00fb0310, 0x00fb2310, 0x00fb4310, 0x00fb6310, - 0x00fb8310, 0x00fba310, 0x00fbc310, 0x00fbe310, - 0x00fc0310, 0x00fc2310, 0x00fc4310, 0x00fc6310, - 0x00fc8310, 0x00fca310, 0x00fcc310, 0x00fce310, - 0x00fd0310, 0x00fd2310, 0x00fd4310, 0x00fd6310, - 0x00fd8310, 0x00fda310, 0x00fdc310, 0x00fde310, - 0x00fe0310, 0x00fe2310, 0x00fe4310, 0x00fe6310, - 0x00fe8310, 0x00fea310, 0x00fec310, 0x00fee310, - 0x00ff0310, 0x00ff2310, 0x00ff4310, 0x00ff6310, - 0x00ff8310, 0x00ffa310, 0x00ffc310, 0x00ffe310, - 0x00001310, 0x00003310, 0x00005310, 0x00007310, - 0x00009310, 0x0000b310, 0x0000d310, 0x0000f310, - 0x00011310, 0x00013310, 0x00015310, 0x00017310, - 0x00019310, 0x0001b310, 0x0001d310, 0x0001f310, - 0x00021310, 0x00023310, 0x00025310, 0x00027310, - 0x00029310, 0x0002b310, 0x0002d310, 0x0002f310, - 0x00031310, 0x00033310, 0x00035310, 0x00037310, - 0x00039310, 0x0003b310, 0x0003d310, 0x0003f310, - 0x00041310, 0x00043310, 0x00045310, 0x00047310, - 0x00049310, 0x0004b310, 0x0004d310, 0x0004f310, - 0x00051310, 0x00053310, 0x00055310, 0x00057310, - 0x00059310, 0x0005b310, 0x0005d310, 0x0005f310, - 0x00061310, 0x00063310, 0x00065310, 0x00067310, - 0x00069310, 0x0006b310, 0x0006d310, 0x0006f310, - 0x00071310, 0x00073310, 0x00075310, 0x00077310, - 0x00079310, 0x0007b310, 0x0007d310, 0x0007f310, - 0x00081310, 0x00083310, 0x00085310, 0x00087310, - 0x00089310, 0x0008b310, 0x0008d310, 0x0008f310, - 0x00091310, 0x00093310, 0x00095310, 0x00097310, - 0x00099310, 0x0009b310, 0x0009d310, 0x0009f310, - 0x000a1310, 0x000a3310, 0x000a5310, 0x000a7310, - 0x000a9310, 0x000ab310, 0x000ad310, 0x000af310, - 0x000b1310, 0x000b3310, 0x000b5310, 0x000b7310, - 0x000b9310, 0x000bb310, 0x000bd310, 0x000bf310, - 0x000c1310, 0x000c3310, 0x000c5310, 0x000c7310, - 0x000c9310, 0x000cb310, 0x000cd310, 0x000cf310, - 0x000d1310, 0x000d3310, 0x000d5310, 0x000d7310, - 0x000d9310, 0x000db310, 0x000dd310, 0x000df310, - 0x000e1310, 0x000e3310, 0x000e5310, 0x000e7310, - 0x000e9310, 0x000eb310, 0x000ed310, 0x000ef310, - 0x000f1310, 0x000f3310, 0x000f5310, 0x000f7310, - 0x000f9310, 0x000fb310, 0x000fd310, 0x000ff310, - 0x00101310, 0x00103310, 0x00105310, 0x00107310, - 0x00109310, 0x0010b310, 0x0010d310, 0x0010f310, - 0x00111310, 0x00113310, 0x00115310, 0x00117310, - 0x00119310, 0x0011b310, 0x0011d310, 0x0011f310, - 0x00121310, 0x00123310, 0x00125310, 0x00127310, - 0x00129310, 0x0012b310, 0x0012d310, 0x0012f310, - 0x00131310, 0x00133310, 0x00135310, 0x00137310, - 0x00139310, 0x0013b310, 0x0013d310, 0x0013f310, - 0x00141310, 0x00143310, 0x00145310, 0x00147310, - 0x00149310, 0x0014b310, 0x0014d310, 0x0014f310, - 0x00151310, 0x00153310, 0x00155310, 0x00157310, - 0x00159310, 0x0015b310, 0x0015d310, 0x0015f310, - 0x00161310, 0x00163310, 0x00165310, 0x00167310, - 0x00169310, 0x0016b310, 0x0016d310, 0x0016f310, - 0x00171310, 0x00173310, 0x00175310, 0x00177310, - 0x00179310, 0x0017b310, 0x0017d310, 0x0017f310, - 0x00181310, 0x00183310, 0x00185310, 0x00187310, - 0x00189310, 0x0018b310, 0x0018d310, 0x0018f310, - 0x00191310, 0x00193310, 0x00195310, 0x00197310, - 0x00199310, 0x0019b310, 0x0019d310, 0x0019f310, - 0x001a1310, 0x001a3310, 0x001a5310, 0x001a7310, - 0x001a9310, 0x001ab310, 0x001ad310, 0x001af310, - 0x001b1310, 0x001b3310, 0x001b5310, 0x001b7310, - 0x001b9310, 0x001bb310, 0x001bd310, 0x001bf310, - 0x001c1310, 0x001c3310, 0x001c5310, 0x001c7310, - 0x001c9310, 0x001cb310, 0x001cd310, 0x001cf310, - 0x001d1310, 0x001d3310, 0x001d5310, 0x001d7310, - 0x001d9310, 0x001db310, 0x001dd310, 0x001df310, - 0x001e1310, 0x001e3310, 0x001e5310, 0x001e7310, - 0x001e9310, 0x001eb310, 0x001ed310, 0x001ef310, - 0x001f1310, 0x001f3310, 0x001f5310, 0x001f7310, - 0x001f9310, 0x001fb310, 0x001fd310, 0x001ff310, - 0x00201310, 0x00203310, 0x00205310, 0x00207310, - 0x00209310, 0x0020b310, 0x0020d310, 0x0020f310, - 0x00211310, 0x00213310, 0x00215310, 0x00217310, - 0x00219310, 0x0021b310, 0x0021d310, 0x0021f310, - 0x00221310, 0x00223310, 0x00225310, 0x00227310, - 0x00229310, 0x0022b310, 0x0022d310, 0x0022f310, - 0x00231310, 0x00233310, 0x00235310, 0x00237310, - 0x00239310, 0x0023b310, 0x0023d310, 0x0023f310, - 0x00241310, 0x00243310, 0x00245310, 0x00247310, - 0x00249310, 0x0024b310, 0x0024d310, 0x0024f310, - 0x00251310, 0x00253310, 0x00255310, 0x00257310, - 0x00259310, 0x0025b310, 0x0025d310, 0x0025f310, - 0x00261310, 0x00263310, 0x00265310, 0x00267310, - 0x00269310, 0x0026b310, 0x0026d310, 0x0026f310, - 0x00271310, 0x00273310, 0x00275310, 0x00277310, - 0x00279310, 0x0027b310, 0x0027d310, 0x0027f310, - 0x00281310, 0x00283310, 0x00285310, 0x00287310, - 0x00289310, 0x0028b310, 0x0028d310, 0x0028f310, - 0x00291310, 0x00293310, 0x00295310, 0x00297310, - 0x00299310, 0x0029b310, 0x0029d310, 0x0029f310, - 0x002a1310, 0x002a3310, 0x002a5310, 0x002a7310, - 0x002a9310, 0x002ab310, 0x002ad310, 0x002af310, - 0x002b1310, 0x002b3310, 0x002b5310, 0x002b7310, - 0x002b9310, 0x002bb310, 0x002bd310, 0x002bf310, - 0x002c1310, 0x002c3310, 0x002c5310, 0x002c7310, - 0x002c9310, 0x002cb310, 0x002cd310, 0x002cf310, - 0x002d1310, 0x002d3310, 0x002d5310, 0x002d7310, - 0x002d9310, 0x002db310, 0x002dd310, 0x002df310, - 0x002e1310, 0x002e3310, 0x002e5310, 0x002e7310, - 0x002e9310, 0x002eb310, 0x002ed310, 0x002ef310, - 0x002f1310, 0x002f3310, 0x002f5310, 0x002f7310, - 0x002f9310, 0x002fb310, 0x002fd310, 0x002ff310, - 0x00301310, 0x00303310, 0x00305310, 0x00307310, - 0x00309310, 0x0030b310, 0x0030d310, 0x0030f310, - 0x00311310, 0x00313310, 0x00315310, 0x00317310, - 0x00319310, 0x0031b310, 0x0031d310, 0x0031f310, - 0x00321310, 0x00323310, 0x00325310, 0x00327310, - 0x00329310, 0x0032b310, 0x0032d310, 0x0032f310, - 0x00331310, 0x00333310, 0x00335310, 0x00337310, - 0x00339310, 0x0033b310, 0x0033d310, 0x0033f310, - 0x00341310, 0x00343310, 0x00345310, 0x00347310, - 0x00349310, 0x0034b310, 0x0034d310, 0x0034f310, - 0x00351310, 0x00353310, 0x00355310, 0x00357310, - 0x00359310, 0x0035b310, 0x0035d310, 0x0035f310, - 0x00361310, 0x00363310, 0x00365310, 0x00367310, - 0x00369310, 0x0036b310, 0x0036d310, 0x0036f310, - 0x00371310, 0x00373310, 0x00375310, 0x00377310, - 0x00379310, 0x0037b310, 0x0037d310, 0x0037f310, - 0x00381310, 0x00383310, 0x00385310, 0x00387310, - 0x00389310, 0x0038b310, 0x0038d310, 0x0038f310, - 0x00391310, 0x00393310, 0x00395310, 0x00397310, - 0x00399310, 0x0039b310, 0x0039d310, 0x0039f310, - 0x003a1310, 0x003a3310, 0x003a5310, 0x003a7310, - 0x003a9310, 0x003ab310, 0x003ad310, 0x003af310, - 0x003b1310, 0x003b3310, 0x003b5310, 0x003b7310, - 0x003b9310, 0x003bb310, 0x003bd310, 0x003bf310, - 0x003c1310, 0x003c3310, 0x003c5310, 0x003c7310, - 0x003c9310, 0x003cb310, 0x003cd310, 0x003cf310, - 0x003d1310, 0x003d3310, 0x003d5310, 0x003d7310, - 0x003d9310, 0x003db310, 0x003dd310, 0x003df310, - 0x003e1310, 0x003e3310, 0x003e5310, 0x003e7310, - 0x003e9310, 0x003eb310, 0x003ed310, 0x003ef310, - 0x003f1310, 0x003f3310, 0x003f5310, 0x003f7310, - 0x003f9310, 0x003fb310, 0x003fd310, 0x003ff310, - 0x00401310, 0x00403310, 0x00405310, 0x00407310, - 0x00409310, 0x0040b310, 0x0040d310, 0x0040f310, - 0x00411310, 0x00413310, 0x00415310, 0x00417310, - 0x00419310, 0x0041b310, 0x0041d310, 0x0041f310, - 0x00421310, 0x00423310, 0x00425310, 0x00427310, - 0x00429310, 0x0042b310, 0x0042d310, 0x0042f310, - 0x00431310, 0x00433310, 0x00435310, 0x00437310, - 0x00439310, 0x0043b310, 0x0043d310, 0x0043f310, - 0x00441310, 0x00443310, 0x00445310, 0x00447310, - 0x00449310, 0x0044b310, 0x0044d310, 0x0044f310, - 0x00451310, 0x00453310, 0x00455310, 0x00457310, - 0x00459310, 0x0045b310, 0x0045d310, 0x0045f310, - 0x00461310, 0x00463310, 0x00465310, 0x00467310, - 0x00469310, 0x0046b310, 0x0046d310, 0x0046f310, - 0x00471310, 0x00473310, 0x00475310, 0x00477310, - 0x00479310, 0x0047b310, 0x0047d310, 0x0047f310, - 0x00481310, 0x00483310, 0x00485310, 0x00487310, - 0x00489310, 0x0048b310, 0x0048d310, 0x0048f310, - 0x00491310, 0x00493310, 0x00495310, 0x00497310, - 0x00499310, 0x0049b310, 0x0049d310, 0x0049f310, - 0x004a1310, 0x004a3310, 0x004a5310, 0x004a7310, - 0x004a9310, 0x004ab310, 0x004ad310, 0x004af310, - 0x004b1310, 0x004b3310, 0x004b5310, 0x004b7310, - 0x004b9310, 0x004bb310, 0x004bd310, 0x004bf310, - 0x004c1310, 0x004c3310, 0x004c5310, 0x004c7310, - 0x004c9310, 0x004cb310, 0x004cd310, 0x004cf310, - 0x004d1310, 0x004d3310, 0x004d5310, 0x004d7310, - 0x004d9310, 0x004db310, 0x004dd310, 0x004df310, - 0x004e1310, 0x004e3310, 0x004e5310, 0x004e7310, - 0x004e9310, 0x004eb310, 0x004ed310, 0x004ef310, - 0x004f1310, 0x004f3310, 0x004f5310, 0x004f7310, - 0x004f9310, 0x004fb310, 0x004fd310, 0x004ff310, - 0x00501310, 0x00503310, 0x00505310, 0x00507310, - 0x00509310, 0x0050b310, 0x0050d310, 0x0050f310, - 0x00511310, 0x00513310, 0x00515310, 0x00517310, - 0x00519310, 0x0051b310, 0x0051d310, 0x0051f310, - 0x00521310, 0x00523310, 0x00525310, 0x00527310, - 0x00529310, 0x0052b310, 0x0052d310, 0x0052f310, - 0x00531310, 0x00533310, 0x00535310, 0x00537310, - 0x00539310, 0x0053b310, 0x0053d310, 0x0053f310, - 0x00541310, 0x00543310, 0x00545310, 0x00547310, - 0x00549310, 0x0054b310, 0x0054d310, 0x0054f310, - 0x00551310, 0x00553310, 0x00555310, 0x00557310, - 0x00559310, 0x0055b310, 0x0055d310, 0x0055f310, - 0x00561310, 0x00563310, 0x00565310, 0x00567310, - 0x00569310, 0x0056b310, 0x0056d310, 0x0056f310, - 0x00571310, 0x00573310, 0x00575310, 0x00577310, - 0x00579310, 0x0057b310, 0x0057d310, 0x0057f310, - 0x00581310, 0x00583310, 0x00585310, 0x00587310, - 0x00589310, 0x0058b310, 0x0058d310, 0x0058f310, - 0x00591310, 0x00593310, 0x00595310, 0x00597310, - 0x00599310, 0x0059b310, 0x0059d310, 0x0059f310, - 0x005a1310, 0x005a3310, 0x005a5310, 0x005a7310, - 0x005a9310, 0x005ab310, 0x005ad310, 0x005af310, - 0x005b1310, 0x005b3310, 0x005b5310, 0x005b7310, - 0x005b9310, 0x005bb310, 0x005bd310, 0x005bf310, - 0x005c1310, 0x005c3310, 0x005c5310, 0x005c7310, - 0x005c9310, 0x005cb310, 0x005cd310, 0x005cf310, - 0x005d1310, 0x005d3310, 0x005d5310, 0x005d7310, - 0x005d9310, 0x005db310, 0x005dd310, 0x005df310, - 0x005e1310, 0x005e3310, 0x005e5310, 0x005e7310, - 0x005e9310, 0x005eb310, 0x005ed310, 0x005ef310, - 0x005f1310, 0x005f3310, 0x005f5310, 0x005f7310, - 0x005f9310, 0x005fb310, 0x005fd310, 0x005ff310, - 0x00601310, 0x00603310, 0x00605310, 0x00607310, - 0x00609310, 0x0060b310, 0x0060d310, 0x0060f310, - 0x00611310, 0x00613310, 0x00615310, 0x00617310, - 0x00619310, 0x0061b310, 0x0061d310, 0x0061f310, - 0x00621310, 0x00623310, 0x00625310, 0x00627310, - 0x00629310, 0x0062b310, 0x0062d310, 0x0062f310, - 0x00631310, 0x00633310, 0x00635310, 0x00637310, - 0x00639310, 0x0063b310, 0x0063d310, 0x0063f310, - 0x00641310, 0x00643310, 0x00645310, 0x00647310, - 0x00649310, 0x0064b310, 0x0064d310, 0x0064f310, - 0x00651310, 0x00653310, 0x00655310, 0x00657310, - 0x00659310, 0x0065b310, 0x0065d310, 0x0065f310, - 0x00661310, 0x00663310, 0x00665310, 0x00667310, - 0x00669310, 0x0066b310, 0x0066d310, 0x0066f310, - 0x00671310, 0x00673310, 0x00675310, 0x00677310, - 0x00679310, 0x0067b310, 0x0067d310, 0x0067f310, - 0x00681310, 0x00683310, 0x00685310, 0x00687310, - 0x00689310, 0x0068b310, 0x0068d310, 0x0068f310, - 0x00691310, 0x00693310, 0x00695310, 0x00697310, - 0x00699310, 0x0069b310, 0x0069d310, 0x0069f310, - 0x006a1310, 0x006a3310, 0x006a5310, 0x006a7310, - 0x006a9310, 0x006ab310, 0x006ad310, 0x006af310, - 0x006b1310, 0x006b3310, 0x006b5310, 0x006b7310, - 0x006b9310, 0x006bb310, 0x006bd310, 0x006bf310, - 0x006c1310, 0x006c3310, 0x006c5310, 0x006c7310, - 0x006c9310, 0x006cb310, 0x006cd310, 0x006cf310, - 0x006d1310, 0x006d3310, 0x006d5310, 0x006d7310, - 0x006d9310, 0x006db310, 0x006dd310, 0x006df310, - 0x006e1310, 0x006e3310, 0x006e5310, 0x006e7310, - 0x006e9310, 0x006eb310, 0x006ed310, 0x006ef310, - 0x006f1310, 0x006f3310, 0x006f5310, 0x006f7310, - 0x006f9310, 0x006fb310, 0x006fd310, 0x006ff310, - 0x00701310, 0x00703310, 0x00705310, 0x00707310, - 0x00709310, 0x0070b310, 0x0070d310, 0x0070f310, - 0x00711310, 0x00713310, 0x00715310, 0x00717310, - 0x00719310, 0x0071b310, 0x0071d310, 0x0071f310, - 0x00721310, 0x00723310, 0x00725310, 0x00727310, - 0x00729310, 0x0072b310, 0x0072d310, 0x0072f310, - 0x00731310, 0x00733310, 0x00735310, 0x00737310, - 0x00739310, 0x0073b310, 0x0073d310, 0x0073f310, - 0x00741310, 0x00743310, 0x00745310, 0x00747310, - 0x00749310, 0x0074b310, 0x0074d310, 0x0074f310, - 0x00751310, 0x00753310, 0x00755310, 0x00757310, - 0x00759310, 0x0075b310, 0x0075d310, 0x0075f310, - 0x00761310, 0x00763310, 0x00765310, 0x00767310, - 0x00769310, 0x0076b310, 0x0076d310, 0x0076f310, - 0x00771310, 0x00773310, 0x00775310, 0x00777310, - 0x00779310, 0x0077b310, 0x0077d310, 0x0077f310, - 0x00781310, 0x00783310, 0x00785310, 0x00787310, - 0x00789310, 0x0078b310, 0x0078d310, 0x0078f310, - 0x00791310, 0x00793310, 0x00795310, 0x00797310, - 0x00799310, 0x0079b310, 0x0079d310, 0x0079f310, - 0x007a1310, 0x007a3310, 0x007a5310, 0x007a7310, - 0x007a9310, 0x007ab310, 0x007ad310, 0x007af310, - 0x007b1310, 0x007b3310, 0x007b5310, 0x007b7310, - 0x007b9310, 0x007bb310, 0x007bd310, 0x007bf310, - 0x007c1310, 0x007c3310, 0x007c5310, 0x007c7310, - 0x007c9310, 0x007cb310, 0x007cd310, 0x007cf310, - 0x007d1310, 0x007d3310, 0x007d5310, 0x007d7310, - 0x007d9310, 0x007db310, 0x007dd310, 0x007df310, - 0x007e1310, 0x007e3310, 0x007e5310, 0x007e7310, - 0x007e9310, 0x007eb310, 0x007ed310, 0x007ef310, - 0x007f1310, 0x007f3310, 0x007f5310, 0x007f7310, - 0x007f9310, 0x007fb310, 0x007fd310, 0x007ff310, - 0x00801310, 0x00803310, 0x00805310, 0x00807310, - 0x00809310, 0x0080b310, 0x0080d310, 0x0080f310, - 0x00811310, 0x00813310, 0x00815310, 0x00817310, - 0x00819310, 0x0081b310, 0x0081d310, 0x0081f310, - 0x00821310, 0x00823310, 0x00825310, 0x00827310, - 0x00829310, 0x0082b310, 0x0082d310, 0x0082f310, - 0x00831310, 0x00833310, 0x00835310, 0x00837310, - 0x00839310, 0x0083b310, 0x0083d310, 0x0083f310, - 0x00841310, 0x00843310, 0x00845310, 0x00847310, - 0x00849310, 0x0084b310, 0x0084d310, 0x0084f310, - 0x00851310, 0x00853310, 0x00855310, 0x00857310, - 0x00859310, 0x0085b310, 0x0085d310, 0x0085f310, - 0x00861310, 0x00863310, 0x00865310, 0x00867310, - 0x00869310, 0x0086b310, 0x0086d310, 0x0086f310, - 0x00871310, 0x00873310, 0x00875310, 0x00877310, - 0x00879310, 0x0087b310, 0x0087d310, 0x0087f310, - 0x00881310, 0x00883310, 0x00885310, 0x00887310, - 0x00889310, 0x0088b310, 0x0088d310, 0x0088f310, - 0x00891310, 0x00893310, 0x00895310, 0x00897310, - 0x00899310, 0x0089b310, 0x0089d310, 0x0089f310, - 0x008a1310, 0x008a3310, 0x008a5310, 0x008a7310, - 0x008a9310, 0x008ab310, 0x008ad310, 0x008af310, - 0x008b1310, 0x008b3310, 0x008b5310, 0x008b7310, - 0x008b9310, 0x008bb310, 0x008bd310, 0x008bf310, - 0x008c1310, 0x008c3310, 0x008c5310, 0x008c7310, - 0x008c9310, 0x008cb310, 0x008cd310, 0x008cf310, - 0x008d1310, 0x008d3310, 0x008d5310, 0x008d7310, - 0x008d9310, 0x008db310, 0x008dd310, 0x008df310, - 0x008e1310, 0x008e3310, 0x008e5310, 0x008e7310, - 0x008e9310, 0x008eb310, 0x008ed310, 0x008ef310, - 0x008f1310, 0x008f3310, 0x008f5310, 0x008f7310, - 0x008f9310, 0x008fb310, 0x008fd310, 0x008ff310, - 0x00901310, 0x00903310, 0x00905310, 0x00907310, - 0x00909310, 0x0090b310, 0x0090d310, 0x0090f310, - 0x00911310, 0x00913310, 0x00915310, 0x00917310, - 0x00919310, 0x0091b310, 0x0091d310, 0x0091f310, - 0x00921310, 0x00923310, 0x00925310, 0x00927310, - 0x00929310, 0x0092b310, 0x0092d310, 0x0092f310, - 0x00931310, 0x00933310, 0x00935310, 0x00937310, - 0x00939310, 0x0093b310, 0x0093d310, 0x0093f310, - 0x00941310, 0x00943310, 0x00945310, 0x00947310, - 0x00949310, 0x0094b310, 0x0094d310, 0x0094f310, - 0x00951310, 0x00953310, 0x00955310, 0x00957310, - 0x00959310, 0x0095b310, 0x0095d310, 0x0095f310, - 0x00961310, 0x00963310, 0x00965310, 0x00967310, - 0x00969310, 0x0096b310, 0x0096d310, 0x0096f310, - 0x00971310, 0x00973310, 0x00975310, 0x00977310, - 0x00979310, 0x0097b310, 0x0097d310, 0x0097f310, - 0x00981310, 0x00983310, 0x00985310, 0x00987310, - 0x00989310, 0x0098b310, 0x0098d310, 0x0098f310, - 0x00991310, 0x00993310, 0x00995310, 0x00997310, - 0x00999310, 0x0099b310, 0x0099d310, 0x0099f310, - 0x009a1310, 0x009a3310, 0x009a5310, 0x009a7310, - 0x009a9310, 0x009ab310, 0x009ad310, 0x009af310, - 0x009b1310, 0x009b3310, 0x009b5310, 0x009b7310, - 0x009b9310, 0x009bb310, 0x009bd310, 0x009bf310, - 0x009c1310, 0x009c3310, 0x009c5310, 0x009c7310, - 0x009c9310, 0x009cb310, 0x009cd310, 0x009cf310, - 0x009d1310, 0x009d3310, 0x009d5310, 0x009d7310, - 0x009d9310, 0x009db310, 0x009dd310, 0x009df310, - 0x009e1310, 0x009e3310, 0x009e5310, 0x009e7310, - 0x009e9310, 0x009eb310, 0x009ed310, 0x009ef310, - 0x009f1310, 0x009f3310, 0x009f5310, 0x009f7310, - 0x009f9310, 0x009fb310, 0x009fd310, 0x009ff310, - 0x00a01310, 0x00a03310, 0x00a05310, 0x00a07310, - 0x00a09310, 0x00a0b310, 0x00a0d310, 0x00a0f310, - 0x00a11310, 0x00a13310, 0x00a15310, 0x00a17310, - 0x00a19310, 0x00a1b310, 0x00a1d310, 0x00a1f310, - 0x00a21310, 0x00a23310, 0x00a25310, 0x00a27310, - 0x00a29310, 0x00a2b310, 0x00a2d310, 0x00a2f310, - 0x00a31310, 0x00a33310, 0x00a35310, 0x00a37310, - 0x00a39310, 0x00a3b310, 0x00a3d310, 0x00a3f310, - 0x00a41310, 0x00a43310, 0x00a45310, 0x00a47310, - 0x00a49310, 0x00a4b310, 0x00a4d310, 0x00a4f310, - 0x00a51310, 0x00a53310, 0x00a55310, 0x00a57310, - 0x00a59310, 0x00a5b310, 0x00a5d310, 0x00a5f310, - 0x00a61310, 0x00a63310, 0x00a65310, 0x00a67310, - 0x00a69310, 0x00a6b310, 0x00a6d310, 0x00a6f310, - 0x00a71310, 0x00a73310, 0x00a75310, 0x00a77310, - 0x00a79310, 0x00a7b310, 0x00a7d310, 0x00a7f310, - 0x00a81310, 0x00a83310, 0x00a85310, 0x00a87310, - 0x00a89310, 0x00a8b310, 0x00a8d310, 0x00a8f310, - 0x00a91310, 0x00a93310, 0x00a95310, 0x00a97310, - 0x00a99310, 0x00a9b310, 0x00a9d310, 0x00a9f310, - 0x00aa1310, 0x00aa3310, 0x00aa5310, 0x00aa7310, - 0x00aa9310, 0x00aab310, 0x00aad310, 0x00aaf310, - 0x00ab1310, 0x00ab3310, 0x00ab5310, 0x00ab7310, - 0x00ab9310, 0x00abb310, 0x00abd310, 0x00abf310, - 0x00ac1310, 0x00ac3310, 0x00ac5310, 0x00ac7310, - 0x00ac9310, 0x00acb310, 0x00acd310, 0x00acf310, - 0x00ad1310, 0x00ad3310, 0x00ad5310, 0x00ad7310, - 0x00ad9310, 0x00adb310, 0x00add310, 0x00adf310, - 0x00ae1310, 0x00ae3310, 0x00ae5310, 0x00ae7310, - 0x00ae9310, 0x00aeb310, 0x00aed310, 0x00aef310, - 0x00af1310, 0x00af3310, 0x00af5310, 0x00af7310, - 0x00af9310, 0x00afb310, 0x00afd310, 0x00aff310, - 0x00b01310, 0x00b03310, 0x00b05310, 0x00b07310, - 0x00b09310, 0x00b0b310, 0x00b0d310, 0x00b0f310, - 0x00b11310, 0x00b13310, 0x00b15310, 0x00b17310, - 0x00b19310, 0x00b1b310, 0x00b1d310, 0x00b1f310, - 0x00b21310, 0x00b23310, 0x00b25310, 0x00b27310, - 0x00b29310, 0x00b2b310, 0x00b2d310, 0x00b2f310, - 0x00b31310, 0x00b33310, 0x00b35310, 0x00b37310, - 0x00b39310, 0x00b3b310, 0x00b3d310, 0x00b3f310, - 0x00b41310, 0x00b43310, 0x00b45310, 0x00b47310, - 0x00b49310, 0x00b4b310, 0x00b4d310, 0x00b4f310, - 0x00b51310, 0x00b53310, 0x00b55310, 0x00b57310, - 0x00b59310, 0x00b5b310, 0x00b5d310, 0x00b5f310, - 0x00b61310, 0x00b63310, 0x00b65310, 0x00b67310, - 0x00b69310, 0x00b6b310, 0x00b6d310, 0x00b6f310, - 0x00b71310, 0x00b73310, 0x00b75310, 0x00b77310, - 0x00b79310, 0x00b7b310, 0x00b7d310, 0x00b7f310, - 0x00b81310, 0x00b83310, 0x00b85310, 0x00b87310, - 0x00b89310, 0x00b8b310, 0x00b8d310, 0x00b8f310, - 0x00b91310, 0x00b93310, 0x00b95310, 0x00b97310, - 0x00b99310, 0x00b9b310, 0x00b9d310, 0x00b9f310, - 0x00ba1310, 0x00ba3310, 0x00ba5310, 0x00ba7310, - 0x00ba9310, 0x00bab310, 0x00bad310, 0x00baf310, - 0x00bb1310, 0x00bb3310, 0x00bb5310, 0x00bb7310, - 0x00bb9310, 0x00bbb310, 0x00bbd310, 0x00bbf310, - 0x00bc1310, 0x00bc3310, 0x00bc5310, 0x00bc7310, - 0x00bc9310, 0x00bcb310, 0x00bcd310, 0x00bcf310, - 0x00bd1310, 0x00bd3310, 0x00bd5310, 0x00bd7310, - 0x00bd9310, 0x00bdb310, 0x00bdd310, 0x00bdf310, - 0x00be1310, 0x00be3310, 0x00be5310, 0x00be7310, - 0x00be9310, 0x00beb310, 0x00bed310, 0x00bef310, - 0x00bf1310, 0x00bf3310, 0x00bf5310, 0x00bf7310, - 0x00bf9310, 0x00bfb310, 0x00bfd310, 0x00bff310, - 0x00c01310, 0x00c03310, 0x00c05310, 0x00c07310, - 0x00c09310, 0x00c0b310, 0x00c0d310, 0x00c0f310, - 0x00c11310, 0x00c13310, 0x00c15310, 0x00c17310, - 0x00c19310, 0x00c1b310, 0x00c1d310, 0x00c1f310, - 0x00c21310, 0x00c23310, 0x00c25310, 0x00c27310, - 0x00c29310, 0x00c2b310, 0x00c2d310, 0x00c2f310, - 0x00c31310, 0x00c33310, 0x00c35310, 0x00c37310, - 0x00c39310, 0x00c3b310, 0x00c3d310, 0x00c3f310, - 0x00c41310, 0x00c43310, 0x00c45310, 0x00c47310, - 0x00c49310, 0x00c4b310, 0x00c4d310, 0x00c4f310, - 0x00c51310, 0x00c53310, 0x00c55310, 0x00c57310, - 0x00c59310, 0x00c5b310, 0x00c5d310, 0x00c5f310, - 0x00c61310, 0x00c63310, 0x00c65310, 0x00c67310, - 0x00c69310, 0x00c6b310, 0x00c6d310, 0x00c6f310, - 0x00c71310, 0x00c73310, 0x00c75310, 0x00c77310, - 0x00c79310, 0x00c7b310, 0x00c7d310, 0x00c7f310, - 0x00c81310, 0x00c83310, 0x00c85310, 0x00c87310, - 0x00c89310, 0x00c8b310, 0x00c8d310, 0x00c8f310, - 0x00c91310, 0x00c93310, 0x00c95310, 0x00c97310, - 0x00c99310, 0x00c9b310, 0x00c9d310, 0x00c9f310, - 0x00ca1310, 0x00ca3310, 0x00ca5310, 0x00ca7310, - 0x00ca9310, 0x00cab310, 0x00cad310, 0x00caf310, - 0x00cb1310, 0x00cb3310, 0x00cb5310, 0x00cb7310, - 0x00cb9310, 0x00cbb310, 0x00cbd310, 0x00cbf310, - 0x00cc1310, 0x00cc3310, 0x00cc5310, 0x00cc7310, - 0x00cc9310, 0x00ccb310, 0x00ccd310, 0x00ccf310, - 0x00cd1310, 0x00cd3310, 0x00cd5310, 0x00cd7310, - 0x00cd9310, 0x00cdb310, 0x00cdd310, 0x00cdf310, - 0x00ce1310, 0x00ce3310, 0x00ce5310, 0x00ce7310, - 0x00ce9310, 0x00ceb310, 0x00ced310, 0x00cef310, - 0x00cf1310, 0x00cf3310, 0x00cf5310, 0x00cf7310, - 0x00cf9310, 0x00cfb310, 0x00cfd310, 0x00cff310, - 0x00d01310, 0x00d03310, 0x00d05310, 0x00d07310, - 0x00d09310, 0x00d0b310, 0x00d0d310, 0x00d0f310, - 0x00d11310, 0x00d13310, 0x00d15310, 0x00d17310, - 0x00d19310, 0x00d1b310, 0x00d1d310, 0x00d1f310, - 0x00d21310, 0x00d23310, 0x00d25310, 0x00d27310, - 0x00d29310, 0x00d2b310, 0x00d2d310, 0x00d2f310, - 0x00d31310, 0x00d33310, 0x00d35310, 0x00d37310, - 0x00d39310, 0x00d3b310, 0x00d3d310, 0x00d3f310, - 0x00d41310, 0x00d43310, 0x00d45310, 0x00d47310, - 0x00d49310, 0x00d4b310, 0x00d4d310, 0x00d4f310, - 0x00d51310, 0x00d53310, 0x00d55310, 0x00d57310, - 0x00d59310, 0x00d5b310, 0x00d5d310, 0x00d5f310, - 0x00d61310, 0x00d63310, 0x00d65310, 0x00d67310, - 0x00d69310, 0x00d6b310, 0x00d6d310, 0x00d6f310, - 0x00d71310, 0x00d73310, 0x00d75310, 0x00d77310, - 0x00d79310, 0x00d7b310, 0x00d7d310, 0x00d7f310, - 0x00d81310, 0x00d83310, 0x00d85310, 0x00d87310, - 0x00d89310, 0x00d8b310, 0x00d8d310, 0x00d8f310, - 0x00d91310, 0x00d93310, 0x00d95310, 0x00d97310, - 0x00d99310, 0x00d9b310, 0x00d9d310, 0x00d9f310, - 0x00da1310, 0x00da3310, 0x00da5310, 0x00da7310, - 0x00da9310, 0x00dab310, 0x00dad310, 0x00daf310, - 0x00db1310, 0x00db3310, 0x00db5310, 0x00db7310, - 0x00db9310, 0x00dbb310, 0x00dbd310, 0x00dbf310, - 0x00dc1310, 0x00dc3310, 0x00dc5310, 0x00dc7310, - 0x00dc9310, 0x00dcb310, 0x00dcd310, 0x00dcf310, - 0x00dd1310, 0x00dd3310, 0x00dd5310, 0x00dd7310, - 0x00dd9310, 0x00ddb310, 0x00ddd310, 0x00ddf310, - 0x00de1310, 0x00de3310, 0x00de5310, 0x00de7310, - 0x00de9310, 0x00deb310, 0x00ded310, 0x00def310, - 0x00df1310, 0x00df3310, 0x00df5310, 0x00df7310, - 0x00df9310, 0x00dfb310, 0x00dfd310, 0x00dff310, - 0x00e01310, 0x00e03310, 0x00e05310, 0x00e07310, - 0x00e09310, 0x00e0b310, 0x00e0d310, 0x00e0f310, - 0x00e11310, 0x00e13310, 0x00e15310, 0x00e17310, - 0x00e19310, 0x00e1b310, 0x00e1d310, 0x00e1f310, - 0x00e21310, 0x00e23310, 0x00e25310, 0x00e27310, - 0x00e29310, 0x00e2b310, 0x00e2d310, 0x00e2f310, - 0x00e31310, 0x00e33310, 0x00e35310, 0x00e37310, - 0x00e39310, 0x00e3b310, 0x00e3d310, 0x00e3f310, - 0x00e41310, 0x00e43310, 0x00e45310, 0x00e47310, - 0x00e49310, 0x00e4b310, 0x00e4d310, 0x00e4f310, - 0x00e51310, 0x00e53310, 0x00e55310, 0x00e57310, - 0x00e59310, 0x00e5b310, 0x00e5d310, 0x00e5f310, - 0x00e61310, 0x00e63310, 0x00e65310, 0x00e67310, - 0x00e69310, 0x00e6b310, 0x00e6d310, 0x00e6f310, - 0x00e71310, 0x00e73310, 0x00e75310, 0x00e77310, - 0x00e79310, 0x00e7b310, 0x00e7d310, 0x00e7f310, - 0x00e81310, 0x00e83310, 0x00e85310, 0x00e87310, - 0x00e89310, 0x00e8b310, 0x00e8d310, 0x00e8f310, - 0x00e91310, 0x00e93310, 0x00e95310, 0x00e97310, - 0x00e99310, 0x00e9b310, 0x00e9d310, 0x00e9f310, - 0x00ea1310, 0x00ea3310, 0x00ea5310, 0x00ea7310, - 0x00ea9310, 0x00eab310, 0x00ead310, 0x00eaf310, - 0x00eb1310, 0x00eb3310, 0x00eb5310, 0x00eb7310, - 0x00eb9310, 0x00ebb310, 0x00ebd310, 0x00ebf310, - 0x00ec1310, 0x00ec3310, 0x00ec5310, 0x00ec7310, - 0x00ec9310, 0x00ecb310, 0x00ecd310, 0x00ecf310, - 0x00ed1310, 0x00ed3310, 0x00ed5310, 0x00ed7310, - 0x00ed9310, 0x00edb310, 0x00edd310, 0x00edf310, - 0x00ee1310, 0x00ee3310, 0x00ee5310, 0x00ee7310, - 0x00ee9310, 0x00eeb310, 0x00eed310, 0x00eef310, - 0x00ef1310, 0x00ef3310, 0x00ef5310, 0x00ef7310, - 0x00ef9310, 0x00efb310, 0x00efd310, 0x00eff310, - 0x00f01310, 0x00f03310, 0x00f05310, 0x00f07310, - 0x00f09310, 0x00f0b310, 0x00f0d310, 0x00f0f310, - 0x00f11310, 0x00f13310, 0x00f15310, 0x00f17310, - 0x00f19310, 0x00f1b310, 0x00f1d310, 0x00f1f310, - 0x00f21310, 0x00f23310, 0x00f25310, 0x00f27310, - 0x00f29310, 0x00f2b310, 0x00f2d310, 0x00f2f310, - 0x00f31310, 0x00f33310, 0x00f35310, 0x00f37310, - 0x00f39310, 0x00f3b310, 0x00f3d310, 0x00f3f310, - 0x00f41310, 0x00f43310, 0x00f45310, 0x00f47310, - 0x00f49310, 0x00f4b310, 0x00f4d310, 0x00f4f310, - 0x00f51310, 0x00f53310, 0x00f55310, 0x00f57310, - 0x00f59310, 0x00f5b310, 0x00f5d310, 0x00f5f310, - 0x00f61310, 0x00f63310, 0x00f65310, 0x00f67310, - 0x00f69310, 0x00f6b310, 0x00f6d310, 0x00f6f310, - 0x00f71310, 0x00f73310, 0x00f75310, 0x00f77310, - 0x00f79310, 0x00f7b310, 0x00f7d310, 0x00f7f310, - 0x00f81310, 0x00f83310, 0x00f85310, 0x00f87310, - 0x00f89310, 0x00f8b310, 0x00f8d310, 0x00f8f310, - 0x00f91310, 0x00f93310, 0x00f95310, 0x00f97310, - 0x00f99310, 0x00f9b310, 0x00f9d310, 0x00f9f310, - 0x00fa1310, 0x00fa3310, 0x00fa5310, 0x00fa7310, - 0x00fa9310, 0x00fab310, 0x00fad310, 0x00faf310, - 0x00fb1310, 0x00fb3310, 0x00fb5310, 0x00fb7310, - 0x00fb9310, 0x00fbb310, 0x00fbd310, 0x00fbf310, - 0x00fc1310, 0x00fc3310, 0x00fc5310, 0x00fc7310, - 0x00fc9310, 0x00fcb310, 0x00fcd310, 0x00fcf310, - 0x00fd1310, 0x00fd3310, 0x00fd5310, 0x00fd7310, - 0x00fd9310, 0x00fdb310, 0x00fdd310, 0x00fdf310, - 0x00fe1310, 0x00fe3310, 0x00fe5310, 0x00fe7310, - 0x00fe9310, 0x00feb310, 0x00fed310, 0x00fef310, - 0x00ff1310, 0x00ff3310, 0x00ff5310, 0x00ff7310, - 0x00ff9310, 0x00ffb310, 0x00ffd310, 0x00fff310, -}; diff --git a/contrib/libzlib-ng/arch/x86/fill_window_sse.c b/contrib/libzlib-ng/arch/x86/fill_window_sse.c deleted file mode 100644 index d82b1d1bcb8..00000000000 --- a/contrib/libzlib-ng/arch/x86/fill_window_sse.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Fill Window with SSE2-optimized hash shifting - * - * Copyright (C) 2013 Intel Corporation - * Authors: - * Arjan van de Ven - * Jim Kukunas - * - * For conditions of distribution and use, see copyright notice in zlib.h - */ -#ifdef X86_SSE2_FILL_WINDOW - -#include -#include "deflate.h" - -extern int read_buf(z_stream *strm, unsigned char *buf, unsigned size); - -ZLIB_INTERNAL void fill_window_sse(deflate_state *s) { - const __m128i xmm_wsize = _mm_set1_epi16(s->w_size); - - register unsigned n; - register Pos *p; - unsigned more; /* Amount of free space at the end of the window. */ - unsigned int wsize = s->w_size; - - Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = (unsigned)(s->window_size -(unsigned long)s->lookahead -(unsigned long)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize+MAX_DIST(s)) { - memcpy(s->window, s->window+wsize, (unsigned)wsize); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - n = s->hash_size; - p = &s->head[n]; - p -= 8; - do { - __m128i value, result; - - value = _mm_loadu_si128((__m128i *)p); - result = _mm_subs_epu16(value, xmm_wsize); - _mm_storeu_si128((__m128i *)p, result); - - p -= 8; - n -= 8; - } while (n > 0); - - n = wsize; - p = &s->prev[n]; - p -= 8; - do { - __m128i value, result; - - value = _mm_loadu_si128((__m128i *)p); - result = _mm_subs_epu16(value, xmm_wsize); - _mm_storeu_si128((__m128i *)p, result); - - p -= 8; - n -= 8; - } while (n > 0); - more += wsize; - } - if (s->strm->avail_in == 0) break; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead + s->insert >= MIN_MATCH) { - unsigned int str = s->strstart - s->insert; - s->ins_h = s->window[str]; - if (str >= 1) - UPDATE_HASH(s, s->ins_h, str + 1 - (MIN_MATCH-1)); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - while (s->insert) { - UPDATE_HASH(s, s->ins_h, str); - s->prev[str & s->w_mask] = s->head[s->ins_h]; - s->head[s->ins_h] = (Pos)str; - str++; - s->insert--; - if (s->lookahead + s->insert < MIN_MATCH) - break; - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - if (s->high_water < s->window_size) { - unsigned long curr = s->strstart + (unsigned long)(s->lookahead); - unsigned long init; - - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT - * bytes or up to end of window, whichever is less. - */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - memset(s->window + curr, 0, (unsigned)init); - s->high_water = curr + init; - } else if (s->high_water < (unsigned long)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data - * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - * to end of window, whichever is less. - */ - init = (unsigned long)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - memset(s->window + s->high_water, 0, (unsigned)init); - s->high_water += init; - } - } - - Assert((unsigned long)s->strstart <= s->window_size - MIN_LOOKAHEAD, "not enough room for search"); -} -#endif diff --git a/contrib/libzlib-ng/arch/x86/insert_string_sse.c b/contrib/libzlib-ng/arch/x86/insert_string_sse.c deleted file mode 100644 index 6d4ddaea519..00000000000 --- a/contrib/libzlib-ng/arch/x86/insert_string_sse.c +++ /dev/null @@ -1,50 +0,0 @@ -/* insert_string_sse -- insert_string variant using SSE4.2's CRC instructions - * - * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - */ - -#include "deflate.h" - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * IN assertion: all calls to to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef X86_SSE4_2_CRC_HASH -Pos insert_string_sse(deflate_state *const s, const Pos str, unsigned int count) { - Pos ret = 0; - unsigned int idx; - unsigned *ip, val, h = 0; - - for (idx = 0; idx < count; idx++) { - ip = (unsigned *)&s->window[str+idx]; - val = *ip; - h = 0; - - if (s->level >= 6) - val &= 0xFFFFFF; - -#ifdef _MSC_VER - h = _mm_crc32_u32(h, val); -#else - __asm__ __volatile__ ( - "crc32 %1,%0\n\t" - : "+r" (h) - : "r" (val) - ); -#endif - - if (s->head[h & s->hash_mask] != str+idx) { - s->prev[(str+idx) & s->w_mask] = s->head[h & s->hash_mask]; - s->head[h & s->hash_mask] = str+idx; - } - } - ret = s->prev[(str+count-1) & s->w_mask]; - return ret; -} -#endif diff --git a/contrib/libzlib-ng/arch/x86/x86.c b/contrib/libzlib-ng/arch/x86/x86.c deleted file mode 100644 index c932627f163..00000000000 --- a/contrib/libzlib-ng/arch/x86/x86.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * x86 feature check - * - * Copyright (C) 2013 Intel Corporation. All rights reserved. - * Author: - * Jim Kukunas - * - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "x86.h" - -ZLIB_INTERNAL int x86_cpu_has_sse2; -ZLIB_INTERNAL int x86_cpu_has_sse42; -ZLIB_INTERNAL int x86_cpu_has_pclmulqdq; - -#ifdef _MSC_VER -#include -#else -// Newer versions of GCC and clang come with cpuid.h -#include -#endif - -static void cpuid(int info, unsigned* eax, unsigned* ebx, unsigned* ecx, unsigned* edx) { -#ifdef _MSC_VER - unsigned int registers[4]; - __cpuid(registers, info); - - *eax = registers[0]; - *ebx = registers[1]; - *ecx = registers[2]; - *edx = registers[3]; -#else - unsigned int _eax; - unsigned int _ebx; - unsigned int _ecx; - unsigned int _edx; - __cpuid(info, _eax, _ebx, _ecx, _edx); - *eax = _eax; - *ebx = _ebx; - *ecx = _ecx; - *edx = _edx; -#endif -} - -void ZLIB_INTERNAL x86_check_features(void) { - unsigned eax, ebx, ecx, edx; - cpuid(1 /*CPU_PROCINFO_AND_FEATUREBITS*/, &eax, &ebx, &ecx, &edx); - - x86_cpu_has_sse2 = edx & 0x4000000; - x86_cpu_has_sse42 = ecx & 0x100000; - x86_cpu_has_pclmulqdq = ecx & 0x2; -} diff --git a/contrib/libzlib-ng/arch/x86/x86.h b/contrib/libzlib-ng/arch/x86/x86.h deleted file mode 100644 index 78be0a661a1..00000000000 --- a/contrib/libzlib-ng/arch/x86/x86.h +++ /dev/null @@ -1,23 +0,0 @@ - /* cpu.h -- check for CPU features - * Copyright (C) 2013 Intel Corporation Jim Kukunas - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#ifndef CPU_H_ -#define CPU_H_ - -#if defined(HAVE_INTERNAL) -# define ZLIB_INTERNAL __attribute__((visibility ("internal"))) -#elif defined(HAVE_HIDDEN) -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -extern int x86_cpu_has_sse2; -extern int x86_cpu_has_sse42; -extern int x86_cpu_has_pclmulqdq; - -void ZLIB_INTERNAL x86_check_features(void); - -#endif /* CPU_H_ */ diff --git a/contrib/libzlib-ng/compress.c b/contrib/libzlib-ng/compress.c deleted file mode 100644 index 9f6f140298f..00000000000 --- a/contrib/libzlib-ng/compress.c +++ /dev/null @@ -1,74 +0,0 @@ -/* compress.c -- compress a memory buffer - * Copyright (C) 1995-2005, 2014 Jean-loup Gailly, Mark Adler. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least 0.1% larger than sourceLen plus - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ -int ZEXPORT compress2(unsigned char *dest, size_t *destLen, const unsigned char *source, - size_t sourceLen, int level) { - z_stream stream; - int err; - const unsigned int max = (unsigned int)0 - 1; - size_t left; - - left = *destLen; - *destLen = 0; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = NULL; - - err = deflateInit(&stream, level); - if (err != Z_OK) - return err; - - stream.next_out = dest; - stream.avail_out = 0; - stream.next_in = (const unsigned char *)source; - stream.avail_in = 0; - - do { - if (stream.avail_out == 0) { - stream.avail_out = left > (unsigned long)max ? max : (unsigned int)left; - left -= stream.avail_out; - } - if (stream.avail_in == 0) { - stream.avail_in = sourceLen > (unsigned long)max ? max : (unsigned int)sourceLen; - sourceLen -= stream.avail_in; - } - err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); - } while (err == Z_OK); - - *destLen = stream.total_out; - deflateEnd(&stream); - return err == Z_STREAM_END ? Z_OK : err; -} - -/* =========================================================================== - */ -int ZEXPORT compress(unsigned char *dest, size_t *destLen, const unsigned char *source, size_t sourceLen) { - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -size_t ZEXPORT compressBound(size_t sourceLen) { - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + (sourceLen >> 25) + 13; -} diff --git a/contrib/libzlib-ng/configure b/contrib/libzlib-ng/configure deleted file mode 100755 index de55744c6f2..00000000000 --- a/contrib/libzlib-ng/configure +++ /dev/null @@ -1,923 +0,0 @@ -#!/bin/sh -# configure script for zlib. -# -# Normally configure builds both a static and a shared library. -# If you want to build just a static library, use: ./configure --static -# -# To impose specific compiler or flags or install directory, use for example: -# prefix=$HOME CC=cc CFLAGS="-O4" ./configure -# or for csh/tcsh users: -# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure) - -# Incorrect settings of CC or CFLAGS may prevent creating a shared library. -# If you have problems, try without defining CC and CFLAGS before reporting -# an error. - -# start off configure.log -echo -------------------- >> configure.log -echo $0 $* >> configure.log -date >> configure.log - -SRCDIR=$(cd $(dirname $0); pwd) -BUILDDIR=$(pwd) - -# set command prefix for cross-compilation -if [ -n "${CHOST}" ]; then - uname="`echo "${CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/'`" - CROSS_PREFIX="${CHOST}-" - ARCH="`echo "${CHOST}" | sed -e 's/-.*//'`" -else - ARCH="`uname -m`" -fi - -case "${ARCH}" in - x86_64) - case "${CFLAGS}" in - *-m32*) - ARCH=i686 - ;; - esac - ;; - i386 | i486 | i586 | i686) - case "${CFLAGS}" in - *-m64*) - ARCH=x86_64 - ;; - esac - ;; -esac - -# destination name for static library -STATICLIB=libz.a - -# destination name for windows import library -IMPORTLIB= - -# extract zlib version numbers from zlib.h -VER=`sed -n -e '/ZLIB_VERSION "/s/.*"\(.*\)".*/\1/p' < ${SRCDIR}/zlib.h` -VER3=`sed -n -e '/ZLIB_VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\).*/\1/p' < ${SRCDIR}/zlib.h` -VER2=`sed -n -e '/ZLIB_VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < ${SRCDIR}/zlib.h` -VER1=`sed -n -e '/ZLIB_VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < ${SRCDIR}/zlib.h` - -# establish commands for library building -if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then - AR=${AR-"${CROSS_PREFIX}ar"} - test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log -else - AR=${AR-"ar"} - test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log -fi -ARFLAGS=${ARFLAGS-"rc"} -if "${CROSS_PREFIX}ranlib" --version >/dev/null 2>/dev/null || test $? -lt 126; then - RANLIB=${RANLIB-"${CROSS_PREFIX}ranlib"} - test -n "${CROSS_PREFIX}" && echo Using ${RANLIB} | tee -a configure.log -else - RANLIB=${RANLIB-"ranlib"} -fi -if "${CROSS_PREFIX}nm" --version >/dev/null 2>/dev/null || test $? -lt 126; then - NM=${NM-"${CROSS_PREFIX}nm"} - test -n "${CROSS_PREFIX}" && echo Using ${NM} | tee -a configure.log -else - NM=${NM-"nm"} -fi - -# set defaults before processing command line options -LDCONFIG=${LDCONFIG-"ldconfig"} -LDSHAREDLIBC="${LDSHAREDLIBC--lc}" -DEFFILE= -RC= -RCFLAGS= -RCOBJS= -STRIP= -ARCHS= -prefix=${prefix-/usr/local} -exec_prefix=${exec_prefix-'${prefix}'} -bindir=${bindir-'${exec_prefix}/bin'} -libdir=${libdir-'${exec_prefix}/lib'} -sharedlibdir=${sharedlibdir-'${libdir}'} -includedir=${includedir-'${prefix}/include'} -mandir=${mandir-'${prefix}/share/man'} -shared_ext='.so' -shared=1 -gzfileops=0 -compat=0 -cover=0 -build32=0 -build64=0 -without_optimizations=0 -without_new_strategies=0 -gcc=0 -old_cc="$CC" -old_cflags="$CFLAGS" -OBJC='$(OBJZ)' -PIC_OBJC='$(PIC_OBJZ)' -INSTALLTARGETS="install-shared install-static" -UNINSTALLTARGETS="uninstall-shared uninstall-static" - -TEST="teststatic" - -# leave this script, optionally in a bad way -leave() -{ - if test "$*" != "0"; then - echo "** $0 aborting." | tee -a configure.log - fi - rm -f $test.[co] $test $test$shared_ext $test.gcno ./--version - echo -------------------- >> configure.log - echo >> configure.log - echo >> configure.log - exit $1 -} - -# process command line options -while test $# -ge 1 -do -case "$1" in - -h* | --help) - echo 'usage:' | tee -a configure.log - echo ' configure [--zlib-compat] [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log - echo ' [--static] [--32] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log - echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log - exit 0 ;; - -p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;; - -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;; - -l*=* | --libdir=*) libdir=`echo $1 | sed 's/.*=//'`; shift ;; - --sharedlibdir=*) sharedlibdir=`echo $1 | sed 's/.*=//'`; shift ;; - -i*=* | --includedir=*) includedir=`echo $1 | sed 's/.*=//'`;shift ;; - -u*=* | --uname=*) uname=`echo $1 | sed 's/.*=//'`;shift ;; - -p* | --prefix) prefix="$2"; shift; shift ;; - -e* | --eprefix) exec_prefix="$2"; shift; shift ;; - -l* | --libdir) libdir="$2"; shift; shift ;; - -i* | --includedir) includedir="$2"; shift; shift ;; - -s* | --shared | --enable-shared) shared=1; shift ;; - -t | --static) shared=0; shift ;; - --zlib-compat) compat=1; shift ;; - --cover) cover=1; shift ;; - -3* | --32) build32=1; shift ;; - -6* | --64) build64=1; shift ;; - -a*=* | --archs=*) ARCHS=`echo $1 | sed 's/.*=//'`; shift ;; - --sysconfdir=*) echo "ignored option: --sysconfdir" | tee -a configure.log; shift ;; - --localstatedir=*) echo "ignored option: --localstatedir" | tee -a configure.log; shift ;; - -noopt | --without-optimizations) without_optimizations=1; shift;; - -oldstrat | --without-new-strategies) without_new_strategies=1; shift;; - *) - echo "unknown option: $1" | tee -a configure.log - echo "$0 --help for help" | tee -a configure.log - leave 1;; - esac -done - -# temporary file name -test=ztest$$ - -# put arguments in log, also put test file in log if used in arguments -show() -{ - case "$*" in - *$test.c*) - echo === $test.c === >> configure.log - cat $test.c >> configure.log - echo === >> configure.log;; - esac - echo $* >> configure.log -} - -# check for gcc vs. cc and set compile and link flags based on the system identified by uname -cat > $test.c <&1` in - *gcc*) gcc=1 ;; -esac - -show $cc -c $test.c -if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then - echo ... using gcc >> configure.log - CC="$cc" -# Re-check arch if gcc is a cross-compiler - GCC_ARCH=`$CC -dumpmachine | sed 's/-.*//g'` - case $GCC_ARCH in - i386 | i486 | i586 | i686) -# Honor user choice if gcc is multilib and 64-bit is requested - if test $build64 -eq 1; then - ARCH=x86_64 - else - ARCH=$GCC_ARCH - fi ;; -# Honor user choice if gcc is multilib and 32-bit is requested - x86_64) - if test $build32 -ne 1; then - ARCH=$GCC_ARCH - fi ;; - esac - CFLAGS="${CFLAGS--O3} ${ARCHS} -Wall" - SFLAGS="${CFLAGS--O3} -fPIC" - LDFLAGS="${LDFLAGS} ${ARCHS}" - if test $build64 -eq 1; then - CFLAGS="${CFLAGS} -m64" - SFLAGS="${SFLAGS} -m64" - fi - if test "${ZLIBGCCWARN}" = "YES"; then - CFLAGS="${CFLAGS} -Wextra -pedantic" - fi - if test -z "$uname"; then - uname=`(uname -s || echo unknown) 2>/dev/null` - fi - case "$uname" in - Linux* | linux* | GNU | GNU/* | solaris*) - LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,${SRCDIR}/zlib.map"} ;; - *BSD | *bsd* | DragonFly) - LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,${SRCDIR}/zlib.map"} - LDCONFIG="ldconfig -m" ;; - CYGWIN* | Cygwin* | cygwin*) - ARFLAGS="rcs" - CFLAGS="${CFLAGS} -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" - SFLAGS="${CFLAGS}" - shared_ext='.dll' - sharedlibdir='${bindir}' - SHAREDLIB=cygz$shared_ext - SHAREDLIBM='' - SHAREDLIBV='' - SHAREDTARGET=$SHAREDLIB - IMPORTLIB='libz.dll.a' - LDSHARED=${LDSHARED-"$cc -shared -Wl,--out-implib,${IMPORTLIB},--version-script,${SRCDIR}/zlib.map"} - LDSHAREDLIBC="" - DEFFILE='win32/zlib.def' - RC='windres' - RCFLAGS='--define GCC_WINDRES' - RCOBJS='zlibrc.o' - STRIP='strip' - EXE='.exe' ;; - MSYS* | msys*) - ARFLAGS="rcs" - SFLAGS="${CFLAGS}" - shared_ext='.dll' - sharedlibdir='${bindir}' - SHAREDLIB=msys-z$shared_ext - SHAREDLIBM='' - SHAREDLIBV='' - SHAREDTARGET=$SHAREDLIB - IMPORTLIB='libz.dll.a' - LDSHARED=${LDSHARED-"$cc -shared -Wl,--out-implib,${IMPORTLIB}"} - LDSHAREDLIBC="" - DEFFILE='win32/zlib.def' - RC='windres' - RCFLAGS='--define GCC_WINDRES' - RCOBJS='zlibrc.o' - STRIP='strip' - EXE='.exe' ;; - MINGW* | mingw*) - ARFLAGS="rcs" - CFLAGS="${CFLAGS} -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_POSIX_C_SOURCE=200809L -D_GNU_SOURCE=1" - SFLAGS="${CFLAGS}" - shared_ext='.dll' - sharedlibdir='${bindir}' - SHAREDLIB=libz-$VER1$shared_ext - SHAREDLIBM='' - SHAREDLIBV='' - SHAREDTARGET=$SHAREDLIB - IMPORTLIB='libz.dll.a' - LDSHARED=${LDSHARED-"$cc -shared -Wl,--out-implib=${IMPORTLIB} -Wl,--version-script=${SRCDIR}/zlib.map"} - LDSHAREDLIBC="" - DEFFILE='win32/zlib.def' - RC='windres' - RCFLAGS='--define GCC_WINDRES' - if [ "$CC" == "mingw32-gcc" ]; then - case $ARCH in - i386 | i486 | i586 | i686) RCFLAGS="${RCFLAGS} -F pe-i386";; - esac; - fi - RCOBJS='zlibrc.o' - STRIP='strip' - EXE='.exe' ;; - QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4 - # (alain.bonnefoy@icbt.com) - LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"} ;; - HP-UX*) - LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"} - case `(uname -m || echo unknown) 2>/dev/null` in - ia64) - shared_ext='.so' - SHAREDLIB='libz.so' ;; - *) - shared_ext='.sl' - SHAREDLIB='libz.sl' ;; - esac ;; - Darwin* | darwin*) - shared_ext='.dylib' - SHAREDLIB=libz$shared_ext - SHAREDLIBV=libz.$VER$shared_ext - SHAREDLIBM=libz.$VER1$shared_ext - SHAREDTARGET=$SHAREDLIBV - LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"} - if libtool -V 2>&1 | grep Apple > /dev/null; then - AR="libtool" - else - AR="/usr/bin/libtool" - fi - ARFLAGS="-o" ;; - *) LDSHARED=${LDSHARED-"$cc -shared"} ;; - esac -else - # find system name and corresponding cc options - CC=${CC-cc} - gcc=0 - echo ... using $CC >> configure.log - if test -z "$uname"; then - uname=`(uname -sr || echo unknown) 2>/dev/null` - fi - case "$uname" in - HP-UX*) SFLAGS=${CFLAGS-"-O +z"} - CFLAGS=${CFLAGS-"-O"} -# LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"} - LDSHARED=${LDSHARED-"ld -b"} - case `(uname -m || echo unknown) 2>/dev/null` in - ia64) - shared_ext='.so' - SHAREDLIB='libz.so' ;; - *) - shared_ext='.sl' - SHAREDLIB='libz.sl' ;; - esac ;; - AIX*) # Courtesy of dbakker@arrayasolutions.com - SFLAGS=${CFLAGS-"-O -qmaxmem=8192"} - CFLAGS=${CFLAGS-"-O -qmaxmem=8192"} - LDSHARED=${LDSHARED-"xlc -G"} ;; - # send working options for other systems to zlib@gzip.org - *) SFLAGS=${CFLAGS-"-O"} - CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -shared"} ;; - esac -fi - -# destination names for shared library if not defined above -SHAREDLIB=${SHAREDLIB-"libz$shared_ext"} -SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"} -SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"} -SHAREDTARGET=${SHAREDTARGET-"libz$shared_ext.$VER"} - -echo >> configure.log - -# define functions for testing compiler and library characteristics and logging the results - -cat > $test.c </dev/null; then - try() - { - show $* - test "`( $* ) 2>&1 | tee -a configure.log`" = "" - } - echo - using any output from compiler to indicate an error >> configure.log -else -try() -{ - show $* - ( $* ) >> configure.log 2>&1 - ret=$? - if test $ret -ne 0; then - echo "(exit code "$ret")" >> configure.log - fi - return $ret -} -fi - -tryboth() -{ - show $* - got=`( $* ) 2>&1` - ret=$? - printf %s "$got" >> configure.log - if test $ret -ne 0; then - return $ret - fi - test "$got" = "" -} - -cat > $test.c << EOF -int foo() { return 0; } -EOF -echo "Checking for obsessive-compulsive compiler options..." >> configure.log -if try $CC -c $CFLAGS $test.c; then - : -else - echo "Compiler error reporting is too harsh for $0 (perhaps remove -Werror)." | tee -a configure.log - leave 1 -fi - -echo >> configure.log - -# see if shared library build supported -cat > $test.c <> configure.log - -# check for large file support, and if none, check for fseeko() -cat > $test.c < -#ifdef __MSYS__ -# define off64_t _off64_t -#endif -off64_t dummy = 0; -EOF -if try $CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c; then - CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1" - SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1" - ALL="${ALL} all64" - TEST="${TEST} test64" - echo "Checking for off64_t... Yes." | tee -a configure.log - echo "Checking for fseeko... Yes." | tee -a configure.log -else - echo "Checking for off64_t... No." | tee -a configure.log - echo >> configure.log - cat > $test.c < -int main(void) { - fseeko(NULL, 0, 0); - return 0; -} -EOF - if try $CC $CFLAGS -o $test $test.c; then - echo "Checking for fseeko... Yes." | tee -a configure.log - else - CFLAGS="${CFLAGS} -DNO_FSEEKO" - SFLAGS="${SFLAGS} -DNO_FSEEKO" - echo "Checking for fseeko... No." | tee -a configure.log - fi -fi - -echo >> configure.log - -# check for strerror() for use by gz* functions -cat > $test.c < -#include -int main() { return strlen(strerror(errno)); } -EOF -if try $CC $CFLAGS -o $test $test.c; then - echo "Checking for strerror... Yes." | tee -a configure.log -else - CFLAGS="${CFLAGS} -DNO_STRERROR" - SFLAGS="${SFLAGS} -DNO_STRERROR" - echo "Checking for strerror... No." | tee -a configure.log -fi - -# We need to remove zconf.h from source directory if building outside of it -if [ "$SRCDIR" != "$BUILDDIR" ]; then rm -f $SRCDIR/zconf.h; fi - -# copy clean zconf.h for subsequent edits -cp -p $SRCDIR/zconf.h.in zconf.h - -echo >> configure.log - -# check for unistd.h and save result in zconf.h -cat > $test.c < -int main() { return 0; } -EOF -if try $CC -c $CFLAGS $test.c; then - sed < zconf.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be/ 1\1 was/" > zconf.temp.h - mv zconf.temp.h zconf.h - echo "Checking for unistd.h... Yes." | tee -a configure.log -else - echo "Checking for unistd.h... No." | tee -a configure.log -fi - -echo >> configure.log - -# check for stdarg.h and save result in zconf.h -cat > $test.c < -int main() { return 0; } -EOF -if try $CC -c $CFLAGS $test.c; then - sed < zconf.h "/^#ifdef HAVE_STDARG_H.* may be/s/def HAVE_STDARG_H\(.*\) may be/ 1\1 was/" > zconf.temp.h - mv zconf.temp.h zconf.h - echo "Checking for stdarg.h... Yes." | tee -a configure.log -else - echo "Checking for stdarg.h... No." | tee -a configure.log -fi - -# if --zlib-compat was requested -if test $compat -eq 1; then - CFLAGS="${CFLAGS} -DZLIB_COMPAT -DWITH_GZFILEOP" - SFLAGS="${SFLAGS} -DZLIB_COMPAT -DWITH_GZFILEOP" - OBJC="${OBJC} \$(OBJG)" - PIC_OBJC="${PIC_OBJC} \$(PIC_OBJG)" - case "$uname" in - CYGWIN* | Cygwin* | cygwin* | MSYS* | msys* | MINGW* | mingw*) - DEFFILE="win32/zlibcompat.def" ;; - esac -fi - -# if code coverage testing was requested, use older gcc if defined, e.g. "gcc-4.2" on Mac OS X -if test $cover -eq 1; then - CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage" - if test -n "$GCC_CLASSIC"; then - CC=$GCC_CLASSIC - fi -fi - -echo >> configure.log - -# Check for ANSI C compliant compiler -cat > $test.c < -#include -#include "zconf.h" -int main() -{ -#ifdef STDC - return 0; -#endif - return 1; -} -EOF -if try $CC -c $CFLAGS $test.c; then - echo "Checking for ANSI C compliant compiler... Yes." | tee -a configure.log - : -else - echo "Checking for ANSI C compliant compiler... No." | tee -a configure.log - echo "Error: ANSI C compatible compiler needed, cannot continue." | tee -a configure.log - leave 1 -fi - -# see if we can hide zlib internal symbols that are linked between separate source files using hidden -if test "$gcc" -eq 1; then - echo >> configure.log - cat > $test.c <> configure.log - echo "Checking for attribute(visibility(hidden)) support... Yes." | tee -a configure.log - else - echo >> configure.log - echo "Checking for attribute(visibility(hidden)) support... No." | tee -a configure.log - fi -fi - -# see if we can hide zlib internal symbols that are linked between separate source files using internal -if test "$gcc" -eq 1; then - echo >> configure.log - cat > $test.c <> configure.log - echo "Checking for attribute(visibility(internal)) support... Yes." | tee -a configure.log - else - echo >> configure.log - echo "Checking for attribute(visibility(internal)) support... No." | tee -a configure.log - fi -fi - -# Check for __builtin_ctzl() support in compiler -cat > $test.c << EOF -int main(void) -{ - unsigned int zero = 0; - long test = __builtin_ctzl(zero); - (void)test; - return 0; -} -EOF -if try ${CC} ${CFLAGS} $test.c; then - echo "Checking for __builtin_ctzl ... Yes." | tee -a configure.log - CFLAGS="$CFLAGS -DHAVE_BUILTIN_CTZL" - SFLAGS="$SFLAGS -DHAVE_BUILTIN_CTZL" -else - echo "Checking for __builtin_ctzl ... No." | tee -a configure.log -fi - -# Check for SSE2 intrinsics -cat > $test.c << EOF -#include -int main(void) -{ - __m128i zero = _mm_setzero_si128(); - (void)zero; - return 0; -} -EOF -if try ${CC} ${CFLAGS} -msse2 $test.c; then - echo "Checking for SSE2 intrinsics ... Yes." | tee -a configure.log - HAVE_SSE2_INTRIN=1 -else - echo "Checking for SSE2 intrinsics ... No." | tee -a configure.log - HAVE_SSE2_INTRIN=0 -fi - -# Check for PCLMULQDQ intrinsics -cat > $test.c << EOF -#include -#include -int main(void) -{ - __m128i a = _mm_setzero_si128(); - __m128i b = _mm_setzero_si128(); - __m128i c = _mm_clmulepi64_si128(a, b, 0x10); - (void)c; - return 0; -} -EOF -if try ${CC} ${CFLAGS} -mpclmul $test.c; then - echo "Checking for PCLMULQDQ intrinsics ... Yes." | tee -a configure.log - HAVE_PCLMULQDQ_INTRIN=1 -else - echo "Checking for PCLMULQDQ intrinsics ... No." | tee -a configure.log - HAVE_PCLMULQDQ_INTRIN=0 -fi - -# Enable deflate_medium at level 4-6 -if test $without_new_strategies -eq 0; then - CFLAGS="${CFLAGS} -DMEDIUM_STRATEGY" - SFLAGS="${SFLAGS} -DMEDIUM_STRATEGY" -fi - -ARCHDIR='arch/generic' -ARCH_STATIC_OBJS='' -ARCH_SHARED_OBJS='' - -# Set ARCH specific FLAGS -case "${ARCH}" in - - # x86 and x86_64 specific optimizations - i386 | i486 | i586 | i686 | x86_64) - ARCHDIR=arch/x86 - - case "${ARCH}" in - x86_64) - CFLAGS="${CFLAGS} -DX86_64 -DX86_NOCHECK_SSE2" - SFLAGS="${SFLAGS} -DX86_64 -DX86_NOCHECK_SSE2" - ;; - i386 | i486 | i586 | i686) - CFLAGS="${CFLAGS} -DX86" - SFLAGS="${SFLAGS} -DX86" - ;; - esac - - CFLAGS="${CFLAGS} -DUNALIGNED_OK -DUNROLL_LESS -DX86_CPUID" - SFLAGS="${SFLAGS} -DUNALIGNED_OK -DUNROLL_LESS -DX86_CPUID" - - # Enable arch-specific optimizations? - if test $without_optimizations -eq 0; then - ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} x86.o" - ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} x86.lo" - - if test ${HAVE_SSE2_INTRIN} -eq 1; then - CFLAGS="${CFLAGS} -DX86_SSE2_FILL_WINDOW" - SFLAGS="${SFLAGS} -DX86_SSE2_FILL_WINDOW" - ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} fill_window_sse.o" - ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} fill_window_sse.lo" - fi - - CFLAGS="${CFLAGS} -DX86_SSE4_2_CRC_HASH" - SFLAGS="${SFLAGS} -DX86_SSE4_2_CRC_HASH" - ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} insert_string_sse.o" - ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} insert_string_sse.lo" - - if test ${HAVE_PCLMULQDQ_INTRIN} -eq 1; then - CFLAGS="${CFLAGS} -DX86_PCLMULQDQ_CRC" - SFLAGS="${SFLAGS} -DX86_PCLMULQDQ_CRC" - ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc_folding.o" - ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc_folding.lo" - fi - - # Enable deflate_quick at level 1? - # requires SSE2: code uses fill_window_sse - if test ${HAVE_SSE2_INTRIN} -eq 1 && test $without_new_strategies -eq 0; then - CFLAGS="${CFLAGS} -DX86_QUICK_STRATEGY" - SFLAGS="${SFLAGS} -DX86_QUICK_STRATEGY" - - ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} deflate_quick.o" - ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} deflate_quick.lo" - fi - fi - ;; - - # ARM specific optimizations - armv3l | armv4b | armv4l | armv4tl | armv5tel | armv5tejl | armv6l | armv6hl | armv7l | armv7hl | armv7hnl) - ARCHDIR=arch/arm - - case "${ARCH}" in - armv6l | armv6hl) - # Tests done on Raspberry pi (armv6hl) indicate that UNALIGNED_OK and UNROLL_LESS both - # provide performance improvements, totaling about 1.5% for the two. - CFLAGS="${CFLAGS} -DUNALIGNED_OK -DUNROLL_LESS" - SFLAGS="${SFLAGS} -DUNALIGNED_OK -DUNROLL_LESS" - ;; - esac - - ;; -esac - -echo "ARCH: ${ARCH}" -echo "Using arch directory: ${ARCHDIR}" - -# show the results in the log -echo >> configure.log -echo ALL = $ALL >> configure.log -echo AR = $AR >> configure.log -echo ARFLAGS = $ARFLAGS >> configure.log -echo CC = $CC >> configure.log -echo CFLAGS = $CFLAGS >> configure.log -echo EXE = $EXE >> configure.log -echo LDCONFIG = $LDCONFIG >> configure.log -echo LDFLAGS = $LDFLAGS >> configure.log -echo LDSHARED = $LDSHARED >> configure.log -echo LDSHAREDLIBC = $LDSHAREDLIBC >> configure.log -echo DEFFILE = $DEFFILE >> configure.log -echo RC = $RC >> configure.log -echo RCFLAGS = $RCFLAGS >> configure.log -echo RCOBJS = $RCOBJS >> configure.log -echo STRIP = $STRIP >> configure.log -echo OBJC = $OBJC >> configure.log -echo PIC_OBJC = $PIC_OBJC >> configure.log -echo RANLIB = $RANLIB >> configure.log -echo SFLAGS = $SFLAGS >> configure.log -echo SHAREDLIB = $SHAREDLIB >> configure.log -echo SHAREDLIBM = $SHAREDLIBM >> configure.log -echo SHAREDLIBV = $SHAREDLIBV >> configure.log -echo SHAREDTARGET = $SHAREDTARGET >> configure.log -echo IMPORTLIB = $IMPORTLIB >> configure.log -echo INSTALLTARGETS = $INSTALLTARGETS >> configure.log -echo UNINSTALLTARGETS = $UNINSTALLTARGETS >> configure.log -echo SRCDIR = $SRCDIR >> configure.log -echo BUILDDIR = $BUILDDIR >> configure.log -echo STATICLIB = $STATICLIB >> configure.log -echo TEST = $TEST >> configure.log -echo VER = $VER >> configure.log -echo exec_prefix = $exec_prefix >> configure.log -echo includedir = $includedir >> configure.log -echo bindir = $bindir >> configure.log -echo libdir = $libdir >> configure.log -echo mandir = $mandir >> configure.log -echo prefix = $prefix >> configure.log -echo sharedlibdir = $sharedlibdir >> configure.log -echo uname = $uname >> configure.log -echo ARCHDIR = ${ARCHDIR} >> configure.log -echo ARCH_STATIC_OBJS = ${ARCH_STATIC_OBJS} >> configure.log -echo ARCH_SHARED_OBJS = ${ARCH_SHARED_OBJS} >> configure.log - -# update Makefile with the configure results - -INCLUDES="-I$SRCDIR" -if [ "$SRCDIR" != "$BUILDDIR" ]; then INCLUDES="-I$BUILDDIR ${INCLUDES}"; fi - -sed < $SRCDIR/Makefile.in " -/^CC *=/s#=.*#=$CC# -/^CFLAGS *=/s#=.*#=$CFLAGS# -/^SFLAGS *=/s#=.*#=$SFLAGS# -/^LDFLAGS *=/s#=.*#=$LDFLAGS# -/^LDSHARED *=/s#=.*#=$LDSHARED# -/^STATICLIB *=/s#=.*#=$STATICLIB# -/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# -/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# -/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# -/^SHAREDTARGET *=/s#=.*#=$SHAREDTARGET# -/^IMPORTLIB *=/s#=.*#=$IMPORTLIB# -/^AR *=/s#=.*#=$AR# -/^ARFLAGS *=/s#=.*#=$ARFLAGS# -/^RANLIB *=/s#=.*#=$RANLIB# -/^LDCONFIG *=/s#=.*#=$LDCONFIG# -/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC# -/^DEFFILE *=/s#=.*#=$DEFFILE# -/^RC *=/s#=.*#=$RC# -/^RCFLAGS *=/s#=.*#=$RCFLAGS# -/^RCOBJS *=/s#=.*#=$RCOBJS# -/^STRIP *=/s#=.*#=$STRIP# -/^EXE *=/s#=.*#=$EXE# -/^prefix *=/s#=.*#= $prefix# -/^exec_prefix *=/s#=.*#= $exec_prefix# -/^bindir *=/s#=.*#= $bindir# -/^libdir *=/s#=.*#= $libdir# -/^sharedlibdir *=/s#=.*#= $sharedlibdir# -/^includedir *=/s#=.*#= $includedir# -/^mandir *=/s#=.*#= $mandir# -/^SRCDIR *=/s#=.*#=$SRCDIR# -/^INCLUDES *=/s#=.*#=$INCLUDES# -/^OBJC *=/s#=.*#= $OBJC# -/^PIC_OBJC *=/s#=.*#= $PIC_OBJC# -/^all: */s#:.*#: $ALL# -/^install-libs: */s#:.*#: $INSTALLTARGETS# -/^uninstall-libs: */s#:.*#: $UNINSTALLTARGETS# -/^ARCHDIR *=/s#=.*#=$ARCHDIR# -/^ARCH_STATIC_OBJS *=/s#=.*#=$ARCH_STATIC_OBJS# -/^ARCH_SHARED_OBJS *=/s#=.*#=$ARCH_SHARED_OBJS# -" > Makefile - -# Generate Makefile in arch dir -mkdir -p $ARCHDIR - -ARCHINCLUDES="-I$SRCDIR/$ARCHDIR -I$SRCDIR" -if [ "$SRCDIR" != "$BUILDDIR" ]; then ARCHINCLUDES="-I$BUILDDIR ${ARCHINCLUDES}"; fi - -sed < $SRCDIR/$ARCHDIR/Makefile.in " -/^CC *=/s#=.*#=$CC# -/^CFLAGS *=/s#=.*#=$CFLAGS# -/^SFLAGS *=/s#=.*#=$SFLAGS# -/^INCLUDES *=/s#=.*#=$ARCHINCLUDES# -/^SRCDIR *=/s#=.*#=$SRCDIR/$ARCHDIR# -/^SRCTOP *=/s#=.*#=$SRCDIR# -" > $ARCHDIR/Makefile - -# Generate Makefile in test dir -mkdir -p test -TESTINCLUDES="-I$SRCDIR" -if [ "$SRCDIR" != "$BUILDDIR" ]; then TESTINCLUDES="${TESTINCLUDES} -I$BUILDDIR"; fi -if test $compat -eq 1; then COMPATTESTS="compattests"; fi -sed < $SRCDIR/test/Makefile.in " -/^CC *=/s#=.*#=$CC# -/^CFLAGS *=/s#=.*#=$CFLAGS# -/^EXE *=/s#=.*#=$EXE# -/^oldtests: */s#:.*#: $TEST# -/^INCLUDES *=/s#=.*#=$TESTINCLUDES# -/^SRCDIR *=/s#=.*#=$SRCDIR/test# -/^SRCTOP *=/s#=.*#=$SRCDIR# -/^COMPATTESTS *=/s#=.*#=$COMPATTESTS# -" > test/Makefile - -# create zlib.pc with the configure results -sed < $SRCDIR/zlib.pc.in " -/^CC *=/s#=.*#=$CC# -/^CFLAGS *=/s#=.*#=$CFLAGS# -/^LDSHARED *=/s#=.*#=$LDSHARED# -/^STATICLIB *=/s#=.*#=$STATICLIB# -/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# -/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# -/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# -/^IMPORTLIB *=/s#=.*#=$IMPORTLIB# -/^AR *=/s#=.*#=$AR# -/^ARFLAGS *=/s#=.*#=$ARFLAGS# -/^RANLIB *=/s#=.*#=$RANLIB# -/^EXE *=/s#=.*#=$EXE# -/^prefix *=/s#=.*#=$prefix# -/^exec_prefix *=/s#=.*#=$exec_prefix# -/^bindir *=/s#=.*#=$bindir# -/^libdir *=/s#=.*#=$libdir# -/^sharedlibdir *=/s#=.*#=$sharedlibdir# -/^includedir *=/s#=.*#=$includedir# -/^mandir *=/s#=.*#=$mandir# -/^LDFLAGS *=/s#=.*#=$LDFLAGS# -" | sed -e " -s/\@VERSION\@/$VER/g; -" > zlib.pc - -# done -leave 0 diff --git a/contrib/libzlib-ng/crc32.c b/contrib/libzlib-ng/crc32.c deleted file mode 100644 index 937f48d211e..00000000000 --- a/contrib/libzlib-ng/crc32.c +++ /dev/null @@ -1,458 +0,0 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - * Thanks to Rodney Brown for his contribution of faster - * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing - * tables for updating the shift register in one step with three exclusive-ors - * instead of four steps with four exclusive-ors. This results in about a - * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. - */ - -/* @(#) $Id$ */ - -#ifdef __MINGW32__ -# include -#elif defined(WIN32) || defined(_WIN32) -# define LITTLE_ENDIAN 1234 -# define BIG_ENDIAN 4321 -# if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64) -# define BYTE_ORDER LITTLE_ENDIAN -# else -# error Unknown endianness! -# endif -#elif __APPLE__ -# include -#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) -# include -#elif defined(__sun) || defined(sun) -# include -# if !defined(LITTLE_ENDIAN) -# define LITTLE_ENDIAN 4321 -# endif -# if !defined(BIG_ENDIAN) -# define BIG_ENDIAN 1234 -# endif -# if !defined(BYTE_ORDER) -# if defined(_BIG_ENDIAN) -# define BYTE_ORDER BIG_ENDIAN -# else -# define BYTE_ORDER LITTLE_ENDIAN -# endif -# endif -#else -# include -#endif - -/* - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore - protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should - first call get_crc_table() to initialize the tables before allowing more than - one thread to use crc32(). - - DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. - */ - -#ifdef MAKECRCH -# include -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ - -#include "deflate.h" - -#if BYTE_ORDER == LITTLE_ENDIAN -static uint32_t crc32_little(uint32_t, const unsigned char *, z_off64_t); -#elif BYTE_ORDER == BIG_ENDIAN -static uint32_t crc32_big(uint32_t, const unsigned char *, z_off64_t); -#endif - -/* Local functions for crc concatenation */ -static uint32_t gf2_matrix_times(uint32_t *mat, uint32_t vec); -static void gf2_matrix_square(uint32_t *square, uint32_t *mat); -static uint32_t crc32_combine_(uint32_t crc1, uint32_t crc2, z_off64_t len2); - - -#ifdef DYNAMIC_CRC_TABLE -static volatile int crc_table_empty = 1; -static uint32_t crc_table[8][256]; -static void make_crc_table(void); -#ifdef MAKECRCH -static void write_table(FILE *, const uint32_t *); -#endif /* MAKECRCH */ -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. - - The first table is simply the CRC of all possible eight bit values. This is - all the information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. The remaining tables - allow for word-at-a-time CRC calculation for both big-endian and little- - endian machines, where a word is four bytes. -*/ -static void make_crc_table() { - uint32_t c; - int n, k; - uint32_t poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static volatile int first = 1; /* flag to limit concurrent making */ - static const unsigned char p[] = {0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26}; - - /* See if another task is already doing this (not thread-safe, but better - than nothing -- significantly reduces duration of vulnerability in - case the advice about DYNAMIC_CRC_TABLE is ignored) */ - if (first) { - first = 0; - - /* make exclusive-or pattern from polynomial (0xedb88320) */ - poly = 0; - for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) - poly |= (uint32_t)1 << (31 - p[n]); - - /* generate a crc for every 8-bit value */ - for (n = 0; n < 256; n++) { - c = (uint32_t)n; - for (k = 0; k < 8; k++) - c = c & 1 ? poly ^ (c >> 1) : c >> 1; - crc_table[0][n] = c; - } - - /* generate crc for each value followed by one, two, and three zeros, - and then the byte reversal of those as well as the first table */ - for (n = 0; n < 256; n++) { - c = crc_table[0][n]; - crc_table[4][n] = ZSWAP32(c); - for (k = 1; k < 4; k++) { - c = crc_table[0][c & 0xff] ^ (c >> 8); - crc_table[k][n] = c; - crc_table[k + 4][n] = ZSWAP32(c); - } - } - - crc_table_empty = 0; - } else { /* not first */ - /* wait for the other guy to finish (not efficient, but rare) */ - while (crc_table_empty) - {} - } - -#ifdef MAKECRCH - /* write out CRC tables to crc32.h */ - { - FILE *out; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); - fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); - fprintf(out, "static const uint32_t "); - fprintf(out, "crc_table[8][256] =\n{\n {\n"); - write_table(out, crc_table[0]); - for (k = 1; k < 8; k++) { - fprintf(out, " },\n {\n"); - write_table(out, crc_table[k]); - } - fprintf(out, " }\n};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH -static void write_table(FILE *out, const uint32_t *table) { - int n; - - for (n = 0; n < 256; n++) - fprintf(out, "%s0x%08lx%s", n % 5 ? "" : " ", - (uint32_t)(table[n]), - n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); -} -#endif /* MAKECRCH */ - -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables of CRC-32s of all single-byte values, made by make_crc_table(). - */ -#include "crc32.h" -#endif /* DYNAMIC_CRC_TABLE */ - -/* ========================================================================= - * This function can be used by asm versions of crc32() - */ -const uint32_t * ZEXPORT get_crc_table(void) { -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - return (const uint32_t *)crc_table; -} - -/* ========================================================================= */ -#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) -#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 -#define DO4 DO1; DO1; DO1; DO1 - -/* ========================================================================= */ -uint32_t ZEXPORT crc32(uint32_t crc, const unsigned char *buf, z_off64_t len) { - if (buf == Z_NULL) return 0; - -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - - if (sizeof(void *) == sizeof(ptrdiff_t)) { -#if BYTE_ORDER == LITTLE_ENDIAN - return crc32_little(crc, buf, len); -#elif BYTE_ORDER == BIG_ENDIAN - return crc32_big(crc, buf, len); -#endif - } - crc = crc ^ 0xffffffff; - -#ifdef UNROLL_LESS - while (len >= 4) { - DO4; - len -= 4; - } -#else - while (len >= 8) { - DO8; - len -= 8; - } -#endif - - if (len) do { - DO1; - } while (--len); - return crc ^ 0xffffffff; -} - - -/* ========================================================================= */ -#if BYTE_ORDER == LITTLE_ENDIAN -#define DOLIT4 c ^= *buf4++; \ - c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ - crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] -#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 - -/* ========================================================================= */ -static uint32_t crc32_little(uint32_t crc, const unsigned char *buf, z_off64_t len) { - register uint32_t c; - register const uint32_t *buf4; - - c = crc; - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - len--; - } - - buf4 = (const uint32_t *)(const void *)buf; - -#ifndef UNROLL_LESS - while (len >= 32) { - DOLIT32; - len -= 32; - } -#endif - - while (len >= 4) { - DOLIT4; - len -= 4; - } - buf = (const unsigned char *)buf4; - - if (len) do { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - } while (--len); - c = ~c; - return c; -} -#endif /* BYTE_ORDER == LITTLE_ENDIAN */ - -/* ========================================================================= */ -#if BYTE_ORDER == BIG_ENDIAN -#define DOBIG4 c ^= *++buf4; \ - c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ - crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] -#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 - -/* ========================================================================= */ -static uint32_t crc32_big(uint32_t crc, const unsigned char *buf, z_off64_t len) { - register uint32_t c; - register const uint32_t *buf4; - - c = ZSWAP32(crc); - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - len--; - } - - buf4 = (const uint32_t *)(const void *)buf; - buf4--; - -#ifndef UNROLL_LESS - while (len >= 32) { - DOBIG32; - len -= 32; - } -#endif - - while (len >= 4) { - DOBIG4; - len -= 4; - } - buf4++; - buf = (const unsigned char *)buf4; - - if (len) do { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - } while (--len); - c = ~c; - return ZSWAP32(c); -} -#endif /* BYTE_ORDER == BIG_ENDIAN */ - - -#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ - -/* ========================================================================= */ -static uint32_t gf2_matrix_times(uint32_t *mat, uint32_t vec) { - uint32_t sum; - - sum = 0; - while (vec) { - if (vec & 1) - sum ^= *mat; - vec >>= 1; - mat++; - } - return sum; -} - -/* ========================================================================= */ -static void gf2_matrix_square(uint32_t *square, uint32_t *mat) { - int n; - - for (n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); -} - -/* ========================================================================= */ -static uint32_t crc32_combine_(uint32_t crc1, uint32_t crc2, z_off64_t len2) { - int n; - uint32_t row; - uint32_t even[GF2_DIM]; /* even-power-of-two zeros operator */ - uint32_t odd[GF2_DIM]; /* odd-power-of-two zeros operator */ - - /* degenerate case (also disallow negative lengths) */ - if (len2 <= 0) - return crc1; - - /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320; /* CRC-32 polynomial */ - row = 1; - for (n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } - - /* put operator for two zero bits in even */ - gf2_matrix_square(even, odd); - - /* put operator for four zero bits in odd */ - gf2_matrix_square(odd, even); - - /* apply len2 zeros to crc1 (first square will put the operator for one - zero byte, eight zero bits, in even) */ - do { - /* apply zeros operator for this bit of len2 */ - gf2_matrix_square(even, odd); - if (len2 & 1) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - if (len2 == 0) - break; - - /* another iteration of the loop with odd and even swapped */ - gf2_matrix_square(odd, even); - if (len2 & 1) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - return crc1; -} - -/* ========================================================================= */ -uint32_t ZEXPORT crc32_combine(uint32_t crc1, uint32_t crc2, z_off_t len2) { - return crc32_combine_(crc1, crc2, len2); -} - -uint32_t ZEXPORT crc32_combine64(uint32_t crc1, uint32_t crc2, z_off64_t len2) { - return crc32_combine_(crc1, crc2, len2); -} - - -#ifdef X86_PCLMULQDQ_CRC -#include "arch/x86/x86.h" -extern void ZLIB_INTERNAL crc_fold_init(deflate_state *const s); -extern void ZLIB_INTERNAL crc_fold_copy(deflate_state *const s, - unsigned char *dst, const unsigned char *src, long len); -extern uint32_t ZLIB_INTERNAL crc_fold_512to32(deflate_state *const s); -#endif - -ZLIB_INTERNAL void crc_reset(deflate_state *const s) { -#ifdef X86_PCLMULQDQ_CRC - if (x86_cpu_has_pclmulqdq) { - crc_fold_init(s); - return; - } -#endif - s->strm->adler = crc32(0L, Z_NULL, 0); -} - -ZLIB_INTERNAL void crc_finalize(deflate_state *const s) { -#ifdef X86_PCLMULQDQ_CRC - if (x86_cpu_has_pclmulqdq) - s->strm->adler = crc_fold_512to32(s); -#endif -} - -ZLIB_INTERNAL void copy_with_crc(z_stream *strm, unsigned char *dst, long size) { -#ifdef X86_PCLMULQDQ_CRC - if (x86_cpu_has_pclmulqdq) { - crc_fold_copy(strm->state, dst, strm->next_in, size); - return; - } -#endif - memcpy(dst, strm->next_in, size); - strm->adler = crc32(strm->adler, dst, size); -} - diff --git a/contrib/libzlib-ng/crc32.h b/contrib/libzlib-ng/crc32.h deleted file mode 100644 index d194d10b5ea..00000000000 --- a/contrib/libzlib-ng/crc32.h +++ /dev/null @@ -1,444 +0,0 @@ -#ifndef CRC32_H_ -#define CRC32_H_ - -/* crc32.h -- tables for rapid CRC calculation - * Generated automatically by crc32.c - */ - -static const uint32_t crc_table[8][256] = -{ - { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d - }, - { - 0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, - 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, - 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, - 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, - 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, - 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, - 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, - 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, - 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, - 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, - 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, - 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, - 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, - 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, - 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, - 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, - 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, - 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, - 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, - 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, - 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, - 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, - 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, - 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, - 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, - 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, - 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, - 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, - 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, - 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, - 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, - 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, - 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, - 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, - 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, - 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, - 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, - 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, - 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, - 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, - 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, - 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, - 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, - 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, - 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, - 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, - 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, - 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, - 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, - 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, - 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, - 0x9324fd72 - }, - { - 0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, - 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, - 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, - 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, - 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, - 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, - 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, - 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, - 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, - 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, - 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, - 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, - 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, - 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, - 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, - 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, - 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, - 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, - 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, - 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, - 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, - 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, - 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, - 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, - 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, - 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, - 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, - 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, - 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, - 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, - 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, - 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, - 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, - 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, - 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, - 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, - 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, - 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, - 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, - 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, - 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, - 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, - 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, - 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, - 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, - 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, - 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, - 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, - 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, - 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, - 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, - 0xbe9834ed - }, - { - 0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, - 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, - 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, - 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, - 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, - 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, - 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, - 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, - 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, - 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, - 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, - 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, - 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, - 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, - 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, - 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, - 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, - 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, - 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, - 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, - 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, - 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, - 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, - 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, - 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, - 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, - 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, - 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, - 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, - 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, - 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, - 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, - 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, - 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, - 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, - 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, - 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, - 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, - 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, - 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, - 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, - 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, - 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, - 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, - 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, - 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, - 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, - 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, - 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, - 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, - 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, - 0xde0506f1 - }, - { - 0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, - 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, - 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, - 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, - 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, - 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, - 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, - 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, - 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, - 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, - 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, - 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, - 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, - 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, - 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, - 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, - 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, - 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, - 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, - 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, - 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, - 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, - 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, - 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, - 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, - 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, - 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, - 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, - 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, - 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, - 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, - 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, - 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, - 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, - 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, - 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, - 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, - 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, - 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, - 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, - 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, - 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, - 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, - 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, - 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, - 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, - 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, - 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, - 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, - 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, - 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, - 0x8def022d - }, - { - 0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64, - 0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1, - 0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e, - 0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61, - 0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82, - 0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff, - 0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7, - 0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da, - 0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139, - 0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6, - 0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89, - 0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c, - 0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0, - 0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d, - 0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a, - 0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177, - 0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de, - 0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b, - 0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824, - 0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e, - 0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad, - 0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0, - 0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d, - 0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60, - 0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83, - 0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822, - 0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d, - 0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8, - 0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171, - 0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c, - 0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b, - 0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6, - 0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca, - 0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f, - 0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430, - 0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf, - 0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c, - 0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51, - 0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9, - 0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84, - 0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67, - 0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398, - 0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7, - 0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62, - 0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e, - 0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923, - 0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4, - 0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9, - 0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070, - 0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5, - 0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a, - 0x72fd2493 - }, - { - 0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907, - 0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f, - 0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a, - 0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e, - 0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512, - 0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14, - 0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b, - 0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d, - 0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731, - 0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925, - 0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620, - 0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28, - 0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70, - 0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176, - 0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d, - 0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b, - 0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b, - 0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63, - 0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266, - 0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a, - 0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446, - 0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40, - 0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557, - 0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51, - 0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d, - 0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0, - 0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5, - 0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed, - 0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd, - 0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb, - 0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0, - 0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6, - 0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de, - 0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6, - 0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3, - 0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7, - 0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb, - 0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd, - 0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92, - 0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094, - 0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598, - 0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c, - 0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489, - 0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81, - 0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9, - 0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af, - 0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4, - 0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2, - 0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2, - 0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba, - 0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf, - 0xed3498be - }, - { - 0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f, - 0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d, - 0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0, - 0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42, - 0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95, - 0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2, - 0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a, - 0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d, - 0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea, - 0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748, - 0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5, - 0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27, - 0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b, - 0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac, - 0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4, - 0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3, - 0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44, - 0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6, - 0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b, - 0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329, - 0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe, - 0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9, - 0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1, - 0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6, - 0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921, - 0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555, - 0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8, - 0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a, - 0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd, - 0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a, - 0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2, - 0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5, - 0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2, - 0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330, - 0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad, - 0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f, - 0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8, - 0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef, - 0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc, - 0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb, - 0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c, - 0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e, - 0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03, - 0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1, - 0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6, - 0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1, - 0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9, - 0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e, - 0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409, - 0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb, - 0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966, - 0xf10605de - } -}; - -#endif /* CRC32_H_ */ diff --git a/contrib/libzlib-ng/deflate.c b/contrib/libzlib-ng/deflate.c deleted file mode 100644 index fb275671777..00000000000 --- a/contrib/libzlib-ng/deflate.c +++ /dev/null @@ -1,1407 +0,0 @@ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://tools.ietf.org/html/rfc1951 - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id$ */ - -#include "deflate.h" -#include "deflate_p.h" -#include "match.h" - -const char deflate_copyright[] = " deflate 1.2.8.f Copyright 1995-2013 Jean-loup Gailly and Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ - -typedef block_state (*compress_func) (deflate_state *s, int flush); -/* Compression function. Returns the block state after the call. */ - -void fill_window (deflate_state *s); -local block_state deflate_stored (deflate_state *s, int flush); -block_state deflate_fast (deflate_state *s, int flush); -block_state deflate_quick (deflate_state *s, int flush); -#ifdef MEDIUM_STRATEGY -block_state deflate_medium (deflate_state *s, int flush); -#endif -block_state deflate_slow (deflate_state *s, int flush); -local block_state deflate_rle (deflate_state *s, int flush); -local block_state deflate_huff (deflate_state *s, int flush); -local void lm_init (deflate_state *s); -local void putShortMSB (deflate_state *s, uint16_t b); -ZLIB_INTERNAL void flush_pending (z_stream *strm); -ZLIB_INTERNAL int read_buf (z_stream *strm, unsigned char *buf, unsigned size); - -extern void crc_reset(deflate_state *const s); -extern void crc_finalize(deflate_state *const s); -extern void copy_with_crc(z_stream *strm, unsigned char *dst, long size); - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - uint16_t good_length; /* reduce lazy search above this match length */ - uint16_t max_lazy; /* do not perform lazy search above this match length */ - uint16_t nice_length; /* quit search above this match length */ - uint16_t max_chain; - compress_func func; -} config; - -local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ - -#ifdef X86_QUICK_STRATEGY -/* 1 */ {4, 4, 8, 4, deflate_quick}, -/* 2 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -#else -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -#endif - -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -#ifdef MEDIUM_STRATEGY -/* 4 */ {4, 4, 16, 16, deflate_medium}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_medium}, -/* 6 */ {8, 16, 128, 128, deflate_medium}, -#else -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -#endif - -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ -#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) - - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - memset((unsigned char *)s->head, 0, (unsigned)(s->hash_size-1)*sizeof(*s->head)); - -/* ========================================================================= */ -int ZEXPORT deflateInit_(z_stream *strm, int level, const char *version, int stream_size) { - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, version, stream_size); - /* Todo: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_(z_stream *strm, int level, int method, int windowBits, - int memLevel, int strategy, const char *version, int stream_size) { - unsigned window_padding = 0; - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - uint16_t *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - -#if defined(X86_SSE2_FILL_WINDOW) || defined(X86_SSE4_2_CRC_HASH) - x86_check_features(); -#endif - - if (version == Z_NULL || version[0] != my_version[0] || stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) - return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = NULL; - } - if (strm->zfree == (free_func)0) - strm->zfree = zcfree; - - if (level == Z_DEFAULT_COMPRESSION) - level = 6; - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; -#ifdef GZIP - } else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; -#endif - } - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 8 || - windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) - windowBits = 9; /* until 256-byte window bug fixed */ - -#ifdef X86_QUICK_STRATEGY - if (level == 1) - windowBits = 13; -#endif - - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) - return Z_MEM_ERROR; - strm->state = (struct internal_state *)s; - s->strm = strm; - - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - -#ifdef X86_SSE4_2_CRC_HASH - if (x86_cpu_has_sse42) - s->hash_bits = 15; - else -#endif - s->hash_bits = memLevel + 7; - - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - -#ifdef X86_PCLMULQDQ_CRC - window_padding = 8; -#endif - - s->window = (unsigned char *) ZALLOC(strm, s->w_size + window_padding, 2*sizeof(unsigned char)); - s->prev = (Pos *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Pos *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->high_water = 0; /* nothing written to s->window yet */ - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - overlay = (uint16_t *) ZALLOC(strm, s->lit_bufsize, sizeof(uint16_t)+2); - s->pending_buf = (unsigned char *) overlay; - s->pending_buf_size = (unsigned long)s->lit_bufsize * (sizeof(uint16_t)+2L); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = ERR_MSG(Z_MEM_ERROR); - deflateEnd(strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize/sizeof(uint16_t); - s->l_buf = s->pending_buf + (1+sizeof(uint16_t))*s->lit_bufsize; - - s->level = level; - s->strategy = strategy; - s->method = (unsigned char)method; - - return deflateReset(strm); -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary(z_stream *strm, const unsigned char *dictionary, unsigned int dictLength) { - deflate_state *s; - unsigned int str, n; - int wrap; - uint32_t avail; - const unsigned char *next; - - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) - return Z_STREAM_ERROR; - s = strm->state; - wrap = s->wrap; - if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) - return Z_STREAM_ERROR; - - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap == 1) - strm->adler = adler32(strm->adler, dictionary, dictLength); - s->wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s->w_size) { - if (wrap == 0) { /* already empty otherwise */ - CLEAR_HASH(s); - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - dictionary += dictLength - s->w_size; /* use the tail */ - dictLength = s->w_size; - } - - /* insert dictionary into window and hash */ - avail = strm->avail_in; - next = strm->next_in; - strm->avail_in = dictLength; - strm->next_in = (const unsigned char *)dictionary; - fill_window(s); - while (s->lookahead >= MIN_MATCH) { - str = s->strstart; - n = s->lookahead - (MIN_MATCH-1); - bulk_insert_str(s, str, n); - s->strstart = str + n; - s->lookahead = MIN_MATCH-1; - fill_window(s); - } - s->strstart += s->lookahead; - s->block_start = (long)s->strstart; - s->insert = s->lookahead; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - strm->next_in = next; - strm->avail_in = avail; - s->wrap = wrap; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateResetKeep(z_stream *strm) { - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = s->wrap ? INIT_STATE : BUSY_STATE; -#ifdef GZIP - strm->adler = s->wrap == 2 ? crc32(0L, Z_NULL, 0) : adler32(0L, Z_NULL, 0); -#else - strm->adler = adler32(0L, Z_NULL, 0); -#endif - s->last_flush = Z_NO_FLUSH; - - _tr_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset(z_stream *strm) { - int ret; - - ret = deflateResetKeep(strm); - if (ret == Z_OK) - lm_init(strm->state); - return ret; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetHeader(z_stream *strm, gz_headerp head) { - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - if (strm->state->wrap != 2) - return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePending(z_stream *strm, uint32_t *pending, int *bits) { - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - if (pending != Z_NULL) - *pending = strm->state->pending; - if (bits != Z_NULL) - *bits = strm->state->bi_valid; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime(z_stream *strm, int bits, int value) { - deflate_state *s; - int put; - - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - s = strm->state; - if ((unsigned char *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) - return Z_BUF_ERROR; - do { - put = Buf_size - s->bi_valid; - if (put > bits) - put = bits; - s->bi_buf |= (uint16_t)((value & ((1 << put) - 1)) << s->bi_valid); - s->bi_valid += put; - _tr_flush_bits(s); - value >>= put; - bits -= put; - } while (bits); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams(z_stream *strm, int level, int strategy) { - deflate_state *s; - compress_func func; - int err = Z_OK; - - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - s = strm->state; - - if (level == Z_DEFAULT_COMPRESSION) - level = 6; - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if ((strategy != s->strategy || func != configuration_table[level].func)) { - /* Flush the last buffer: */ - err = deflate(strm, Z_BLOCK); - if (err == Z_BUF_ERROR && s->pending == 0) - err = Z_OK; - } - if (s->level != level) { - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return err; -} - -/* ========================================================================= */ -int ZEXPORT deflateTune(z_stream *strm, int good_length, int max_lazy, int nice_length, int max_chain) { - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - s = strm->state; - s->good_match = good_length; - s->max_lazy_match = max_lazy; - s->nice_match = nice_length; - s->max_chain_length = max_chain; - return Z_OK; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns - * a close to exact, as well as small, upper bound on the compressed size. - * They are coded as constants here for a reason--if the #define's are - * changed, then this function needs to be changed as well. The return - * value for 15 and 8 only works for those exact settings. - * - * For any setting other than those defaults for windowBits and memLevel, - * the value returned is a conservative worst case for the maximum expansion - * resulting from using fixed blocks instead of stored blocks, which deflate - * can emit on compressed data for some combinations of the parameters. - * - * This function could be more sophisticated to provide closer upper bounds for - * every combination of windowBits and memLevel. But even the conservative - * upper bound of about 14% expansion does not seem onerous for output buffer - * allocation. - */ -unsigned long ZEXPORT deflateBound(z_stream *strm, unsigned long sourceLen) { - deflate_state *s; - unsigned long complen, wraplen; - unsigned char *str; - - /* conservative upper bound for compressed data */ - complen = sourceLen + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; - - /* if can't get parameters, return conservative bound plus zlib wrapper */ - if (strm == Z_NULL || strm->state == Z_NULL) - return complen + 6; - - /* compute wrapper length */ - s = strm->state; - switch (s->wrap) { - case 0: /* raw deflate */ - wraplen = 0; - break; - case 1: /* zlib wrapper */ - wraplen = 6 + (s->strstart ? 4 : 0); - break; - case 2: /* gzip wrapper */ - wraplen = 18; - if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ - if (s->gzhead->extra != Z_NULL) { - wraplen += 2 + s->gzhead->extra_len; - } - str = s->gzhead->name; - if (str != Z_NULL) { - do { - wraplen++; - } while (*str++); - } - str = s->gzhead->comment; - if (str != Z_NULL) { - do { - wraplen++; - } while (*str++); - } - if (s->gzhead->hcrc) - wraplen += 2; - } - break; - default: /* for compiler happiness */ - wraplen = 6; - } - - /* if not default parameters, return conservative bound */ - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return complen + wraplen; - - /* default settings: return tight bound for that case */ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + (sourceLen >> 25) + 13 - 6 + wraplen; -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB(deflate_state *s, uint16_t b) { - put_byte(s, (unsigned char)(b >> 8)); - put_byte(s, (unsigned char)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->next_out buffer and copying into it. - * (See also read_buf()). - */ -ZLIB_INTERNAL void flush_pending(z_stream *strm) { - uint32_t len; - deflate_state *s = strm->state; - - _tr_flush_bits(s); - len = s->pending; - if (len > strm->avail_out) - len = strm->avail_out; - if (len == 0) - return; - - memcpy(strm->next_out, s->pending_out, len); - strm->next_out += len; - s->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - s->pending -= len; - if (s->pending == 0) { - s->pending_out = s->pending_buf; - } -} - -/* ========================================================================= */ -int ZEXPORT deflate(z_stream *strm, int flush) { - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || flush > Z_BLOCK || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || (strm->avail_in != 0 && strm->next_in == Z_NULL) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) - ERR_RETURN(strm, Z_BUF_ERROR); - - s->strm = strm; /* just in case */ - old_flush = s->last_flush; - s->last_flush = flush; - - /* Write the header */ - if (s->status == INIT_STATE) { -#ifdef GZIP - if (s->wrap == 2) { - crc_reset(s); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == Z_NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - } else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) ); - put_byte(s, (unsigned char)(s->gzhead->time & 0xff)); - put_byte(s, (unsigned char)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (unsigned char)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (unsigned char)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != Z_NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } else -#endif - { - unsigned int header = (Z_DEFLATED + ((s->w_bits-8) << 4)) << 8; - unsigned int level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) - header |= PRESET_DICT; - header += 31 - (header % 31); - - s->status = BUSY_STATE; - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uint16_t)(strm->adler >> 16)); - putShortMSB(s, (uint16_t)strm->adler); - } - strm->adler = adler32(0L, Z_NULL, 0); - } - } -#ifdef GZIP - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != Z_NULL) { - uint32_t beg = s->pending; /* start of bytes to update crc */ - - while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) - break; - } - put_byte(s, s->gzhead->extra[s->gzindex]); - s->gzindex++; - } - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); - if (s->gzindex == s->gzhead->extra_len) { - s->gzindex = 0; - s->status = NAME_STATE; - } - } else { - s->status = NAME_STATE; - } - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != Z_NULL) { - uint32_t beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); - if (val == 0) { - s->gzindex = 0; - s->status = COMMENT_STATE; - } - } else { - s->status = COMMENT_STATE; - } - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != Z_NULL) { - uint32_t beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); - if (val == 0) - s->status = HCRC_STATE; - } else { - s->status = HCRC_STATE; - } - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) - flush_pending(strm); - if (s->pending + 2 <= s->pending_buf_size) { - put_byte(s, (unsigned char)(strm->adler & 0xff)); - put_byte(s, (unsigned char)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - } - } else { - s->status = BUSY_STATE; - } - } -#endif - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - -#ifdef X86_QUICK_STRATEGY - if (s->level == 1 && !x86_cpu_has_sse42) - bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - (s->strategy == Z_RLE ? deflate_rle(s, flush) : deflate_fast(s, flush)); - else -#endif - bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - (s->strategy == Z_RLE ? deflate_rle(s, flush) : (*(configuration_table[s->level].func))(s, flush)); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - if (s->lookahead == 0) { - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - Assert(strm->avail_out > 0, "bug2"); - - if (flush != Z_FINISH) - return Z_OK; - if (s->wrap <= 0) - return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - crc_finalize(s); - put_byte(s, (unsigned char)(strm->adler & 0xff)); - put_byte(s, (unsigned char)((strm->adler >> 8) & 0xff)); - put_byte(s, (unsigned char)((strm->adler >> 16) & 0xff)); - put_byte(s, (unsigned char)((strm->adler >> 24) & 0xff)); - put_byte(s, (unsigned char)(strm->total_in & 0xff)); - put_byte(s, (unsigned char)((strm->total_in >> 8) & 0xff)); - put_byte(s, (unsigned char)((strm->total_in >> 16) & 0xff)); - put_byte(s, (unsigned char)((strm->total_in >> 24) & 0xff)); - } else -#endif - { - putShortMSB(s, (uint16_t)(strm->adler >> 16)); - putShortMSB(s, (uint16_t)strm->adler); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) - s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd(z_stream *strm) { - int status; - - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - - status = strm->state->status; - if (status != INIT_STATE && - status != EXTRA_STATE && - status != NAME_STATE && - status != COMMENT_STATE && - status != HCRC_STATE && - status != BUSY_STATE && - status != FINISH_STATE) { - return Z_STREAM_ERROR; - } - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - */ -int ZEXPORT deflateCopy(z_stream *dest, z_stream *source) { - deflate_state *ds; - deflate_state *ss; - uint16_t *overlay; - - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - memcpy((void *)dest, (void *)source, sizeof(z_stream)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) - return Z_MEM_ERROR; - dest->state = (struct internal_state *) ds; - memcpy((void *)ds, (void *)ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (unsigned char *) ZALLOC(dest, ds->w_size, 2*sizeof(unsigned char)); - ds->prev = (Pos *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Pos *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (uint16_t *) ZALLOC(dest, ds->lit_bufsize, sizeof(uint16_t)+2); - ds->pending_buf = (unsigned char *) overlay; - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || ds->pending_buf == Z_NULL) { - deflateEnd(dest); - return Z_MEM_ERROR; - } - - memcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(unsigned char)); - memcpy((void *)ds->prev, (void *)ss->prev, ds->w_size * sizeof(Pos)); - memcpy((void *)ds->head, (void *)ss->head, ds->hash_size * sizeof(Pos)); - memcpy(ds->pending_buf, ss->pending_buf, (unsigned int)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize/sizeof(uint16_t); - ds->l_buf = ds->pending_buf + (1+sizeof(uint16_t))*ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -ZLIB_INTERNAL int read_buf(z_stream *strm, unsigned char *buf, unsigned size) { - uint32_t len = strm->avail_in; - - if (len > size) - len = size; - if (len == 0) - return 0; - - strm->avail_in -= len; - -#ifdef GZIP - if (strm->state->wrap == 2) - copy_with_crc(strm, buf, len); - else -#endif - { - memcpy(buf, strm->next_in, len); - if (strm->state->wrap == 1) - strm->adler = adler32(strm->adler, buf, len); - } - strm->next_in += len; - strm->total_in += len; - - return (int)len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init(deflate_state *s) { - s->window_size = (unsigned long)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->insert = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -} - -#ifdef DEBUG -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -void check_match(deflate_state *s, IPos start, IPos match, int length) { - /* check that the match is indeed a match */ - if (memcmp(s->window + match, s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr, "\\[%u,%d]", start-match, length); - do { - putc(s->window[start++], stderr); - } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* DEBUG */ - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -#ifdef X86_SSE2_FILL_WINDOW -extern void fill_window_sse(deflate_state *s); -#endif -void fill_window_c(deflate_state *s); - -void fill_window(deflate_state *s) { -#ifdef X86_SSE2_FILL_WINDOW -# ifndef X86_NOCHECK_SSE2 - if (x86_cpu_has_sse2) { -# endif - fill_window_sse(s); -# ifndef X86_NOCHECK_SSE2 - } else { - fill_window_c(s); - } -# endif - -#else - fill_window_c(s); -#endif -} - -void fill_window_c(deflate_state *s) { - register unsigned n; - register Pos *p; - unsigned more; /* Amount of free space at the end of the window. */ - unsigned int wsize = s->w_size; - - Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = (unsigned)(s->window_size -(unsigned long)s->lookahead -(unsigned long)s->strstart); - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize+MAX_DIST(s)) { - memcpy(s->window, s->window+wsize, (unsigned)wsize); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - n = s->hash_size; - p = &s->head[n]; -#ifdef NOT_TWEAK_COMPILER - do { - unsigned m; - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - } while (--n); -#else - /* As of I make this change, gcc (4.8.*) isn't able to vectorize - * this hot loop using saturated-subtraction on x86-64 architecture. - * To avoid this defect, we can change the loop such that - * o. the pointer advance forward, and - * o. demote the variable 'm' to be local to the loop, and - * choose type "Pos" (instead of 'unsigned int') for the - * variable to avoid unncessary zero-extension. - */ - { - unsigned int i; - Pos *q = p - n; - for (i = 0; i < n; i++) { - Pos m = *q; - Pos t = wsize; - *q++ = (Pos)(m >= t ? m-t: NIL); - } - } - -#endif /* NOT_TWEAK_COMPILER */ - n = wsize; - p = &s->prev[n]; -#ifdef NOT_TWEAK_COMPILER - do { - unsigned m; - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#else - { - unsigned int i; - Pos *q = p - n; - for (i = 0; i < n; i++) { - Pos m = *q; - Pos t = wsize; - *q++ = (Pos)(m >= t ? m-t: NIL); - } - } -#endif /* NOT_TWEAK_COMPILER */ - more += wsize; - } - if (s->strm->avail_in == 0) - break; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead + s->insert >= MIN_MATCH) { - unsigned int str = s->strstart - s->insert; - s->ins_h = s->window[str]; - if (str >= 1) - UPDATE_HASH(s, s->ins_h, str + 1 - (MIN_MATCH-1)); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - while (s->insert) { - UPDATE_HASH(s, s->ins_h, str); - s->prev[str & s->w_mask] = s->head[s->ins_h]; - s->head[s->ins_h] = (Pos)str; - str++; - s->insert--; - if (s->lookahead + s->insert < MIN_MATCH) - break; - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - if (s->high_water < s->window_size) { - unsigned long curr = s->strstart + (unsigned long)(s->lookahead); - unsigned long init; - - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT - * bytes or up to end of window, whichever is less. - */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - memset(s->window + curr, 0, (unsigned)init); - s->high_water = curr + init; - } else if (s->high_water < (unsigned long)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data - * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - * to end of window, whichever is less. - */ - init = (unsigned long)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - memset(s->window + s->high_water, 0, (unsigned)init); - s->high_water += init; - } - } - - Assert((unsigned long)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "not enough room for search"); -} - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. - */ -local block_state deflate_stored(deflate_state *s, int flush) { - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: - */ - unsigned long max_block_size = 0xffff; - unsigned long max_start; - - if (max_block_size > s->pending_buf_size - 5) { - max_block_size = (uint32_t)(s->pending_buf_size - 5); - } - - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s->lookahead <= 1) { - Assert(s->strstart < s->w_size+MAX_DIST(s) || s->block_start >= (long)s->w_size, "slide too late"); - - fill_window(s); - if (s->lookahead == 0 && flush == Z_NO_FLUSH) - return need_more; - - if (s->lookahead == 0) - break; /* flush the current block */ - } - Assert(s->block_start >= 0L, "block gone"); - - s->strstart += s->lookahead; - s->lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - max_start = s->block_start + max_block_size; - if (s->strstart == 0 || (unsigned long)s->strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s->lookahead = (unsigned int)(s->strstart - max_start); - s->strstart = (unsigned int)max_start; - FLUSH_BLOCK(s, 0); - } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: - */ - if (s->strstart - (unsigned int)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); - } - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if ((long)s->strstart > s->block_start) - FLUSH_BLOCK(s, 0); - return block_done; -} - - -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -local block_state deflate_rle(deflate_state *s, int flush) { - int bflush; /* set if current block must be flushed */ - unsigned int prev; /* byte at distance one to match */ - unsigned char *scan, *strend; /* scan goes up to strend for length of run */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s->lookahead <= MAX_MATCH) { - fill_window(s); - if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) - break; /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s->match_length = 0; - if (s->lookahead >= MIN_MATCH && s->strstart > 0) { - scan = s->window + s->strstart - 1; - prev = *scan; - if (prev == *++scan && prev == *++scan && prev == *++scan) { - strend = s->window + s->strstart + MAX_MATCH; - do { - } while (prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - scan < strend); - s->match_length = MAX_MATCH - (int)(strend - scan); - if (s->match_length > s->lookahead) - s->match_length = s->lookahead; - } - Assert(scan <= s->window+(unsigned int)(s->window_size-1), "wild scan"); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, s->match_length); - - _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - s->strstart += s->match_length; - s->match_length = 0; - } else { - /* No match, output a literal byte */ - Tracevv((stderr, "%c", s->window[s->strstart])); - _tr_tally_lit(s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) - FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} - -/* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ -local block_state deflate_huff(deflate_state *s, int flush) { - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s->lookahead == 0) { - fill_window(s); - if (s->lookahead == 0) { - if (flush == Z_NO_FLUSH) - return need_more; - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s->match_length = 0; - Tracevv((stderr, "%c", s->window[s->strstart])); - _tr_tally_lit(s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - if (bflush) - FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} diff --git a/contrib/libzlib-ng/deflate.h b/contrib/libzlib-ng/deflate.h deleted file mode 100644 index 2d3202641d8..00000000000 --- a/contrib/libzlib-ng/deflate.h +++ /dev/null @@ -1,459 +0,0 @@ -#ifndef DEFLATE_H_ -#define DEFLATE_H_ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2012 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer creation by deflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip encoding - should be left enabled. */ -#ifndef NO_GZIP -# define GZIP -#endif - -#define NIL 0 -/* Tail of hash chains */ - - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define Buf_size 16 -/* size of bit buffer in bi_buf */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define INIT_STATE 42 -#define EXTRA_STATE 69 -#define NAME_STATE 73 -#define COMMENT_STATE 91 -#define HCRC_STATE 103 -#define BUSY_STATE 113 -#define FINISH_STATE 666 -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - uint16_t freq; /* frequency count */ - uint16_t code; /* bit string */ - } fc; - union { - uint16_t dad; /* father node in Huffman tree */ - uint16_t len; /* length of bit string */ - } dl; -} ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - const static_tree_desc *stat_desc; /* the corresponding static tree */ -} tree_desc; - -typedef uint16_t Pos; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct internal_state { - z_stream *strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - unsigned char *pending_buf; /* output still pending */ - unsigned long pending_buf_size; /* size of pending_buf */ - unsigned char *pending_out; /* next pending byte to output to the stream */ - unsigned int pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - gz_headerp gzhead; /* gzip header information to write */ - unsigned int gzindex; /* where in extra, name, or comment */ - unsigned char method; /* can only be DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - -#ifdef X86_PCLMULQDQ_CRC - unsigned ALIGNED_(16) crc0[4 * 5]; -#endif - - /* used by deflate.c: */ - - unsigned int w_size; /* LZ77 window size (32K by default) */ - unsigned int w_bits; /* log2(w_size) (8..16) */ - unsigned int w_mask; /* w_size - 1 */ - - unsigned char *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - unsigned long window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Pos *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Pos *head; /* Heads of the hash chains or NIL. */ - - unsigned int ins_h; /* hash index of string to be inserted */ - unsigned int hash_size; /* number of elements in hash table */ - unsigned int hash_bits; /* log2(hash_size) */ - unsigned int hash_mask; /* hash_size-1 */ - - unsigned int hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - unsigned int match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - unsigned int strstart; /* start of string to insert */ - unsigned int match_start; /* start of matching string */ - unsigned int lookahead; /* number of valid bytes ahead in window */ - - unsigned int prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - unsigned int max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - unsigned int max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - unsigned int good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to suppress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - uint16_t bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - unsigned char depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - unsigned char *l_buf; /* buffer for literals or lengths */ - - unsigned int lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - unsigned int last_lit; /* running index in l_buf */ - - uint16_t *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - unsigned long opt_len; /* bit length of current block with optimal trees */ - unsigned long static_len; /* bit length of current block with static trees */ - unsigned int matches; /* number of string matches in current block */ - unsigned int insert; /* bytes at end of window left to insert */ - -#ifdef DEBUG - unsigned long compressed_len; /* total bit length of compressed file mod 2^32 */ - unsigned long bits_sent; /* bit length of compressed data sent mod 2^32 */ -#endif - - uint16_t bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - unsigned long high_water; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ -} deflate_state; - -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#if defined(__x86_64) || defined(__i386_) -/* Compared to the else-clause's implementation, there are few advantages: - * - s->pending is loaded only once (else-clause's implementation needs to - * load s->pending twice due to the alias between s->pending and - * s->pending_buf[]. - * - no instructions for extracting bytes from short. - * - needs less registers - * - stores to adjacent bytes are merged into a single store, albeit at the - * cost of penalty of potentially unaligned access. - */ -#define put_short(s, w) { \ - s->pending += 2; \ - *(uint16_t*)(&s->pending_buf[s->pending - 2]) = (w) ; \ -} -#else -#define put_short(s, w) { \ - put_byte(s, (unsigned char)((w) & 0xff)); \ - put_byte(s, (unsigned char)((uint16_t)(w) >> 8)); \ -} -#endif - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - -#define WIN_INIT MAX_MATCH -/* Number of bytes after end of data in window to initialize in order to avoid - memory checker errors from longest match routines */ - - /* in trees.c */ -void ZLIB_INTERNAL _tr_init(deflate_state *s); -int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc); -void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, char *buf, unsigned long stored_len, int last); -void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s); -void ZLIB_INTERNAL _tr_align(deflate_state *s); -void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, char *buf, unsigned long stored_len, int last); -void ZLIB_INTERNAL bi_windup(deflate_state *s); - -#define d_code(dist) ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. _dist_code[256] and _dist_code[257] are never - * used. - */ - -#ifndef DEBUG -/* Inline versions of _tr_tally for speed: */ - -# if defined(GEN_TREES_H) - extern unsigned char ZLIB_INTERNAL _length_code[]; - extern unsigned char ZLIB_INTERNAL _dist_code[]; -# else - extern const unsigned char ZLIB_INTERNAL _length_code[]; - extern const unsigned char ZLIB_INTERNAL _dist_code[]; -# endif - -# define _tr_tally_lit(s, c, flush) \ - { unsigned char cc = (c); \ - s->d_buf[s->last_lit] = 0; \ - s->l_buf[s->last_lit++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { unsigned char len = (length); \ - uint16_t dist = (distance); \ - s->d_buf[s->last_lit] = dist; \ - s->l_buf[s->last_lit++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -#else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) -#endif - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. - */ -#ifdef X86_SSE4_2_CRC_HASH -#define UPDATE_HASH(s, h, i) \ - do {\ - if (s->level < 6) \ - h = (3483 * (s->window[i]) +\ - 23081* (s->window[i+1]) +\ - 6954 * (s->window[i+2]) +\ - 20947* (s->window[i+3])) & s->hash_mask;\ - else\ - h = (25881* (s->window[i]) +\ - 24674* (s->window[i+1]) +\ - 25811* (s->window[i+2])) & s->hash_mask;\ - } while (0) -#else -# define UPDATE_HASH(s, h, i) (h = (((h) << s->hash_shift) ^ (s->window[i + (MIN_MATCH-1)])) & s->hash_mask) -#endif - -#ifndef DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) -/* Send a code of the given tree. c and tree must not have side effects */ - -#else /* DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose > 2) { \ - fprintf(stderr, "\ncd %3d ", (c)); \ - } \ - send_bits(s, tree[c].Code, tree[c].Len); \ - } -#endif - -#ifdef DEBUG -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -local void send_bits(deflate_state *s, int value, int length) { - Tracevv((stderr, " l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (unsigned long)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (uint16_t)value << s->bi_valid; - put_short(s, s->bi_buf); - s->bi_buf = (uint16_t)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= (uint16_t)value << s->bi_valid; - s->bi_valid += length; - } -} -#else -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ - s->bi_buf |= (uint16_t)val << s->bi_valid;\ - put_short(s, s->bi_buf);\ - s->bi_buf = (uint16_t)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (uint16_t)(value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif - -#endif /* DEFLATE_H_ */ diff --git a/contrib/libzlib-ng/deflate_fast.c b/contrib/libzlib-ng/deflate_fast.c deleted file mode 100644 index edfe53d7f7d..00000000000 --- a/contrib/libzlib-ng/deflate_fast.c +++ /dev/null @@ -1,114 +0,0 @@ -/* deflate_fast.c -- compress data using the fast strategy of deflation algorithm - * - * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "deflate.h" -#include "deflate_p.h" -#include "match.h" - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -block_state deflate_fast(deflate_state *s, int flush) { - IPos hash_head; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) - break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - hash_head = insert_string(s, s->strstart); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match(s, hash_head); - /* longest_match() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ - if (s->match_length <= s->max_insert_length && s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - s->strstart++; -#ifdef NOT_TWEAK_COMPILER - do { - insert_string(s, s->strstart); - s->strstart++; - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); -#else - { - bulk_insert_str(s, s->strstart, s->match_length); - s->strstart += s->match_length; - s->match_length = 0; - } -#endif - } else { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->strstart+2 - (MIN_MATCH)); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr, "%c", s->window[s->strstart])); - _tr_tally_lit(s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) - FLUSH_BLOCK(s, 0); - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} diff --git a/contrib/libzlib-ng/deflate_medium.c b/contrib/libzlib-ng/deflate_medium.c deleted file mode 100644 index 731b8a26850..00000000000 --- a/contrib/libzlib-ng/deflate_medium.c +++ /dev/null @@ -1,322 +0,0 @@ -/* deflate_medium.c -- The deflate_medium deflate strategy - * - * Copyright (C) 2013 Intel Corporation. All rights reserved. - * Authors: - * Arjan van de Ven - * - * For conditions of distribution and use, see copyright notice in zlib.h - */ -#ifdef MEDIUM_STRATEGY -#include "deflate.h" -#include "deflate_p.h" -#include "match.h" - -struct match { - unsigned int match_start; - unsigned int match_length; - unsigned int strstart; - unsigned int orgstart; -}; - -#define MAX_DIST2 ((1 << MAX_WBITS) - MIN_LOOKAHEAD) - -static int tr_tally_dist(deflate_state *s, int distance, int length) { - return _tr_tally(s, distance, length); -} - -static int tr_tally_lit(deflate_state *s, int c) { - return _tr_tally(s, 0, c); -} - -static int emit_match(deflate_state *s, struct match match) { - int flush = 0; - - /* matches that are not long enough we need to emit as litterals */ - if (match.match_length < MIN_MATCH) { - while (match.match_length) { - flush += tr_tally_lit(s, s->window[match.strstart]); - s->lookahead--; - match.strstart++; - match.match_length--; - } - return flush; - } - - check_match(s, match.strstart, match.match_start, match.match_length); - - flush += tr_tally_dist(s, match.strstart - match.match_start, match.match_length - MIN_MATCH); - - s->lookahead -= match.match_length; - return flush; -} - -static void insert_match(deflate_state *s, struct match match) { - if (unlikely(s->lookahead <= match.match_length + MIN_MATCH)) - return; - - /* matches that are not long enough we need to emit as litterals */ - if (match.match_length < MIN_MATCH) { -#ifdef NOT_TWEAK_COMPILER - while (match.match_length) { - match.strstart++; - match.match_length--; - - if (match.match_length) { - if (match.strstart >= match.orgstart) { - insert_string(s, match.strstart); - } - } - } -#else - if (likely(match.match_length == 1)) { - match.strstart++; - match.match_length = 0; - }else{ - match.strstart++; - match.match_length--; - if (match.strstart >= match.orgstart) { - bulk_insert_str(s, match.strstart, match.match_length); - } - match.strstart += match.match_length; - match.match_length = 0; - } -#endif - return; - } - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ - if (match.match_length <= 16* s->max_insert_length && s->lookahead >= MIN_MATCH) { - match.match_length--; /* string at strstart already in table */ - match.strstart++; -#ifdef NOT_TWEAK_COMPILER - do { - if (likely(match.strstart >= match.orgstart)) { - insert_string(s, match.strstart); - } - match.strstart++; - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--match.match_length != 0); -#else - if (likely(match.strstart >= match.orgstart)) { - bulk_insert_str(s, match.strstart, match.match_length); - } - match.strstart += match.match_length; - match.match_length = 0; -#endif - } else { - match.strstart += match.match_length; - match.match_length = 0; - s->ins_h = s->window[match.strstart]; - if (match.strstart >= 1) - UPDATE_HASH(s, s->ins_h, match.strstart+2-MIN_MATCH); -#if MIN_MATCH != 3 -#warning Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } -} - -static void fizzle_matches(deflate_state *s, struct match *current, struct match *next) { - IPos limit; - unsigned char *match, *orig; - int changed = 0; - struct match c, n; - /* step zero: sanity checks */ - - if (current->match_length <= 1) - return; - - if (unlikely(current->match_length > 1 + next->match_start)) - return; - - if (unlikely(current->match_length > 1 + next->strstart)) - return; - - match = s->window - current->match_length + 1 + next->match_start; - orig = s->window - current->match_length + 1 + next->strstart; - - /* quick exit check.. if this fails then don't bother with anything else */ - if (likely(*match != *orig)) - return; - - /* check the overlap case and just give up. We can do better in theory, - * but unlikely to be worth it - */ - if (next->match_start + next->match_length >= current->strstart) - return; - - c = *current; - n = *next; - - /* step one: try to move the "next" match to the left as much as possible */ - limit = next->strstart > MAX_DIST2 ? next->strstart - MAX_DIST2 : 0; - - match = s->window + n.match_start - 1; - orig = s->window + n.strstart - 1; - - while (*match == *orig) { - if (c.match_length < 1) - break; - if (n.strstart <= limit) - break; - if (n.match_length >= 256) - break; - if (n.match_start <= 0) - break; - - n.strstart--; - n.match_start--; - n.match_length++; - c.match_length--; - match--; - orig--; - changed++; - } - - if (!changed) - return; - - if (c.match_length <= 1 && n.match_length != 2) { - n.orgstart++; - *current = c; - *next = n; - } else { - return; - } -} - -block_state deflate_medium(deflate_state *s, int flush) { - struct match current_match, next_match; - - memset(¤t_match, 0, sizeof(struct match)); - memset(&next_match, 0, sizeof(struct match)); - - for (;;) { - IPos hash_head = 0; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next current_match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) - break; /* flush the current block */ - next_match.match_length = 0; - } - s->prev_length = 2; - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - - /* If we already have a future match from a previous round, just use that */ - if (next_match.match_length > 0) { - current_match = next_match; - next_match.match_length = 0; - - } else { - hash_head = 0; - if (s->lookahead >= MIN_MATCH) { - hash_head = insert_string(s, s->strstart); - } - - /* set up the initial match to be a 1 byte literal */ - current_match.match_start = 0; - current_match.match_length = 1; - current_match.strstart = s->strstart; - current_match.orgstart = current_match.strstart; - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - - if (hash_head != 0 && s->strstart - hash_head <= MAX_DIST2) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - current_match.match_length = longest_match(s, hash_head); - current_match.match_start = s->match_start; - if (current_match.match_length < MIN_MATCH) - current_match.match_length = 1; - if (current_match.match_start >= current_match.strstart) { - /* this can happen due to some restarts */ - current_match.match_length = 1; - } - } - } - - insert_match(s, current_match); - - /* now, look ahead one */ - if (s->lookahead > MIN_LOOKAHEAD) { - s->strstart = current_match.strstart + current_match.match_length; - hash_head = insert_string(s, s->strstart); - - /* set up the initial match to be a 1 byte literal */ - next_match.match_start = 0; - next_match.match_length = 1; - next_match.strstart = s->strstart; - next_match.orgstart = next_match.strstart; - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != 0 && s->strstart - hash_head <= MAX_DIST2) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - next_match.match_length = longest_match(s, hash_head); - next_match.match_start = s->match_start; - if (next_match.match_start >= next_match.strstart) { - /* this can happen due to some restarts */ - next_match.match_length = 1; - } - if (next_match.match_length < MIN_MATCH) - next_match.match_length = 1; - else - fizzle_matches(s, ¤t_match, &next_match); - } - - /* short matches with a very long distance are rarely a good idea encoding wise */ - if (next_match.match_length == 3 && (next_match.strstart - next_match.match_start) > 12000) - next_match.match_length = 1; - s->strstart = current_match.strstart; - - } else { - next_match.match_length = 0; - } - - /* now emit the current match */ - bflush = emit_match(s, current_match); - - /* move the "cursor" forward */ - s->strstart += current_match.match_length; - - if (bflush) - FLUSH_BLOCK(s, 0); - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - - return block_done; -} -#endif diff --git a/contrib/libzlib-ng/deflate_p.h b/contrib/libzlib-ng/deflate_p.h deleted file mode 100644 index 4b8282d46bc..00000000000 --- a/contrib/libzlib-ng/deflate_p.h +++ /dev/null @@ -1,96 +0,0 @@ -/* deflate_p.h -- Private inline functions and macros shared with more than - * one deflate method - * - * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - */ - -#ifndef DEFLATE_P_H -#define DEFLATE_P_H - -#if defined(X86_CPUID) -# include "arch/x86/x86.h" -#endif - -/* Forward declare common non-inlined functions declared in deflate.c */ - -#ifdef DEBUG -void check_match(deflate_state *s, IPos start, IPos match, int length); -#else -#define check_match(s, start, match, length) -#endif -void fill_window(deflate_state *s); -void flush_pending(z_stream *strm); - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * IN assertion: all calls to to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). - */ - -#ifdef X86_SSE4_2_CRC_HASH -extern Pos insert_string_sse(deflate_state *const s, const Pos str, uInt count); -#endif - -local inline Pos insert_string_c(deflate_state *const s, const Pos str, uInt count) { - Pos ret = 0; - uInt idx; - - for (idx = 0; idx < count; idx++) { - UPDATE_HASH(s, s->ins_h, str+idx); - if (s->head[s->ins_h] != str+idx) { - s->prev[(str+idx) & s->w_mask] = s->head[s->ins_h]; - s->head[s->ins_h] = str+idx; - } - } - ret = s->prev[(str+count-1) & s->w_mask]; - return ret; -} - -local inline Pos insert_string(deflate_state *const s, const Pos str) { -#ifdef X86_SSE4_2_CRC_HASH - if (x86_cpu_has_sse42) - return insert_string_sse(s, str, 1); -#endif - return insert_string_c(s, str, 1); -} - -#ifndef NOT_TWEAK_COMPILER -local inline void bulk_insert_str(deflate_state *const s, Pos startpos, uInt count) { -# ifdef X86_SSE4_2_CRC_HASH - if (x86_cpu_has_sse42) { - insert_string_sse(s, startpos, count); - } else -# endif - { - insert_string_c(s, startpos, count); - } -} -#endif /* NOT_TWEAK_COMPILER */ - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, last) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (char *)&s->window[(unsigned)s->block_start] : \ - (char *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (last)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr, "[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, last) { \ - FLUSH_BLOCK_ONLY(s, last); \ - if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ -} - -#endif diff --git a/contrib/libzlib-ng/deflate_slow.c b/contrib/libzlib-ng/deflate_slow.c deleted file mode 100644 index 6a855f0c837..00000000000 --- a/contrib/libzlib-ng/deflate_slow.c +++ /dev/null @@ -1,160 +0,0 @@ -/* deflate_slow.c -- compress data using the slow strategy of deflation algorithm - * - * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "deflate.h" -#include "deflate_p.h" -#include "match.h" - -/* =========================================================================== - * Local data - */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -/* =========================================================================== - * Same as deflate_medium, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -block_state deflate_slow(deflate_state *s, int flush) { - IPos hash_head; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) - break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - hash_head = insert_string(s, s->strstart); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match(s, hash_head); - /* longest_match() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - _tr_tally_dist(s, s->strstart -1 - s->prev_match, s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - -#ifdef NOT_TWEAK_COMPILER - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - insert_string(s, s->strstart); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; -#else - { - uInt mov_fwd = s->prev_length - 2; - uInt insert_cnt = mov_fwd; - if (unlikely(insert_cnt > max_insert - s->strstart)) - insert_cnt = max_insert - s->strstart; - - bulk_insert_str(s, s->strstart + 1, insert_cnt); - s->prev_length = 0; - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart += mov_fwd + 1; - } -#endif /*NOT_TWEAK_COMPILER*/ - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr, "%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) - return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert(flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr, "%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - s->match_available = 0; - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} diff --git a/contrib/libzlib-ng/doc/algorithm.txt b/contrib/libzlib-ng/doc/algorithm.txt deleted file mode 100644 index c97f495020b..00000000000 --- a/contrib/libzlib-ng/doc/algorithm.txt +++ /dev/null @@ -1,209 +0,0 @@ -1. Compression algorithm (deflate) - -The deflation algorithm used by gzip (also zip and zlib) is a variation of -LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in -the input data. The second occurrence of a string is replaced by a -pointer to the previous string, in the form of a pair (distance, -length). Distances are limited to 32K bytes, and lengths are limited -to 258 bytes. When a string does not occur anywhere in the previous -32K bytes, it is emitted as a sequence of literal bytes. (In this -description, `string' must be taken as an arbitrary sequence of bytes, -and is not restricted to printable characters.) - -Literals or match lengths are compressed with one Huffman tree, and -match distances are compressed with another tree. The trees are stored -in a compact form at the start of each block. The blocks can have any -size (except that the compressed data for one block must fit in -available memory). A block is terminated when deflate() determines that -it would be useful to start another block with fresh trees. (This is -somewhat similar to the behavior of LZW-based _compress_.) - -Duplicated strings are found using a hash table. All input strings of -length 3 are inserted in the hash table. A hash index is computed for -the next 3 bytes. If the hash chain for this index is not empty, all -strings in the chain are compared with the current input string, and -the longest match is selected. - -The hash chains are searched starting with the most recent strings, to -favor small distances and thus take advantage of the Huffman encoding. -The hash chains are singly linked. There are no deletions from the -hash chains, the algorithm simply discards matches that are too old. - -To avoid a worst-case situation, very long hash chains are arbitrarily -truncated at a certain length, determined by a runtime option (level -parameter of deflateInit). So deflate() does not always find the longest -possible match but generally finds a match which is long enough. - -deflate() also defers the selection of matches with a lazy evaluation -mechanism. After a match of length N has been found, deflate() searches for -a longer match at the next input byte. If a longer match is found, the -previous match is truncated to a length of one (thus producing a single -literal byte) and the process of lazy evaluation begins again. Otherwise, -the original match is kept, and the next match search is attempted only N -steps later. - -The lazy match evaluation is also subject to a runtime parameter. If -the current match is long enough, deflate() reduces the search for a longer -match, thus speeding up the whole process. If compression ratio is more -important than speed, deflate() attempts a complete second search even if -the first match is already long enough. - -The lazy match evaluation is not performed for the fastest compression -modes (level parameter 1 to 3). For these fast modes, new strings -are inserted in the hash table only when no match was found, or -when the match is not too long. This degrades the compression ratio -but saves time since there are both fewer insertions and fewer searches. - - -2. Decompression algorithm (inflate) - -2.1 Introduction - -The key question is how to represent a Huffman code (or any prefix code) so -that you can decode fast. The most important characteristic is that shorter -codes are much more common than longer codes, so pay attention to decoding the -short codes fast, and let the long codes take longer to decode. - -inflate() sets up a first level table that covers some number of bits of -input less than the length of longest code. It gets that many bits from the -stream, and looks it up in the table. The table will tell if the next -code is that many bits or less and how many, and if it is, it will tell -the value, else it will point to the next level table for which inflate() -grabs more bits and tries to decode a longer code. - -How many bits to make the first lookup is a tradeoff between the time it -takes to decode and the time it takes to build the table. If building the -table took no time (and if you had infinite memory), then there would only -be a first level table to cover all the way to the longest code. However, -building the table ends up taking a lot longer for more bits since short -codes are replicated many times in such a table. What inflate() does is -simply to make the number of bits in the first table a variable, and then -to set that variable for the maximum speed. - -For inflate, which has 286 possible codes for the literal/length tree, the size -of the first table is nine bits. Also the distance trees have 30 possible -values, and the size of the first table is six bits. Note that for each of -those cases, the table ended up one bit longer than the ``average'' code -length, i.e. the code length of an approximately flat code which would be a -little more than eight bits for 286 symbols and a little less than five bits -for 30 symbols. - - -2.2 More details on the inflate table lookup - -Ok, you want to know what this cleverly obfuscated inflate tree actually -looks like. You are correct that it's not a Huffman tree. It is simply a -lookup table for the first, let's say, nine bits of a Huffman symbol. The -symbol could be as short as one bit or as long as 15 bits. If a particular -symbol is shorter than nine bits, then that symbol's translation is duplicated -in all those entries that start with that symbol's bits. For example, if the -symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a -symbol is nine bits long, it appears in the table once. - -If the symbol is longer than nine bits, then that entry in the table points -to another similar table for the remaining bits. Again, there are duplicated -entries as needed. The idea is that most of the time the symbol will be short -and there will only be one table look up. (That's whole idea behind data -compression in the first place.) For the less frequent long symbols, there -will be two lookups. If you had a compression method with really long -symbols, you could have as many levels of lookups as is efficient. For -inflate, two is enough. - -So a table entry either points to another table (in which case nine bits in -the above example are gobbled), or it contains the translation for the symbol -and the number of bits to gobble. Then you start again with the next -ungobbled bit. - -You may wonder: why not just have one lookup table for how ever many bits the -longest symbol is? The reason is that if you do that, you end up spending -more time filling in duplicate symbol entries than you do actually decoding. -At least for deflate's output that generates new trees every several 10's of -kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code -would take too long if you're only decoding several thousand symbols. At the -other extreme, you could make a new table for every bit in the code. In fact, -that's essentially a Huffman tree. But then you spend too much time -traversing the tree while decoding, even for short symbols. - -So the number of bits for the first lookup table is a trade of the time to -fill out the table vs. the time spent looking at the second level and above of -the table. - -Here is an example, scaled down: - -The code being decoded, with 10 symbols, from 1 to 6 bits long: - -A: 0 -B: 10 -C: 1100 -D: 11010 -E: 11011 -F: 11100 -G: 11101 -H: 11110 -I: 111110 -J: 111111 - -Let's make the first table three bits long (eight entries): - -000: A,1 -001: A,1 -010: A,1 -011: A,1 -100: B,2 -101: B,2 -110: -> table X (gobble 3 bits) -111: -> table Y (gobble 3 bits) - -Each entry is what the bits decode as and how many bits that is, i.e. how -many bits to gobble. Or the entry points to another table, with the number of -bits to gobble implicit in the size of the table. - -Table X is two bits long since the longest code starting with 110 is five bits -long: - -00: C,1 -01: C,1 -10: D,2 -11: E,2 - -Table Y is three bits long since the longest code starting with 111 is six -bits long: - -000: F,2 -001: F,2 -010: G,2 -011: G,2 -100: H,2 -101: H,2 -110: I,3 -111: J,3 - -So what we have here are three tables with a total of 20 entries that had to -be constructed. That's compared to 64 entries for a single table. Or -compared to 16 entries for a Huffman tree (six two entry tables and one four -entry table). Assuming that the code ideally represents the probability of -the symbols, it takes on the average 1.25 lookups per symbol. That's compared -to one lookup for the single table, or 1.66 lookups per symbol for the -Huffman tree. - -There, I think that gives you a picture of what's going on. For inflate, the -meaning of a particular symbol is often more than just a letter. It can be a -byte (a "literal"), or it can be either a length or a distance which -indicates a base value and a number of bits to fetch after the code that is -added to the base value. Or it might be the special end-of-block code. The -data structures created in inftrees.c try to encode all that information -compactly in the tables. - - -Jean-loup Gailly Mark Adler -jloup@gzip.org madler@alumni.caltech.edu - - -References: - -[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data -Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, -pp. 337-343. - -``DEFLATE Compressed Data Format Specification'' available in -http://tools.ietf.org/html/rfc1951 diff --git a/contrib/libzlib-ng/doc/rfc1950.txt b/contrib/libzlib-ng/doc/rfc1950.txt deleted file mode 100644 index ce6428a0f2e..00000000000 --- a/contrib/libzlib-ng/doc/rfc1950.txt +++ /dev/null @@ -1,619 +0,0 @@ - - - - - - -Network Working Group P. Deutsch -Request for Comments: 1950 Aladdin Enterprises -Category: Informational J-L. Gailly - Info-ZIP - May 1996 - - - ZLIB Compressed Data Format Specification version 3.3 - -Status of This Memo - - This memo provides information for the Internet community. This memo - does not specify an Internet standard of any kind. Distribution of - this memo is unlimited. - -IESG Note: - - The IESG takes no position on the validity of any Intellectual - Property Rights statements contained in this document. - -Notices - - Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly - - Permission is granted to copy and distribute this document for any - purpose and without charge, including translations into other - languages and incorporation into compilations, provided that the - copyright notice and this notice are preserved, and that any - substantive changes or deletions from the original are clearly - marked. - - A pointer to the latest version of this and related documentation in - HTML format can be found at the URL - . - -Abstract - - This specification defines a lossless compressed data format. The - data can be produced or consumed, even for an arbitrarily long - sequentially presented input data stream, using only an a priori - bounded amount of intermediate storage. The format presently uses - the DEFLATE compression method but can be easily extended to use - other compression methods. It can be implemented readily in a manner - not covered by patents. This specification also defines the ADLER-32 - checksum (an extension and improvement of the Fletcher checksum), - used for detection of data corruption, and provides an algorithm for - computing it. - - - - -Deutsch & Gailly Informational [Page 1] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - -Table of Contents - - 1. Introduction ................................................... 2 - 1.1. Purpose ................................................... 2 - 1.2. Intended audience ......................................... 3 - 1.3. Scope ..................................................... 3 - 1.4. Compliance ................................................ 3 - 1.5. Definitions of terms and conventions used ................ 3 - 1.6. Changes from previous versions ............................ 3 - 2. Detailed specification ......................................... 3 - 2.1. Overall conventions ....................................... 3 - 2.2. Data format ............................................... 4 - 2.3. Compliance ................................................ 7 - 3. References ..................................................... 7 - 4. Source code .................................................... 8 - 5. Security Considerations ........................................ 8 - 6. Acknowledgements ............................................... 8 - 7. Authors' Addresses ............................................. 8 - 8. Appendix: Rationale ............................................ 9 - 9. Appendix: Sample code ..........................................10 - -1. Introduction - - 1.1. Purpose - - The purpose of this specification is to define a lossless - compressed data format that: - - * Is independent of CPU type, operating system, file system, - and character set, and hence can be used for interchange; - - * Can be produced or consumed, even for an arbitrarily long - sequentially presented input data stream, using only an a - priori bounded amount of intermediate storage, and hence can - be used in data communications or similar structures such as - Unix filters; - - * Can use a number of different compression methods; - - * Can be implemented readily in a manner not covered by - patents, and hence can be practiced freely. - - The data format defined by this specification does not attempt to - allow random access to compressed data. - - - - - - - -Deutsch & Gailly Informational [Page 2] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - 1.2. Intended audience - - This specification is intended for use by implementors of software - to compress data into zlib format and/or decompress data from zlib - format. - - The text of the specification assumes a basic background in - programming at the level of bits and other primitive data - representations. - - 1.3. Scope - - The specification specifies a compressed data format that can be - used for in-memory compression of a sequence of arbitrary bytes. - - 1.4. Compliance - - Unless otherwise indicated below, a compliant decompressor must be - able to accept and decompress any data set that conforms to all - the specifications presented here; a compliant compressor must - produce data sets that conform to all the specifications presented - here. - - 1.5. Definitions of terms and conventions used - - byte: 8 bits stored or transmitted as a unit (same as an octet). - (For this specification, a byte is exactly 8 bits, even on - machines which store a character on a number of bits different - from 8.) See below, for the numbering of bits within a byte. - - 1.6. Changes from previous versions - - Version 3.1 was the first public release of this specification. - In version 3.2, some terminology was changed and the Adler-32 - sample code was rewritten for clarity. In version 3.3, the - support for a preset dictionary was introduced, and the - specification was converted to RFC style. - -2. Detailed specification - - 2.1. Overall conventions - - In the diagrams below, a box like this: - - +---+ - | | <-- the vertical bars might be missing - +---+ - - - - -Deutsch & Gailly Informational [Page 3] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - represents one byte; a box like this: - - +==============+ - | | - +==============+ - - represents a variable number of bytes. - - Bytes stored within a computer do not have a "bit order", since - they are always treated as a unit. However, a byte considered as - an integer between 0 and 255 does have a most- and least- - significant bit, and since we write numbers with the most- - significant digit on the left, we also write bytes with the most- - significant bit on the left. In the diagrams below, we number the - bits of a byte so that bit 0 is the least-significant bit, i.e., - the bits are numbered: - - +--------+ - |76543210| - +--------+ - - Within a computer, a number may occupy multiple bytes. All - multi-byte numbers in the format described here are stored with - the MOST-significant byte first (at the lower memory address). - For example, the decimal number 520 is stored as: - - 0 1 - +--------+--------+ - |00000010|00001000| - +--------+--------+ - ^ ^ - | | - | + less significant byte = 8 - + more significant byte = 2 x 256 - - 2.2. Data format - - A zlib stream has the following structure: - - 0 1 - +---+---+ - |CMF|FLG| (more-->) - +---+---+ - - - - - - - - -Deutsch & Gailly Informational [Page 4] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - (if FLG.FDICT set) - - 0 1 2 3 - +---+---+---+---+ - | DICTID | (more-->) - +---+---+---+---+ - - +=====================+---+---+---+---+ - |...compressed data...| ADLER32 | - +=====================+---+---+---+---+ - - Any data which may appear after ADLER32 are not part of the zlib - stream. - - CMF (Compression Method and flags) - This byte is divided into a 4-bit compression method and a 4- - bit information field depending on the compression method. - - bits 0 to 3 CM Compression method - bits 4 to 7 CINFO Compression info - - CM (Compression method) - This identifies the compression method used in the file. CM = 8 - denotes the "deflate" compression method with a window size up - to 32K. This is the method used by gzip and PNG (see - references [1] and [2] in Chapter 3, below, for the reference - documents). CM = 15 is reserved. It might be used in a future - version of this specification to indicate the presence of an - extra field before the compressed data. - - CINFO (Compression info) - For CM = 8, CINFO is the base-2 logarithm of the LZ77 window - size, minus eight (CINFO=7 indicates a 32K window size). Values - of CINFO above 7 are not allowed in this version of the - specification. CINFO is not defined in this specification for - CM not equal to 8. - - FLG (FLaGs) - This flag byte is divided as follows: - - bits 0 to 4 FCHECK (check bits for CMF and FLG) - bit 5 FDICT (preset dictionary) - bits 6 to 7 FLEVEL (compression level) - - The FCHECK value must be such that CMF and FLG, when viewed as - a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG), - is a multiple of 31. - - - - -Deutsch & Gailly Informational [Page 5] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - FDICT (Preset dictionary) - If FDICT is set, a DICT dictionary identifier is present - immediately after the FLG byte. The dictionary is a sequence of - bytes which are initially fed to the compressor without - producing any compressed output. DICT is the Adler-32 checksum - of this sequence of bytes (see the definition of ADLER32 - below). The decompressor can use this identifier to determine - which dictionary has been used by the compressor. - - FLEVEL (Compression level) - These flags are available for use by specific compression - methods. The "deflate" method (CM = 8) sets these flags as - follows: - - 0 - compressor used fastest algorithm - 1 - compressor used fast algorithm - 2 - compressor used default algorithm - 3 - compressor used maximum compression, slowest algorithm - - The information in FLEVEL is not needed for decompression; it - is there to indicate if recompression might be worthwhile. - - compressed data - For compression method 8, the compressed data is stored in the - deflate compressed data format as described in the document - "DEFLATE Compressed Data Format Specification" by L. Peter - Deutsch. (See reference [3] in Chapter 3, below) - - Other compressed data formats are not specified in this version - of the zlib specification. - - ADLER32 (Adler-32 checksum) - This contains a checksum value of the uncompressed data - (excluding any dictionary data) computed according to Adler-32 - algorithm. This algorithm is a 32-bit extension and improvement - of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073 - standard. See references [4] and [5] in Chapter 3, below) - - Adler-32 is composed of two sums accumulated per byte: s1 is - the sum of all bytes, s2 is the sum of all s1 values. Both sums - are done modulo 65521. s1 is initialized to 1, s2 to zero. The - Adler-32 checksum is stored as s2*65536 + s1 in most- - significant-byte first (network) order. - - - - - - - - -Deutsch & Gailly Informational [Page 6] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - 2.3. Compliance - - A compliant compressor must produce streams with correct CMF, FLG - and ADLER32, but need not support preset dictionaries. When the - zlib data format is used as part of another standard data format, - the compressor may use only preset dictionaries that are specified - by this other data format. If this other format does not use the - preset dictionary feature, the compressor must not set the FDICT - flag. - - A compliant decompressor must check CMF, FLG, and ADLER32, and - provide an error indication if any of these have incorrect values. - A compliant decompressor must give an error indication if CM is - not one of the values defined in this specification (only the - value 8 is permitted in this version), since another value could - indicate the presence of new features that would cause subsequent - data to be interpreted incorrectly. A compliant decompressor must - give an error indication if FDICT is set and DICTID is not the - identifier of a known preset dictionary. A decompressor may - ignore FLEVEL and still be compliant. When the zlib data format - is being used as a part of another standard format, a compliant - decompressor must support all the preset dictionaries specified by - the other format. When the other format does not use the preset - dictionary feature, a compliant decompressor must reject any - stream in which the FDICT flag is set. - -3. References - - [1] Deutsch, L.P.,"GZIP Compressed Data Format Specification", - available in ftp://ftp.uu.net/pub/archiving/zip/doc/ - - [2] Thomas Boutell, "PNG (Portable Network Graphics) specification", - available in ftp://ftp.uu.net/graphics/png/documents/ - - [3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", - available in ftp://ftp.uu.net/pub/archiving/zip/doc/ - - [4] Fletcher, J. G., "An Arithmetic Checksum for Serial - Transmissions," IEEE Transactions on Communications, Vol. COM-30, - No. 1, January 1982, pp. 247-252. - - [5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms," - November, 1993, pp. 144, 145. (Available from - gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073. - - - - - - - -Deutsch & Gailly Informational [Page 7] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - -4. Source code - - Source code for a C language implementation of a "zlib" compliant - library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/. - -5. Security Considerations - - A decoder that fails to check the ADLER32 checksum value may be - subject to undetected data corruption. - -6. Acknowledgements - - Trademarks cited in this document are the property of their - respective owners. - - Jean-Loup Gailly and Mark Adler designed the zlib format and wrote - the related software described in this specification. Glenn - Randers-Pehrson converted this document to RFC and HTML format. - -7. Authors' Addresses - - L. Peter Deutsch - Aladdin Enterprises - 203 Santa Margarita Ave. - Menlo Park, CA 94025 - - Phone: (415) 322-0103 (AM only) - FAX: (415) 322-1734 - EMail: - - - Jean-Loup Gailly - - EMail: - - Questions about the technical content of this specification can be - sent by email to - - Jean-Loup Gailly and - Mark Adler - - Editorial comments on this specification can be sent by email to - - L. Peter Deutsch and - Glenn Randers-Pehrson - - - - - - -Deutsch & Gailly Informational [Page 8] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - -8. Appendix: Rationale - - 8.1. Preset dictionaries - - A preset dictionary is specially useful to compress short input - sequences. The compressor can take advantage of the dictionary - context to encode the input in a more compact manner. The - decompressor can be initialized with the appropriate context by - virtually decompressing a compressed version of the dictionary - without producing any output. However for certain compression - algorithms such as the deflate algorithm this operation can be - achieved without actually performing any decompression. - - The compressor and the decompressor must use exactly the same - dictionary. The dictionary may be fixed or may be chosen among a - certain number of predefined dictionaries, according to the kind - of input data. The decompressor can determine which dictionary has - been chosen by the compressor by checking the dictionary - identifier. This document does not specify the contents of - predefined dictionaries, since the optimal dictionaries are - application specific. Standard data formats using this feature of - the zlib specification must precisely define the allowed - dictionaries. - - 8.2. The Adler-32 algorithm - - The Adler-32 algorithm is much faster than the CRC32 algorithm yet - still provides an extremely low probability of undetected errors. - - The modulo on unsigned long accumulators can be delayed for 5552 - bytes, so the modulo operation time is negligible. If the bytes - are a, b, c, the second sum is 3a + 2b + c + 3, and so is position - and order sensitive, unlike the first sum, which is just a - checksum. That 65521 is prime is important to avoid a possible - large class of two-byte errors that leave the check unchanged. - (The Fletcher checksum uses 255, which is not prime and which also - makes the Fletcher check insensitive to single byte changes 0 <-> - 255.) - - The sum s1 is initialized to 1 instead of zero to make the length - of the sequence part of s2, so that the length does not have to be - checked separately. (Any sequence of zeroes has a Fletcher - checksum of zero.) - - - - - - - - -Deutsch & Gailly Informational [Page 9] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - -9. Appendix: Sample code - - The following C code computes the Adler-32 checksum of a data buffer. - It is written for clarity, not for speed. The sample code is in the - ANSI C programming language. Non C users may find it easier to read - with these hints: - - & Bitwise AND operator. - >> Bitwise right shift operator. When applied to an - unsigned quantity, as here, right shift inserts zero bit(s) - at the left. - << Bitwise left shift operator. Left shift inserts zero - bit(s) at the right. - ++ "n++" increments the variable n. - % modulo operator: a % b is the remainder of a divided by b. - - #define BASE 65521 /* largest prime smaller than 65536 */ - - /* - Update a running Adler-32 checksum with the bytes buf[0..len-1] - and return the updated checksum. The Adler-32 checksum should be - initialized to 1. - - Usage example: - - unsigned long adler = 1L; - - while (read_buffer(buffer, length) != EOF) { - adler = update_adler32(adler, buffer, length); - } - if (adler != original_adler) error(); - */ - unsigned long update_adler32(unsigned long adler, - unsigned char *buf, int len) - { - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int n; - - for (n = 0; n < len; n++) { - s1 = (s1 + buf[n]) % BASE; - s2 = (s2 + s1) % BASE; - } - return (s2 << 16) + s1; - } - - /* Return the adler32 of the bytes buf[0..len-1] */ - - - - -Deutsch & Gailly Informational [Page 10] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - unsigned long adler32(unsigned char *buf, int len) - { - return update_adler32(1L, buf, len); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Deutsch & Gailly Informational [Page 11] - diff --git a/contrib/libzlib-ng/doc/rfc1951.txt b/contrib/libzlib-ng/doc/rfc1951.txt deleted file mode 100644 index 403c8c722ff..00000000000 --- a/contrib/libzlib-ng/doc/rfc1951.txt +++ /dev/null @@ -1,955 +0,0 @@ - - - - - - -Network Working Group P. Deutsch -Request for Comments: 1951 Aladdin Enterprises -Category: Informational May 1996 - - - DEFLATE Compressed Data Format Specification version 1.3 - -Status of This Memo - - This memo provides information for the Internet community. This memo - does not specify an Internet standard of any kind. Distribution of - this memo is unlimited. - -IESG Note: - - The IESG takes no position on the validity of any Intellectual - Property Rights statements contained in this document. - -Notices - - Copyright (c) 1996 L. Peter Deutsch - - Permission is granted to copy and distribute this document for any - purpose and without charge, including translations into other - languages and incorporation into compilations, provided that the - copyright notice and this notice are preserved, and that any - substantive changes or deletions from the original are clearly - marked. - - A pointer to the latest version of this and related documentation in - HTML format can be found at the URL - . - -Abstract - - This specification defines a lossless compressed data format that - compresses data using a combination of the LZ77 algorithm and Huffman - coding, with efficiency comparable to the best currently available - general-purpose compression methods. The data can be produced or - consumed, even for an arbitrarily long sequentially presented input - data stream, using only an a priori bounded amount of intermediate - storage. The format can be implemented readily in a manner not - covered by patents. - - - - - - - - -Deutsch Informational [Page 1] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - -Table of Contents - - 1. Introduction ................................................... 2 - 1.1. Purpose ................................................... 2 - 1.2. Intended audience ......................................... 3 - 1.3. Scope ..................................................... 3 - 1.4. Compliance ................................................ 3 - 1.5. Definitions of terms and conventions used ................ 3 - 1.6. Changes from previous versions ............................ 4 - 2. Compressed representation overview ............................. 4 - 3. Detailed specification ......................................... 5 - 3.1. Overall conventions ....................................... 5 - 3.1.1. Packing into bytes .................................. 5 - 3.2. Compressed block format ................................... 6 - 3.2.1. Synopsis of prefix and Huffman coding ............... 6 - 3.2.2. Use of Huffman coding in the "deflate" format ....... 7 - 3.2.3. Details of block format ............................. 9 - 3.2.4. Non-compressed blocks (BTYPE=00) ................... 11 - 3.2.5. Compressed blocks (length and distance codes) ...... 11 - 3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12 - 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13 - 3.3. Compliance ............................................... 14 - 4. Compression algorithm details ................................. 14 - 5. References .................................................... 16 - 6. Security Considerations ....................................... 16 - 7. Source code ................................................... 16 - 8. Acknowledgements .............................................. 16 - 9. Author's Address .............................................. 17 - -1. Introduction - - 1.1. Purpose - - The purpose of this specification is to define a lossless - compressed data format that: - * Is independent of CPU type, operating system, file system, - and character set, and hence can be used for interchange; - * Can be produced or consumed, even for an arbitrarily long - sequentially presented input data stream, using only an a - priori bounded amount of intermediate storage, and hence - can be used in data communications or similar structures - such as Unix filters; - * Compresses data with efficiency comparable to the best - currently available general-purpose compression methods, - and in particular considerably better than the "compress" - program; - * Can be implemented readily in a manner not covered by - patents, and hence can be practiced freely; - - - -Deutsch Informational [Page 2] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - * Is compatible with the file format produced by the current - widely used gzip utility, in that conforming decompressors - will be able to read data produced by the existing gzip - compressor. - - The data format defined by this specification does not attempt to: - - * Allow random access to compressed data; - * Compress specialized data (e.g., raster graphics) as well - as the best currently available specialized algorithms. - - A simple counting argument shows that no lossless compression - algorithm can compress every possible input data set. For the - format defined here, the worst case expansion is 5 bytes per 32K- - byte block, i.e., a size increase of 0.015% for large data sets. - English text usually compresses by a factor of 2.5 to 3; - executable files usually compress somewhat less; graphical data - such as raster images may compress much more. - - 1.2. Intended audience - - This specification is intended for use by implementors of software - to compress data into "deflate" format and/or decompress data from - "deflate" format. - - The text of the specification assumes a basic background in - programming at the level of bits and other primitive data - representations. Familiarity with the technique of Huffman coding - is helpful but not required. - - 1.3. Scope - - The specification specifies a method for representing a sequence - of bytes as a (usually shorter) sequence of bits, and a method for - packing the latter bit sequence into bytes. - - 1.4. Compliance - - Unless otherwise indicated below, a compliant decompressor must be - able to accept and decompress any data set that conforms to all - the specifications presented here; a compliant compressor must - produce data sets that conform to all the specifications presented - here. - - 1.5. Definitions of terms and conventions used - - Byte: 8 bits stored or transmitted as a unit (same as an octet). - For this specification, a byte is exactly 8 bits, even on machines - - - -Deutsch Informational [Page 3] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - which store a character on a number of bits different from eight. - See below, for the numbering of bits within a byte. - - String: a sequence of arbitrary bytes. - - 1.6. Changes from previous versions - - There have been no technical changes to the deflate format since - version 1.1 of this specification. In version 1.2, some - terminology was changed. Version 1.3 is a conversion of the - specification to RFC style. - -2. Compressed representation overview - - A compressed data set consists of a series of blocks, corresponding - to successive blocks of input data. The block sizes are arbitrary, - except that non-compressible blocks are limited to 65,535 bytes. - - Each block is compressed using a combination of the LZ77 algorithm - and Huffman coding. The Huffman trees for each block are independent - of those for previous or subsequent blocks; the LZ77 algorithm may - use a reference to a duplicated string occurring in a previous block, - up to 32K input bytes before. - - Each block consists of two parts: a pair of Huffman code trees that - describe the representation of the compressed data part, and a - compressed data part. (The Huffman trees themselves are compressed - using Huffman encoding.) The compressed data consists of a series of - elements of two types: literal bytes (of strings that have not been - detected as duplicated within the previous 32K input bytes), and - pointers to duplicated strings, where a pointer is represented as a - pair . The representation used in the - "deflate" format limits distances to 32K bytes and lengths to 258 - bytes, but does not limit the size of a block, except for - uncompressible blocks, which are limited as noted above. - - Each type of value (literals, distances, and lengths) in the - compressed data is represented using a Huffman code, using one code - tree for literals and lengths and a separate code tree for distances. - The code trees for each block appear in a compact form just before - the compressed data for that block. - - - - - - - - - - -Deutsch Informational [Page 4] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - -3. Detailed specification - - 3.1. Overall conventions In the diagrams below, a box like this: - - +---+ - | | <-- the vertical bars might be missing - +---+ - - represents one byte; a box like this: - - +==============+ - | | - +==============+ - - represents a variable number of bytes. - - Bytes stored within a computer do not have a "bit order", since - they are always treated as a unit. However, a byte considered as - an integer between 0 and 255 does have a most- and least- - significant bit, and since we write numbers with the most- - significant digit on the left, we also write bytes with the most- - significant bit on the left. In the diagrams below, we number the - bits of a byte so that bit 0 is the least-significant bit, i.e., - the bits are numbered: - - +--------+ - |76543210| - +--------+ - - Within a computer, a number may occupy multiple bytes. All - multi-byte numbers in the format described here are stored with - the least-significant byte first (at the lower memory address). - For example, the decimal number 520 is stored as: - - 0 1 - +--------+--------+ - |00001000|00000010| - +--------+--------+ - ^ ^ - | | - | + more significant byte = 2 x 256 - + less significant byte = 8 - - 3.1.1. Packing into bytes - - This document does not address the issue of the order in which - bits of a byte are transmitted on a bit-sequential medium, - since the final data format described here is byte- rather than - - - -Deutsch Informational [Page 5] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - bit-oriented. However, we describe the compressed block format - in below, as a sequence of data elements of various bit - lengths, not a sequence of bytes. We must therefore specify - how to pack these data elements into bytes to form the final - compressed byte sequence: - - * Data elements are packed into bytes in order of - increasing bit number within the byte, i.e., starting - with the least-significant bit of the byte. - * Data elements other than Huffman codes are packed - starting with the least-significant bit of the data - element. - * Huffman codes are packed starting with the most- - significant bit of the code. - - In other words, if one were to print out the compressed data as - a sequence of bytes, starting with the first byte at the - *right* margin and proceeding to the *left*, with the most- - significant bit of each byte on the left as usual, one would be - able to parse the result from right to left, with fixed-width - elements in the correct MSB-to-LSB order and Huffman codes in - bit-reversed order (i.e., with the first bit of the code in the - relative LSB position). - - 3.2. Compressed block format - - 3.2.1. Synopsis of prefix and Huffman coding - - Prefix coding represents symbols from an a priori known - alphabet by bit sequences (codes), one code for each symbol, in - a manner such that different symbols may be represented by bit - sequences of different lengths, but a parser can always parse - an encoded string unambiguously symbol-by-symbol. - - We define a prefix code in terms of a binary tree in which the - two edges descending from each non-leaf node are labeled 0 and - 1 and in which the leaf nodes correspond one-for-one with (are - labeled with) the symbols of the alphabet; then the code for a - symbol is the sequence of 0's and 1's on the edges leading from - the root to the leaf labeled with that symbol. For example: - - - - - - - - - - - -Deutsch Informational [Page 6] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - /\ Symbol Code - 0 1 ------ ---- - / \ A 00 - /\ B B 1 - 0 1 C 011 - / \ D 010 - A /\ - 0 1 - / \ - D C - - A parser can decode the next symbol from an encoded input - stream by walking down the tree from the root, at each step - choosing the edge corresponding to the next input bit. - - Given an alphabet with known symbol frequencies, the Huffman - algorithm allows the construction of an optimal prefix code - (one which represents strings with those symbol frequencies - using the fewest bits of any possible prefix codes for that - alphabet). Such a code is called a Huffman code. (See - reference [1] in Chapter 5, references for additional - information on Huffman codes.) - - Note that in the "deflate" format, the Huffman codes for the - various alphabets must not exceed certain maximum code lengths. - This constraint complicates the algorithm for computing code - lengths from symbol frequencies. Again, see Chapter 5, - references for details. - - 3.2.2. Use of Huffman coding in the "deflate" format - - The Huffman codes used for each alphabet in the "deflate" - format have two additional rules: - - * All codes of a given bit length have lexicographically - consecutive values, in the same order as the symbols - they represent; - - * Shorter codes lexicographically precede longer codes. - - - - - - - - - - - - -Deutsch Informational [Page 7] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - We could recode the example above to follow this rule as - follows, assuming that the order of the alphabet is ABCD: - - Symbol Code - ------ ---- - A 10 - B 0 - C 110 - D 111 - - I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are - lexicographically consecutive. - - Given this rule, we can define the Huffman code for an alphabet - just by giving the bit lengths of the codes for each symbol of - the alphabet in order; this is sufficient to determine the - actual codes. In our example, the code is completely defined - by the sequence of bit lengths (2, 1, 3, 3). The following - algorithm generates the codes as integers, intended to be read - from most- to least-significant bit. The code lengths are - initially in tree[I].Len; the codes are produced in - tree[I].Code. - - 1) Count the number of codes for each code length. Let - bl_count[N] be the number of codes of length N, N >= 1. - - 2) Find the numerical value of the smallest code for each - code length: - - code = 0; - bl_count[0] = 0; - for (bits = 1; bits <= MAX_BITS; bits++) { - code = (code + bl_count[bits-1]) << 1; - next_code[bits] = code; - } - - 3) Assign numerical values to all codes, using consecutive - values for all codes of the same length with the base - values determined at step 2. Codes that are never used - (which have a bit length of zero) must not be assigned a - value. - - for (n = 0; n <= max_code; n++) { - len = tree[n].Len; - if (len != 0) { - tree[n].Code = next_code[len]; - next_code[len]++; - } - - - -Deutsch Informational [Page 8] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - } - - Example: - - Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3, - 3, 2, 4, 4). After step 1, we have: - - N bl_count[N] - - ----------- - 2 1 - 3 5 - 4 2 - - Step 2 computes the following next_code values: - - N next_code[N] - - ------------ - 1 0 - 2 0 - 3 2 - 4 14 - - Step 3 produces the following code values: - - Symbol Length Code - ------ ------ ---- - A 3 010 - B 3 011 - C 3 100 - D 3 101 - E 3 110 - F 2 00 - G 4 1110 - H 4 1111 - - 3.2.3. Details of block format - - Each block of compressed data begins with 3 header bits - containing the following data: - - first bit BFINAL - next 2 bits BTYPE - - Note that the header bits do not necessarily begin on a byte - boundary, since a block does not necessarily occupy an integral - number of bytes. - - - - - -Deutsch Informational [Page 9] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - BFINAL is set if and only if this is the last block of the data - set. - - BTYPE specifies how the data are compressed, as follows: - - 00 - no compression - 01 - compressed with fixed Huffman codes - 10 - compressed with dynamic Huffman codes - 11 - reserved (error) - - The only difference between the two compressed cases is how the - Huffman codes for the literal/length and distance alphabets are - defined. - - In all cases, the decoding algorithm for the actual data is as - follows: - - do - read block header from input stream. - if stored with no compression - skip any remaining bits in current partially - processed byte - read LEN and NLEN (see next section) - copy LEN bytes of data to output - otherwise - if compressed with dynamic Huffman codes - read representation of code trees (see - subsection below) - loop (until end of block code recognized) - decode literal/length value from input stream - if value < 256 - copy value (literal byte) to output stream - otherwise - if value = end of block (256) - break from loop - otherwise (value = 257..285) - decode distance from input stream - - move backwards distance bytes in the output - stream, and copy length bytes from this - position to the output stream. - end loop - while not last block - - Note that a duplicated string reference may refer to a string - in a previous block; i.e., the backward distance may cross one - or more block boundaries. However a distance cannot refer past - the beginning of the output stream. (An application using a - - - -Deutsch Informational [Page 10] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - preset dictionary might discard part of the output stream; a - distance can refer to that part of the output stream anyway) - Note also that the referenced string may overlap the current - position; for example, if the last 2 bytes decoded have values - X and Y, a string reference with - adds X,Y,X,Y,X to the output stream. - - We now specify each compression method in turn. - - 3.2.4. Non-compressed blocks (BTYPE=00) - - Any bits of input up to the next byte boundary are ignored. - The rest of the block consists of the following information: - - 0 1 2 3 4... - +---+---+---+---+================================+ - | LEN | NLEN |... LEN bytes of literal data...| - +---+---+---+---+================================+ - - LEN is the number of data bytes in the block. NLEN is the - one's complement of LEN. - - 3.2.5. Compressed blocks (length and distance codes) - - As noted above, encoded data blocks in the "deflate" format - consist of sequences of symbols drawn from three conceptually - distinct alphabets: either literal bytes, from the alphabet of - byte values (0..255), or pairs, - where the length is drawn from (3..258) and the distance is - drawn from (1..32,768). In fact, the literal and length - alphabets are merged into a single alphabet (0..285), where - values 0..255 represent literal bytes, the value 256 indicates - end-of-block, and values 257..285 represent length codes - (possibly in conjunction with extra bits following the symbol - code) as follows: - - - - - - - - - - - - - - - - -Deutsch Informational [Page 11] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - Extra Extra Extra - Code Bits Length(s) Code Bits Lengths Code Bits Length(s) - ---- ---- ------ ---- ---- ------- ---- ---- ------- - 257 0 3 267 1 15,16 277 4 67-82 - 258 0 4 268 1 17,18 278 4 83-98 - 259 0 5 269 2 19-22 279 4 99-114 - 260 0 6 270 2 23-26 280 4 115-130 - 261 0 7 271 2 27-30 281 5 131-162 - 262 0 8 272 2 31-34 282 5 163-194 - 263 0 9 273 3 35-42 283 5 195-226 - 264 0 10 274 3 43-50 284 5 227-257 - 265 1 11,12 275 3 51-58 285 0 258 - 266 1 13,14 276 3 59-66 - - The extra bits should be interpreted as a machine integer - stored with the most-significant bit first, e.g., bits 1110 - represent the value 14. - - Extra Extra Extra - Code Bits Dist Code Bits Dist Code Bits Distance - ---- ---- ---- ---- ---- ------ ---- ---- -------- - 0 0 1 10 4 33-48 20 9 1025-1536 - 1 0 2 11 4 49-64 21 9 1537-2048 - 2 0 3 12 5 65-96 22 10 2049-3072 - 3 0 4 13 5 97-128 23 10 3073-4096 - 4 1 5,6 14 6 129-192 24 11 4097-6144 - 5 1 7,8 15 6 193-256 25 11 6145-8192 - 6 2 9-12 16 7 257-384 26 12 8193-12288 - 7 2 13-16 17 7 385-512 27 12 12289-16384 - 8 3 17-24 18 8 513-768 28 13 16385-24576 - 9 3 25-32 19 8 769-1024 29 13 24577-32768 - - 3.2.6. Compression with fixed Huffman codes (BTYPE=01) - - The Huffman codes for the two alphabets are fixed, and are not - represented explicitly in the data. The Huffman code lengths - for the literal/length alphabet are: - - Lit Value Bits Codes - --------- ---- ----- - 0 - 143 8 00110000 through - 10111111 - 144 - 255 9 110010000 through - 111111111 - 256 - 279 7 0000000 through - 0010111 - 280 - 287 8 11000000 through - 11000111 - - - -Deutsch Informational [Page 12] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - The code lengths are sufficient to generate the actual codes, - as described above; we show the codes in the table for added - clarity. Literal/length values 286-287 will never actually - occur in the compressed data, but participate in the code - construction. - - Distance codes 0-31 are represented by (fixed-length) 5-bit - codes, with possible additional bits as shown in the table - shown in Paragraph 3.2.5, above. Note that distance codes 30- - 31 will never actually occur in the compressed data. - - 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) - - The Huffman codes for the two alphabets appear in the block - immediately after the header bits and before the actual - compressed data, first the literal/length code and then the - distance code. Each code is defined by a sequence of code - lengths, as discussed in Paragraph 3.2.2, above. For even - greater compactness, the code length sequences themselves are - compressed using a Huffman code. The alphabet for code lengths - is as follows: - - 0 - 15: Represent code lengths of 0 - 15 - 16: Copy the previous code length 3 - 6 times. - The next 2 bits indicate repeat length - (0 = 3, ... , 3 = 6) - Example: Codes 8, 16 (+2 bits 11), - 16 (+2 bits 10) will expand to - 12 code lengths of 8 (1 + 6 + 5) - 17: Repeat a code length of 0 for 3 - 10 times. - (3 bits of length) - 18: Repeat a code length of 0 for 11 - 138 times - (7 bits of length) - - A code length of 0 indicates that the corresponding symbol in - the literal/length or distance alphabet will not occur in the - block, and should not participate in the Huffman code - construction algorithm given earlier. If only one distance - code is used, it is encoded using one bit, not zero bits; in - this case there is a single code length of one, with one unused - code. One distance code of zero bits means that there are no - distance codes used at all (the data is all literals). - - We can now define the format of the block: - - 5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286) - 5 Bits: HDIST, # of Distance codes - 1 (1 - 32) - 4 Bits: HCLEN, # of Code Length codes - 4 (4 - 19) - - - -Deutsch Informational [Page 13] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - (HCLEN + 4) x 3 bits: code lengths for the code length - alphabet given just above, in the order: 16, 17, 18, - 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 - - These code lengths are interpreted as 3-bit integers - (0-7); as above, a code length of 0 means the - corresponding symbol (literal/length or distance code - length) is not used. - - HLIT + 257 code lengths for the literal/length alphabet, - encoded using the code length Huffman code - - HDIST + 1 code lengths for the distance alphabet, - encoded using the code length Huffman code - - The actual compressed data of the block, - encoded using the literal/length and distance Huffman - codes - - The literal/length symbol 256 (end of data), - encoded using the literal/length Huffman code - - The code length repeat codes can cross from HLIT + 257 to the - HDIST + 1 code lengths. In other words, all code lengths form - a single sequence of HLIT + HDIST + 258 values. - - 3.3. Compliance - - A compressor may limit further the ranges of values specified in - the previous section and still be compliant; for example, it may - limit the range of backward pointers to some value smaller than - 32K. Similarly, a compressor may limit the size of blocks so that - a compressible block fits in memory. - - A compliant decompressor must accept the full range of possible - values defined in the previous section, and must accept blocks of - arbitrary size. - -4. Compression algorithm details - - While it is the intent of this document to define the "deflate" - compressed data format without reference to any particular - compression algorithm, the format is related to the compressed - formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below); - since many variations of LZ77 are patented, it is strongly - recommended that the implementor of a compressor follow the general - algorithm presented here, which is known not to be patented per se. - The material in this section is not part of the definition of the - - - -Deutsch Informational [Page 14] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - specification per se, and a compressor need not follow it in order to - be compliant. - - The compressor terminates a block when it determines that starting a - new block with fresh trees would be useful, or when the block size - fills up the compressor's block buffer. - - The compressor uses a chained hash table to find duplicated strings, - using a hash function that operates on 3-byte sequences. At any - given point during compression, let XYZ be the next 3 input bytes to - be examined (not necessarily all different, of course). First, the - compressor examines the hash chain for XYZ. If the chain is empty, - the compressor simply writes out X as a literal byte and advances one - byte in the input. If the hash chain is not empty, indicating that - the sequence XYZ (or, if we are unlucky, some other 3 bytes with the - same hash function value) has occurred recently, the compressor - compares all strings on the XYZ hash chain with the actual input data - sequence starting at the current point, and selects the longest - match. - - The compressor searches the hash chains starting with the most recent - strings, to favor small distances and thus take advantage of the - Huffman encoding. The hash chains are singly linked. There are no - deletions from the hash chains; the algorithm simply discards matches - that are too old. To avoid a worst-case situation, very long hash - chains are arbitrarily truncated at a certain length, determined by a - run-time parameter. - - To improve overall compression, the compressor optionally defers the - selection of matches ("lazy matching"): after a match of length N has - been found, the compressor searches for a longer match starting at - the next input byte. If it finds a longer match, it truncates the - previous match to a length of one (thus producing a single literal - byte) and then emits the longer match. Otherwise, it emits the - original match, and, as described above, advances N bytes before - continuing. - - Run-time parameters also control this "lazy match" procedure. If - compression ratio is most important, the compressor attempts a - complete second search regardless of the length of the first match. - In the normal case, if the current match is "long enough", the - compressor reduces the search for a longer match, thus speeding up - the process. If speed is most important, the compressor inserts new - strings in the hash table only when no match was found, or when the - match is not "too long". This degrades the compression ratio but - saves time since there are both fewer insertions and fewer searches. - - - - - -Deutsch Informational [Page 15] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - -5. References - - [1] Huffman, D. A., "A Method for the Construction of Minimum - Redundancy Codes", Proceedings of the Institute of Radio - Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101. - - [2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data - Compression", IEEE Transactions on Information Theory, Vol. 23, - No. 3, pp. 337-343. - - [3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources, - available in ftp://ftp.uu.net/pub/archiving/zip/doc/ - - [4] Gailly, J.-L., and Adler, M., GZIP documentation and sources, - available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/ - - [5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix - encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169. - - [6] Hirschberg and Lelewer, "Efficient decoding of prefix codes," - Comm. ACM, 33,4, April 1990, pp. 449-459. - -6. Security Considerations - - Any data compression method involves the reduction of redundancy in - the data. Consequently, any corruption of the data is likely to have - severe effects and be difficult to correct. Uncompressed text, on - the other hand, will probably still be readable despite the presence - of some corrupted bytes. - - It is recommended that systems using this data format provide some - means of validating the integrity of the compressed data. See - reference [3], for example. - -7. Source code - - Source code for a C language implementation of a "deflate" compliant - compressor and decompressor is available within the zlib package at - ftp://ftp.uu.net/pub/archiving/zip/zlib/. - -8. Acknowledgements - - Trademarks cited in this document are the property of their - respective owners. - - Phil Katz designed the deflate format. Jean-Loup Gailly and Mark - Adler wrote the related software described in this specification. - Glenn Randers-Pehrson converted this document to RFC and HTML format. - - - -Deutsch Informational [Page 16] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - -9. Author's Address - - L. Peter Deutsch - Aladdin Enterprises - 203 Santa Margarita Ave. - Menlo Park, CA 94025 - - Phone: (415) 322-0103 (AM only) - FAX: (415) 322-1734 - EMail: - - Questions about the technical content of this specification can be - sent by email to: - - Jean-Loup Gailly and - Mark Adler - - Editorial comments on this specification can be sent by email to: - - L. Peter Deutsch and - Glenn Randers-Pehrson - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Deutsch Informational [Page 17] - diff --git a/contrib/libzlib-ng/doc/rfc1952.txt b/contrib/libzlib-ng/doc/rfc1952.txt deleted file mode 100644 index a8e51b4567f..00000000000 --- a/contrib/libzlib-ng/doc/rfc1952.txt +++ /dev/null @@ -1,675 +0,0 @@ - - - - - - -Network Working Group P. Deutsch -Request for Comments: 1952 Aladdin Enterprises -Category: Informational May 1996 - - - GZIP file format specification version 4.3 - -Status of This Memo - - This memo provides information for the Internet community. This memo - does not specify an Internet standard of any kind. Distribution of - this memo is unlimited. - -IESG Note: - - The IESG takes no position on the validity of any Intellectual - Property Rights statements contained in this document. - -Notices - - Copyright (c) 1996 L. Peter Deutsch - - Permission is granted to copy and distribute this document for any - purpose and without charge, including translations into other - languages and incorporation into compilations, provided that the - copyright notice and this notice are preserved, and that any - substantive changes or deletions from the original are clearly - marked. - - A pointer to the latest version of this and related documentation in - HTML format can be found at the URL - . - -Abstract - - This specification defines a lossless compressed data format that is - compatible with the widely used GZIP utility. The format includes a - cyclic redundancy check value for detecting data corruption. The - format presently uses the DEFLATE method of compression but can be - easily extended to use other compression methods. The format can be - implemented readily in a manner not covered by patents. - - - - - - - - - - -Deutsch Informational [Page 1] - -RFC 1952 GZIP File Format Specification May 1996 - - -Table of Contents - - 1. Introduction ................................................... 2 - 1.1. Purpose ................................................... 2 - 1.2. Intended audience ......................................... 3 - 1.3. Scope ..................................................... 3 - 1.4. Compliance ................................................ 3 - 1.5. Definitions of terms and conventions used ................. 3 - 1.6. Changes from previous versions ............................ 3 - 2. Detailed specification ......................................... 4 - 2.1. Overall conventions ....................................... 4 - 2.2. File format ............................................... 5 - 2.3. Member format ............................................. 5 - 2.3.1. Member header and trailer ........................... 6 - 2.3.1.1. Extra field ................................... 8 - 2.3.1.2. Compliance .................................... 9 - 3. References .................................................. 9 - 4. Security Considerations .................................... 10 - 5. Acknowledgements ........................................... 10 - 6. Author's Address ........................................... 10 - 7. Appendix: Jean-Loup Gailly's gzip utility .................. 11 - 8. Appendix: Sample CRC Code .................................. 11 - -1. Introduction - - 1.1. Purpose - - The purpose of this specification is to define a lossless - compressed data format that: - - * Is independent of CPU type, operating system, file system, - and character set, and hence can be used for interchange; - * Can compress or decompress a data stream (as opposed to a - randomly accessible file) to produce another data stream, - using only an a priori bounded amount of intermediate - storage, and hence can be used in data communications or - similar structures such as Unix filters; - * Compresses data with efficiency comparable to the best - currently available general-purpose compression methods, - and in particular considerably better than the "compress" - program; - * Can be implemented readily in a manner not covered by - patents, and hence can be practiced freely; - * Is compatible with the file format produced by the current - widely used gzip utility, in that conforming decompressors - will be able to read data produced by the existing gzip - compressor. - - - - -Deutsch Informational [Page 2] - -RFC 1952 GZIP File Format Specification May 1996 - - - The data format defined by this specification does not attempt to: - - * Provide random access to compressed data; - * Compress specialized data (e.g., raster graphics) as well as - the best currently available specialized algorithms. - - 1.2. Intended audience - - This specification is intended for use by implementors of software - to compress data into gzip format and/or decompress data from gzip - format. - - The text of the specification assumes a basic background in - programming at the level of bits and other primitive data - representations. - - 1.3. Scope - - The specification specifies a compression method and a file format - (the latter assuming only that a file can store a sequence of - arbitrary bytes). It does not specify any particular interface to - a file system or anything about character sets or encodings - (except for file names and comments, which are optional). - - 1.4. Compliance - - Unless otherwise indicated below, a compliant decompressor must be - able to accept and decompress any file that conforms to all the - specifications presented here; a compliant compressor must produce - files that conform to all the specifications presented here. The - material in the appendices is not part of the specification per se - and is not relevant to compliance. - - 1.5. Definitions of terms and conventions used - - byte: 8 bits stored or transmitted as a unit (same as an octet). - (For this specification, a byte is exactly 8 bits, even on - machines which store a character on a number of bits different - from 8.) See below for the numbering of bits within a byte. - - 1.6. Changes from previous versions - - There have been no technical changes to the gzip format since - version 4.1 of this specification. In version 4.2, some - terminology was changed, and the sample CRC code was rewritten for - clarity and to eliminate the requirement for the caller to do pre- - and post-conditioning. Version 4.3 is a conversion of the - specification to RFC style. - - - -Deutsch Informational [Page 3] - -RFC 1952 GZIP File Format Specification May 1996 - - -2. Detailed specification - - 2.1. Overall conventions - - In the diagrams below, a box like this: - - +---+ - | | <-- the vertical bars might be missing - +---+ - - represents one byte; a box like this: - - +==============+ - | | - +==============+ - - represents a variable number of bytes. - - Bytes stored within a computer do not have a "bit order", since - they are always treated as a unit. However, a byte considered as - an integer between 0 and 255 does have a most- and least- - significant bit, and since we write numbers with the most- - significant digit on the left, we also write bytes with the most- - significant bit on the left. In the diagrams below, we number the - bits of a byte so that bit 0 is the least-significant bit, i.e., - the bits are numbered: - - +--------+ - |76543210| - +--------+ - - This document does not address the issue of the order in which - bits of a byte are transmitted on a bit-sequential medium, since - the data format described here is byte- rather than bit-oriented. - - Within a computer, a number may occupy multiple bytes. All - multi-byte numbers in the format described here are stored with - the least-significant byte first (at the lower memory address). - For example, the decimal number 520 is stored as: - - 0 1 - +--------+--------+ - |00001000|00000010| - +--------+--------+ - ^ ^ - | | - | + more significant byte = 2 x 256 - + less significant byte = 8 - - - -Deutsch Informational [Page 4] - -RFC 1952 GZIP File Format Specification May 1996 - - - 2.2. File format - - A gzip file consists of a series of "members" (compressed data - sets). The format of each member is specified in the following - section. The members simply appear one after another in the file, - with no additional information before, between, or after them. - - 2.3. Member format - - Each member has the following structure: - - +---+---+---+---+---+---+---+---+---+---+ - |ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->) - +---+---+---+---+---+---+---+---+---+---+ - - (if FLG.FEXTRA set) - - +---+---+=================================+ - | XLEN |...XLEN bytes of "extra field"...| (more-->) - +---+---+=================================+ - - (if FLG.FNAME set) - - +=========================================+ - |...original file name, zero-terminated...| (more-->) - +=========================================+ - - (if FLG.FCOMMENT set) - - +===================================+ - |...file comment, zero-terminated...| (more-->) - +===================================+ - - (if FLG.FHCRC set) - - +---+---+ - | CRC16 | - +---+---+ - - +=======================+ - |...compressed blocks...| (more-->) - +=======================+ - - 0 1 2 3 4 5 6 7 - +---+---+---+---+---+---+---+---+ - | CRC32 | ISIZE | - +---+---+---+---+---+---+---+---+ - - - - -Deutsch Informational [Page 5] - -RFC 1952 GZIP File Format Specification May 1996 - - - 2.3.1. Member header and trailer - - ID1 (IDentification 1) - ID2 (IDentification 2) - These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139 - (0x8b, \213), to identify the file as being in gzip format. - - CM (Compression Method) - This identifies the compression method used in the file. CM - = 0-7 are reserved. CM = 8 denotes the "deflate" - compression method, which is the one customarily used by - gzip and which is documented elsewhere. - - FLG (FLaGs) - This flag byte is divided into individual bits as follows: - - bit 0 FTEXT - bit 1 FHCRC - bit 2 FEXTRA - bit 3 FNAME - bit 4 FCOMMENT - bit 5 reserved - bit 6 reserved - bit 7 reserved - - If FTEXT is set, the file is probably ASCII text. This is - an optional indication, which the compressor may set by - checking a small amount of the input data to see whether any - non-ASCII characters are present. In case of doubt, FTEXT - is cleared, indicating binary data. For systems which have - different file formats for ascii text and binary data, the - decompressor can use FTEXT to choose the appropriate format. - We deliberately do not specify the algorithm used to set - this bit, since a compressor always has the option of - leaving it cleared and a decompressor always has the option - of ignoring it and letting some other program handle issues - of data conversion. - - If FHCRC is set, a CRC16 for the gzip header is present, - immediately before the compressed data. The CRC16 consists - of the two least significant bytes of the CRC32 for all - bytes of the gzip header up to and not including the CRC16. - [The FHCRC bit was never set by versions of gzip up to - 1.2.4, even though it was documented with a different - meaning in gzip 1.2.4.] - - If FEXTRA is set, optional extra fields are present, as - described in a following section. - - - -Deutsch Informational [Page 6] - -RFC 1952 GZIP File Format Specification May 1996 - - - If FNAME is set, an original file name is present, - terminated by a zero byte. The name must consist of ISO - 8859-1 (LATIN-1) characters; on operating systems using - EBCDIC or any other character set for file names, the name - must be translated to the ISO LATIN-1 character set. This - is the original name of the file being compressed, with any - directory components removed, and, if the file being - compressed is on a file system with case insensitive names, - forced to lower case. There is no original file name if the - data was compressed from a source other than a named file; - for example, if the source was stdin on a Unix system, there - is no file name. - - If FCOMMENT is set, a zero-terminated file comment is - present. This comment is not interpreted; it is only - intended for human consumption. The comment must consist of - ISO 8859-1 (LATIN-1) characters. Line breaks should be - denoted by a single line feed character (10 decimal). - - Reserved FLG bits must be zero. - - MTIME (Modification TIME) - This gives the most recent modification time of the original - file being compressed. The time is in Unix format, i.e., - seconds since 00:00:00 GMT, Jan. 1, 1970. (Note that this - may cause problems for MS-DOS and other systems that use - local rather than Universal time.) If the compressed data - did not come from a file, MTIME is set to the time at which - compression started. MTIME = 0 means no time stamp is - available. - - XFL (eXtra FLags) - These flags are available for use by specific compression - methods. The "deflate" method (CM = 8) sets these flags as - follows: - - XFL = 2 - compressor used maximum compression, - slowest algorithm - XFL = 4 - compressor used fastest algorithm - - OS (Operating System) - This identifies the type of file system on which compression - took place. This may be useful in determining end-of-line - convention for text files. The currently defined values are - as follows: - - - - - - -Deutsch Informational [Page 7] - -RFC 1952 GZIP File Format Specification May 1996 - - - 0 - FAT filesystem (MS-DOS, OS/2, NT/Win32) - 1 - Amiga - 2 - VMS (or OpenVMS) - 3 - Unix - 4 - VM/CMS - 5 - Atari TOS - 6 - HPFS filesystem (OS/2, NT) - 7 - Macintosh - 8 - Z-System - 9 - CP/M - 10 - TOPS-20 - 11 - NTFS filesystem (NT) - 12 - QDOS - 13 - Acorn RISCOS - 255 - unknown - - XLEN (eXtra LENgth) - If FLG.FEXTRA is set, this gives the length of the optional - extra field. See below for details. - - CRC32 (CRC-32) - This contains a Cyclic Redundancy Check value of the - uncompressed data computed according to CRC-32 algorithm - used in the ISO 3309 standard and in section 8.1.1.6.2 of - ITU-T recommendation V.42. (See http://www.iso.ch for - ordering ISO documents. See gopher://info.itu.ch for an - online version of ITU-T V.42.) - - ISIZE (Input SIZE) - This contains the size of the original (uncompressed) input - data modulo 2^32. - - 2.3.1.1. Extra field - - If the FLG.FEXTRA bit is set, an "extra field" is present in - the header, with total length XLEN bytes. It consists of a - series of subfields, each of the form: - - +---+---+---+---+==================================+ - |SI1|SI2| LEN |... LEN bytes of subfield data ...| - +---+---+---+---+==================================+ - - SI1 and SI2 provide a subfield ID, typically two ASCII letters - with some mnemonic value. Jean-Loup Gailly - is maintaining a registry of subfield - IDs; please send him any subfield ID you wish to use. Subfield - IDs with SI2 = 0 are reserved for future use. The following - IDs are currently defined: - - - -Deutsch Informational [Page 8] - -RFC 1952 GZIP File Format Specification May 1996 - - - SI1 SI2 Data - ---------- ---------- ---- - 0x41 ('A') 0x70 ('P') Apollo file type information - - LEN gives the length of the subfield data, excluding the 4 - initial bytes. - - 2.3.1.2. Compliance - - A compliant compressor must produce files with correct ID1, - ID2, CM, CRC32, and ISIZE, but may set all the other fields in - the fixed-length part of the header to default values (255 for - OS, 0 for all others). The compressor must set all reserved - bits to zero. - - A compliant decompressor must check ID1, ID2, and CM, and - provide an error indication if any of these have incorrect - values. It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC - at least so it can skip over the optional fields if they are - present. It need not examine any other part of the header or - trailer; in particular, a decompressor may ignore FTEXT and OS - and always produce binary output, and still be compliant. A - compliant decompressor must give an error indication if any - reserved bit is non-zero, since such a bit could indicate the - presence of a new field that would cause subsequent data to be - interpreted incorrectly. - -3. References - - [1] "Information Processing - 8-bit single-byte coded graphic - character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987). - The ISO 8859-1 (Latin-1) character set is a superset of 7-bit - ASCII. Files defining this character set are available as - iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/ - - [2] ISO 3309 - - [3] ITU-T recommendation V.42 - - [4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", - available in ftp://ftp.uu.net/pub/archiving/zip/doc/ - - [5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in - ftp://prep.ai.mit.edu/pub/gnu/ - - [6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table - Look-Up", Communications of the ACM, 31(8), pp.1008-1013. - - - - -Deutsch Informational [Page 9] - -RFC 1952 GZIP File Format Specification May 1996 - - - [7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal, - pp.118-133. - - [8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt, - describing the CRC concept. - -4. Security Considerations - - Any data compression method involves the reduction of redundancy in - the data. Consequently, any corruption of the data is likely to have - severe effects and be difficult to correct. Uncompressed text, on - the other hand, will probably still be readable despite the presence - of some corrupted bytes. - - It is recommended that systems using this data format provide some - means of validating the integrity of the compressed data, such as by - setting and checking the CRC-32 check value. - -5. Acknowledgements - - Trademarks cited in this document are the property of their - respective owners. - - Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler, - the related software described in this specification. Glenn - Randers-Pehrson converted this document to RFC and HTML format. - -6. Author's Address - - L. Peter Deutsch - Aladdin Enterprises - 203 Santa Margarita Ave. - Menlo Park, CA 94025 - - Phone: (415) 322-0103 (AM only) - FAX: (415) 322-1734 - EMail: - - Questions about the technical content of this specification can be - sent by email to: - - Jean-Loup Gailly and - Mark Adler - - Editorial comments on this specification can be sent by email to: - - L. Peter Deutsch and - Glenn Randers-Pehrson - - - -Deutsch Informational [Page 10] - -RFC 1952 GZIP File Format Specification May 1996 - - -7. Appendix: Jean-Loup Gailly's gzip utility - - The most widely used implementation of gzip compression, and the - original documentation on which this specification is based, were - created by Jean-Loup Gailly . Since this - implementation is a de facto standard, we mention some more of its - features here. Again, the material in this section is not part of - the specification per se, and implementations need not follow it to - be compliant. - - When compressing or decompressing a file, gzip preserves the - protection, ownership, and modification time attributes on the local - file system, since there is no provision for representing protection - attributes in the gzip file format itself. Since the file format - includes a modification time, the gzip decompressor provides a - command line switch that assigns the modification time from the file, - rather than the local modification time of the compressed input, to - the decompressed output. - -8. Appendix: Sample CRC Code - - The following sample code represents a practical implementation of - the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42 - for a formal specification.) - - The sample code is in the ANSI C programming language. Non C users - may find it easier to read with these hints: - - & Bitwise AND operator. - ^ Bitwise exclusive-OR operator. - >> Bitwise right shift operator. When applied to an - unsigned quantity, as here, right shift inserts zero - bit(s) at the left. - ! Logical NOT operator. - ++ "n++" increments the variable n. - 0xNNN 0x introduces a hexadecimal (base 16) constant. - Suffix L indicates a long value (at least 32 bits). - - /* Table of CRCs of all 8-bit messages. */ - unsigned long crc_table[256]; - - /* Flag: has the table been computed? Initially false. */ - int crc_table_computed = 0; - - /* Make the table for a fast CRC. */ - void make_crc_table(void) - { - unsigned long c; - - - -Deutsch Informational [Page 11] - -RFC 1952 GZIP File Format Specification May 1996 - - - int n, k; - for (n = 0; n < 256; n++) { - c = (unsigned long) n; - for (k = 0; k < 8; k++) { - if (c & 1) { - c = 0xedb88320L ^ (c >> 1); - } else { - c = c >> 1; - } - } - crc_table[n] = c; - } - crc_table_computed = 1; - } - - /* - Update a running crc with the bytes buf[0..len-1] and return - the updated crc. The crc should be initialized to zero. Pre- and - post-conditioning (one's complement) is performed within this - function so it shouldn't be done by the caller. Usage example: - - unsigned long crc = 0L; - - while (read_buffer(buffer, length) != EOF) { - crc = update_crc(crc, buffer, length); - } - if (crc != original_crc) error(); - */ - unsigned long update_crc(unsigned long crc, - unsigned char *buf, int len) - { - unsigned long c = crc ^ 0xffffffffL; - int n; - - if (!crc_table_computed) - make_crc_table(); - for (n = 0; n < len; n++) { - c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); - } - return c ^ 0xffffffffL; - } - - /* Return the CRC of the bytes buf[0..len-1]. */ - unsigned long crc(unsigned char *buf, int len) - { - return update_crc(0L, buf, len); - } - - - - -Deutsch Informational [Page 12] - diff --git a/contrib/libzlib-ng/doc/txtvsbin.txt b/contrib/libzlib-ng/doc/txtvsbin.txt deleted file mode 100644 index 3d0f0634f72..00000000000 --- a/contrib/libzlib-ng/doc/txtvsbin.txt +++ /dev/null @@ -1,107 +0,0 @@ -A Fast Method for Identifying Plain Text Files -============================================== - - -Introduction ------------- - -Given a file coming from an unknown source, it is sometimes desirable -to find out whether the format of that file is plain text. Although -this may appear like a simple task, a fully accurate detection of the -file type requires heavy-duty semantic analysis on the file contents. -It is, however, possible to obtain satisfactory results by employing -various heuristics. - -Previous versions of PKZip and other zip-compatible compression tools -were using a crude detection scheme: if more than 80% (4/5) of the bytes -found in a certain buffer are within the range [7..127], the file is -labeled as plain text, otherwise it is labeled as binary. A prominent -limitation of this scheme is the restriction to Latin-based alphabets. -Other alphabets, like Greek, Cyrillic or Asian, make extensive use of -the bytes within the range [128..255], and texts using these alphabets -are most often misidentified by this scheme; in other words, the rate -of false negatives is sometimes too high, which means that the recall -is low. Another weakness of this scheme is a reduced precision, due to -the false positives that may occur when binary files containing large -amounts of textual characters are misidentified as plain text. - -In this article we propose a new, simple detection scheme that features -a much increased precision and a near-100% recall. This scheme is -designed to work on ASCII, Unicode and other ASCII-derived alphabets, -and it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.) -and variable-sized encodings (ISO-2022, UTF-8, etc.). Wider encodings -(UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however. - - -The Algorithm -------------- - -The algorithm works by dividing the set of bytecodes [0..255] into three -categories: -- The white list of textual bytecodes: - 9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255. -- The gray list of tolerated bytecodes: - 7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC). -- The black list of undesired, non-textual bytecodes: - 0 (NUL) to 6, 14 to 31. - -If a file contains at least one byte that belongs to the white list and -no byte that belongs to the black list, then the file is categorized as -plain text; otherwise, it is categorized as binary. (The boundary case, -when the file is empty, automatically falls into the latter category.) - - -Rationale ---------- - -The idea behind this algorithm relies on two observations. - -The first observation is that, although the full range of 7-bit codes -[0..127] is properly specified by the ASCII standard, most control -characters in the range [0..31] are not used in practice. The only -widely-used, almost universally-portable control codes are 9 (TAB), -10 (LF) and 13 (CR). There are a few more control codes that are -recognized on a reduced range of platforms and text viewers/editors: -7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these -codes are rarely (if ever) used alone, without being accompanied by -some printable text. Even the newer, portable text formats such as -XML avoid using control characters outside the list mentioned here. - -The second observation is that most of the binary files tend to contain -control characters, especially 0 (NUL). Even though the older text -detection schemes observe the presence of non-ASCII codes from the range -[128..255], the precision rarely has to suffer if this upper range is -labeled as textual, because the files that are genuinely binary tend to -contain both control characters and codes from the upper range. On the -other hand, the upper range needs to be labeled as textual, because it -is used by virtually all ASCII extensions. In particular, this range is -used for encoding non-Latin scripts. - -Since there is no counting involved, other than simply observing the -presence or the absence of some byte values, the algorithm produces -consistent results, regardless what alphabet encoding is being used. -(If counting were involved, it could be possible to obtain different -results on a text encoded, say, using ISO-8859-16 versus UTF-8.) - -There is an extra category of plain text files that are "polluted" with -one or more black-listed codes, either by mistake or by peculiar design -considerations. In such cases, a scheme that tolerates a small fraction -of black-listed codes would provide an increased recall (i.e. more true -positives). This, however, incurs a reduced precision overall, since -false positives are more likely to appear in binary files that contain -large chunks of textual data. Furthermore, "polluted" plain text should -be regarded as binary by general-purpose text detection schemes, because -general-purpose text processing algorithms might not be applicable. -Under this premise, it is safe to say that our detection method provides -a near-100% recall. - -Experiments have been run on many files coming from various platforms -and applications. We tried plain text files, system logs, source code, -formatted office documents, compiled object code, etc. The results -confirm the optimistic assumptions about the capabilities of this -algorithm. - - --- -Cosmin Truta -Last updated: 2006-May-28 diff --git a/contrib/libzlib-ng/gzclose.c b/contrib/libzlib-ng/gzclose.c deleted file mode 100644 index 48d6a86f04b..00000000000 --- a/contrib/libzlib-ng/gzclose.c +++ /dev/null @@ -1,23 +0,0 @@ -/* gzclose.c -- zlib gzclose() function - * Copyright (C) 2004, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* gzclose() is in a separate file so that it is linked in only if it is used. - That way the other gzclose functions can be used instead to avoid linking in - unneeded compression or decompression routines. */ -int ZEXPORT gzclose(gzFile file) { -#ifndef NO_GZCOMPRESS - gz_statep state; - - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); -#else - return gzclose_r(file); -#endif -} diff --git a/contrib/libzlib-ng/gzguts.h b/contrib/libzlib-ng/gzguts.h deleted file mode 100644 index 0921f176abf..00000000000 --- a/contrib/libzlib-ng/gzguts.h +++ /dev/null @@ -1,158 +0,0 @@ -#ifndef GZGUTS_H_ -#define GZGUTS_H_ -/* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#ifdef _LARGEFILE64_SOURCE -# ifndef _LARGEFILE_SOURCE -# define _LARGEFILE_SOURCE 1 -# endif -# ifdef _FILE_OFFSET_BITS -# undef _FILE_OFFSET_BITS -# endif -#endif - -#if defined(HAVE_INTERNAL) -# define ZLIB_INTERNAL __attribute__((visibility ("internal"))) -#elif defined(HAVE_HIDDEN) -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include -#include -#include -#include -#include -#include "zlib.h" - -#ifdef WIN32 -# include -#endif - -#if defined(_MSC_VER) || defined(WIN32) -# include -#endif - -#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW__) -# define WIDECHAR -#endif - -#ifdef WINAPI_FAMILY -# define open _open -# define read _read -# define write _write -# define close _close -#endif - -/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -#if !defined(STDC99) && !defined(__CYGWIN__) && !defined(__MINGW__) && defined(WIN32) -# if !defined(vsnprintf) -# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) -# define vsnprintf _vsnprintf -# endif -# endif -#endif - -/* unlike snprintf (which is required in C99), _snprintf does not guarantee - null termination of the result -- however this is only used in gzlib.c - where the result is assured to fit in the space provided */ -#if defined(_MSC_VER) && _MSC_VER < 1900 -# define snprintf _snprintf -#endif - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -/* get errno and strerror definition */ -#ifndef NO_STRERROR -# include -# define zstrerror() strerror(errno) -#else -# define zstrerror() "stdio error (consult errno)" -#endif - -/* provide prototypes for these when building zlib without LFS */ -#if (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) && defined(WITH_GZFILEOP) - ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); - ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); - ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); - ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); -#endif - -/* default memLevel */ -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif - -/* default i/o buffer size -- double this for output when reading (this and - twice this must be able to fit in an unsigned type) */ -#define GZBUFSIZE 8192 - -/* gzip modes, also provide a little integrity check on the passed structure */ -#define GZ_NONE 0 -#define GZ_READ 7247 -#define GZ_WRITE 31153 -#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ - -/* values for gz_state how */ -#define LOOK 0 /* look for a gzip header */ -#define COPY 1 /* copy input directly */ -#define GZIP 2 /* decompress a gzip stream */ - -/* internal gzip file state data structure */ -typedef struct { - /* exposed contents for gzgetc() macro */ - struct gzFile_s x; /* "x" for exposed */ - /* x.have: number of bytes available at x.next */ - /* x.next: next output data to deliver or write */ - /* x.pos: current position in uncompressed data */ - /* used for both reading and writing */ - int mode; /* see gzip modes above */ - int fd; /* file descriptor */ - char *path; /* path or fd for error messages */ - unsigned size; /* buffer size, zero if not allocated yet */ - unsigned want; /* requested buffer size, default is GZBUFSIZE */ - unsigned char *in; /* input buffer (double-sized when writing) */ - unsigned char *out; /* output buffer (double-sized when reading) */ - int direct; /* 0 if processing gzip, 1 if transparent */ - /* just for reading */ - int how; /* 0: get header, 1: copy, 2: decompress */ - z_off64_t start; /* where the gzip data started, for rewinding */ - int eof; /* true if end of input file reached */ - int past; /* true if read requested past end */ - /* just for writing */ - int level; /* compression level */ - int strategy; /* compression strategy */ - /* seek request */ - z_off64_t skip; /* amount to skip (already rewound if backwards) */ - int seek; /* true if seek request pending */ - /* error information */ - int err; /* error code */ - char *msg; /* error message */ - /* zlib inflate or deflate stream */ - z_stream strm; /* stream structure in-place (not a pointer) */ -} gz_state; -typedef gz_state *gz_statep; - -/* shared functions */ -void ZLIB_INTERNAL gz_error(gz_statep, int, const char *); - -/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t - value -- needed when comparing unsigned to z_off64_t, which is signed - (possible z_off64_t types off_t, off64_t, and long are all signed) */ -#ifdef INT_MAX -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) -#else -unsigned ZLIB_INTERNAL gz_intmax(void); -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) -#endif - -#endif /* GZGUTS_H_ */ diff --git a/contrib/libzlib-ng/gzlib.c b/contrib/libzlib-ng/gzlib.c deleted file mode 100644 index e5ebe5fa7fa..00000000000 --- a/contrib/libzlib-ng/gzlib.c +++ /dev/null @@ -1,518 +0,0 @@ -/* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -#if defined(WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__) -# define LSEEK _lseeki64 -#else -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 -# define LSEEK lseek64 -#else -# define LSEEK lseek -#endif -#endif - -/* Local functions */ -local void gz_reset(gz_statep); -local gzFile gz_open(const void *, int, const char *); - -/* Reset gzip file state */ -local void gz_reset(gz_statep state) { - state->x.have = 0; /* no output data available */ - if (state->mode == GZ_READ) { /* for reading ... */ - state->eof = 0; /* not at end of file */ - state->past = 0; /* have not read past end yet */ - state->how = LOOK; /* look for gzip header */ - } - state->seek = 0; /* no seek request pending */ - gz_error(state, Z_OK, NULL); /* clear error */ - state->x.pos = 0; /* no uncompressed data yet */ - state->strm.avail_in = 0; /* no input data yet */ -} - -/* Open a gzip file either by name or file descriptor. */ -local gzFile gz_open(const void *path, int fd, const char *mode) { - gz_statep state; - size_t len; - int oflag; -#ifdef O_CLOEXEC - int cloexec = 0; -#endif -#ifdef O_EXCL - int exclusive = 0; -#endif - - /* check input */ - if (path == NULL) - return NULL; - - /* allocate gzFile structure to return */ - state = (gz_statep)malloc(sizeof(gz_state)); - if (state == NULL) - return NULL; - state->size = 0; /* no buffers allocated yet */ - state->want = GZBUFSIZE; /* requested buffer size */ - state->msg = NULL; /* no error message yet */ - - /* interpret mode */ - state->mode = GZ_NONE; - state->level = Z_DEFAULT_COMPRESSION; - state->strategy = Z_DEFAULT_STRATEGY; - state->direct = 0; - while (*mode) { - if (*mode >= '0' && *mode <= '9') { - state->level = *mode - '0'; - } else { - switch (*mode) { - case 'r': - state->mode = GZ_READ; - break; -#ifndef NO_GZCOMPRESS - case 'w': - state->mode = GZ_WRITE; - break; - case 'a': - state->mode = GZ_APPEND; - break; -#endif - case '+': /* can't read and write at the same time */ - free(state); - return NULL; - case 'b': /* ignore -- will request binary anyway */ - break; -#ifdef O_CLOEXEC - case 'e': - cloexec = 1; - break; -#endif -#ifdef O_EXCL - case 'x': - exclusive = 1; - break; -#endif - case 'f': - state->strategy = Z_FILTERED; - break; - case 'h': - state->strategy = Z_HUFFMAN_ONLY; - break; - case 'R': - state->strategy = Z_RLE; - break; - case 'F': - state->strategy = Z_FIXED; - break; - case 'T': - state->direct = 1; - break; - default: /* could consider as an error, but just ignore */ - {} - } - } - mode++; - } - - /* must provide an "r", "w", or "a" */ - if (state->mode == GZ_NONE) { - free(state); - return NULL; - } - - /* can't force transparent read */ - if (state->mode == GZ_READ) { - if (state->direct) { - free(state); - return NULL; - } - state->direct = 1; /* for empty file */ - } - - /* save the path name for error messages */ -#ifdef WIDECHAR - if (fd == -2) { - len = wcstombs(NULL, path, 0); - if (len == (size_t)-1) - len = 0; - } else -#endif - len = strlen((const char *)path); - state->path = (char *)malloc(len + 1); - if (state->path == NULL) { - free(state); - return NULL; - } -#ifdef WIDECHAR - if (fd == -2) - if (len) { - wcstombs(state->path, path, len + 1); - } else { - *(state->path) = 0; - } - else -#endif - snprintf(state->path, len + 1, "%s", (const char *)path); - - /* compute the flags for open() */ - oflag = -#ifdef O_LARGEFILE - O_LARGEFILE | -#endif -#ifdef O_BINARY - O_BINARY | -#endif -#ifdef O_CLOEXEC - (cloexec ? O_CLOEXEC : 0) | -#endif - (state->mode == GZ_READ ? - O_RDONLY : - (O_WRONLY | O_CREAT | -#ifdef O_EXCL - (exclusive ? O_EXCL : 0) | -#endif - (state->mode == GZ_WRITE ? - O_TRUNC : - O_APPEND))); - - /* open the file with the appropriate flags (or just use fd) */ - state->fd = fd > -1 ? fd : ( -#if defined(WIN32) || defined(__MINGW__) - fd == -2 ? _wopen(path, oflag, 0666) : -#elif __CYGWIN__ - fd == -2 ? open(state->path, oflag, 0666) : -#endif - open((const char *)path, oflag, 0666)); - if (state->fd == -1) { - free(state->path); - free(state); - return NULL; - } - if (state->mode == GZ_APPEND) { - LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ - state->mode = GZ_WRITE; /* simplify later checks */ - } - - /* save the current position for rewinding (only if reading) */ - if (state->mode == GZ_READ) { - state->start = LSEEK(state->fd, 0, SEEK_CUR); - if (state->start == -1) state->start = 0; - } - - /* initialize stream */ - gz_reset(state); - - /* return stream */ - return (gzFile)state; -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen(const char *path, const char *mode) { - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen64(const char *path, const char *mode) { - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzdopen(int fd, const char *mode) { - char *path; /* identifier for error messages */ - gzFile gz; - - if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) - return NULL; - snprintf(path, 7 + 3 * sizeof(int), "", fd); /* for debugging */ - gz = gz_open(path, fd, mode); - free(path); - return gz; -} - -/* -- see zlib.h -- */ -#ifdef WIDECHAR -gzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode) { - return gz_open(path, -2, mode); -} -#endif - -/* -- see zlib.h -- */ -int ZEXPORT gzbuffer(gzFile file, unsigned size) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* make sure we haven't already allocated memory */ - if (state->size != 0) - return -1; - - /* check and set requested size */ - if ((size << 1) < size) - return -1; /* need to be able to double it */ - if (size < 2) - size = 2; /* need two bytes to check magic header */ - state->want = size; - return 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzrewind(gzFile file) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* back up and start over */ - if (LSEEK(state->fd, state->start, SEEK_SET) == -1) - return -1; - gz_reset(state); - return 0; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzseek64(gzFile file, z_off64_t offset, int whence) { - unsigned n; - z_off64_t ret; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* check that there's no error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - - /* can only seek from start or relative to current position */ - if (whence != SEEK_SET && whence != SEEK_CUR) - return -1; - - /* normalize offset to a SEEK_CUR specification */ - if (whence == SEEK_SET) - offset -= state->x.pos; - else if (state->seek) - offset += state->skip; - state->seek = 0; - - /* if within raw area while reading, just go there */ - if (state->mode == GZ_READ && state->how == COPY && state->x.pos + offset >= 0) { - ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); - if (ret == -1) - return -1; - state->x.have = 0; - state->eof = 0; - state->past = 0; - state->seek = 0; - gz_error(state, Z_OK, NULL); - state->strm.avail_in = 0; - state->x.pos += offset; - return state->x.pos; - } - - /* calculate skip amount, rewinding if needed for back seek when reading */ - if (offset < 0) { - if (state->mode != GZ_READ) /* writing -- can't go backwards */ - return -1; - offset += state->x.pos; - if (offset < 0) /* before start of file! */ - return -1; - if (gzrewind(file) == -1) /* rewind, then skip to offset */ - return -1; - } - - /* if reading, skip what's in output buffer (one less gzgetc() check) */ - if (state->mode == GZ_READ) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? (unsigned)offset : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - offset -= n; - } - - /* request skip (if not zero) */ - if (offset) { - state->seek = 1; - state->skip = offset; - } - return state->x.pos + offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzseek(gzFile file, z_off_t offset, int whence) { - z_off64_t ret; - - ret = gzseek64(file, (z_off64_t)offset, whence); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gztell64(gzFile file) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* return position */ - return state->x.pos + (state->seek ? state->skip : 0); -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gztell(gzFile file) { - z_off64_t ret; - - ret = gztell64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzoffset64(gzFile file) { - z_off64_t offset; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* compute and return effective offset in file */ - offset = LSEEK(state->fd, 0, SEEK_CUR); - if (offset == -1) - return -1; - if (state->mode == GZ_READ) /* reading */ - offset -= state->strm.avail_in; /* don't count buffered input */ - return offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzoffset(gzFile file) { - z_off64_t ret; - - ret = gzoffset64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzeof(gzFile file) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return 0; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return 0; - - /* return end-of-file state */ - return state->mode == GZ_READ ? state->past : 0; -} - -/* -- see zlib.h -- */ -const char * ZEXPORT gzerror(gzFile file, int *errnum) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return NULL; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return NULL; - - /* return error information */ - if (errnum != NULL) - *errnum = state->err; - return state->err == Z_MEM_ERROR ? "out of memory" : (state->msg == NULL ? "" : state->msg); -} - -/* -- see zlib.h -- */ -void ZEXPORT gzclearerr(gzFile file) { - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return; - - /* clear error and end-of-file */ - if (state->mode == GZ_READ) { - state->eof = 0; - state->past = 0; - } - gz_error(state, Z_OK, NULL); -} - -/* Create an error message in allocated memory and set state->err and - state->msg accordingly. Free any previous error message already there. Do - not try to free or allocate space if the error is Z_MEM_ERROR (out of - memory). Simply save the error message as a static string. If there is an - allocation failure constructing the error message, then convert the error to - out of memory. */ -void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { - /* free previously allocated message and clear */ - if (state->msg != NULL) { - if (state->err != Z_MEM_ERROR) - free(state->msg); - state->msg = NULL; - } - - /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ - if (err != Z_OK && err != Z_BUF_ERROR) - state->x.have = 0; - - /* set error code, and if no message, then done */ - state->err = err; - if (msg == NULL) - return; - - /* for an out of memory error, return literal string when requested */ - if (err == Z_MEM_ERROR) - return; - - /* construct error message with path */ - if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { - state->err = Z_MEM_ERROR; - return; - } - snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, "%s%s%s", state->path, ": ", msg); - return; -} - -#ifndef INT_MAX -/* portably return maximum value for an int (when limits.h presumed not - available) -- we need to do this to cover cases where 2's complement not - used, since C standard permits 1's complement and sign-bit representations, - otherwise we could just use ((unsigned)-1) >> 1 */ -unsigned ZLIB_INTERNAL gz_intmax() { - unsigned p, q; - - p = 1; - do { - q = p; - p <<= 1; - p++; - } while (p > q); - return q >> 1; -} -#endif diff --git a/contrib/libzlib-ng/gzread.c b/contrib/libzlib-ng/gzread.c deleted file mode 100644 index 5db2c5045ba..00000000000 --- a/contrib/libzlib-ng/gzread.c +++ /dev/null @@ -1,538 +0,0 @@ -/* gzread.c -- zlib functions for reading gzip files - * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* Local functions */ -local int gz_load(gz_statep, unsigned char *, unsigned, unsigned *); -local int gz_avail(gz_statep); -local int gz_look(gz_statep); -local int gz_decomp(gz_statep); -local int gz_fetch(gz_statep); -local int gz_skip(gz_statep, z_off64_t); - -/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from - state->fd, and update state->eof, state->err, and state->msg as appropriate. - This function needs to loop on read(), since read() is not guaranteed to - read the number of bytes requested, depending on the type of descriptor. */ -local int gz_load(gz_statep state, unsigned char *buf, unsigned len, unsigned *have) { - int ret; - - *have = 0; - do { - ret = read(state->fd, buf + *have, len - *have); - if (ret <= 0) - break; - *have += ret; - } while (*have < len); - if (ret < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - if (ret == 0) - state->eof = 1; - return 0; -} - -/* Load up input buffer and set eof flag if last data loaded -- return -1 on - error, 0 otherwise. Note that the eof flag is set when the end of the input - file is reached, even though there may be unused data in the buffer. Once - that data has been used, no more attempts will be made to read the file. - If strm->avail_in != 0, then the current data is moved to the beginning of - the input buffer, and then the remainder of the buffer is loaded with the - available data from the input file. */ -local int gz_avail(gz_statep state) { - unsigned got; - z_stream *strm = &(state->strm); - - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - if (state->eof == 0) { - if (strm->avail_in) { /* copy what's there to the start */ - unsigned char *p = state->in; - unsigned const char *q = strm->next_in; - unsigned n = strm->avail_in; - do { - *p++ = *q++; - } while (--n); - } - if (gz_load(state, state->in + strm->avail_in, state->size - strm->avail_in, &got) == -1) - return -1; - strm->avail_in += got; - strm->next_in = state->in; - } - return 0; -} - -/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. - If this is the first time in, allocate required memory. state->how will be - left unchanged if there is no more input data available, will be set to COPY - if there is no gzip header and direct copying will be performed, or it will - be set to GZIP for decompression. If direct copying, then leftover input - data from the input buffer will be copied to the output buffer. In that - case, all further file reads will be directly to either the output buffer or - a user buffer. If decompressing, the inflate state will be initialized. - gz_look() will return 0 on success or -1 on failure. */ -local int gz_look(gz_statep state) { - z_stream *strm = &(state->strm); - - /* allocate read buffers and inflate memory */ - if (state->size == 0) { - /* allocate buffers */ - state->in = (unsigned char *)malloc(state->want); - state->out = (unsigned char *)malloc(state->want << 1); - if (state->in == NULL || state->out == NULL) { - if (state->out != NULL) - free(state->out); - if (state->in != NULL) - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - state->size = state->want; - - /* allocate inflate memory */ - state->strm.zalloc = Z_NULL; - state->strm.zfree = Z_NULL; - state->strm.opaque = Z_NULL; - state->strm.avail_in = 0; - state->strm.next_in = Z_NULL; - if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ - free(state->out); - free(state->in); - state->size = 0; - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - } - - /* get at least the magic bytes in the input buffer */ - if (strm->avail_in < 2) { - if (gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) - return 0; - } - - /* look for gzip magic bytes -- if there, do gzip decoding (note: there is - a logical dilemma here when considering the case of a partially written - gzip file, to wit, if a single 31 byte is written, then we cannot tell - whether this is a single-byte file, or just a partially written gzip - file -- for here we assume that if a gzip file is being written, then - the header will be written in a single operation, so that reading a - single byte is sufficient indication that it is not a gzip file) */ - if (strm->avail_in > 1 && - strm->next_in[0] == 31 && strm->next_in[1] == 139) { - inflateReset(strm); - state->how = GZIP; - state->direct = 0; - return 0; - } - - /* no gzip header -- if we were decoding gzip before, then this is trailing - garbage. Ignore the trailing garbage and finish. */ - if (state->direct == 0) { - strm->avail_in = 0; - state->eof = 1; - state->x.have = 0; - return 0; - } - - /* doing raw i/o, copy any leftover input to output -- this assumes that - the output buffer is larger than the input buffer, which also assures - space for gzungetc() */ - state->x.next = state->out; - if (strm->avail_in) { - memcpy(state->x.next, strm->next_in, strm->avail_in); - state->x.have = strm->avail_in; - strm->avail_in = 0; - } - state->how = COPY; - state->direct = 1; - return 0; -} - -/* Decompress from input to the provided next_out and avail_out in the state. - On return, state->x.have and state->x.next point to the just decompressed - data. If the gzip stream completes, state->how is reset to LOOK to look for - the next gzip stream or raw data, once state->x.have is depleted. Returns 0 - on success, -1 on failure. */ -local int gz_decomp(gz_statep state) { - int ret = Z_OK; - unsigned had; - z_stream *strm = &(state->strm); - - /* fill output buffer up to end of deflate stream */ - had = strm->avail_out; - do { - /* get more input for inflate() */ - if (strm->avail_in == 0 && gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) { - gz_error(state, Z_BUF_ERROR, "unexpected end of file"); - break; - } - - /* decompress and handle errors */ - ret = inflate(strm, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { - gz_error(state, Z_STREAM_ERROR, "internal error: inflate stream corrupt"); - return -1; - } - if (ret == Z_MEM_ERROR) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ - gz_error(state, Z_DATA_ERROR, strm->msg == NULL ? "compressed data error" : strm->msg); - return -1; - } - } while (strm->avail_out && ret != Z_STREAM_END); - - /* update available output */ - state->x.have = had - strm->avail_out; - state->x.next = strm->next_out - state->x.have; - - /* if the gzip stream completed successfully, look for another */ - if (ret == Z_STREAM_END) - state->how = LOOK; - - /* good decompression */ - return 0; -} - -/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. - Data is either copied from the input file or decompressed from the input - file depending on state->how. If state->how is LOOK, then a gzip header is - looked for to determine whether to copy or decompress. Returns -1 on error, - otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the - end of the input file has been reached and all data has been processed. */ -local int gz_fetch(gz_statep state) { - z_stream *strm = &(state->strm); - - do { - switch (state->how) { - case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ - if (gz_look(state) == -1) - return -1; - if (state->how == LOOK) - return 0; - break; - case COPY: /* -> COPY */ - if (gz_load(state, state->out, state->size << 1, &(state->x.have)) - == -1) - return -1; - state->x.next = state->out; - return 0; - case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ - strm->avail_out = state->size << 1; - strm->next_out = state->out; - if (gz_decomp(state) == -1) - return -1; - } - } while (state->x.have == 0 && (!state->eof || strm->avail_in)); - return 0; -} - -/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ -local int gz_skip(gz_statep state, z_off64_t len) { - unsigned n; - - /* skip over len bytes or reach end-of-file, whichever comes first */ - while (len) - /* skip over whatever is in output buffer */ - if (state->x.have) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? - (unsigned)len : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - len -= n; - } else if (state->eof && state->strm.avail_in == 0) { - /* output buffer empty -- return if we're at the end of the input */ - break; - } else { - /* need more data to skip -- load up output buffer */ - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return -1; - } - return 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzread(gzFile file, void *buf, unsigned len) { - unsigned got, n; - gz_statep state; - z_stream *strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids the flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); - return -1; - } - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return -1; - } - - /* get len bytes to buf, or less than len if at the end */ - got = 0; - do { - /* first just try copying data from the output buffer */ - if (state->x.have) { - n = state->x.have > len ? len : state->x.have; - memcpy(buf, state->x.next, n); - state->x.next += n; - state->x.have -= n; - } else if (state->eof && strm->avail_in == 0) { - /* output buffer empty -- return if we're at the end of the input */ - state->past = 1; /* tried to read past end */ - break; - } else if (state->how == LOOK || len < (state->size << 1)) { - /* need output data -- for small len or new stream load up our output buffer */ - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return -1; - continue; /* no progress yet -- go back to copy above */ - /* the copy above assures that we will leave with space in the - output buffer, allowing at least one gzungetc() to succeed */ - } else if (state->how == COPY) { /* read directly */ - /* large len -- read directly into user buffer */ - if (gz_load(state, (unsigned char *)buf, len, &n) == -1) - return -1; - } else { /* state->how == GZIP */ - /* large len -- decompress directly into user buffer */ - strm->avail_out = len; - strm->next_out = (unsigned char *)buf; - if (gz_decomp(state) == -1) - return -1; - n = state->x.have; - state->x.have = 0; - } - - /* update progress */ - len -= n; - buf = (char *)buf + n; - got += n; - state->x.pos += n; - } while (len); - - /* return number of bytes read into user buffer (will fit in int) */ - return (int)got; -} - -/* -- see zlib.h -- */ -#undef gzgetc -int ZEXPORT gzgetc(gzFile file) { - int ret; - unsigned char buf[1]; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* try output buffer (no need to check for skip request) */ - if (state->x.have) { - state->x.have--; - state->x.pos++; - return *(state->x.next)++; - } - - /* nothing there -- try gzread() */ - ret = gzread(file, buf, 1); - return ret < 1 ? -1 : buf[0]; -} - -int ZEXPORT gzgetc_(gzFile file) { - return gzgetc(file); -} - -/* -- see zlib.h -- */ -int ZEXPORT gzungetc(int c, gzFile file) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return -1; - } - - /* can't push EOF */ - if (c < 0) - return -1; - - /* if output buffer empty, put byte at end (allows more pushing) */ - if (state->x.have == 0) { - state->x.have = 1; - state->x.next = state->out + (state->size << 1) - 1; - state->x.next[0] = c; - state->x.pos--; - state->past = 0; - return c; - } - - /* if no room, give up (must have already done a gzungetc()) */ - if (state->x.have == (state->size << 1)) { - gz_error(state, Z_DATA_ERROR, "out of room to push characters"); - return -1; - } - - /* slide output data if needed and insert byte before existing data */ - if (state->x.next == state->out) { - unsigned char *src = state->out + state->x.have; - unsigned char *dest = state->out + (state->size << 1); - while (src > state->out) - *--dest = *--src; - state->x.next = dest; - } - state->x.have++; - state->x.next--; - state->x.next[0] = c; - state->x.pos--; - state->past = 0; - return c; -} - -/* -- see zlib.h -- */ -char * ZEXPORT gzgets(gzFile file, char *buf, int len) { - unsigned left, n; - char *str; - unsigned char *eol; - gz_statep state; - - /* check parameters and get internal structure */ - if (file == NULL || buf == NULL || len < 1) - return NULL; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return NULL; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return NULL; - } - - /* copy output bytes up to new line or len - 1, whichever comes first -- - append a terminating zero to the string (we don't check for a zero in - the contents, let the user worry about that) */ - str = buf; - left = (unsigned)len - 1; - if (left) do { - /* assure that something is in the output buffer */ - if (state->x.have == 0 && gz_fetch(state) == -1) - return NULL; /* error */ - if (state->x.have == 0) { /* end of file */ - state->past = 1; /* read past end */ - break; /* return what we have */ - } - - /* look for end-of-line in current output buffer */ - n = state->x.have > left ? left : state->x.have; - eol = (unsigned char *)memchr(state->x.next, '\n', n); - if (eol != NULL) - n = (unsigned)(eol - state->x.next) + 1; - - /* copy through end-of-line, or remainder if not found */ - memcpy(buf, state->x.next, n); - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - left -= n; - buf += n; - } while (left && eol == NULL); - - /* return terminated string, or if nothing, end of file */ - if (buf == str) - return NULL; - buf[0] = 0; - return str; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzdirect(gzFile file) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - - state = (gz_statep)file; - - /* if the state is not known, but we can find out, then do so (this is - mainly for right after a gzopen() or gzdopen()) */ - if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) - (void)gz_look(state); - - /* return 1 if transparent, 0 if processing a gzip stream */ - return state->direct; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_r(gzFile file) { - int ret, err; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - - state = (gz_statep)file; - - /* check that we're reading */ - if (state->mode != GZ_READ) - return Z_STREAM_ERROR; - - /* free memory and close file */ - if (state->size) { - inflateEnd(&(state->strm)); - free(state->out); - free(state->in); - } - err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; - gz_error(state, Z_OK, NULL); - free(state->path); - ret = close(state->fd); - free(state); - return ret ? Z_ERRNO : err; -} diff --git a/contrib/libzlib-ng/gzwrite.c b/contrib/libzlib-ng/gzwrite.c deleted file mode 100644 index dedaee0cd45..00000000000 --- a/contrib/libzlib-ng/gzwrite.c +++ /dev/null @@ -1,457 +0,0 @@ -/* gzwrite.c -- zlib functions for writing gzip files - * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include -#include "gzguts.h" - -/* Local functions */ -local int gz_init(gz_statep); -local int gz_comp(gz_statep, int); -local int gz_zero(gz_statep, z_off64_t); - -/* Initialize state for writing a gzip file. Mark initialization by setting - state->size to non-zero. Return -1 on failure or 0 on success. */ -local int gz_init(gz_statep state) { - int ret; - z_stream *strm = &(state->strm); - - /* allocate input buffer (double size for gzprintf) */ - state->in = (unsigned char *)malloc(state->want << 1); - if (state->in == NULL) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* only need output buffer and deflate state if compressing */ - if (!state->direct) { - /* allocate output buffer */ - state->out = (unsigned char *)malloc(state->want); - if (state->out == NULL) { - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* allocate deflate memory, set up for gzip compression */ - strm->zalloc = Z_NULL; - strm->zfree = Z_NULL; - strm->opaque = Z_NULL; - ret = deflateInit2(strm, state->level, Z_DEFLATED, MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); - if (ret != Z_OK) { - free(state->out); - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - strm->next_in = NULL; - } - - /* mark state as initialized */ - state->size = state->want; - - /* initialize write buffer if compressing */ - if (!state->direct) { - strm->avail_out = state->size; - strm->next_out = state->out; - state->x.next = strm->next_out; - } - return 0; -} - -/* Compress whatever is at avail_in and next_in and write to the output file. - Return -1 if there is an error writing to the output file, otherwise 0. - flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, - then the deflate() state is reset to start a new gzip stream. If gz->direct - is true, then simply write to the output file without compressing, and - ignore flush. */ -local int gz_comp(gz_statep state, int flush) { - int ret, got; - unsigned have; - z_stream *strm = &(state->strm); - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return -1; - - /* write directly if requested */ - if (state->direct) { - while (strm->avail_in) { - if ((got = write(state->fd, strm->next_in, strm->avail_in)) < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - strm->avail_in -= got; - strm->next_in += got; - } - return 0; - } - - /* run deflate() on provided input until it produces no more output */ - ret = Z_OK; - do { - /* write out current buffer contents if full, or if flushing, but if - doing Z_FINISH then don't write until we get to Z_STREAM_END */ - if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && (flush != Z_FINISH || ret == Z_STREAM_END))) { - while (strm->next_out > state->x.next) { - if ((got = write(state->fd, state->x.next, strm->next_out - state->x.next)) < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - state->x.next += got; - } - if (strm->avail_out == 0) { - strm->avail_out = state->size; - strm->next_out = state->out; - } - } - - /* compress */ - have = strm->avail_out; - ret = deflate(strm, flush); - if (ret == Z_STREAM_ERROR) { - gz_error(state, Z_STREAM_ERROR, "internal error: deflate stream corrupt"); - return -1; - } - have -= strm->avail_out; - } while (have); - - /* if that completed a deflate stream, allow another to start */ - if (flush == Z_FINISH) - deflateReset(strm); - - /* all done, no errors */ - return 0; -} - -/* Compress len zeros to output. Return -1 on error, 0 on success. */ -local int gz_zero(gz_statep state, z_off64_t len) { - int first; - unsigned n; - z_stream *strm = &(state->strm); - - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - - /* compress len zeros (len guaranteed > 0) */ - first = 1; - while (len) { - n = GT_OFF(state->size) || (z_off64_t)state->size > len ? (unsigned)len : state->size; - if (first) { - memset(state->in, 0, n); - first = 0; - } - strm->avail_in = n; - strm->next_in = state->in; - state->x.pos += n; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - len -= n; - } - return 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzwrite(gzFile file, void const *buf, unsigned len) { - unsigned put = len; - gz_statep state; - z_stream *strm; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids the flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); - return 0; - } - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return 0; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } - - /* for small len, copy to input buffer, otherwise compress directly */ - if (len < state->size) { - /* copy to input buffer, compress when full */ - do { - unsigned have, copy; - - if (strm->avail_in == 0) - strm->next_in = state->in; - have = (unsigned)((strm->next_in + strm->avail_in) - state->in); - copy = state->size - have; - if (copy > len) - copy = len; - memcpy(state->in + have, buf, copy); - strm->avail_in += copy; - state->x.pos += copy; - buf = (const char *)buf + copy; - len -= copy; - if (len && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - } while (len); - } else { - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - - /* directly compress user buffer to file */ - strm->avail_in = len; - strm->next_in = (const unsigned char *)buf; - state->x.pos += len; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - } - - /* input was all buffered or compressed (put will fit in int) */ - return (int)put; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputc(gzFile file, int c) { - unsigned have; - unsigned char buf[1]; - gz_statep state; - z_stream *strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return -1; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } - - /* try writing to input buffer for speed (state->size == 0 if buffer not - initialized) */ - if (state->size) { - if (strm->avail_in == 0) - strm->next_in = state->in; - have = (unsigned)((strm->next_in + strm->avail_in) - state->in); - if (have < state->size) { - state->in[have] = c; - strm->avail_in++; - state->x.pos++; - return c & 0xff; - } - } - - /* no room in buffer or not initialized, use gz_write() */ - buf[0] = c; - if (gzwrite(file, buf, 1) != 1) - return -1; - return c & 0xff; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputs(gzFile file, const char *str) { - int ret; - unsigned len; - - /* write string */ - len = (unsigned)strlen(str); - ret = gzwrite(file, str, len); - return ret == 0 && len != 0 ? -1 : ret; -} - -/* -- see zlib.h -- */ -int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { - int len, left; - char *next; - gz_statep state; - z_stream *strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return 0; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } - - /* do the printf() into the input buffer, put length in len -- the input - buffer is double-sized just for this function, so there is guaranteed to - be state->size bytes available after the current contents */ - if (strm->avail_in == 0) - strm->next_in = state->in; - next = (char *)(strm->next_in + strm->avail_in); - next[state->size - 1] = 0; - len = vsnprintf(next, state->size, format, va); - - /* check that printf() results fit in buffer */ - if (len == 0 || len >= state->size || next[state->size - 1] != 0) - return 0; - - /* update buffer and position, compress first half if past that */ - strm->avail_in += len; - state->x.pos += len; - if (strm->avail_in >= state->size) { - left = strm->avail_in - state->size; - strm->avail_in = state->size; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - memcpy(state->in, state->in + state->size, left); - strm->next_in = state->in; - strm->avail_in = left; - } - return (int)len; -} - -int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) { - va_list va; - int ret; - - va_start(va, format); - ret = gzvprintf(file, format, va); - va_end(va); - return ret; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzflush(gzFile file, int flush) { - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* check flush parameter */ - if (flush < 0 || flush > Z_FINISH) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } - - /* compress remaining data with requested flush */ - gz_comp(state, flush); - return state->err; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzsetparams(gzFile file, int level, int strategy) { - gz_statep state; - z_stream *strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* if no change is requested, then do nothing */ - if (level == state->level && strategy == state->strategy) - return Z_OK; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } - - /* change compression parameters for subsequent input */ - if (state->size) { - /* flush previous input with previous parameters before changing */ - if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) - return state->err; - deflateParams(strm, level, strategy); - } - state->level = level; - state->strategy = strategy; - return Z_OK; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_w(gzFile file) { - int ret = Z_OK; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're writing */ - if (state->mode != GZ_WRITE) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - ret = state->err; - } - - /* flush, free memory, and close file */ - if (gz_comp(state, Z_FINISH) == -1) - ret = state->err; - if (state->size) { - if (!state->direct) { - (void)deflateEnd(&(state->strm)); - free(state->out); - } - free(state->in); - } - gz_error(state, Z_OK, NULL); - free(state->path); - if (close(state->fd) == -1) - ret = Z_ERRNO; - free(state); - return ret; -} diff --git a/contrib/libzlib-ng/infback.c b/contrib/libzlib-ng/infback.c deleted file mode 100644 index 9f3dc4645e8..00000000000 --- a/contrib/libzlib-ng/infback.c +++ /dev/null @@ -1,612 +0,0 @@ -/* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2011 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - This code is largely copied from inflate.c. Normally either infback.o or - inflate.o would be linked into an application--not both. The interface - with inffast.c is retained so that optimized assembler-coded versions of - inflate_fast() can be used with either inflate.c or infback.c. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* function prototypes */ -local void fixedtables(struct inflate_state *state); - -/* - strm provides memory allocation functions in zalloc and zfree, or - Z_NULL to use the library memory allocation functions. - - windowBits is in the range 8..15, and window is a user-supplied - window and output buffer that is 2**windowBits bytes. - */ -int ZEXPORT inflateBackInit_(z_stream *strm, int windowBits, unsigned char *window, - const char *version, int stream_size) { - struct inflate_state *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = NULL; - } - if (strm->zfree == (free_func)0) - strm->zfree = zcfree; - state = (struct inflate_state *)ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) - return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state *)state; - state->dmax = 32768U; - state->wbits = windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->wnext = 0; - state->whave = 0; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(struct inflate_state *state) { -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -/* Macros for inflateBack(): */ - -/* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Assure that some input is available. If input is requested, but denied, - then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflateBack() - with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (*next++ << bits); \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflateBack() with - an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - (hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Assure that some output space is available, by writing out the window - if it's full. If the write fails, return from inflateBack() with a - Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* - strm provides the memory allocation functions and window buffer on input, - and provides information on the unused input on return. For Z_DATA_ERROR - returns, strm will also provide an error message. - - in() and out() are the call-back input and output functions. When - inflateBack() needs more input, it calls in(). When inflateBack() has - filled the window with output, or when it completes with data in the - window, it calls out() to write out the data. The application must not - change the provided input until in() is called again or inflateBack() - returns. The application must not change the window/output buffer until - inflateBack() returns. - - in() and out() are called with a descriptor parameter provided in the - inflateBack() call. This parameter can be a structure that provides the - information required to do the read or write, as well as accumulated - information on the input and output such as totals and check values. - - in() should return zero on failure. out() should return non-zero on - failure. If either in() or out() fails, than inflateBack() returns a - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it - was in() or out() that caused in the error. Otherwise, inflateBack() - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format - error, or Z_MEM_ERROR if it could not allocate memory for the state. - inflateBack() can also return Z_STREAM_ERROR if the input parameters - are not correct, i.e. strm is Z_NULL or the state was not initialized. - */ -int ZEXPORT inflateBack(z_stream *strm, in_func in, void *in_desc, out_func out, void *out_desc) { - struct inflate_state *state; - const unsigned char *next; /* next input */ - unsigned char *put; /* next output */ - unsigned have, left; /* available input and output */ - uint32_t hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const uint16_t order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state *)strm->state; - - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; - - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (uint16_t)hold; - Tracev((stderr, "inflate: stored length %u\n", state->length)); - INITBITS(); - - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) - copy = have; - if (copy > left) - copy = left; - memcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (uint16_t)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if (here.bits <= bits) - break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (uint16_t)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) - break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } - - /* get a literal, length, or end-of-block code */ - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if (here.bits <= bits) - break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)last.bits + (unsigned)here.bits <= bits) - break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - state->length = here.val; - - /* process literal */ - if (here.op == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } - - /* process end of block */ - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - - /* invalid code */ - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - - /* length code -- get extra bits, if any */ - state->extra = (here.op & 15); - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - - /* get distance code */ - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if (here.bits <= bits) - break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)last.bits + (unsigned)here.bits <= bits) - break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = here.val; - - /* get distance extra bits, if any */ - state->extra = (here.op & 15); - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? left : 0)) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) - copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; - - case DONE: - /* inflate stream terminated properly -- write leftover output */ - ret = Z_STREAM_END; - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left)) - ret = Z_BUF_ERROR; - } - goto inf_leave; - - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - - default: /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } - - /* Return unused input */ - inf_leave: - strm->next_in = next; - strm->avail_in = have; - return ret; -} - -int ZEXPORT inflateBackEnd(z_stream *strm) { - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} diff --git a/contrib/libzlib-ng/inffast.c b/contrib/libzlib-ng/inffast.c deleted file mode 100644 index 8acb261d008..00000000000 --- a/contrib/libzlib-ng/inffast.c +++ /dev/null @@ -1,328 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2008, 2010, 2013 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* Allow machine dependent optimization for post-increment or pre-increment. - Based on testing to date, - Pre-increment preferred for: - - PowerPC G3 (Adler) - - MIPS R5000 (Randers-Pehrson) - Post-increment preferred for: - - none - No measurable difference: - - Pentium III (Anderson) - - M68060 (Nikl) - */ -#ifdef POSTINC -# define OFF 0 -# define PUP(a) *(a)++ -#else -# define OFF 1 -# define PUP(a) *++(a) -#endif - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - (hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void ZLIB_INTERNAL inflate_fast(z_stream *strm, unsigned long start) { - /* start: inflate()'s starting value for strm->avail_out */ - struct inflate_state *state; - const unsigned char *in; /* local strm->next_in */ - const unsigned char *last; /* have enough input while in < last */ - unsigned char *out; /* local strm->next_out */ - unsigned char *beg; /* inflate()'s initial strm->next_out */ - unsigned char *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char *window; /* allocated sliding window, if wsize != 0 */ - uint32_t hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const *lcode; /* local strm->lencode */ - code const *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code here; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state *)strm->state; - in = strm->next_in - OFF; - last = in + (strm->avail_in - 5); - out = strm->next_out - OFF; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - wnext = state->wnext; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (PUP(in) << bits); - bits += 8; - hold += (PUP(in) << bits); - bits += 8; - } - here = lcode[hold & lmask]; - dolen: - DROPBITS(here.bits); - op = here.op; - if (op == 0) { /* literal */ - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - PUP(out) = (unsigned char)(here.val); - } else if (op & 16) { /* length base */ - len = here.val; - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (PUP(in) << bits); - bits += 8; - } - len += BITS(op); - DROPBITS(op); - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (PUP(in) << bits); - bits += 8; - hold += (PUP(in) << bits); - bits += 8; - } - here = dcode[hold & dmask]; - dodist: - DROPBITS(here.bits); - op = here.op; - if (op & 16) { /* distance base */ - dist = here.val; - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (PUP(in) << bits); - bits += 8; - if (bits < op) { - hold += (PUP(in) << bits); - bits += 8; - } - } - dist += BITS(op); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - DROPBITS(op); - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state->sane) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - if (len <= op - whave) { - do { - PUP(out) = 0; - } while (--len); - continue; - } - len -= op - whave; - do { - PUP(out) = 0; - } while (--op > whave); - if (op == 0) { - from = out - dist; - do { - PUP(out) = PUP(from); - } while (--len); - continue; - } -#endif - } - from = window - OFF; - if (wnext == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = window - OFF; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - } else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } while (len > 2); - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - } else if ((op & 64) == 0) { /* 2nd level distance code */ - here = dcode[here.val + BITS(op)]; - goto dodist; - } else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } else if ((op & 64) == 0) { /* 2nd level length code */ - here = lcode[here.val + BITS(op)]; - goto dolen; - } else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in + OFF; - strm->next_out = out + OFF; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and wnext == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ diff --git a/contrib/libzlib-ng/inffast.h b/contrib/libzlib-ng/inffast.h deleted file mode 100644 index 0d75614772a..00000000000 --- a/contrib/libzlib-ng/inffast.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef INFFAST_H_ -#define INFFAST_H_ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void ZLIB_INTERNAL inflate_fast(z_stream *strm, unsigned long start); - -#endif /* INFFAST_H_ */ diff --git a/contrib/libzlib-ng/inffixed.h b/contrib/libzlib-ng/inffixed.h deleted file mode 100644 index d6283277694..00000000000 --- a/contrib/libzlib-ng/inffixed.h +++ /dev/null @@ -1,94 +0,0 @@ - /* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - - /* WARNING: this file should *not* be used by applications. - It is part of the implementation of this library and is - subject to change. Applications should only use zlib.h. - */ - - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; - - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; diff --git a/contrib/libzlib-ng/inflate.c b/contrib/libzlib-ng/inflate.c deleted file mode 100644 index de1f0124e55..00000000000 --- a/contrib/libzlib-ng/inflate.c +++ /dev/null @@ -1,1467 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2012 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common wnext == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -/* function prototypes */ -local void fixedtables(struct inflate_state *state); -local int updatewindow(z_stream *strm, const unsigned char *end, uint32_t copy); -#ifdef BUILDFIXED - void makefixed(void); -#endif -local uint32_t syncsearch(uint32_t *have, const unsigned char *buf, uint32_t len); - -int ZEXPORT inflateResetKeep(z_stream *strm) { - struct inflate_state *state; - - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - if (state->wrap) /* to support ill-conceived Java test suite */ - strm->adler = state->wrap & 1; - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->dmax = 32768U; - state->head = Z_NULL; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - state->sane = 1; - state->back = -1; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflateReset(z_stream *strm) { - struct inflate_state *state; - - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state *)strm->state; - state->wsize = 0; - state->whave = 0; - state->wnext = 0; - return inflateResetKeep(strm); -} - -int ZEXPORT inflateReset2(z_stream *strm, int windowBits) { - int wrap; - struct inflate_state *state; - - /* get the state */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state *)strm->state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } else { - wrap = (windowBits >> 4) + 1; -#ifdef GUNZIP - if (windowBits < 48) - windowBits &= 15; -#endif - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) - return Z_STREAM_ERROR; - if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { - ZFREE(strm, state->window); - state->window = Z_NULL; - } - - /* update state and reset the rest of it */ - state->wrap = wrap; - state->wbits = (unsigned)windowBits; - return inflateReset(strm); -} - -int ZEXPORT inflateInit2_(z_stream *strm, int windowBits, const char *version, int stream_size) { - int ret; - struct inflate_state *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = NULL; - } - if (strm->zfree == (free_func)0) - strm->zfree = zcfree; - state = (struct inflate_state *) ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) - return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state *)state; - state->window = Z_NULL; - ret = inflateReset2(strm, windowBits); - if (ret != Z_OK) { - ZFREE(strm, state); - strm->state = Z_NULL; - } - return ret; -} - -int ZEXPORT inflateInit_(z_stream *strm, const char *version, int stream_size) { - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -int ZEXPORT inflatePrime(z_stream *strm, int bits, int value) { - struct inflate_state *state; - - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state *)strm->state; - if (bits < 0) { - state->hold = 0; - state->bits = 0; - return Z_OK; - } - if (bits > 16 || state->bits + bits > 32) - return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += (unsigned)value << state->bits; - state->bits += bits; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(struct inflate_state *state) { -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed(void) { - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) - printf("\n "); - printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, - state.lencode[low].bits, state.lencode[low].val); - if (++low == size) - break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) - printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, state.distcode[low].val); - if (++low == size) - break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow(z_stream *strm, const unsigned char *end, uint32_t copy) { - struct inflate_state *state; - uint32_t dist; - - state = (struct inflate_state *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char *) ZALLOC(strm, 1U << state->wbits, sizeof(unsigned char)); - if (state->window == Z_NULL) - return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->wnext = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state->wsize) { - memcpy(state->window, end - state->wsize, state->wsize); - state->wnext = 0; - state->whave = state->wsize; - } else { - dist = state->wsize - state->wnext; - if (dist > copy) - dist = copy; - memcpy(state->window + state->wnext, end - copy, dist); - copy -= dist; - if (copy) { - memcpy(state->window, end - copy, copy); - state->wnext = copy; - state->whave = state->wsize; - } else { - state->wnext += dist; - if (state->wnext == state->wsize) - state->wnext = 0; - if (state->whave < state->wsize) - state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (*next++ << bits); \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - (hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate(z_stream *strm, int flush) { - struct inflate_state *state; - const unsigned char *next; /* next input */ - unsigned char *put; /* next output */ - unsigned have, left; /* available input and output */ - uint32_t hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - uint32_t in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const uint16_t order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state *)strm->state; - if (state->mode == TYPE) /* skip check */ - state->mode = TYPEDO; - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - if (state->wbits == 0) - state->wbits = 15; - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - state->flags = 0; /* expect zlib header */ - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - if (len > 15 || len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if (state->flags & 0x0200) - CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if (state->flags & 0x0200) - CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if (state->flags & 0x0200) - CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (uint16_t)hold; - if (state->head != Z_NULL) - state->head->extra_len = (uint16_t)hold; - if (state->flags & 0x0200) - CRC2(state->check, hold); - INITBITS(); - } else if (state->head != Z_NULL) { - state->head->extra = Z_NULL; - } - state->mode = EXTRA; - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) - copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; - memcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) - goto inf_leave; - } - state->length = 0; - state->mode = NAME; - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && state->head->name != Z_NULL && state->length < state->head->name_max) - state->head->name[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) - goto inf_leave; - } else if (state->head != Z_NULL) { - state->head->name = Z_NULL; - } - state->length = 0; - state->mode = COMMENT; - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && state->head->comment != Z_NULL - && state->length < state->head->comm_max) - state->head->comment[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) - goto inf_leave; - } else if (state->head != Z_NULL) { - state->head->comment = Z_NULL; - } - state->mode = HCRC; - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if (hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = ZSWAP32(hold); - INITBITS(); - state->mode = DICT; - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - case TYPE: - if (flush == Z_BLOCK || flush == Z_TREES) - goto inf_leave; - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); - state->mode = LEN_; /* decode codes */ - if (flush == Z_TREES) { - DROPBITS(2); - goto inf_leave; - } - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (uint16_t)hold; - Tracev((stderr, "inflate: stored length %u\n", state->length)); - INITBITS(); - state->mode = COPY_; - if (flush == Z_TREES) - goto inf_leave; - case COPY_: - state->mode = COPY; - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - memcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (uint16_t)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (const code *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if (here.bits <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (uint16_t)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) - break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (const code *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (const code *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN_; - if (flush == Z_TREES) - goto inf_leave; - case LEN_: - state->mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - if (state->mode == TYPE) - state->back = -1; - break; - } - state->back = 0; - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if (here.bits <= bits) - break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)last.bits + (unsigned)here.bits <= bits) - break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - state->length = here.val; - if ((int)(here.op) == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - state->mode = LIT; - break; - } - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->back = -1; - state->mode = TYPE; - break; - } - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (here.op & 15); - state->mode = LENEXT; - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->was = state->length; - state->mode = DIST; - case DIST: - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if (here.bits <= bits) - break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)last.bits + (unsigned)here.bits <= bits) - break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = here.val; - state->extra = (here.op & 15); - state->mode = DISTEXT; - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->whave) { - if (state->sane) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - Trace((stderr, "inflate.c too far\n")); - copy -= state->whave; - if (copy > state->length) - copy = state->length; - if (copy > left) - copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = 0; - } while (--copy); - if (state->length == 0) - state->mode = LEN; - break; -#endif - } - if (copy > state->wnext) { - copy -= state->wnext; - from = state->window + (state->wsize - copy); - } else { - from = state->window + (state->wnext - copy); - } - if (copy > state->length) - copy = state->length; - } else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) - copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) - state->mode = LEN; - break; - case LIT: - if (left == 0) - goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if (out) - strm->adler = state->check = UPDATE(state->check, put - out, out); - out = left; - if (( -#ifdef GUNZIP - state->flags ? hold : -#endif - ZSWAP32(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if (hold != (state->total & 0xffffffffUL)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (out != strm->avail_out && state->mode < BAD && (state->mode < CHECK || flush != Z_FINISH))) { - if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if (state->wrap && out) - strm->adler = state->check = UPDATE(state->check, strm->next_out - out, out); - strm->data_type = state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0) + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd(z_stream *strm) { - struct inflate_state *state; - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state *)strm->state; - if (state->window != Z_NULL) - ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateGetDictionary(z_stream *strm, unsigned char *dictionary, unsigned int *dictLength) { - struct inflate_state *state; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state *)strm->state; - - /* copy dictionary */ - if (state->whave && dictionary != Z_NULL) { - memcpy(dictionary, state->window + state->wnext, state->whave - state->wnext); - memcpy(dictionary + state->whave - state->wnext, state->window, state->wnext); - } - if (dictLength != Z_NULL) - *dictLength = state->whave; - return Z_OK; -} - -int ZEXPORT inflateSetDictionary(z_stream *strm, const unsigned char *dictionary, unsigned int dictLength) { - struct inflate_state *state; - unsigned long dictid; - int ret; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary identifier */ - if (state->mode == DICT) { - dictid = adler32(0L, Z_NULL, 0); - dictid = adler32(dictid, dictionary, dictLength); - if (dictid != state->check) - return Z_DATA_ERROR; - } - - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow(strm, dictionary + dictLength, dictLength); - if (ret) { - state->mode = MEM; - return Z_MEM_ERROR; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader(z_stream *strm, gz_headerp head) { - struct inflate_state *state; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state *)strm->state; - if ((state->wrap & 2) == 0) - return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch(uint32_t *have, const unsigned char *buf, uint32_t len) { - uint32_t got; - uint32_t next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync(z_stream *strm) { - unsigned len; /* number of bytes to look at or looked at */ - size_t in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state *state; - - /* check parameters */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) - return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) - return Z_DATA_ERROR; - in = strm->total_in; - out = strm->total_out; - inflateReset(strm); - strm->total_in = in; - strm->total_out = out; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint(z_stream *strm) { - struct inflate_state *state; - - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(z_stream *dest, z_stream *source) { - struct inflate_state *state; - struct inflate_state *copy; - unsigned char *window; - unsigned wsize; - - /* check input */ - if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || - source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state *)source->state; - - /* allocate space */ - copy = (struct inflate_state *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) - return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char *) ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - memcpy((void *)dest, (void *)source, sizeof(z_stream)); - memcpy((void *)copy, (void *)state, sizeof(struct inflate_state)); - if (state->lencode >= state->codes && state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - memcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state *)copy; - return Z_OK; -} - -int ZEXPORT inflateUndermine(z_stream *strm, int subvert) { - struct inflate_state *state; - - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state *)strm->state; -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - state->sane = !subvert; - return Z_OK; -#else - state->sane = 1; - return Z_DATA_ERROR; -#endif -} - -long ZEXPORT inflateMark(z_stream *strm) { - struct inflate_state *state; - - if (strm == Z_NULL || strm->state == Z_NULL) - return 0xFFFFFFFFFFFF0000L; - state = (struct inflate_state *)strm->state; - return ((long)(state->back) << 16) + (state->mode == COPY ? state->length : - (state->mode == MATCH ? state->was - state->length : 0)); -} diff --git a/contrib/libzlib-ng/inflate.h b/contrib/libzlib-ng/inflate.h deleted file mode 100644 index 2bf129db153..00000000000 --- a/contrib/libzlib-ng/inflate.h +++ /dev/null @@ -1,127 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2009 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -#ifndef INFLATE_H_ -#define INFLATE_H_ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY_, /* i/o: same as COPY below, but only first time in */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN_, /* i: same as LEN below, but only first time in */ - LEN, /* i: waiting for length/lit/eob code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to BAD or MEM on error -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) or (raw) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> - HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - (raw) -> TYPEDO - Read deflate blocks: - TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK - STORED -> COPY_ -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN_ - LEN_ -> LEN - Read deflate codes in fixed or dynamic block: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* state maintained between inflate() calls. Approximately 10K bytes. */ -struct inflate_state { - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - uint32_t wsize; /* window size or zero if not using window */ - uint32_t whave; /* valid bytes in the window */ - uint32_t wnext; /* window write index */ - unsigned char *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - uint32_t hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - uint32_t length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const *lencode; /* starting table for length/literal codes */ - code const *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - uint32_t have; /* number of code lengths in lens[] */ - code *next; /* next available space in codes[] */ - uint16_t lens[320]; /* temporary storage for code lengths */ - uint16_t work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ - int sane; /* if false, allow invalid distance too far */ - int back; /* bits back of last unprocessed length/lit */ - unsigned was; /* initial length of match */ -}; - -#endif /* INFLATE_H_ */ diff --git a/contrib/libzlib-ng/inftrees.c b/contrib/libzlib-ng/inftrees.c deleted file mode 100644 index e02272cf864..00000000000 --- a/contrib/libzlib-ng/inftrees.c +++ /dev/null @@ -1,298 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2013 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = " inflate 1.2.8.f Copyright 1995-2013 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int ZLIB_INTERNAL inflate_table(codetype type, uint16_t *lens, unsigned codes, - code * *table, unsigned *bits, uint16_t *work) { - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code here; /* table entry for duplication */ - code *next; /* next available space in table */ - const uint16_t *base; /* base value table to use */ - const uint16_t *extra; /* extra bits table to use */ - int end; /* use base and extra for symbol > end */ - uint16_t count[MAXBITS+1]; /* number of codes of each length */ - uint16_t offs[MAXBITS+1]; /* offsets in table for each length */ - static const uint16_t lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const uint16_t lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78}; - static const uint16_t dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const uint16_t dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)1; - here.val = (uint16_t)0; - *(*table)++ = here; /* make a table to force an error */ - *(*table)++ = here; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (uint16_t)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - end = 19; - break; - case LENS: - base = lbase; - base -= 257; - extra = lext; - extra -= 257; - end = 256; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - end = -1; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here.bits = (unsigned char)(len - drop); - if ((int)(work[sym]) < end) { - here.op = (unsigned char)0; - here.val = work[sym]; - } else if ((int)(work[sym]) > end) { - here.op = (unsigned char)(extra[work[sym]]); - here.val = base[work[sym]]; - } else { - here.op = (unsigned char)(32 + 64); /* end of block */ - here.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = here; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } else { - huff = 0; - } - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) - break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) - break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if ((type == LENS && used > ENOUGH_LENS) || (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (uint16_t)(next - *table); - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff != 0) { - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)(len - drop); - here.val = (uint16_t)0; - next[huff] = here; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} diff --git a/contrib/libzlib-ng/inftrees.h b/contrib/libzlib-ng/inftrees.h deleted file mode 100644 index eaf3df1ca66..00000000000 --- a/contrib/libzlib-ng/inftrees.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef INFTREES_H_ -#define INFTREES_H_ - -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - uint16_t val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of the dynamic table. The maximum number of code structures is - 1444, which is the sum of 852 for literal/length codes and 592 for distance - codes. These values were found by exhaustive searches using the program - examples/enough.c found in the zlib distribtution. The arguments to that - program are the number of symbols, the initial root table size, and the - maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the - inflate_table() calls in inflate.c and infback.c. If the root table size is - changed, then these maximum sizes would be need to be recalculated and - updated. */ -#define ENOUGH_LENS 852 -#define ENOUGH_DISTS 592 -#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) - -/* Type of code to build for inflate_table() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -int ZLIB_INTERNAL inflate_table (codetype type, uint16_t *lens, unsigned codes, - code * *table, unsigned *bits, uint16_t *work); - -#endif /* INFTREES_H_ */ diff --git a/contrib/libzlib-ng/match.c b/contrib/libzlib-ng/match.c deleted file mode 100644 index 25b3b14ce07..00000000000 --- a/contrib/libzlib-ng/match.c +++ /dev/null @@ -1,471 +0,0 @@ -/* - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is garbage. - * - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >=1 - * OUT assertion: the match length is not greater than s->lookahead - */ - -#include "deflate.h" - -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - - /* Only use std3_longest_match for little_endian systems, also avoid using it with - non-gcc compilers since the __builtin_ctzl() function might not be optimized. */ -# if defined(__GNUC__) && defined(HAVE_BUILTIN_CTZL) && ((__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \ - || defined(__LITTLE_ENDIAN__)) -# define std3_longest_match -# elif(defined(_MSC_VER) && defined(_WIN32)) -# define std3_longest_match -# else -# define std2_longest_match -# endif - -#else -# define std1_longest_match -#endif - - -#if defined(_MSC_VER) && !defined(__clang__) -#include -/* This is not a general purpose replacement for __builtin_ctzl. The function expects that value is != 0 - * Because of that assumption trailing_zero is not initialized and the return value of _BitScanForward is not checked - */ -static __forceinline unsigned long __builtin_ctzl(unsigned long value) -{ - unsigned long trailing_zero; - _BitScanForward(&trailing_zero, value); - return trailing_zero; -} -#endif - - - -#ifdef std1_longest_match - -/* - * Standard longest_match - * - */ -ZLIB_INTERNAL unsigned longest_match(deflate_state *const s, IPos cur_match) { - const unsigned wmask = s->w_mask; - const Pos *prev = s->prev; - - unsigned chain_length; - IPos limit; - unsigned int len, best_len, nice_match; - unsigned char *scan, *match, *strend, scan_end, scan_end1; - - /* - * The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple - * of 16. It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* - * Do not waste too much time if we already have a good match - */ - best_len = s->prev_length; - chain_length = s->max_chain_length; - if (best_len >= s->good_match) - chain_length >>= 2; - - /* - * Do not looks for matches beyond the end of the input. This is - * necessary to make deflate deterministic - */ - nice_match = (unsigned int)s->nice_match > s->lookahead ? s->lookahead : s->nice_match; - - /* - * Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0 - */ - limit = s->strstart > MAX_DIST(s) ? s->strstart - MAX_DIST(s) : 0; - - scan = s->window + s->strstart; - strend = s->window + s->strstart + MAX_MATCH; - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; - - Assert((unsigned long)s->strstart <= s->window_size - MIN_LOOKAHEAD, "need lookahead"); - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* - * Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks - * below for insufficient lookahead only occur occasionally - * for performance reasons. Therefore uninitialized memory - * will be accessed and conditional jumps will be made that - * depend on those values. However the length of the match - * is limited to the lookahead, so the output of deflate is not - * affected by the uninitialized values. - */ - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) - continue; - - /* - * The check at best_len-1 can be removed because it will - * be made again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since - * they are always equal when the other bytes match, given - * that the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2; - match++; - Assert(*scan == *match, "match[2]?"); - - /* - * We check for insufficient lookahead only every 8th - * comparision; the 256th check will be made at strstart + 258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned int)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) - break; - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; - } else { - /* - * The probability of finding a match later if we here - * is pretty low, so for performance it's best to - * outright stop here for the lower compression levels - */ - if (s->level < 6) - break; - } - } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length); - - if ((unsigned int)best_len <= s->lookahead) - return best_len; - return s->lookahead; -} -#endif - -#ifdef std2_longest_match -/* - * UNALIGNED_OK longest_match - * - */ -ZLIB_INTERNAL unsigned longest_match(deflate_state *const s, IPos cur_match) { - const unsigned wmask = s->w_mask; - const Pos *prev = s->prev; - - uint16_t scan_start, scan_end; - unsigned chain_length; - IPos limit; - unsigned int len, best_len, nice_match; - unsigned char *scan, *strend; - - /* - * The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple - * of 16. It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* - * Do not waste too much time if we already have a good match - */ - best_len = s->prev_length; - chain_length = s->max_chain_length; - if (best_len >= s->good_match) - chain_length >>= 2; - - /* - * Do not looks for matches beyond the end of the input. This is - * necessary to make deflate deterministic - */ - nice_match = (unsigned int)s->nice_match > s->lookahead ? s->lookahead : s->nice_match; - - /* - * Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0 - */ - limit = s->strstart > MAX_DIST(s) ? s->strstart - MAX_DIST(s) : 0; - - scan = s->window + s->strstart; - strend = s->window + s->strstart + MAX_MATCH - 1; - scan_start = *(uint16_t *)scan; - scan_end = *(uint16_t *)(scan + best_len-1); - - Assert((unsigned long)s->strstart <= s->window_size - MIN_LOOKAHEAD, "need lookahead"); - do { - unsigned char *match; - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* - * Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks - * below for insufficient lookahead only occur occasionally - * for performance reasons. Therefore uninitialized memory - * will be accessed and conditional jumps will be made that - * depend on those values. However the length of the match - * is limited to the lookahead, so the output of deflate is not - * affected by the uninitialized values. - */ - if (likely((*(uint16_t *)(match + best_len - 1) != scan_end))) - continue; - if (*(uint16_t *)match != scan_start) - continue; - - /* It is not necessary to compare scan[2] and match[2] since - * they are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. Compare 2 - * bytes at a time at strstart+3, +5, ... up to strstart+257. - * We check for insufficient lookahead only every 4th - * comparison; the 128th check will be made at strstart+257. - * If MAX_MATCH-2 is not a multiple of 8, it is necessary to - * put more guard bytes at the end of the window, or to check - * more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++; - match++; - - do { - } while (*(uint16_t *)(scan += 2)== *(uint16_t *)(match += 2) && - *(uint16_t *)(scan += 2)== *(uint16_t *)(match += 2) && - *(uint16_t *)(scan += 2)== *(uint16_t *)(match += 2) && - *(uint16_t *)(scan += 2)== *(uint16_t *)(match += 2) && - scan < strend); - - /* - * Here, scan <= window + strstart + 257 - */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) - scan++; - - len = (MAX_MATCH -1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) - break; - scan_end = *(uint16_t *)(scan + best_len - 1); - } else { - /* - * The probability of finding a match later if we here - * is pretty low, so for performance it's best to - * outright stop here for the lower compression levels - */ - if (s->level < 6) - break; - } - } while (--chain_length && (cur_match = prev[cur_match & wmask]) > limit); - - if ((unsigned)best_len <= s->lookahead) - return best_len; - return s->lookahead; -} -#endif - -#ifdef std3_longest_match -/* longest_match() with minor change to improve performance (in terms of - * execution time). - * - * The pristine longest_match() function is sketched bellow (strip the - * then-clause of the "#ifdef UNALIGNED_OK"-directive) - * - * ------------------------------------------------------------ - * unsigned int longest_match(...) { - * ... - * do { - * match = s->window + cur_match; //s0 - * if (*(ushf*)(match+best_len-1) != scan_end || //s1 - * *(ushf*)match != scan_start) continue; //s2 - * ... - * - * do { - * } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - * *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - * *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - * *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - * scan < strend); //s3 - * - * ... - * } while(cond); //s4 - * - * ------------------------------------------------------------- - * - * The change include: - * - * 1) The hottest statements of the function is: s0, s1 and s4. Pull them - * together to form a new loop. The benefit is two-fold: - * - * o. Ease the compiler to yield good code layout: the conditional-branch - * corresponding to s1 and its biased target s4 become very close (likely, - * fit in the same cache-line), hence improving instruction-fetching - * efficiency. - * - * o. Ease the compiler to promote "s->window" into register. "s->window" - * is loop-invariant; it is supposed to be promoted into register and keep - * the value throughout the entire loop. However, there are many such - * loop-invariant, and x86-family has small register file; "s->window" is - * likely to be chosen as register-allocation victim such that its value - * is reloaded from memory in every single iteration. By forming a new loop, - * "s->window" is loop-invariant of that newly created tight loop. It is - * lot easier for compiler to promote this quantity to register and keep - * its value throughout the entire small loop. - * - * 2) Transfrom s3 such that it examines sizeof(long)-byte-match at a time. - * This is done by: - * ------------------------------------------------ - * v1 = load from "scan" by sizeof(long) bytes - * v2 = load from "match" by sizeof(lnog) bytes - * v3 = v1 xor v2 - * match-bit = little-endian-machine(yes-for-x86) ? - * count-trailing-zero(v3) : - * count-leading-zero(v3); - * - * match-byte = match-bit/8 - * - * "scan" and "match" advance if necessary - * ------------------------------------------------- - */ - -ZLIB_INTERNAL unsigned longest_match(deflate_state *const s, IPos cur_match) { - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register unsigned char *scan = s->window + s->strstart; /* current string */ - register unsigned char *match; /* matched string */ - register unsigned int len; /* length of current match */ - unsigned int best_len = s->prev_length; /* best match length so far */ - unsigned int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Pos *prev = s->prev; - unsigned int wmask = s->w_mask; - - register unsigned char *strend = s->window + s->strstart + MAX_MATCH; - register uint16_t scan_start = *(uint16_t*)scan; - register uint16_t scan_end = *(uint16_t*)(scan+best_len-1); - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((unsigned int)nice_match > s->lookahead) nice_match = s->lookahead; - - Assert((unsigned long)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ - unsigned char *win = s->window; - int cont = 1; - do { - match = win + cur_match; - if (likely(*(uint16_t*)(match+best_len-1) != scan_end)) { - if ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0) { - continue; - } else { - cont = 0; - } - } - break; - } while (1); - - if (!cont) - break; - - if (*(uint16_t*)match != scan_start) - continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - scan += 2, match+=2; - Assert(*scan == *match, "match[2]?"); - do { - unsigned long sv = *(unsigned long*)(void*)scan; - unsigned long mv = *(unsigned long*)(void*)match; - unsigned long xor = sv ^ mv; - if (xor) { - int match_byte = __builtin_ctzl(xor) / 8; - scan += match_byte; - match += match_byte; - break; - } else { - scan += sizeof(unsigned long); - match += sizeof(unsigned long); - } - } while (scan < strend); - - if (scan > strend) - scan = strend; - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) - break; - scan_end = *(uint16_t*)(scan+best_len-1); - } else { - /* - * The probability of finding a match later if we here - * is pretty low, so for performance it's best to - * outright stop here for the lower compression levels - */ - if (s->level < 6) - break; - } - } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length != 0); - - if ((unsigned int)best_len <= s->lookahead) - return (unsigned int)best_len; - return s->lookahead; -} -#endif diff --git a/contrib/libzlib-ng/match.h b/contrib/libzlib-ng/match.h deleted file mode 100644 index 70842019849..00000000000 --- a/contrib/libzlib-ng/match.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef MATCH_H_ -#define MATCH_H_ - -unsigned int longest_match (deflate_state *s, IPos cur_match); - -#endif /* MATCH_H_ */ diff --git a/contrib/libzlib-ng/test/.gitignore b/contrib/libzlib-ng/test/.gitignore deleted file mode 100644 index 2c3af0a08cb..00000000000 --- a/contrib/libzlib-ng/test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# ignore Makefiles; they're all automatically generated -Makefile diff --git a/contrib/libzlib-ng/test/CVE-2002-0059/test.gz b/contrib/libzlib-ng/test/CVE-2002-0059/test.gz deleted file mode 100644 index c5c3e184b1a90692f1c2dc729eb106476d231378..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4610 zcmb2|=3oE==C>CV8G$T;1@EN)&o6EfRlAUMpn;K@jYq;DVU#f%2%{-sG#8BKg3(+s vnhQpA!DucR%>|>mU^Ewu=7P~&Fq#WSbHQjX7-G5L2b -#include -#include -#include - -int main(void) { -gzFile f; -int ret; - -if(!(f = gzopen("/dev/null", "w"))) { -perror("/dev/null"); -exit(1); -} -ret = gzprintf(f, "%10240s", ""); -printf("gzprintf -> %d\n", ret); -ret = gzclose(f); -printf("gzclose -> %d [%d]\n", ret, errno); -exit(0); -} diff --git a/contrib/libzlib-ng/test/CVE-2004-0797/test.gz b/contrib/libzlib-ng/test/CVE-2004-0797/test.gz deleted file mode 100644 index 62dcf34bddbfe2c2e861c7929c21dc2f731dd000..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 ocmb2|=3oE==C>CV85!7kBn%P`G%zxAfEl}iz!@q6kpjs906!lM=l}o! diff --git a/contrib/libzlib-ng/test/CVE-2005-1849/test.gz b/contrib/libzlib-ng/test/CVE-2005-1849/test.gz deleted file mode 100644 index b28f278263c0a3154faeb3c3dd7b083a3a593c8d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 kcmb2|=3oE==C@ZA85!7kBn%P`G%zxAz!-252m>Ss01LtkQvd(} diff --git a/contrib/libzlib-ng/test/CVE-2005-2096/test.gz b/contrib/libzlib-ng/test/CVE-2005-2096/test.gz deleted file mode 100644 index 11590aeab9ac844087776ab66eb2f5d2c9f6d013..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52 pcmb2|=3oE==C>CV84oltGP4!m+X - -#include -#include -#include - -#define TESTFILE "foo.gz" - -#define CHECK_ERR(err, msg) { \ - if (err != Z_OK) { \ - fprintf(stderr, "%s error: %d\n", msg, err); \ - exit(1); \ - } \ -} - -const char hello[] = "hello, hello!"; -/* "hello world" would be more standard, but the repeated "hello" - * stresses the compression code better, sorry... - */ - -const char dictionary[] = "hello"; -unsigned long dictId; /* Adler32 value of the dictionary */ - -void test_deflate (unsigned char *compr, size_t comprLen); -void test_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen); -void test_large_deflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen); -void test_large_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen); -void test_flush (unsigned char *compr, size_t *comprLen); -void test_sync (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen); -void test_dict_deflate (unsigned char *compr, size_t comprLen); -void test_dict_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen); -int main (int argc, char *argv[]); - - -static alloc_func zalloc = (alloc_func)0; -static free_func zfree = (free_func)0; - -void test_compress (unsigned char *compr, size_t comprLen, - unsigned char *uncompr, size_t uncomprLen); - -/* =========================================================================== - * Test compress() and uncompress() - */ -void test_compress(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) -{ - int err; - size_t len = strlen(hello)+1; - - err = compress(compr, &comprLen, (const unsigned char*)hello, len); - CHECK_ERR(err, "compress"); - - strcpy((char*)uncompr, "garbage"); - - err = uncompress(uncompr, &uncomprLen, compr, comprLen); - CHECK_ERR(err, "uncompress"); - - if (strcmp((char*)uncompr, hello)) { - fprintf(stderr, "bad uncompress\n"); - exit(1); - } else { - printf("uncompress(): %s\n", (char *)uncompr); - } -} - -#ifdef WITH_GZFILEOP -void test_gzio (const char *fname, - unsigned char *uncompr, unsigned long uncomprLen); - -/* =========================================================================== - * Test read/write of .gz files - */ -void test_gzio(const char *fname, unsigned char *uncompr, unsigned long uncomprLen) -{ -#ifdef NO_GZCOMPRESS - fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); -#else - int err; - int len = (int)strlen(hello)+1; - gzFile file; - z_off_t pos; - - file = gzopen(fname, "wb"); - if (file == NULL) { - fprintf(stderr, "gzopen error\n"); - exit(1); - } - gzputc(file, 'h'); - if (gzputs(file, "ello") != 4) { - fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err)); - exit(1); - } - if (gzprintf(file, ", %s!", "hello") != 8) { - fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err)); - exit(1); - } - gzseek(file, 1L, SEEK_CUR); /* add one zero byte */ - gzclose(file); - - file = gzopen(fname, "rb"); - if (file == NULL) { - fprintf(stderr, "gzopen error\n"); - exit(1); - } - strcpy((char*)uncompr, "garbage"); - - if (gzread(file, uncompr, (unsigned)uncomprLen) != len) { - fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); - exit(1); - } - if (strcmp((char*)uncompr, hello)) { - fprintf(stderr, "bad gzread: %s\n", (char*)uncompr); - exit(1); - } else { - printf("gzread(): %s\n", (char*)uncompr); - } - - pos = gzseek(file, -8L, SEEK_CUR); - if (pos != 6 || gztell(file) != pos) { - fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n", - (long)pos, (long)gztell(file)); - exit(1); - } - - if (gzgetc(file) != ' ') { - fprintf(stderr, "gzgetc error\n"); - exit(1); - } - - if (gzungetc(' ', file) != ' ') { - fprintf(stderr, "gzungetc error\n"); - exit(1); - } - - gzgets(file, (char*)uncompr, (int)uncomprLen); - if (strlen((char*)uncompr) != 7) { /* " hello!" */ - fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err)); - exit(1); - } - if (strcmp((char*)uncompr, hello + 6)) { - fprintf(stderr, "bad gzgets after gzseek\n"); - exit(1); - } else { - printf("gzgets() after gzseek: %s\n", (char*)uncompr); - } - - gzclose(file); -#endif -} - -#endif /* WITH_GZFILEOP */ - -/* =========================================================================== - * Test deflate() with small buffers - */ -void test_deflate(unsigned char *compr, size_t comprLen) -{ - z_stream c_stream; /* compression stream */ - int err; - unsigned long len = (unsigned long)strlen(hello)+1; - - c_stream.zalloc = zalloc; - c_stream.zfree = zfree; - c_stream.opaque = (void *)0; - - err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); - CHECK_ERR(err, "deflateInit"); - - c_stream.next_in = (const unsigned char *)hello; - c_stream.next_out = compr; - - while (c_stream.total_in != len && c_stream.total_out < comprLen) { - c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ - err = deflate(&c_stream, Z_NO_FLUSH); - CHECK_ERR(err, "deflate"); - } - /* Finish the stream, still forcing small buffers: */ - for (;;) { - c_stream.avail_out = 1; - err = deflate(&c_stream, Z_FINISH); - if (err == Z_STREAM_END) break; - CHECK_ERR(err, "deflate"); - } - - err = deflateEnd(&c_stream); - CHECK_ERR(err, "deflateEnd"); -} - -/* =========================================================================== - * Test inflate() with small buffers - */ -void test_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) -{ - int err; - z_stream d_stream; /* decompression stream */ - - strcpy((char*)uncompr, "garbage"); - - d_stream.zalloc = zalloc; - d_stream.zfree = zfree; - d_stream.opaque = (void *)0; - - d_stream.next_in = compr; - d_stream.avail_in = 0; - d_stream.next_out = uncompr; - - err = inflateInit(&d_stream); - CHECK_ERR(err, "inflateInit"); - - while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { - d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ - err = inflate(&d_stream, Z_NO_FLUSH); - if (err == Z_STREAM_END) break; - CHECK_ERR(err, "inflate"); - } - - err = inflateEnd(&d_stream); - CHECK_ERR(err, "inflateEnd"); - - if (strcmp((char*)uncompr, hello)) { - fprintf(stderr, "bad inflate\n"); - exit(1); - } else { - printf("inflate(): %s\n", (char *)uncompr); - } -} - -/* =========================================================================== - * Test deflate() with large buffers and dynamic change of compression level - */ -void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) -{ - z_stream c_stream; /* compression stream */ - int err; - - c_stream.zalloc = zalloc; - c_stream.zfree = zfree; - c_stream.opaque = (void *)0; - - err = deflateInit(&c_stream, Z_BEST_SPEED); - CHECK_ERR(err, "deflateInit"); - - c_stream.next_out = compr; - c_stream.avail_out = (unsigned int)comprLen; - - /* At this point, uncompr is still mostly zeroes, so it should compress - * very well: - */ - c_stream.next_in = uncompr; - c_stream.avail_in = (unsigned int)uncomprLen; - err = deflate(&c_stream, Z_NO_FLUSH); - CHECK_ERR(err, "deflate"); - if (c_stream.avail_in != 0) { - fprintf(stderr, "deflate not greedy\n"); - exit(1); - } - - /* Feed in already compressed data and switch to no compression: */ - deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); - c_stream.next_in = compr; - c_stream.avail_in = (unsigned int)comprLen/2; - err = deflate(&c_stream, Z_NO_FLUSH); - CHECK_ERR(err, "deflate"); - - /* Switch back to compressing mode: */ - deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); - c_stream.next_in = uncompr; - c_stream.avail_in = (unsigned int)uncomprLen; - err = deflate(&c_stream, Z_NO_FLUSH); - CHECK_ERR(err, "deflate"); - - err = deflate(&c_stream, Z_FINISH); - if (err != Z_STREAM_END) { - fprintf(stderr, "deflate should report Z_STREAM_END\n"); - exit(1); - } - err = deflateEnd(&c_stream); - CHECK_ERR(err, "deflateEnd"); -} - -/* =========================================================================== - * Test inflate() with large buffers - */ -void test_large_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) -{ - int err; - z_stream d_stream; /* decompression stream */ - - strcpy((char*)uncompr, "garbage"); - - d_stream.zalloc = zalloc; - d_stream.zfree = zfree; - d_stream.opaque = (void *)0; - - d_stream.next_in = compr; - d_stream.avail_in = (unsigned int)comprLen; - - err = inflateInit(&d_stream); - CHECK_ERR(err, "inflateInit"); - - for (;;) { - d_stream.next_out = uncompr; /* discard the output */ - d_stream.avail_out = (unsigned int)uncomprLen; - err = inflate(&d_stream, Z_NO_FLUSH); - if (err == Z_STREAM_END) break; - CHECK_ERR(err, "large inflate"); - } - - err = inflateEnd(&d_stream); - CHECK_ERR(err, "inflateEnd"); - - if (d_stream.total_out != 2*uncomprLen + comprLen/2) { - fprintf(stderr, "bad large inflate: %zu\n", d_stream.total_out); - exit(1); - } else { - printf("large_inflate(): OK\n"); - } -} - -/* =========================================================================== - * Test deflate() with full flush - */ -void test_flush(unsigned char *compr, size_t *comprLen) -{ - z_stream c_stream; /* compression stream */ - int err; - unsigned int len = (unsigned int)strlen(hello)+1; - - c_stream.zalloc = zalloc; - c_stream.zfree = zfree; - c_stream.opaque = (void *)0; - - err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); - CHECK_ERR(err, "deflateInit"); - - c_stream.next_in = (const unsigned char *)hello; - c_stream.next_out = compr; - c_stream.avail_in = 3; - c_stream.avail_out = (unsigned int)*comprLen; - err = deflate(&c_stream, Z_FULL_FLUSH); - CHECK_ERR(err, "deflate"); - - compr[3]++; /* force an error in first compressed block */ - c_stream.avail_in = len - 3; - - err = deflate(&c_stream, Z_FINISH); - if (err != Z_STREAM_END) { - CHECK_ERR(err, "deflate"); - } - err = deflateEnd(&c_stream); - CHECK_ERR(err, "deflateEnd"); - - *comprLen = c_stream.total_out; -} - -/* =========================================================================== - * Test inflateSync() - */ -void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) -{ - int err; - z_stream d_stream; /* decompression stream */ - - strcpy((char*)uncompr, "garbage"); - - d_stream.zalloc = zalloc; - d_stream.zfree = zfree; - d_stream.opaque = (void *)0; - - d_stream.next_in = compr; - d_stream.avail_in = 2; /* just read the zlib header */ - - err = inflateInit(&d_stream); - CHECK_ERR(err, "inflateInit"); - - d_stream.next_out = uncompr; - d_stream.avail_out = (unsigned int)uncomprLen; - - err = inflate(&d_stream, Z_NO_FLUSH); - CHECK_ERR(err, "inflate"); - - d_stream.avail_in = (unsigned int)comprLen-2; /* read all compressed data */ - err = inflateSync(&d_stream); /* but skip the damaged part */ - CHECK_ERR(err, "inflateSync"); - - err = inflate(&d_stream, Z_FINISH); - if (err != Z_DATA_ERROR) { - fprintf(stderr, "inflate should report DATA_ERROR\n"); - /* Because of incorrect adler32 */ - exit(1); - } - err = inflateEnd(&d_stream); - CHECK_ERR(err, "inflateEnd"); - - printf("after inflateSync(): hel%s\n", (char *)uncompr); -} - -/* =========================================================================== - * Test deflate() with preset dictionary - */ -void test_dict_deflate(unsigned char *compr, size_t comprLen) -{ - z_stream c_stream; /* compression stream */ - int err; - - c_stream.zalloc = zalloc; - c_stream.zfree = zfree; - c_stream.opaque = (void *)0; - - err = deflateInit(&c_stream, Z_BEST_COMPRESSION); - CHECK_ERR(err, "deflateInit"); - - err = deflateSetDictionary(&c_stream, - (const unsigned char*)dictionary, (int)sizeof(dictionary)); - CHECK_ERR(err, "deflateSetDictionary"); - - dictId = c_stream.adler; - c_stream.next_out = compr; - c_stream.avail_out = (unsigned int)comprLen; - - c_stream.next_in = (const unsigned char *)hello; - c_stream.avail_in = (unsigned int)strlen(hello)+1; - - err = deflate(&c_stream, Z_FINISH); - if (err != Z_STREAM_END) { - fprintf(stderr, "deflate should report Z_STREAM_END\n"); - exit(1); - } - err = deflateEnd(&c_stream); - CHECK_ERR(err, "deflateEnd"); -} - -/* =========================================================================== - * Test inflate() with a preset dictionary - */ -void test_dict_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) -{ - int err; - z_stream d_stream; /* decompression stream */ - - strcpy((char*)uncompr, "garbage"); - - d_stream.zalloc = zalloc; - d_stream.zfree = zfree; - d_stream.opaque = (void *)0; - - d_stream.next_in = compr; - d_stream.avail_in = (unsigned int)comprLen; - - err = inflateInit(&d_stream); - CHECK_ERR(err, "inflateInit"); - - d_stream.next_out = uncompr; - d_stream.avail_out = (unsigned int)uncomprLen; - - for (;;) { - err = inflate(&d_stream, Z_NO_FLUSH); - if (err == Z_STREAM_END) break; - if (err == Z_NEED_DICT) { - if (d_stream.adler != dictId) { - fprintf(stderr, "unexpected dictionary"); - exit(1); - } - err = inflateSetDictionary(&d_stream, (const unsigned char*)dictionary, - (int)sizeof(dictionary)); - } - CHECK_ERR(err, "inflate with dict"); - } - - err = inflateEnd(&d_stream); - CHECK_ERR(err, "inflateEnd"); - - if (strcmp((char*)uncompr, hello)) { - fprintf(stderr, "bad inflate with dict\n"); - exit(1); - } else { - printf("inflate with dictionary: %s\n", (char *)uncompr); - } -} - -/* =========================================================================== - * Usage: example [output.gz [input.gz]] - */ - -int main(int argc, char *argv[]) -{ - unsigned char *compr, *uncompr; - size_t comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ - size_t uncomprLen = comprLen; - static const char* myVersion = ZLIB_VERSION; - - if (zlibVersion()[0] != myVersion[0]) { - fprintf(stderr, "incompatible zlib version\n"); - exit(1); - - } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) { - fprintf(stderr, "warning: different zlib version\n"); - } - - printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n", - ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags()); - - compr = (unsigned char*)calloc((unsigned int)comprLen, 1); - uncompr = (unsigned char*)calloc((unsigned int)uncomprLen, 1); - /* compr and uncompr are cleared to avoid reading uninitialized - * data and to ensure that uncompr compresses well. - */ - if (compr == Z_NULL || uncompr == Z_NULL) { - printf("out of memory\n"); - exit(1); - } - - test_compress(compr, comprLen, uncompr, uncomprLen); - -#ifdef WITH_GZFILEOP - test_gzio((argc > 1 ? argv[1] : TESTFILE), - uncompr, uncomprLen); -#endif - - test_deflate(compr, comprLen); - test_inflate(compr, comprLen, uncompr, uncomprLen); - - test_large_deflate(compr, comprLen, uncompr, uncomprLen); - test_large_inflate(compr, comprLen, uncompr, uncomprLen); - - test_flush(compr, &comprLen); - test_sync(compr, comprLen, uncompr, uncomprLen); - comprLen = uncomprLen; - - test_dict_deflate(compr, comprLen); - test_dict_inflate(compr, comprLen, uncompr, uncomprLen); - - free(compr); - free(uncompr); - - return 0; -} diff --git a/contrib/libzlib-ng/test/infcover.c b/contrib/libzlib-ng/test/infcover.c deleted file mode 100644 index 5555a155fc3..00000000000 --- a/contrib/libzlib-ng/test/infcover.c +++ /dev/null @@ -1,668 +0,0 @@ -/* infcover.c -- test zlib's inflate routines with full code coverage - * Copyright (C) 2011 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* to use, do: ./configure --cover && make cover */ - -#include -#include -#include -#include -#include "zlib.h" - -/* get definition of internal structure so we can mess with it (see pull()), - and so we can call inflate_trees() (see cover5()) */ -#define ZLIB_INTERNAL -#include "inftrees.h" -#include "inflate.h" - -/* -- memory tracking routines -- */ - -/* - These memory tracking routines are provided to zlib and track all of zlib's - allocations and deallocations, check for LIFO operations, keep a current - and high water mark of total bytes requested, optionally set a limit on the - total memory that can be allocated, and when done check for memory leaks. - - They are used as follows: - - z_stream strm; - mem_setup(&strm) initializes the memory tracking and sets the - zalloc, zfree, and opaque members of strm to use - memory tracking for all zlib operations on strm - mem_limit(&strm, limit) sets a limit on the total bytes requested -- a - request that exceeds this limit will result in an - allocation failure (returns NULL) -- setting the - limit to zero means no limit, which is the default - after mem_setup() - mem_used(&strm, "msg") prints to stderr "msg" and the total bytes used - mem_high(&strm, "msg") prints to stderr "msg" and the high water mark - mem_done(&strm, "msg") ends memory tracking, releases all allocations - for the tracking as well as leaked zlib blocks, if - any. If there was anything unusual, such as leaked - blocks, non-FIFO frees, or frees of addresses not - allocated, then "msg" and information about the - problem is printed to stderr. If everything is - normal, nothing is printed. mem_done resets the - strm members to Z_NULL to use the default memory - allocation routines on the next zlib initialization - using strm. - */ - -/* these items are strung together in a linked list, one for each allocation */ -struct mem_item { - void *ptr; /* pointer to allocated memory */ - size_t size; /* requested size of allocation */ - struct mem_item *next; /* pointer to next item in list, or NULL */ -}; - -/* this structure is at the root of the linked list, and tracks statistics */ -struct mem_zone { - struct mem_item *first; /* pointer to first item in list, or NULL */ - size_t total, highwater; /* total allocations, and largest total */ - size_t limit; /* memory allocation limit, or 0 if no limit */ - int notlifo, rogue; /* counts of non-LIFO frees and rogue frees */ -}; - -/* memory allocation routine to pass to zlib */ -static void *mem_alloc(void *mem, unsigned count, unsigned size) -{ - void *ptr; - struct mem_item *item; - struct mem_zone *zone = mem; - size_t len = count * (size_t)size; - - /* induced allocation failure */ - if (zone == NULL || (zone->limit && zone->total + len > zone->limit)) - return NULL; - - /* perform allocation using the standard library, fill memory with a - non-zero value to make sure that the code isn't depending on zeros */ - ptr = malloc(len); - if (ptr == NULL) - return NULL; - memset(ptr, 0xa5, len); - - /* create a new item for the list */ - item = malloc(sizeof(struct mem_item)); - if (item == NULL) { - free(ptr); - return NULL; - } - item->ptr = ptr; - item->size = len; - - /* insert item at the beginning of the list */ - item->next = zone->first; - zone->first = item; - - /* update the statistics */ - zone->total += item->size; - if (zone->total > zone->highwater) - zone->highwater = zone->total; - - /* return the allocated memory */ - return ptr; -} - -/* memory free routine to pass to zlib */ -static void mem_free(void *mem, void *ptr) -{ - struct mem_item *item, *next; - struct mem_zone *zone = mem; - - /* if no zone, just do a free */ - if (zone == NULL) { - free(ptr); - return; - } - - /* point next to the item that matches ptr, or NULL if not found -- remove - the item from the linked list if found */ - next = zone->first; - if (next) { - if (next->ptr == ptr) - zone->first = next->next; /* first one is it, remove from list */ - else { - do { /* search the linked list */ - item = next; - next = item->next; - } while (next != NULL && next->ptr != ptr); - if (next) { /* if found, remove from linked list */ - item->next = next->next; - zone->notlifo++; /* not a LIFO free */ - } - - } - } - - /* if found, update the statistics and free the item */ - if (next) { - zone->total -= next->size; - free(next); - } - - /* if not found, update the rogue count */ - else - zone->rogue++; - - /* in any case, do the requested free with the standard library function */ - free(ptr); -} - -/* set up a controlled memory allocation space for monitoring, set the stream - parameters to the controlled routines, with opaque pointing to the space */ -static void mem_setup(z_stream *strm) -{ - struct mem_zone *zone; - - zone = malloc(sizeof(struct mem_zone)); - assert(zone != NULL); - zone->first = NULL; - zone->total = 0; - zone->highwater = 0; - zone->limit = 0; - zone->notlifo = 0; - zone->rogue = 0; - strm->opaque = zone; - strm->zalloc = mem_alloc; - strm->zfree = mem_free; -} - -/* set a limit on the total memory allocation, or 0 to remove the limit */ -static void mem_limit(z_stream *strm, size_t limit) -{ - struct mem_zone *zone = strm->opaque; - - zone->limit = limit; -} - -/* show the current total requested allocations in bytes */ -static void mem_used(z_stream *strm, char *prefix) -{ - struct mem_zone *zone = strm->opaque; - - fprintf(stderr, "%s: %zu allocated\n", prefix, zone->total); -} - -/* show the high water allocation in bytes */ -static void mem_high(z_stream *strm, char *prefix) -{ - struct mem_zone *zone = strm->opaque; - - fprintf(stderr, "%s: %zu high water mark\n", prefix, zone->highwater); -} - -/* release the memory allocation zone -- if there are any surprises, notify */ -static void mem_done(z_stream *strm, char *prefix) -{ - int count = 0; - struct mem_item *item, *next; - struct mem_zone *zone = strm->opaque; - - /* show high water mark */ - mem_high(strm, prefix); - - /* free leftover allocations and item structures, if any */ - item = zone->first; - while (item != NULL) { - free(item->ptr); - next = item->next; - free(item); - item = next; - count++; - } - - /* issue alerts about anything unexpected */ - if (count || zone->total) - fprintf(stderr, "** %s: %zu bytes in %d blocks not freed\n", - prefix, zone->total, count); - if (zone->notlifo) - fprintf(stderr, "** %s: %d frees not LIFO\n", prefix, zone->notlifo); - if (zone->rogue) - fprintf(stderr, "** %s: %d frees not recognized\n", - prefix, zone->rogue); - - /* free the zone and delete from the stream */ - free(zone); - strm->opaque = Z_NULL; - strm->zalloc = Z_NULL; - strm->zfree = Z_NULL; -} - -/* -- inflate test routines -- */ - -/* Decode a hexadecimal string, set *len to length, in[] to the bytes. This - decodes liberally, in that hex digits can be adjacent, in which case two in - a row writes a byte. Or they can be delimited by any non-hex character, - where the delimiters are ignored except when a single hex digit is followed - by a delimiter, where that single digit writes a byte. The returned data is - allocated and must eventually be freed. NULL is returned if out of memory. - If the length is not needed, then len can be NULL. */ -static unsigned char *h2b(const char *hex, unsigned *len) -{ - unsigned char *in, *re; - unsigned next, val; - - in = malloc((strlen(hex) + 1) >> 1); - if (in == NULL) - return NULL; - next = 0; - val = 1; - do { - if (*hex >= '0' && *hex <= '9') - val = (val << 4) + *hex - '0'; - else if (*hex >= 'A' && *hex <= 'F') - val = (val << 4) + *hex - 'A' + 10; - else if (*hex >= 'a' && *hex <= 'f') - val = (val << 4) + *hex - 'a' + 10; - else if (val != 1 && val < 32) /* one digit followed by delimiter */ - val += 240; /* make it look like two digits */ - if (val > 255) { /* have two digits */ - in[next++] = val & 0xff; /* save the decoded byte */ - val = 1; /* start over */ - } - } while (*hex++); /* go through the loop with the terminating null */ - if (len != NULL) - *len = next; - re = realloc(in, next); - return re == NULL ? in : re; -} - -/* generic inflate() run, where hex is the hexadecimal input data, what is the - text to include in an error message, step is how much input data to feed - inflate() on each call, or zero to feed it all, win is the window bits - parameter to inflateInit2(), len is the size of the output buffer, and err - is the error code expected from the first inflate() call (the second - inflate() call is expected to return Z_STREAM_END). If win is 47, then - header information is collected with inflateGetHeader(). If a zlib stream - is looking for a dictionary, then an empty dictionary is provided. - inflate() is run until all of the input data is consumed. */ -static void inf(char *hex, char *what, unsigned step, int win, unsigned len, int err) -{ - int ret; - unsigned have; - unsigned char *in, *out; - z_stream strm, copy; - gz_header head; - - mem_setup(&strm); - strm.avail_in = 0; - strm.next_in = Z_NULL; - ret = inflateInit2(&strm, win); - if (ret != Z_OK) { - mem_done(&strm, what); - return; - } - out = malloc(len); assert(out != NULL); - if (win == 47) { - head.extra = out; - head.extra_max = len; - head.name = out; - head.name_max = len; - head.comment = out; - head.comm_max = len; - ret = inflateGetHeader(&strm, &head); assert(ret == Z_OK); - } - in = h2b(hex, &have); assert(in != NULL); - if (step == 0 || step > have) - step = have; - strm.avail_in = step; - have -= step; - strm.next_in = in; - do { - strm.avail_out = len; - strm.next_out = out; - ret = inflate(&strm, Z_NO_FLUSH); assert(err == 9 || ret == err); - if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_NEED_DICT) - break; - if (ret == Z_NEED_DICT) { - ret = inflateSetDictionary(&strm, in, 1); - assert(ret == Z_DATA_ERROR); - mem_limit(&strm, 1); - ret = inflateSetDictionary(&strm, out, 0); - assert(ret == Z_MEM_ERROR); - mem_limit(&strm, 0); - ((struct inflate_state *)strm.state)->mode = DICT; - ret = inflateSetDictionary(&strm, out, 0); - assert(ret == Z_OK); - ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_BUF_ERROR); - } - ret = inflateCopy(©, &strm); assert(ret == Z_OK); - ret = inflateEnd(©); assert(ret == Z_OK); - err = 9; /* don't care next time around */ - have += strm.avail_in; - strm.avail_in = step > have ? have : step; - have -= strm.avail_in; - } while (strm.avail_in); - free(in); - free(out); - ret = inflateReset2(&strm, -8); assert(ret == Z_OK); - ret = inflateEnd(&strm); assert(ret == Z_OK); - mem_done(&strm, what); -} - -/* cover all of the lines in inflate.c up to inflate() */ -static void cover_support(void) -{ - int ret; - z_stream strm; - - mem_setup(&strm); - strm.avail_in = 0; - strm.next_in = Z_NULL; - ret = inflateInit(&strm); assert(ret == Z_OK); - mem_used(&strm, "inflate init"); - ret = inflatePrime(&strm, 5, 31); assert(ret == Z_OK); - ret = inflatePrime(&strm, -1, 0); assert(ret == Z_OK); - ret = inflateSetDictionary(&strm, Z_NULL, 0); - assert(ret == Z_STREAM_ERROR); - ret = inflateEnd(&strm); assert(ret == Z_OK); - mem_done(&strm, "prime"); - - inf("63 0", "force window allocation", 0, -15, 1, Z_OK); - inf("63 18 5", "force window replacement", 0, -8, 259, Z_OK); - inf("63 18 68 30 d0 0 0", "force split window update", 4, -8, 259, Z_OK); - inf("3 0", "use fixed blocks", 0, -15, 1, Z_STREAM_END); - inf("", "bad window size", 0, 1, 0, Z_STREAM_ERROR); - - mem_setup(&strm); - strm.avail_in = 0; - strm.next_in = Z_NULL; - ret = inflateInit_(&strm, ZLIB_VERSION + 1, (int)sizeof(z_stream)); - assert(ret == Z_VERSION_ERROR); - mem_done(&strm, "wrong version"); - - strm.avail_in = 0; - strm.next_in = Z_NULL; - ret = inflateInit(&strm); assert(ret == Z_OK); - ret = inflateEnd(&strm); assert(ret == Z_OK); - fputs("inflate built-in memory routines\n", stderr); -} - -/* cover all inflate() header and trailer cases and code after inflate() */ -static void cover_wrap(void) -{ - int ret; - z_stream strm, copy; - unsigned char dict[257]; - - ret = inflate(Z_NULL, 0); assert(ret == Z_STREAM_ERROR); - ret = inflateEnd(Z_NULL); assert(ret == Z_STREAM_ERROR); - ret = inflateCopy(Z_NULL, Z_NULL); assert(ret == Z_STREAM_ERROR); - fputs("inflate bad parameters\n", stderr); - - inf("1f 8b 0 0", "bad gzip method", 0, 31, 0, Z_DATA_ERROR); - inf("1f 8b 8 80", "bad gzip flags", 0, 31, 0, Z_DATA_ERROR); - inf("77 85", "bad zlib method", 0, 15, 0, Z_DATA_ERROR); - inf("8 99", "set window size from header", 0, 0, 0, Z_OK); - inf("78 9c", "bad zlib window size", 0, 8, 0, Z_DATA_ERROR); - inf("78 9c 63 0 0 0 1 0 1", "check adler32", 0, 15, 1, Z_STREAM_END); - inf("1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0", "bad header crc", 0, 47, 1, - Z_DATA_ERROR); - inf("1f 8b 8 2 0 0 0 0 0 0 1d 26 3 0 0 0 0 0 0 0 0 0", "check gzip length", - 0, 47, 0, Z_STREAM_END); - inf("78 90", "bad zlib header check", 0, 47, 0, Z_DATA_ERROR); - inf("8 b8 0 0 0 1", "need dictionary", 0, 8, 0, Z_NEED_DICT); - inf("78 9c 63 0", "compute adler32", 0, 15, 1, Z_OK); - - mem_setup(&strm); - strm.avail_in = 0; - strm.next_in = Z_NULL; - ret = inflateInit2(&strm, -8); - strm.avail_in = 2; - strm.next_in = (void *)"\x63"; - strm.avail_out = 1; - strm.next_out = (void *)&ret; - mem_limit(&strm, 1); - ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR); - ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR); - mem_limit(&strm, 0); - memset(dict, 0, 257); - ret = inflateSetDictionary(&strm, dict, 257); - assert(ret == Z_OK); - mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256); - ret = inflatePrime(&strm, 16, 0); assert(ret == Z_OK); - strm.avail_in = 2; - strm.next_in = (void *)"\x80"; - ret = inflateSync(&strm); assert(ret == Z_DATA_ERROR); - ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_STREAM_ERROR); - strm.avail_in = 4; - strm.next_in = (void *)"\0\0\xff\xff"; - ret = inflateSync(&strm); assert(ret == Z_OK); - (void)inflateSyncPoint(&strm); - ret = inflateCopy(©, &strm); assert(ret == Z_MEM_ERROR); - mem_limit(&strm, 0); - ret = inflateUndermine(&strm, 1); assert(ret == Z_DATA_ERROR); - (void)inflateMark(&strm); - ret = inflateEnd(&strm); assert(ret == Z_OK); - mem_done(&strm, "miscellaneous, force memory errors"); -} - -/* input and output functions for inflateBack() */ -static unsigned pull(void *desc, const unsigned char **buf) -{ - static unsigned int next = 0; - static unsigned char dat[] = {0x63, 0, 2, 0}; - struct inflate_state *state; - - if (desc == Z_NULL) { - next = 0; - return 0; /* no input (already provided at next_in) */ - } - state = (void *)((z_stream *)desc)->state; - if (state != Z_NULL) - state->mode = SYNC; /* force an otherwise impossible situation */ - return next < sizeof(dat) ? (*buf = dat + next++, 1) : 0; -} - -static int push(void *desc, unsigned char *buf, unsigned len) -{ - buf += len; - return desc != Z_NULL; /* force error if desc not null */ -} - -/* cover inflateBack() up to common deflate data cases and after those */ -static void cover_back(void) -{ - int ret; - z_stream strm; - unsigned char win[32768]; - - ret = inflateBackInit_(Z_NULL, 0, win, 0, 0); - assert(ret == Z_VERSION_ERROR); - ret = inflateBackInit(Z_NULL, 0, win); assert(ret == Z_STREAM_ERROR); - ret = inflateBack(Z_NULL, Z_NULL, Z_NULL, Z_NULL, Z_NULL); - assert(ret == Z_STREAM_ERROR); - ret = inflateBackEnd(Z_NULL); assert(ret == Z_STREAM_ERROR); - fputs("inflateBack bad parameters\n", stderr); - - mem_setup(&strm); - ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK); - strm.avail_in = 2; - strm.next_in = (void *)"\x03"; - ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL); - assert(ret == Z_STREAM_END); - /* force output error */ - strm.avail_in = 3; - strm.next_in = (void *)"\x63\x00"; - ret = inflateBack(&strm, pull, Z_NULL, push, &strm); - assert(ret == Z_BUF_ERROR); - /* force mode error by mucking with state */ - ret = inflateBack(&strm, pull, &strm, push, Z_NULL); - assert(ret == Z_STREAM_ERROR); - ret = inflateBackEnd(&strm); assert(ret == Z_OK); - mem_done(&strm, "inflateBack bad state"); - - ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK); - ret = inflateBackEnd(&strm); assert(ret == Z_OK); - fputs("inflateBack built-in memory routines\n", stderr); -} - -/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */ -static int try(char *hex, char *id, int err) -{ - int ret; - unsigned len, size; - unsigned char *in, *out, *win; - char *prefix; - z_stream strm; - - /* convert to hex */ - in = h2b(hex, &len); - assert(in != NULL); - - /* allocate work areas */ - size = len << 3; - out = malloc(size); - assert(out != NULL); - win = malloc(32768); - assert(win != NULL); - prefix = malloc(strlen(id) + 6); - assert(prefix != NULL); - - /* first with inflate */ - strcpy(prefix, id); - strcat(prefix, "-late"); - mem_setup(&strm); - strm.avail_in = 0; - strm.next_in = Z_NULL; - ret = inflateInit2(&strm, err < 0 ? 47 : -15); - assert(ret == Z_OK); - strm.avail_in = len; - strm.next_in = in; - do { - strm.avail_out = size; - strm.next_out = out; - ret = inflate(&strm, Z_TREES); - assert(ret != Z_STREAM_ERROR && ret != Z_MEM_ERROR); - if (ret == Z_DATA_ERROR || ret == Z_NEED_DICT) - break; - } while (strm.avail_in || strm.avail_out == 0); - if (err) { - assert(ret == Z_DATA_ERROR); - assert(strcmp(id, strm.msg) == 0); - } - inflateEnd(&strm); - mem_done(&strm, prefix); - - /* then with inflateBack */ - if (err >= 0) { - strcpy(prefix, id); - strcat(prefix, "-back"); - mem_setup(&strm); - ret = inflateBackInit(&strm, 15, win); - assert(ret == Z_OK); - strm.avail_in = len; - strm.next_in = in; - ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL); - assert(ret != Z_STREAM_ERROR); - if (err) { - assert(ret == Z_DATA_ERROR); - assert(strcmp(id, strm.msg) == 0); - } - inflateBackEnd(&strm); - mem_done(&strm, prefix); - } - - /* clean up */ - free(prefix); - free(win); - free(out); - free(in); - return ret; -} - -/* cover deflate data cases in both inflate() and inflateBack() */ -static void cover_inflate(void) -{ - try("0 0 0 0 0", "invalid stored block lengths", 1); - try("3 0", "fixed", 0); - try("6", "invalid block type", 1); - try("1 1 0 fe ff 0", "stored", 0); - try("fc 0 0", "too many length or distance symbols", 1); - try("4 0 fe ff", "invalid code lengths set", 1); - try("4 0 24 49 0", "invalid bit length repeat", 1); - try("4 0 24 e9 ff ff", "invalid bit length repeat", 1); - try("4 0 24 e9 ff 6d", "invalid code -- missing end-of-block", 1); - try("4 80 49 92 24 49 92 24 71 ff ff 93 11 0", - "invalid literal/lengths set", 1); - try("4 80 49 92 24 49 92 24 f b4 ff ff c3 84", "invalid distances set", 1); - try("4 c0 81 8 0 0 0 0 20 7f eb b 0 0", "invalid literal/length code", 1); - try("2 7e ff ff", "invalid distance code", 1); - try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 1); - - /* also trailer mismatch just in inflate() */ - try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1", "incorrect data check", -1); - try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1", - "incorrect length check", -1); - try("5 c0 21 d 0 0 0 80 b0 fe 6d 2f 91 6c", "pull 17", 0); - try("5 e0 81 91 24 cb b2 2c 49 e2 f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f", - "long code", 0); - try("ed c0 1 1 0 0 0 40 20 ff 57 1b 42 2c 4f", "length extra", 0); - try("ed cf c1 b1 2c 47 10 c4 30 fa 6f 35 1d 1 82 59 3d fb be 2e 2a fc f c", - "long distance and extra", 0); - try("ed c0 81 0 0 0 0 80 a0 fd a9 17 a9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 " - "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6", "window end", 0); - inf("2 8 20 80 0 3 0", "inflate_fast TYPE return", 0, -15, 258, - Z_STREAM_END); - inf("63 18 5 40 c 0", "window wrap", 3, -8, 300, Z_OK); -} - -/* cover remaining lines in inftrees.c */ -static void cover_trees(void) -{ - int ret; - unsigned bits; - uint16_t lens[16], work[16]; - code *next, table[ENOUGH_DISTS]; - - /* we need to call inflate_table() directly in order to manifest not- - enough errors, since zlib insures that enough is always enough */ - for (bits = 0; bits < 15; bits++) - lens[bits] = (uint16_t)(bits + 1); - lens[15] = 15; - next = table; - bits = 15; - ret = inflate_table(DISTS, lens, 16, &next, &bits, work); - assert(ret == 1); - next = table; - bits = 1; - ret = inflate_table(DISTS, lens, 16, &next, &bits, work); - assert(ret == 1); - fputs("inflate_table not enough errors\n", stderr); -} - -/* cover remaining inffast.c decoding and window copying */ -static void cover_fast(void) -{ - inf("e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68" - " ff 7f 0f 0 0 0", "fast length extra bits", 0, -8, 258, Z_DATA_ERROR); - inf("25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49" - " 50 fe ff ff 3f 0 0", "fast distance extra bits", 0, -8, 258, - Z_DATA_ERROR); - inf("3 7e 0 0 0 0 0", "fast invalid distance code", 0, -8, 258, - Z_DATA_ERROR); - inf("1b 7 0 0 0 0 0", "fast invalid literal/length code", 0, -8, 258, - Z_DATA_ERROR); - inf("d c7 1 ae eb 38 c 4 41 a0 87 72 de df fb 1f b8 36 b1 38 5d ff ff 0", - "fast 2nd level codes and too far back", 0, -8, 258, Z_DATA_ERROR); - inf("63 18 5 8c 10 8 0 0 0 0", "very common case", 0, -8, 259, Z_OK); - inf("63 60 60 18 c9 0 8 18 18 18 26 c0 28 0 29 0 0 0", - "contiguous and wrap around window", 6, -8, 259, Z_OK); - inf("63 0 3 0 0 0 0 0", "copy direct from output", 0, -8, 259, - Z_STREAM_END); -} - -int main(void) -{ - fprintf(stderr, "%s\n", zlibVersion()); - cover_support(); - cover_wrap(); - cover_back(); - cover_inflate(); - cover_trees(); - cover_fast(); - return 0; -} diff --git a/contrib/libzlib-ng/test/minigzip.c b/contrib/libzlib-ng/test/minigzip.c deleted file mode 100644 index 9c71fd1b8d5..00000000000 --- a/contrib/libzlib-ng/test/minigzip.c +++ /dev/null @@ -1,530 +0,0 @@ -/* minigzip.c -- simulate gzip using the zlib compression library - * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * minigzip is a minimal implementation of the gzip utility. This is - * only an example of using zlib and isn't meant to replace the - * full-featured gzip. No attempt is made to deal with file systems - * limiting names to 14 or 8+3 characters, etc... Error checking is - * very limited. So use minigzip only for testing; use gzip for the - * real thing. - */ - -/* @(#) $Id$ */ - -#include "zlib.h" -#include - -#include -#include - -#ifdef USE_MMAP -# include -# include -# include -#endif - -#if defined(WIN32) || defined(__CYGWIN__) -# include -# include -# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) -#else -# define SET_BINARY_MODE(file) -#endif - -#if defined(_MSC_VER) && _MSC_VER < 1900 -# define snprintf _snprintf -#endif - -#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) -#ifndef WIN32 /* unlink already in stdio.h for WIN32 */ - extern int unlink (const char *); -#endif -#endif - -#ifndef GZ_SUFFIX -# define GZ_SUFFIX ".gz" -#endif -#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) - -#define BUFLEN 16384 /* read buffer size */ -#define BUFLENW (BUFLEN * 3) /* write buffer size */ -#define MAX_NAME_LEN 1024 - -#ifndef WITH_GZFILEOP -/* without WITH_GZFILEOP, create simplified gz* functions using deflate and inflate */ - -#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE) -# include /* for unlink() */ -#endif - -void *myalloc (void *, unsigned, unsigned); -void myfree (void *, void *); - -void *myalloc(void *q, unsigned n, unsigned m) -{ - (void)q; - return calloc(n, m); -} - -void myfree(void *q, void *p) -{ - (void)q; - free(p); -} - -typedef struct gzFile_s { - FILE *file; - int write; - int err; - const char *msg; - z_stream strm; - unsigned char *buf; -} *gzFile; - -gzFile gzopen (const char *, const char *); -gzFile gzdopen (int, const char *); -gzFile gz_open (const char *, int, const char *); - -gzFile gzopen(const char *path, const char *mode) -{ - return gz_open(path, -1, mode); -} - -gzFile gzdopen(int fd, const char *mode) -{ - return gz_open(NULL, fd, mode); -} - -gzFile gz_open(const char *path, int fd, const char *mode) -{ - gzFile gz; - int ret; - int level = Z_DEFAULT_COMPRESSION; - const char *plevel = mode; - - gz = malloc(sizeof(struct gzFile_s)); - if (gz == NULL) - return NULL; - gz->write = strchr(mode, 'w') != NULL; - gz->strm.zalloc = myalloc; - gz->strm.zfree = myfree; - gz->strm.opaque = Z_NULL; - gz->buf = malloc(gz->write ? BUFLENW : BUFLEN); - - if (gz->buf == NULL) { - free(gz); - return NULL; - } - - while (*plevel) { - if (*plevel >= '0' && *plevel <= '9') { - level = *plevel - '0'; - break; - } - plevel++; - } - if (gz->write) - ret = deflateInit2(&(gz->strm), level, 8, 15 + 16, 8, 0); - else { - gz->strm.next_in = 0; - gz->strm.avail_in = Z_NULL; - ret = inflateInit2(&(gz->strm), 15 + 16); - } - if (ret != Z_OK) { - free(gz); - return NULL; - } - gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") : - fopen(path, gz->write ? "wb" : "rb"); - if (gz->file == NULL) { - gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm)); - free(gz); - return NULL; - } - gz->err = 0; - gz->msg = ""; - return gz; -} - -int gzwrite (gzFile, const void *, unsigned); - -int gzwrite(gzFile gz, const void *buf, unsigned len) -{ - z_stream *strm; - - if (gz == NULL || !gz->write) - return 0; - strm = &(gz->strm); - strm->next_in = (void *)buf; - strm->avail_in = len; - do { - strm->next_out = gz->buf; - strm->avail_out = BUFLENW; - (void)deflate(strm, Z_NO_FLUSH); - fwrite(gz->buf, 1, BUFLENW - strm->avail_out, gz->file); - } while (strm->avail_out == 0); - return len; -} - -int gzread (gzFile, void *, unsigned); - -int gzread(gzFile gz, void *buf, unsigned len) -{ - z_stream *strm; - - if (gz == NULL || gz->write || gz->err) - return 0; - strm = &(gz->strm); - strm->next_out = buf; - strm->avail_out = len; - do { - if (strm->avail_in == 0) - { - strm->next_in = gz->buf; - strm->avail_in = (uint32_t)fread(gz->buf, 1, BUFLEN, gz->file); - } - if (strm->avail_in > 0) - { - int ret = inflate(strm, Z_NO_FLUSH); - if (ret == Z_DATA_ERROR) { - gz->err = ret; - gz->msg = strm->msg; - return 0; - } - else if (ret == Z_STREAM_END) - inflateReset(strm); - } - else - break; - } while (strm->avail_out); - return len - strm->avail_out; -} - -int gzclose (gzFile); - -int gzclose(gzFile gz) -{ - z_stream *strm; - - if (gz == NULL) - return Z_STREAM_ERROR; - strm = &(gz->strm); - if (gz->write) { - strm->next_in = Z_NULL; - strm->avail_in = 0; - do { - strm->next_out = gz->buf; - strm->avail_out = BUFLENW; - (void)deflate(strm, Z_FINISH); - fwrite(gz->buf, 1, BUFLENW - strm->avail_out, gz->file); - } while (strm->avail_out == 0); - deflateEnd(strm); - } - else - inflateEnd(strm); - free(gz->buf); - fclose(gz->file); - free(gz); - return Z_OK; -} - -const char *gzerror (gzFile, int *); - -const char *gzerror(gzFile gz, int *err) -{ - *err = gz->err; - return gz->msg; -} - -#endif - -char *prog; - -void error (const char *msg); -void gz_compress (FILE *in, gzFile out); -#ifdef USE_MMAP -int gz_compress_mmap (FILE *in, gzFile out); -#endif -void gz_uncompress (gzFile in, FILE *out); -void file_compress (char *file, char *mode); -void file_uncompress (char *file); -int main (int argc, char *argv[]); - -/* =========================================================================== - * Display error message and exit - */ -void error(const char *msg) -{ - fprintf(stderr, "%s: %s\n", prog, msg); - exit(1); -} - -/* =========================================================================== - * Compress input to output then close both files. - */ - -void gz_compress(FILE *in, gzFile out) -{ - char buf[BUFLEN]; - int len; - int err; - -#ifdef USE_MMAP - /* Try first compressing with mmap. If mmap fails (minigzip used in a - * pipe), use the normal fread loop. - */ - if (gz_compress_mmap(in, out) == Z_OK) return; -#endif - for (;;) { - len = (int)fread(buf, 1, sizeof(buf), in); - if (ferror(in)) { - perror("fread"); - exit(1); - } - if (len == 0) break; - - if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err)); - } - fclose(in); - if (gzclose(out) != Z_OK) error("failed gzclose"); -} - -#ifdef USE_MMAP /* MMAP version, Miguel Albrecht */ - -/* Try compressing the input file at once using mmap. Return Z_OK if - * if success, Z_ERRNO otherwise. - */ -int gz_compress_mmap(FILE *in, gzFile out) -{ - int len; - int err; - int ifd = fileno(in); - caddr_t buf; /* mmap'ed buffer for the entire input file */ - off_t buf_len; /* length of the input file */ - struct stat sb; - - /* Determine the size of the file, needed for mmap: */ - if (fstat(ifd, &sb) < 0) return Z_ERRNO; - buf_len = sb.st_size; - if (buf_len <= 0) return Z_ERRNO; - - /* Now do the actual mmap: */ - buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); - if (buf == (caddr_t)(-1)) return Z_ERRNO; - - /* Compress the whole file at once: */ - len = gzwrite(out, (char *)buf, (unsigned)buf_len); - - if (len != (int)buf_len) error(gzerror(out, &err)); - - munmap(buf, buf_len); - fclose(in); - if (gzclose(out) != Z_OK) error("failed gzclose"); - return Z_OK; -} -#endif /* USE_MMAP */ - -/* =========================================================================== - * Uncompress input to output then close both files. - */ -void gz_uncompress(gzFile in, FILE *out) -{ - char buf[BUFLENW]; - int len; - int err; - - for (;;) { - len = gzread(in, buf, sizeof(buf)); - if (len < 0) error (gzerror(in, &err)); - if (len == 0) break; - - if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { - error("failed fwrite"); - } - } - if (fclose(out)) error("failed fclose"); - - if (gzclose(in) != Z_OK) error("failed gzclose"); -} - - -/* =========================================================================== - * Compress the given file: create a corresponding .gz file and remove the - * original. - */ -void file_compress(char *file, char *mode) -{ - char outfile[MAX_NAME_LEN]; - FILE *in; - gzFile out; - - if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) { - fprintf(stderr, "%s: filename too long\n", prog); - exit(1); - } - - snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX); - - in = fopen(file, "rb"); - if (in == NULL) { - perror(file); - exit(1); - } - out = gzopen(outfile, mode); - if (out == NULL) { - fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); - exit(1); - } - gz_compress(in, out); - - unlink(file); -} - - -/* =========================================================================== - * Uncompress the given file and remove the original. - */ -void file_uncompress(char *file) -{ - char buf[MAX_NAME_LEN]; - char *infile, *outfile; - FILE *out; - gzFile in; - size_t len = strlen(file); - - if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) { - fprintf(stderr, "%s: filename too long\n", prog); - exit(1); - } - - snprintf(buf, sizeof(buf), "%s", file); - - if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { - infile = file; - outfile = buf; - outfile[len-3] = '\0'; - } else { - outfile = file; - infile = buf; - snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX); - } - in = gzopen(infile, "rb"); - if (in == NULL) { - fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); - exit(1); - } - out = fopen(outfile, "wb"); - if (out == NULL) { - perror(file); - exit(1); - } - - gz_uncompress(in, out); - - unlink(infile); -} - - -/* =========================================================================== - * Usage: minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...] - * -c : write to standard output - * -d : decompress - * -f : compress with Z_FILTERED - * -h : compress with Z_HUFFMAN_ONLY - * -r : compress with Z_RLE - * -1 to -9 : compression level - */ - -int main(int argc, char *argv[]) -{ - int copyout = 0; - int uncompr = 0; - gzFile file; - char *bname, outmode[20]; - - snprintf(outmode, sizeof(outmode), "%s", "wb6 "); - - prog = argv[0]; - bname = strrchr(argv[0], '/'); - if (bname) - bname++; - else - bname = argv[0]; - argc--, argv++; - - if (!strcmp(bname, "gunzip")) - uncompr = 1; - else if (!strcmp(bname, "zcat")) - copyout = uncompr = 1; - - while (argc > 0) { - if (strcmp(*argv, "-c") == 0) - copyout = 1; - else if (strcmp(*argv, "-d") == 0) - uncompr = 1; - else if (strcmp(*argv, "-f") == 0) - outmode[3] = 'f'; - else if (strcmp(*argv, "-h") == 0) - outmode[3] = 'h'; - else if (strcmp(*argv, "-r") == 0) - outmode[3] = 'R'; - else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' && - (*argv)[2] == 0) - outmode[2] = (*argv)[1]; - else - break; - argc--, argv++; - } - if (outmode[3] == ' ') - outmode[3] = 0; - if (argc == 0) { - SET_BINARY_MODE(stdin); - SET_BINARY_MODE(stdout); - if (uncompr) { - file = gzdopen(fileno(stdin), "rb"); - if (file == NULL) error("can't gzdopen stdin"); - gz_uncompress(file, stdout); - } else { - file = gzdopen(fileno(stdout), outmode); - if (file == NULL) error("can't gzdopen stdout"); - gz_compress(stdin, file); - } - } else { - if (copyout) { - SET_BINARY_MODE(stdout); - } - do { - if (uncompr) { - if (copyout) { - file = gzopen(*argv, "rb"); - if (file == NULL) - fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv); - else - gz_uncompress(file, stdout); - } else { - file_uncompress(*argv); - } - } else { - if (copyout) { - FILE * in = fopen(*argv, "rb"); - - if (in == NULL) { - perror(*argv); - } else { - file = gzdopen(fileno(stdout), outmode); - if (file == NULL) error("can't gzdopen stdout"); - - gz_compress(in, file); - } - - } else { - file_compress(*argv, outmode); - } - } - } while (argv++, --argc); - } - return 0; -} diff --git a/contrib/libzlib-ng/test/testCVEinputs.sh b/contrib/libzlib-ng/test/testCVEinputs.sh deleted file mode 100755 index 046856e7884..00000000000 --- a/contrib/libzlib-ng/test/testCVEinputs.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -TESTDIR="$(dirname "$0")" - -CVEs="CVE-2002-0059 CVE-2004-0797 CVE-2005-1849 CVE-2005-2096" - -for CVE in $CVEs; do - fail=0 - for testcase in ${TESTDIR}/${CVE}/*.gz; do - ../minigzip -d < "$testcase" - # we expect that a 1 error code is OK - # for a vulnerable failure we'd expect 134 or similar - if [ $? -ne 1 ]; then - fail=1 - fi - done - if [ $fail -eq 0 ]; then - echo " --- zlib not vulnerable to $CVE ---"; - else - echo " --- zlib VULNERABLE to $CVE ---"; exit 1; - fi -done - diff --git a/contrib/libzlib-ng/treebuild.xml b/contrib/libzlib-ng/treebuild.xml deleted file mode 100644 index 38d29d75efc..00000000000 --- a/contrib/libzlib-ng/treebuild.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - - zip compression library - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/contrib/libzlib-ng/trees.c b/contrib/libzlib-ng/trees.c deleted file mode 100644 index ee756fc5a25..00000000000 --- a/contrib/libzlib-ng/trees.c +++ /dev/null @@ -1,1119 +0,0 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2012 Jean-loup Gailly - * detect_data_type() function provided freely by Cosmin Truta, 2006 - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id$ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef DEBUG -# include -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local const int extra_blbits[BL_CODES] /* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local const unsigned char bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) -/* non ANSI compilers may not accept trees.h */ - -ZLIB_INTERNAL ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const int *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - unsigned int max_length; /* max bit length for the codes */ -}; - -local const static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local const static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local const static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init (void); -local void init_block (deflate_state *s); -local void pqdownheap (deflate_state *s, ct_data *tree, int k); -local void gen_bitlen (deflate_state *s, tree_desc *desc); -local void gen_codes (ct_data *tree, int max_code, uint16_t *bl_count); -local void build_tree (deflate_state *s, tree_desc *desc); -local void scan_tree (deflate_state *s, ct_data *tree, int max_code); -local void send_tree (deflate_state *s, ct_data *tree, int max_code); -local int build_bl_tree (deflate_state *s); -local void send_all_trees (deflate_state *s, int lcodes, int dcodes, int blcodes); -local void compress_block (deflate_state *s, const ct_data *ltree, const ct_data *dtree); -local int detect_data_type (deflate_state *s); -local unsigned bi_reverse (unsigned value, int length); -local void bi_flush (deflate_state *s); -local void copy_block (deflate_state *s, char *buf, unsigned len, int header); - -#ifdef GEN_TREES_H -local void gen_trees_header(void); -#endif - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init(void) { -#if defined(GEN_TREES_H) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - uint16_t bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) - return; - - /* For some embedded targets, global variables are not initialized: */ -#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1 << extra_lbits[code]); n++) { - _length_code[length++] = (unsigned char)code; - } - } - Assert(length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - _length_code[length-1] = (unsigned char)code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1 << extra_dbits[code]); n++) { - _dist_code[dist++] = (unsigned char)code; - } - } - Assert(dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1 << (extra_dbits[code]-7)); n++) { - _dist_code[256 + dist++] = (unsigned char)code; - } - } - Assert(dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) - bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) */ -} - -/* =========================================================================== - * Genererate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef DEBUG -# include -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) - -void gen_trees_header() { - FILE *header = fopen("trees.h", "w"); - int i; - - Assert(header != NULL, "Can't open trees.h"); - fprintf(header, "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "ZLIB_INTERNAL const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const unsigned char ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, "const unsigned char ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%d%s", base_length[i], SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5d%s", base_dist[i], SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void ZLIB_INTERNAL _tr_init(deflate_state *s) { - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(deflate_state *s) { - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) - s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) - s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) - s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(deflate_state *s, ct_data *tree, int k) { - /* tree: the tree to restore */ - /* k: node to move down */ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) - break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; - k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(deflate_state *s, tree_desc *desc) { - /* desc: the tree descriptor */ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const int *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - unsigned int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - unsigned int bits; /* bit length */ - int xbits; /* extra bits */ - uint16_t f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) - s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) - bits = max_length, overflow++; - tree[n].Len = (uint16_t)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) /* not a leaf node */ - continue; - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) - xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (unsigned long)f * (bits + xbits); - if (stree) - s->static_len += (unsigned long)f * (stree[n].Len + xbits); - } - if (overflow == 0) - return; - - Trace((stderr, "\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) - bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) - continue; - if (tree[m].Len != bits) { - Trace((stderr, "code %d bits %d->%u\n", m, tree[m].Len, bits)); - s->opt_len += (long)((bits - tree[m].Len) * tree[m].Freq); - tree[m].Len = (uint16_t)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes(ct_data *tree, int max_code, uint16_t *bl_count) { - /* tree: the tree to decorate */ - /* max_code: largest code with non zero frequency */ - /* bl_count: number of codes at each bit length */ - uint16_t next_code[MAX_BITS+1]; /* next code value for each bit length */ - uint16_t code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits-1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert(code + bl_count[MAX_BITS]-1 == (1 << MAX_BITS)-1, "inconsistent bit counts"); - Tracev((stderr, "\ngen_codes: max_code %d ", max_code)); - - for (n = 0; n <= max_code; n++) { - int len = tree[n].Len; - if (len == 0) - continue; - /* Now reverse the bits */ - tree[n].Code = bi_reverse(next_code[len]++, len); - - Tracecv(tree != static_ltree, (stderr, "\nn %3d %c l %2d c %4x (%x) ", - n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); - } -} - -/* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ -local void build_tree(deflate_state *s, tree_desc *desc) { - /* desc: the tree descriptor */ - ct_data *tree = desc->dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; - if (stree) - s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) - pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (unsigned char)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (uint16_t)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr, "\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree(deflate_state *s, ct_data *tree, int max_code) { - /* tree: the tree to be scanned */ - /* max_code: and its largest code of non zero frequency */ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) - max_count = 138, min_count = 3; - - tree[max_code+1].Len = (uint16_t)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) - s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; - prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree(deflate_state *s, ct_data *tree, int max_code) { - /* tree: the tree to be scanned */ - /* max_code and its largest code of non zero frequency */ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) - max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; - nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { - send_code(s, curlen, s->bl_tree); - } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); - count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); - send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); - send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); - send_bits(s, count-11, 7); - } - count = 0; - prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(deflate_state *s) { - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) - break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*(max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %lu, stat %lu", s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(deflate_state *s, int lcodes, int dcodes, int blcodes) { - int rank; /* index in bl_order */ - - Assert(lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert(lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2u ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %lu", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %lu", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %lu", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, char *buf, unsigned long stored_len, int last) { - /* buf: input block */ - /* stored_len: length of input block */ - /* last: one if this is the last block for a file */ - send_bits(s, (STORED_BLOCK << 1)+last, 3); /* send block type */ -#ifdef DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (unsigned long)~7L; - s->compressed_len += (stored_len + 4) << 3; -#endif - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ -} - -/* =========================================================================== - * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) - */ -void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s) { - bi_flush(s); -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ -void ZLIB_INTERNAL _tr_align(deflate_state *s) { - send_bits(s, STATIC_TREES << 1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. - */ -void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, char *buf, unsigned long stored_len, int last) { - /* buf: input block, or NULL if too old */ - /* stored_len: length of input block */ - /* last: one if this is the last block for a file */ - unsigned long opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - /* Check if the file is binary or text */ - if (s->strm->data_type == Z_UNKNOWN) - s->strm->data_type = detect_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %lu, stat %lu", s->opt_len, s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %lu, stat %lu", s->opt_len, s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len+3+7) >> 3; - static_lenb = (s->static_len+3+7) >> 3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, s->last_lit)); - - if (static_lenb <= opt_lenb) - opt_lenb = static_lenb; - - } else { - Assert(buf != NULL, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != NULL) { /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != NULL) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, last); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES << 1)+last, 3); - compress_block(s, (const ct_data *)static_ltree, (const ct_data *)static_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { - send_bits(s, (DYN_TREES << 1)+last, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, max_blindex+1); - compress_block(s, (const ct_data *)s->dyn_ltree, (const ct_data *)s->dyn_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->opt_len; -#endif - } - Assert(s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and unsigned long implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); -#ifdef DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr, "\ncomprlen %lu(%lu) ", s->compressed_len>>3, s->compressed_len-7*last)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { - /* dist: distance of matched string */ - /* lc: match length-MIN_MATCH or unmatched char (if dist==0) */ - s->d_buf[s->last_lit] = (uint16_t)dist; - s->l_buf[s->last_lit++] = (unsigned char)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((uint16_t)dist < (uint16_t)MAX_DIST(s) && - (uint16_t)lc <= (uint16_t)(MAX_MATCH-MIN_MATCH) && - (uint16_t)d_code(dist) < (uint16_t)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - -#ifdef TRUNCATE_BLOCK - /* Try to guess if it is profitable to stop the current block here */ - if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { - /* Compute an upper bound for the compressed length */ - unsigned long out_length = (unsigned long)s->last_lit*8L; - unsigned long in_length = (unsigned long)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (unsigned long)s->dyn_dtree[dcode].Freq * (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr, "\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) - return 1; - } -#endif - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(deflate_state *s, const ct_data *ltree, const ct_data *dtree) { - /* ltree: literal tree */ - /* dtree: distance tree */ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) { - do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr, " '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert(code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert((unsigned int)(s->pending) < s->lit_bufsize + 2*lx, "pendingBuf overflow"); - } while (lx < s->last_lit); - } - - send_code(s, END_BLOCK, ltree); -} - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "black list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local int detect_data_type(deflate_state *s) { - /* black_mask is the bit mask of black-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - unsigned long black_mask = 0xf3ffc07fUL; - int n; - - /* Check for non-textual ("black-listed") bytes. */ - for (n = 0; n <= 31; n++, black_mask >>= 1) - if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) - return Z_BINARY; - - /* Check for textual ("white-listed") bytes. */ - if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 || s->dyn_ltree[13].Freq != 0) - return Z_TEXT; - for (n = 32; n < LITERALS; n++) - if (s->dyn_ltree[n].Freq != 0) - return Z_TEXT; - - /* There are no "black-listed" or "white-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(unsigned code, int len) { - /* code: the value to invert */ - /* len: its bit length */ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(deflate_state *s) { - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (unsigned char)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -ZLIB_INTERNAL void bi_windup(deflate_state *s) { - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (unsigned char)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} - -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -local void copy_block(deflate_state *s, char *buf, unsigned len, int header) { - /* buf: the input data */ - /* len: its length */ - /* header: true if block header must be written */ - bi_windup(s); /* align on byte boundary */ - - if (header) { - put_short(s, (uint16_t)len); - put_short(s, (uint16_t)~len); -#ifdef DEBUG - s->bits_sent += 2*16; -#endif - } -#ifdef DEBUG - s->bits_sent += (unsigned long)len << 3; -#endif - while (len--) { - put_byte(s, *buf++); - } -} - diff --git a/contrib/libzlib-ng/trees.h b/contrib/libzlib-ng/trees.h deleted file mode 100644 index debfbdd8584..00000000000 --- a/contrib/libzlib-ng/trees.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef TREES_H_ -#define TREES_H_ - -/* header created automatically with -DGEN_TREES_H */ - -ZLIB_INTERNAL const ct_data static_ltree[L_CODES+2] = { -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -}; - -local const ct_data static_dtree[D_CODES] = { -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -}; - -const unsigned char ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const unsigned char ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -local const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - -#endif /* TREES_H_ */ diff --git a/contrib/libzlib-ng/uncompr.c b/contrib/libzlib-ng/uncompr.c deleted file mode 100644 index c2af140db1e..00000000000 --- a/contrib/libzlib-ng/uncompr.c +++ /dev/null @@ -1,75 +0,0 @@ -/* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003, 2010, 2014 Jean-loup Gailly, Mark Adler. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted, including if the - input data is an incomplete zlib stream. -*/ -int ZEXPORT uncompress(unsigned char *dest, size_t *destLen, const unsigned char *source, size_t sourceLen) { - z_stream stream; - int err; - const unsigned int max = (unsigned int)0 - 1; - size_t left; - unsigned char buf[1]; /* for detection of incomplete stream when *destLen == 0 */ - - if (*destLen) { - left = *destLen; - *destLen = 0; - } - else { - left = 1; - dest = buf; - } - - stream.next_in = (const unsigned char *)source; - stream.avail_in = 0; - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = NULL; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - stream.next_out = dest; - stream.avail_out = 0; - - do { - if (stream.avail_out == 0) { - stream.avail_out = left > (unsigned long)max ? max : (unsigned int)left; - left -= stream.avail_out; - } - if (stream.avail_in == 0) { - stream.avail_in = sourceLen > (unsigned long)max ? max : (unsigned int)sourceLen; - sourceLen -= stream.avail_in; - } - err = inflate(&stream, Z_NO_FLUSH); - } while (err == Z_OK); - - if (dest != buf) - *destLen = stream.total_out; - else if (stream.total_out && err == Z_BUF_ERROR) - left = 1; - - inflateEnd(&stream); - return err == Z_STREAM_END ? Z_OK : - err == Z_NEED_DICT ? Z_DATA_ERROR : - err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : - err; -} diff --git a/contrib/libzlib-ng/win32/DLL_FAQ.txt b/contrib/libzlib-ng/win32/DLL_FAQ.txt deleted file mode 100644 index 12c009018c3..00000000000 --- a/contrib/libzlib-ng/win32/DLL_FAQ.txt +++ /dev/null @@ -1,397 +0,0 @@ - - Frequently Asked Questions about ZLIB1.DLL - - -This document describes the design, the rationale, and the usage -of the official DLL build of zlib, named ZLIB1.DLL. If you have -general questions about zlib, you should see the file "FAQ" found -in the zlib distribution, or at the following location: - http://www.gzip.org/zlib/zlib_faq.html - - - 1. What is ZLIB1.DLL, and how can I get it? - - - ZLIB1.DLL is the official build of zlib as a DLL. - (Please remark the character '1' in the name.) - - Pointers to a precompiled ZLIB1.DLL can be found in the zlib - web site at: - http://www.zlib.net/ - - Applications that link to ZLIB1.DLL can rely on the following - specification: - - * The exported symbols are exclusively defined in the source - files "zlib.h" and "zlib.def", found in an official zlib - source distribution. - * The symbols are exported by name, not by ordinal. - * The exported names are undecorated. - * The calling convention of functions is "C" (CDECL). - * The ZLIB1.DLL binary is linked to MSVCRT.DLL. - - The archive in which ZLIB1.DLL is bundled contains compiled - test programs that must run with a valid build of ZLIB1.DLL. - It is recommended to download the prebuilt DLL from the zlib - web site, instead of building it yourself, to avoid potential - incompatibilities that could be introduced by your compiler - and build settings. If you do build the DLL yourself, please - make sure that it complies with all the above requirements, - and it runs with the precompiled test programs, bundled with - the original ZLIB1.DLL distribution. - - If, for any reason, you need to build an incompatible DLL, - please use a different file name. - - - 2. Why did you change the name of the DLL to ZLIB1.DLL? - What happened to the old ZLIB.DLL? - - - The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required - compilation settings that were incompatible to those used by - a static build. The DLL settings were supposed to be enabled - by defining the macro ZLIB_DLL, before including "zlib.h". - Incorrect handling of this macro was silently accepted at - build time, resulting in two major problems: - - * ZLIB_DLL was missing from the old makefile. When building - the DLL, not all people added it to the build options. In - consequence, incompatible incarnations of ZLIB.DLL started - to circulate around the net. - - * When switching from using the static library to using the - DLL, applications had to define the ZLIB_DLL macro and - to recompile all the sources that contained calls to zlib - functions. Failure to do so resulted in creating binaries - that were unable to run with the official ZLIB.DLL build. - - The only possible solution that we could foresee was to make - a binary-incompatible change in the DLL interface, in order to - remove the dependency on the ZLIB_DLL macro, and to release - the new DLL under a different name. - - We chose the name ZLIB1.DLL, where '1' indicates the major - zlib version number. We hope that we will not have to break - the binary compatibility again, at least not as long as the - zlib-1.x series will last. - - There is still a ZLIB_DLL macro, that can trigger a more - efficient build and use of the DLL, but compatibility no - longer dependents on it. - - - 3. Can I build ZLIB.DLL from the new zlib sources, and replace - an old ZLIB.DLL, that was built from zlib-1.1.4 or earlier? - - - In principle, you can do it by assigning calling convention - keywords to the macros ZEXPORT and ZEXPORTVA. In practice, - it depends on what you mean by "an old ZLIB.DLL", because the - old DLL exists in several mutually-incompatible versions. - You have to find out first what kind of calling convention is - being used in your particular ZLIB.DLL build, and to use the - same one in the new build. If you don't know what this is all - about, you might be better off if you would just leave the old - DLL intact. - - - 4. Can I compile my application using the new zlib interface, and - link it to an old ZLIB.DLL, that was built from zlib-1.1.4 or - earlier? - - - The official answer is "no"; the real answer depends again on - what kind of ZLIB.DLL you have. Even if you are lucky, this - course of action is unreliable. - - If you rebuild your application and you intend to use a newer - version of zlib (post- 1.1.4), it is strongly recommended to - link it to the new ZLIB1.DLL. - - - 5. Why are the zlib symbols exported by name, and not by ordinal? - - - Although exporting symbols by ordinal is a little faster, it - is risky. Any single glitch in the maintenance or use of the - DEF file that contains the ordinals can result in incompatible - builds and frustrating crashes. Simply put, the benefits of - exporting symbols by ordinal do not justify the risks. - - Technically, it should be possible to maintain ordinals in - the DEF file, and still export the symbols by name. Ordinals - exist in every DLL, and even if the dynamic linking performed - at the DLL startup is searching for names, ordinals serve as - hints, for a faster name lookup. However, if the DEF file - contains ordinals, the Microsoft linker automatically builds - an implib that will cause the executables linked to it to use - those ordinals, and not the names. It is interesting to - notice that the GNU linker for Win32 does not suffer from this - problem. - - It is possible to avoid the DEF file if the exported symbols - are accompanied by a "__declspec(dllexport)" attribute in the - source files. You can do this in zlib by predefining the - ZLIB_DLL macro. - - - 6. I see that the ZLIB1.DLL functions use the "C" (CDECL) calling - convention. Why not use the STDCALL convention? - STDCALL is the standard convention in Win32, and I need it in - my Visual Basic project! - - (For readability, we use CDECL to refer to the convention - triggered by the "__cdecl" keyword, STDCALL to refer to - the convention triggered by "__stdcall", and FASTCALL to - refer to the convention triggered by "__fastcall".) - - - Most of the native Windows API functions (without varargs) use - indeed the WINAPI convention (which translates to STDCALL in - Win32), but the standard C functions use CDECL. If a user - application is intrinsically tied to the Windows API (e.g. - it calls native Windows API functions such as CreateFile()), - sometimes it makes sense to decorate its own functions with - WINAPI. But if ANSI C or POSIX portability is a goal (e.g. - it calls standard C functions such as fopen()), it is not a - sound decision to request the inclusion of , or to - use non-ANSI constructs, for the sole purpose to make the user - functions STDCALL-able. - - The functionality offered by zlib is not in the category of - "Windows functionality", but is more like "C functionality". - - Technically, STDCALL is not bad; in fact, it is slightly - faster than CDECL, and it works with variable-argument - functions, just like CDECL. It is unfortunate that, in spite - of using STDCALL in the Windows API, it is not the default - convention used by the C compilers that run under Windows. - The roots of the problem reside deep inside the unsafety of - the K&R-style function prototypes, where the argument types - are not specified; but that is another story for another day. - - The remaining fact is that CDECL is the default convention. - Even if an explicit convention is hard-coded into the function - prototypes inside C headers, problems may appear. The - necessity to expose the convention in users' callbacks is one - of these problems. - - The calling convention issues are also important when using - zlib in other programming languages. Some of them, like Ada - (GNAT) and Fortran (GNU G77), have C bindings implemented - initially on Unix, and relying on the C calling convention. - On the other hand, the pre- .NET versions of Microsoft Visual - Basic require STDCALL, while Borland Delphi prefers, although - it does not require, FASTCALL. - - In fairness to all possible uses of zlib outside the C - programming language, we choose the default "C" convention. - Anyone interested in different bindings or conventions is - encouraged to maintain specialized projects. The "contrib/" - directory from the zlib distribution already holds a couple - of foreign bindings, such as Ada, C++, and Delphi. - - - 7. I need a DLL for my Visual Basic project. What can I do? - - - Define the ZLIB_WINAPI macro before including "zlib.h", when - building both the DLL and the user application (except that - you don't need to define anything when using the DLL in Visual - Basic). The ZLIB_WINAPI macro will switch on the WINAPI - (STDCALL) convention. The name of this DLL must be different - than the official ZLIB1.DLL. - - Gilles Vollant has contributed a build named ZLIBWAPI.DLL, - with the ZLIB_WINAPI macro turned on, and with the minizip - functionality built in. For more information, please read - the notes inside "contrib/vstudio/readme.txt", found in the - zlib distribution. - - - 8. I need to use zlib in my Microsoft .NET project. What can I - do? - - - Henrik Ravn has contributed a .NET wrapper around zlib. Look - into contrib/dotzlib/, inside the zlib distribution. - - - 9. If my application uses ZLIB1.DLL, should I link it to - MSVCRT.DLL? Why? - - - It is not required, but it is recommended to link your - application to MSVCRT.DLL, if it uses ZLIB1.DLL. - - The executables (.EXE, .DLL, etc.) that are involved in the - same process and are using the C run-time library (i.e. they - are calling standard C functions), must link to the same - library. There are several libraries in the Win32 system: - CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc. - Since ZLIB1.DLL is linked to MSVCRT.DLL, the executables that - depend on it should also be linked to MSVCRT.DLL. - - -10. Why are you saying that ZLIB1.DLL and my application should - be linked to the same C run-time (CRT) library? I linked my - application and my DLLs to different C libraries (e.g. my - application to a static library, and my DLLs to MSVCRT.DLL), - and everything works fine. - - - If a user library invokes only pure Win32 API (accessible via - and the related headers), its DLL build will work - in any context. But if this library invokes standard C API, - things get more complicated. - - There is a single Win32 library in a Win32 system. Every - function in this library resides in a single DLL module, that - is safe to call from anywhere. On the other hand, there are - multiple versions of the C library, and each of them has its - own separate internal state. Standalone executables and user - DLLs that call standard C functions must link to a C run-time - (CRT) library, be it static or shared (DLL). Intermixing - occurs when an executable (not necessarily standalone) and a - DLL are linked to different CRTs, and both are running in the - same process. - - Intermixing multiple CRTs is possible, as long as their - internal states are kept intact. The Microsoft Knowledge Base - articles KB94248 "HOWTO: Use the C Run-Time" and KB140584 - "HOWTO: Link with the Correct C Run-Time (CRT) Library" - mention the potential problems raised by intermixing. - - If intermixing works for you, it's because your application - and DLLs are avoiding the corruption of each of the CRTs' - internal states, maybe by careful design, or maybe by fortune. - - Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such - as those provided by Borland, raises similar problems. - - -11. Why are you linking ZLIB1.DLL to MSVCRT.DLL? - - - MSVCRT.DLL exists on every Windows 95 with a new service pack - installed, or with Microsoft Internet Explorer 4 or later, and - on all other Windows 4.x or later (Windows 98, Windows NT 4, - or later). It is freely distributable; if not present in the - system, it can be downloaded from Microsoft or from other - software provider for free. - - The fact that MSVCRT.DLL does not exist on a virgin Windows 95 - is not so problematic. Windows 95 is scarcely found nowadays, - Microsoft ended its support a long time ago, and many recent - applications from various vendors, including Microsoft, do not - even run on it. Furthermore, no serious user should run - Windows 95 without a proper update installed. - - -12. Why are you not linking ZLIB1.DLL to - <> ? - - - We considered and abandoned the following alternatives: - - * Linking ZLIB1.DLL to a static C library (LIBC.LIB, or - LIBCMT.LIB) is not a good option. People are using the DLL - mainly to save disk space. If you are linking your program - to a static C library, you may as well consider linking zlib - in statically, too. - - * Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because - CRTDLL.DLL is present on every Win32 installation. - Unfortunately, it has a series of problems: it does not - work properly with Microsoft's C++ libraries, it does not - provide support for 64-bit file offsets, (and so on...), - and Microsoft discontinued its support a long time ago. - - * Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied - with the Microsoft .NET platform, and Visual C++ 7.0/7.1, - raises problems related to the status of ZLIB1.DLL as a - system component. According to the Microsoft Knowledge Base - article KB326922 "INFO: Redistribution of the Shared C - Runtime Component in Visual C++ .NET", MSVCR70.DLL and - MSVCR71.DLL are not supposed to function as system DLLs, - because they may clash with MSVCRT.DLL. Instead, the - application's installer is supposed to put these DLLs - (if needed) in the application's private directory. - If ZLIB1.DLL depends on a non-system runtime, it cannot - function as a redistributable system component. - - * Linking ZLIB1.DLL to non-Microsoft runtimes, such as - Borland's, or Cygwin's, raises problems related to the - reliable presence of these runtimes on Win32 systems. - It's easier to let the DLL build of zlib up to the people - who distribute these runtimes, and who may proceed as - explained in the answer to Question 14. - - -13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL, - how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0 - (Visual Studio .NET) or newer? - - - Due to the problems explained in the Microsoft Knowledge Base - article KB326922 (see the previous answer), the C runtime that - comes with the VC7 environment is no longer considered a - system component. That is, it should not be assumed that this - runtime exists, or may be installed in a system directory. - Since ZLIB1.DLL is supposed to be a system component, it may - not depend on a non-system component. - - In order to link ZLIB1.DLL and your application to MSVCRT.DLL - in VC7, you need the library of Visual C++ 6.0 or older. If - you don't have this library at hand, it's probably best not to - use ZLIB1.DLL. - - We are hoping that, in the future, Microsoft will provide a - way to build applications linked to a proper system runtime, - from the Visual C++ environment. Until then, you have a - couple of alternatives, such as linking zlib in statically. - If your application requires dynamic linking, you may proceed - as explained in the answer to Question 14. - - -14. I need to link my own DLL build to a CRT different than - MSVCRT.DLL. What can I do? - - - Feel free to rebuild the DLL from the zlib sources, and link - it the way you want. You should, however, clearly state that - your build is unofficial. You should give it a different file - name, and/or install it in a private directory that can be - accessed by your application only, and is not visible to the - others (i.e. it's neither in the PATH, nor in the SYSTEM or - SYSTEM32 directories). Otherwise, your build may clash with - applications that link to the official build. - - For example, in Cygwin, zlib is linked to the Cygwin runtime - CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL. - - -15. May I include additional pieces of code that I find useful, - link them in ZLIB1.DLL, and export them? - - - No. A legitimate build of ZLIB1.DLL must not include code - that does not originate from the official zlib source code. - But you can make your own private DLL build, under a different - file name, as suggested in the previous answer. - - For example, zlib is a part of the VCL library, distributed - with Borland Delphi and C++ Builder. The DLL build of VCL - is a redistributable file, named VCLxx.DLL. - - -16. May I remove some functionality out of ZLIB1.DLL, by enabling - macros like NO_GZCOMPRESS or NO_GZIP at compile time? - - - No. A legitimate build of ZLIB1.DLL must provide the complete - zlib functionality, as implemented in the official zlib source - code. But you can make your own private DLL build, under a - different file name, as suggested in the previous answer. - - -17. I made my own ZLIB1.DLL build. Can I test it for compliance? - - - We prefer that you download the official DLL from the zlib - web site. If you need something peculiar from this DLL, you - can send your suggestion to the zlib mailing list. - - However, in case you do rebuild the DLL yourself, you can run - it with the test programs found in the DLL distribution. - Running these test programs is not a guarantee of compliance, - but a failure can imply a detected problem. - -** - -This document is written and maintained by -Cosmin Truta diff --git a/contrib/libzlib-ng/win32/Makefile.msc b/contrib/libzlib-ng/win32/Makefile.msc deleted file mode 100644 index b6375ccb4f8..00000000000 --- a/contrib/libzlib-ng/win32/Makefile.msc +++ /dev/null @@ -1,154 +0,0 @@ -# Makefile for zlib using Microsoft (Visual) C -# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler -# -# Usage: -# nmake -f win32/Makefile.msc (standard build) -# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build) - -# The toplevel directory of the source tree. -# -TOP = . - -# optional build flags -LOC = - -# variables -STATICLIB = zlib.lib -SHAREDLIB = zlib1.dll -IMPLIB = zdll.lib - -CC = cl -LD = link -AR = lib -RC = rc -CP = copy /y -CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC) -WFLAGS = -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DX86_PCLMULQDQ_CRC -DX86_SSE2_FILL_WINDOW -DX86_CPUID -DX86_SSE4_2_CRC_HASH -DUNALIGNED_OK -DUNROLL_LESS -DX86_QUICK_STRATEGY -LDFLAGS = -nologo -debug -incremental:no -opt:ref -manifest -ARFLAGS = -nologo -RCFLAGS = /dWIN32 /r -DEFFILE = zlib.def -WITH_GZFILEOP = - -OBJS = adler32.obj compress.obj crc32.obj deflate.obj deflate_fast.obj deflate_quick.obj deflate_slow.obj \ - infback.obj inflate.obj inftrees.obj inffast.obj match.obj trees.obj uncompr.obj zutil.obj x86.obj fill_window_sse.obj insert_string_sse.obj crc_folding.obj -!if "$(WITH_GZFILEOP)" != "" -WFLAGS = $(WFLAGS) -DWITH_GZFILEOP -OBJS = $(OBJS) gzclose.obj gzlib.obj gzread.obj gzwrite.obj -DEFFILE = zlibcompat.def -!endif - -# targets -all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \ - example.exe minigzip.exe example_d.exe minigzip_d.exe - -$(STATICLIB): $(OBJS) - $(AR) $(ARFLAGS) -out:$@ $(OBJS) - -$(IMPLIB): $(SHAREDLIB) - -$(SHAREDLIB): $(TOP)/win32/zlib.def $(OBJS) zlib1.res - $(LD) $(LDFLAGS) -def:$(TOP)/win32/$(DEFFILE) -dll -implib:$(IMPLIB) \ - -out:$@ -base:0x5A4C0000 $(OBJS) zlib1.res - if exist $@.manifest \ - mt -nologo -manifest $@.manifest -outputresource:$@;2 - -example.exe: example.obj $(STATICLIB) - $(LD) $(LDFLAGS) example.obj $(STATICLIB) - if exist $@.manifest \ - mt -nologo -manifest $@.manifest -outputresource:$@;1 - -minigzip.exe: minigzip.obj $(STATICLIB) - $(LD) $(LDFLAGS) minigzip.obj $(STATICLIB) - if exist $@.manifest \ - mt -nologo -manifest $@.manifest -outputresource:$@;1 - -example_d.exe: example.obj $(IMPLIB) - $(LD) $(LDFLAGS) -out:$@ example.obj $(IMPLIB) - if exist $@.manifest \ - mt -nologo -manifest $@.manifest -outputresource:$@;1 - -minigzip_d.exe: minigzip.obj $(IMPLIB) - $(LD) $(LDFLAGS) -out:$@ minigzip.obj $(IMPLIB) - if exist $@.manifest \ - mt -nologo -manifest $@.manifest -outputresource:$@;1 - -{$(TOP)}.c.obj: - $(CC) -c $(WFLAGS) $(CFLAGS) $< - -{$(TOP)/arch/x86}.c.obj: - $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $< - -{$(TOP)/test}.c.obj: - $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $< - -$(TOP)/zconf.h: $(TOP)/zconf.h.in - $(CP) $(TOP)\zconf.h.in $(TOP)\zconf.h - -adler32.obj: $(TOP)/adler32.c $(TOP)/zlib.h $(TOP)/zconf.h - -compress.obj: $(TOP)/compress.c $(TOP)/zlib.h $(TOP)/zconf.h - -crc32.obj: $(TOP)/crc32.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/crc32.h - -deflate.obj: $(TOP)/deflate.c $(TOP)/deflate.h $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h - -gzclose.obj: $(TOP)/gzclose.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h - -gzlib.obj: $(TOP)/gzlib.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h - -gzread.obj: $(TOP)/gzread.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h - -gzwrite.obj: $(TOP)/gzwrite.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h - -infback.obj: $(TOP)/infback.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \ - $(TOP)/inffast.h $(TOP)/inffixed.h - -inffast.obj: $(TOP)/inffast.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \ - $(TOP)/inffast.h - -inflate.obj: $(TOP)/inflate.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \ - $(TOP)/inffast.h $(TOP)/inffixed.h - -inftrees.obj: $(TOP)/inftrees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h - -match.obj: $(TOP)/match.c $(TOP)/deflate.h - -trees.obj: $(TOP)/trees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/deflate.h $(TOP)/trees.h - -uncompr.obj: $(TOP)/uncompr.c $(TOP)/zlib.h $(TOP)/zconf.h - -zutil.obj: $(TOP)/zutil.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h - -example.obj: $(TOP)/test/example.c $(TOP)/zlib.h $(TOP)/zconf.h - -minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zlib.h $(TOP)/zconf.h - -zlib1.res: $(TOP)/win32/zlib1.rc - $(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/zlib1.rc - -# testing -test: example.exe minigzip.exe - example - echo hello world | minigzip | minigzip -d - -testdll: example_d.exe minigzip_d.exe - example_d - echo hello world | minigzip_d | minigzip_d -d - - -# cleanup -clean: - -del $(STATICLIB) - -del $(SHAREDLIB) - -del $(IMPLIB) - -del *.obj - -del *.res - -del *.exp - -del *.exe - -del *.pdb - -del *.manifest - -del foo.gz - -distclean: clean - -del zconf.h diff --git a/contrib/libzlib-ng/win32/README-WIN32.txt b/contrib/libzlib-ng/win32/README-WIN32.txt deleted file mode 100644 index 3d77d521e83..00000000000 --- a/contrib/libzlib-ng/win32/README-WIN32.txt +++ /dev/null @@ -1,103 +0,0 @@ -ZLIB DATA COMPRESSION LIBRARY - -zlib 1.2.8 is a general purpose data compression library. All the code is -thread safe. The data format used by the zlib library is described by RFCs -(Request for Comments) 1950 to 1952 in the files -http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) -and rfc1952.txt (gzip format). - -All functions of the compression library are documented in the file zlib.h -(volunteer to write man pages welcome, contact zlib@gzip.org). Two compiled -examples are distributed in this package, example and minigzip. The example_d -and minigzip_d flavors validate that the zlib1.dll file is working correctly. - -Questions about zlib should be sent to . The zlib home page -is http://zlib.net/ . Before reporting a problem, please check this site to -verify that you have the latest version of zlib; otherwise get the latest -version and check whether the problem still exists or not. - -PLEASE read DLL_FAQ.txt, and the the zlib FAQ http://zlib.net/zlib_faq.html -before asking for help. - - -Manifest: - -The package zlib-1.2.8-win32-x86.zip will contain the following files: - - README-WIN32.txt This document - ChangeLog Changes since previous zlib packages - DLL_FAQ.txt Frequently asked questions about zlib1.dll - zlib.3.pdf Documentation of this library in Adobe Acrobat format - - example.exe A statically-bound example (using zlib.lib, not the dll) - example.pdb Symbolic information for debugging example.exe - - example_d.exe A zlib1.dll bound example (using zdll.lib) - example_d.pdb Symbolic information for debugging example_d.exe - - minigzip.exe A statically-bound test program (using zlib.lib, not the dll) - minigzip.pdb Symbolic information for debugging minigzip.exe - - minigzip_d.exe A zlib1.dll bound test program (using zdll.lib) - minigzip_d.pdb Symbolic information for debugging minigzip_d.exe - - zlib.h Install these files into the compilers' INCLUDE path to - zconf.h compile programs which use zlib.lib or zdll.lib - - zdll.lib Install these files into the compilers' LIB path if linking - zdll.exp a compiled program to the zlib1.dll binary - - zlib.lib Install these files into the compilers' LIB path to link zlib - zlib.pdb into compiled programs, without zlib1.dll runtime dependency - (zlib.pdb provides debugging info to the compile time linker) - - zlib1.dll Install this binary shared library into the system PATH, or - the program's runtime directory (where the .exe resides) - zlib1.pdb Install in the same directory as zlib1.dll, in order to debug - an application crash using WinDbg or similar tools. - -All .pdb files above are entirely optional, but are very useful to a developer -attempting to diagnose program misbehavior or a crash. Many additional -important files for developers can be found in the zlib127.zip source package -available from http://zlib.net/ - review that package's README file for details. - - -Acknowledgments: - -The deflate format used by zlib was defined by Phil Katz. The deflate and -zlib specifications were written by L. Peter Deutsch. Thanks to all the -people who reported problems and suggested various improvements in zlib; they -are too numerous to cite here. - - -Copyright notice: - - (C) 1995-2012 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - -If you use the zlib library in a product, we would appreciate *not* receiving -lengthy legal documents to sign. The sources are provided for free but without -warranty of any kind. The library has been entirely written by Jean-loup -Gailly and Mark Adler; it does not include third-party code. - -If you redistribute modified sources, we would appreciate that you include in -the file ChangeLog history information documenting your changes. Please read -the FAQ for more information on the distribution of modified source versions. diff --git a/contrib/libzlib-ng/win32/VisualC.txt b/contrib/libzlib-ng/win32/VisualC.txt deleted file mode 100644 index 579a5fc9e0f..00000000000 --- a/contrib/libzlib-ng/win32/VisualC.txt +++ /dev/null @@ -1,3 +0,0 @@ - -To build zlib using the Microsoft Visual C++ environment, -use the appropriate project from the projects/ directory. diff --git a/contrib/libzlib-ng/win32/zlib.def b/contrib/libzlib-ng/win32/zlib.def deleted file mode 100644 index 1d0c8947a5b..00000000000 --- a/contrib/libzlib-ng/win32/zlib.def +++ /dev/null @@ -1,55 +0,0 @@ -; zlib data compression library -EXPORTS -; basic functions - zlibVersion - deflate - deflateEnd - inflate - inflateEnd -; advanced functions - deflateSetDictionary - deflateCopy - deflateReset - deflateParams - deflateTune - deflateBound - deflatePending - deflatePrime - deflateSetHeader - inflateSetDictionary - inflateGetDictionary - inflateSync - inflateCopy - inflateReset - inflateReset2 - inflatePrime - inflateMark - inflateGetHeader - inflateBack - inflateBackEnd - zlibCompileFlags -; utility functions - compress - compress2 - compressBound - uncompress -; large file functions - adler32_combine64 - crc32_combine64 -; checksum functions - adler32 - crc32 - adler32_combine - crc32_combine -; various hacks, don't look :) - deflateInit_ - deflateInit2_ - inflateInit_ - inflateInit2_ - inflateBackInit_ - zError - inflateSyncPoint - get_crc_table - inflateUndermine - inflateResetKeep - deflateResetKeep diff --git a/contrib/libzlib-ng/win32/zlib1.rc b/contrib/libzlib-ng/win32/zlib1.rc deleted file mode 100644 index 5c0feed1b44..00000000000 --- a/contrib/libzlib-ng/win32/zlib1.rc +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include "../zlib.h" - -#ifdef GCC_WINDRES -VS_VERSION_INFO VERSIONINFO -#else -VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE -#endif - FILEVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 - PRODUCTVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -#ifdef _DEBUG - FILEFLAGS 1 -#else - FILEFLAGS 0 -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_DLL - FILESUBTYPE 0 // not used -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904E4" - //language ID = U.S. English, char set = Windows, Multilingual - BEGIN - VALUE "FileDescription", "zlib data compression library\0" - VALUE "FileVersion", ZLIB_VERSION "\0" - VALUE "InternalName", "zlib1.dll\0" - VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0" - VALUE "OriginalFilename", "zlib1.dll\0" - VALUE "ProductName", "zlib\0" - VALUE "ProductVersion", ZLIB_VERSION "\0" - VALUE "Comments", "For more information visit http://www.zlib.net/\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0409, 1252 - END -END diff --git a/contrib/libzlib-ng/win32/zlibcompat.def b/contrib/libzlib-ng/win32/zlibcompat.def deleted file mode 100644 index face655183a..00000000000 --- a/contrib/libzlib-ng/win32/zlibcompat.def +++ /dev/null @@ -1,86 +0,0 @@ -; zlib data compression library -EXPORTS -; basic functions - zlibVersion - deflate - deflateEnd - inflate - inflateEnd -; advanced functions - deflateSetDictionary - deflateCopy - deflateReset - deflateParams - deflateTune - deflateBound - deflatePending - deflatePrime - deflateSetHeader - inflateSetDictionary - inflateGetDictionary - inflateSync - inflateCopy - inflateReset - inflateReset2 - inflatePrime - inflateMark - inflateGetHeader - inflateBack - inflateBackEnd - zlibCompileFlags -; utility functions - compress - compress2 - compressBound - uncompress - gzopen - gzdopen - gzbuffer - gzsetparams - gzread - gzwrite - gzprintf - gzvprintf - gzputs - gzgets - gzputc - gzgetc - gzungetc - gzflush - gzseek - gzrewind - gztell - gzoffset - gzeof - gzdirect - gzclose - gzclose_r - gzclose_w - gzerror - gzclearerr -; large file functions - gzopen64 - gzseek64 - gztell64 - gzoffset64 - adler32_combine64 - crc32_combine64 -; checksum functions - adler32 - crc32 - adler32_combine - crc32_combine -; various hacks, don't look :) - deflateInit_ - deflateInit2_ - inflateInit_ - inflateInit2_ - inflateBackInit_ - gzgetc_ - zError - inflateSyncPoint - get_crc_table - inflateUndermine - inflateResetKeep - deflateResetKeep - gzopen_w diff --git a/contrib/libzlib-ng/zconf.h.in b/contrib/libzlib-ng/zconf.h.in deleted file mode 100644 index 7cacf1b79ed..00000000000 --- a/contrib/libzlib-ng/zconf.h.in +++ /dev/null @@ -1,176 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2013 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif - -#ifdef __STDC_VERSION__ -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# define MAX_MEM_LEVEL 9 -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# define ZEXPORTVA WINAPIV -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -/* Fallback for something that includes us. */ -typedef unsigned char Byte; -typedef Byte Bytef; - -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -typedef char charf; -typedef int intf; -typedef uInt uIntf; -typedef uLong uLongf; - -typedef void const *voidpc; -typedef void *voidpf; -typedef void *voidp; - -#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_UNISTD_H -#endif - -#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_STDARG_H -#endif - -#include /* for off_t */ -#include /* for va_list */ - -#ifdef WIN32 -# include /* for wchar_t */ -#endif - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) -# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ -# ifndef z_off_t -# define z_off_t off_t -# endif -#endif - -#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 -# define Z_LFS64 -#endif - -#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) -# define Z_LARGE64 -#endif - -#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) -# define Z_WANT64 -#endif - -#if !defined(SEEK_SET) && defined(WITH_GZFILEOP) -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long -#endif - -#if !defined(WIN32) && defined(Z_LARGE64) -# define z_off64_t off64_t -#else -# if defined(__MSYS__) -# define z_off64_t _off64_t -# elif defined(WIN32) && !defined(__GNUC__) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif -#endif - -#endif /* ZCONF_H */ diff --git a/contrib/libzlib-ng/zlib.3 b/contrib/libzlib-ng/zlib.3 deleted file mode 100644 index 1cc38059d78..00000000000 --- a/contrib/libzlib-ng/zlib.3 +++ /dev/null @@ -1,169 +0,0 @@ -.TH ZLIB 3 "7 July 2015" -.SH NAME -zlib \- compression/decompression library -.SH SYNOPSIS -[see -.I zlib.h -for full description] -.SH DESCRIPTION -The -.I zlib -library is a general purpose data compression library. -The code is thread safe, assuming that the standard library functions -used are thread safe, such as memory allocation routines. -It provides in-memory compression and decompression functions, -including integrity checks of the uncompressed data. -This version of the library supports only one compression method (deflation) -but other algorithms may be added later -with the same stream interface. -.LP -Compression can be done in a single step if the buffers are large enough -or can be done by repeated calls of the compression function. -In the latter case, -the application must provide more input and/or consume the output -(providing more output space) before each call. -.LP -The library also supports reading and writing files in -.IR gzip (1) -(.gz) format -with an interface similar to that of stdio. -.LP -The library does not install any signal handler. -The decoder checks the consistency of the compressed data, -so the library should never crash even in the case of corrupted input. -.LP -All functions of the compression library are documented in the file -.IR zlib.h . -The distribution source includes examples of use of the library -in the files -.I test/example.c -and -.IR test/minigzip.c, -as well as other examples in the -.IR examples/ -directory. -.LP -Changes to this version are documented in the file -.I ChangeLog -that accompanies the source. -.LP -.I zlib -is available in Java using the java.util.zip package: -.IP -http://java.sun.com/developer/technicalArticles/Programming/compression/ -.LP -A Perl interface to -.IR zlib , -written by Paul Marquess (pmqs@cpan.org), -is available at CPAN (Comprehensive Perl Archive Network) sites, -including: -.IP -http://search.cpan.org/~pmqs/IO-Compress-Zlib/ -.LP -A Python interface to -.IR zlib , -written by A.M. Kuchling (amk@magnet.com), -is available in Python 1.5 and later versions: -.IP -http://docs.python.org/library/zlib.html -.LP -.I zlib -is built into -.IR tcl: -.IP -http://wiki.tcl.tk/4610 -.LP -An experimental package to read and write files in .zip format, -written on top of -.I zlib -by Gilles Vollant (info@winimage.com), -is available at: -.IP -http://www.winimage.com/zLibDll/minizip.html -and also in the -.I contrib/minizip -directory of the main -.I zlib -source distribution. -.SH "SEE ALSO" -The -.I zlib -web site can be found at: -.IP -http://zlib.net/ -.LP -The data format used by the zlib library is described by RFC -(Request for Comments) 1950 to 1952 in the files: -.IP -http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) -.br -http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) -.br -http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) -.LP -Mark Nelson wrote an article about -.I zlib -for the Jan. 1997 issue of Dr. Dobb's Journal; -a copy of the article is available at: -.IP -http://marknelson.us/1997/01/01/zlib-engine/ -.SH "REPORTING PROBLEMS" -Before reporting a problem, -please check the -.I zlib -web site to verify that you have the latest version of -.IR zlib ; -otherwise, -obtain the latest version and see if the problem still exists. -Please read the -.I zlib -FAQ at: -.IP -http://zlib.net/zlib_faq.html -.LP -before asking for help. -Send questions and/or comments to zlib@gzip.org, -or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). -.SH AUTHORS AND LICENSE -Version 1.2.8.1 -.LP -Copyright (C) 1995-2015 Jean-loup Gailly and Mark Adler -.LP -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. -.LP -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: -.LP -.nr step 1 1 -.IP \n[step]. 3 -The origin of this software must not be misrepresented; you must not -claim that you wrote the original software. If you use this software -in a product, an acknowledgment in the product documentation would be -appreciated but is not required. -.IP \n+[step]. -Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. -.IP \n+[step]. -This notice may not be removed or altered from any source distribution. -.LP -Jean-loup Gailly Mark Adler -.br -jloup@gzip.org madler@alumni.caltech.edu -.LP -The deflate format used by -.I zlib -was defined by Phil Katz. -The deflate and -.I zlib -specifications were written by L. Peter Deutsch. -Thanks to all the people who reported problems and suggested various -improvements in -.IR zlib ; -who are too numerous to cite here. -.LP -UNIX manual page by R. P. C. Rodgers, -U.S. National Library of Medicine (rodgers@nlm.nih.gov). -.\" end of man page diff --git a/contrib/libzlib-ng/zlib.3.pdf b/contrib/libzlib-ng/zlib.3.pdf deleted file mode 100644 index a346b5d7e24834806b0871b209637c728fb36d60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8734 zcmcgyc|6o>+eadkB}+)9$uc7`yJ0M2-wiSxOO#;-leL+#muyG-WLHRJUy>zz3rU6S zLM3F05=xee>iv!CoX*pE-sgEgpYwTt|G4M+UDtJgukF6C`~H!&)H6^-!Z0A&2X8K1 z1u20MU|*LbAa!-P8O6t);Q_`16f3v^)r&!)f#C*TBnCx~;_6GL;PD_jgGM2FgM!j? z9a`guYXxtu+KypMPQgUjw>eI>FBw(nR$xtcGv6}0B05}bkEZG;*B0dazZDz0GJb*q z!A4dYp#x^RbEPgCO)f4{uHqA7Q9|RI?`wvfO7IYJ-{EL7{oTjN!jt#b_XSMmd)md0 ziw&-decEjxWF9XkHQ2BiO=?Mb=uJojv?wj&~&Qk{-JhWY8BD z8EET!7#8-Hvw79@e(SPCzn1;s+1JeVlOl6Iqe;gPS9Kh53i&Gi_NMMDg-(z3aI3ek zs& zLd0iNOWJSGh?+vE;t;8Vl}$tAVpZ?g3lzwSxt9V5#Ne75Uq8HVUM^l;=#*Ry31vKu zrMdjJ$l6cqnloM4x;lFkA&bMzF~*I3Gc6FqZcleF(Wad%5s&4DlFJ6`Wip4#=Gu-C zJ~`sHI6jiOopMwnbb;sdp0)BJ*l@a>Z#g{isuH$@!Q&PArAue99A zb#S>Ma5J3qLLANv_r6P}5|dY6cCxPI=FOAaAGui*`zItgxcYaRY{w4RBJ*`j+#+0s zz*LtwYLHY*wSuTZw!M7zSQd0nBPN+kUhpJ_Lt1=iM6N>@7XGTNFND05v| zkwY=`>f|087mR*w z))jbhJ~mNpidwMgu8#8on8=VjRjX?B;yJmqP-k~*+GTu~hOkJm?mQc+2eX|M@@g;h z$Z+0pf=Pp+Hcm{CkMM|d;#MRl+gLxnda~Rgvefp&f$8UYGL$}Mnj$;*$I$206SOv+ zw0H}MY?GZcH+N9{j>(0#<2+pUQR(&7NE35eK_`U?L`05Rr0scT*)c7mXz=xH2@?xZ zYGreI4k4$#>3T`8E}}JOfFpWp?YPqpwx@OSn3YZ1>y4I;7@bBi+jhu#mGtfRIwp#a ztZXw5=h}}EAb+jhpLCne^TQ;zObA)4B?ZB?-Prm`BS=!Z^5$W-p@Ixm;mu z*B!D7NK#CEnYGo+aG&>8Pxo}6JckmaHhDLWJ*r`Ue(d)<@*>hN%kyPzbJ_ZCN0F_~ zH_sycW*EG}Hu4Q%#I0yhHm@+qie#(JyHh;6mMo>l8IxR~!`n0@Fk9qgr|Z#h62sp| zTw(V5UQ#o58h)}ms5o?u%H1st!Xs|p>`CGmL)x7E~jF0Niav7W}|LIwU^Wft4|_3dxKmg zv~BI$vNPBXS2Cs~jbwyB#}HbNXxTUoZGOpyu1Q(s4JWE$V&8Q%O*bm`pE7}1tUDX{*aVzc#C@-Dw;ZJ^ioEWbmF-v zo9p=jrz7bo*~Tro`{)8@SmbnuI?VC`!X#3NRIKcmD&=IsKW0rY>P=MVC1G#*<|`BFoSo_~j?AkyKEM^^1=e@4h4!EEyIpNQ z1BX_7{pp_RaV}$7Cob<7kBCedeh;$JicZyeBs^ww=8dc3iHFKl zXx*Z{sO)a#fdKK9uHTBI__FkwcPbBRt(9ku6+aF+q$J`S=x8X$oEXes$@f{M)JU|s zJY(B`?Rutg5$N2Kz-6YG?fuM5y=2$R*Id+gX_Tx-q(UU(=H>P}vYq+eJ)&43>{(Z? zp{y%Og2O89wrcf6O5--z5+eK3PR`$pUf3A%h76(r*pU=Q*S+(+X;s`-r{Gn5VrWrCmJ(FGu3S4 zNc)F7FMtayC?ib64C)v&Q|**_j^E*zep`+lulfY7_gQ}Zxp$?#{mR~9YiwiBrC#TK z#dW6T8DE>LFDvb|H1x{Z!-mG5%bK%uENHlP!o6U2`Of~{%O0g$E_y;r zj}5l?n4ipVTPmD6X!4~f6gtM^T7FINlyBA~e!aF`nScX#*Ui+#URS!uuf7Iz$T)X` zsE3y;R^@sSkB*xOf5N;{?ON&0a&7k9`oSuq8~bz5lqSQfY*51K zx7umWJWtaXuI(~Mo_J(h(_D>dTV>d;IzHV-<$$yTThxoAc+#j~cO`Gz<19cawYV zPH#2cH3!L3F=sw_optps$8O2r1QAEQ-wgR8`}H;-JZDg&?dbo+uw_iS;I|x|PYK1% zx^?gG?wT!Kp}jnHUif&n36i#7>Ea5M*C>)*^3Ab`0;#a;pQXxcF8g_5C2BD~r!71_ zZ3%G+D3E=7ZT5P8r4CGBPO|pvUVH9SCPSoohg3A3@|qw!Znki2RqxCAB3qj@_XyJa z+MuuYCAW8ymCIXS`>^p(Ww=?ZWv({Z&WI%HRh&307bM(b&6YMD8Se zd3=9j+YJG_7{&6+u$C(=qzAj{!{^R9lu}*S?r(rm$soUcd5q~ z&My|>cqO^2AMr;`n|&GOOdU(R9az8Ew_-?VhCo8b7X>&p376(G{WI3B)cy<+RCWw4!RVgfIKFY{7Lip(j|4eYf{=+ zR~I`PpKNr5n-Zpue=8OJ?n{8S9YoiZl&sG5kZ27qX$H;vH{2>xhnmiJS6A86i)k0v zugSw8t3?g){=Aw9F}}+}*U#1b4vJVsZ`%_q3OXIlyI2$h_jelO@rt_~Pz#_h`-)?YrmW4`WSXIkbhqOF-x$wC;S)pK*sN`~sp;VWUI?;j1tL9Tx#+gO_E z=_SfO;&XJf9o#|R)EuB0>KU*gre5VfQm>4W$zG3*bv+mmJU%zbq6z`x*@gaXdqyZz=!H#vD zWBo;ARM4RBG$iJiQy-Fb5d4qFzT>vfXcKzdj<4F9y^|rnBbQ3>99p?sp+JU{J93TW zOv<6vcJ?$G-2FAaw_S`b{fb*#r>t8B9xXAh;E&fYYl%-qzkseE_JX7g#+20aNEf#@ zM>psTeNn_tKG}sOe{c@deCMu$j12+Q7qd8N3$ozN36P<5?7FRx)fe!8xXyz49ex2flk28t`HQ#>XYRk_7H zN_)=kNS)l*(JiMNrQEuFHqiHae&m7s4AhC`m$Jdi>&MpKyl$CY?HipQ-SayKtfN+I zYb!eRLZF{MpF0PKUL~djHSO8w(EHT8Z(Op4T13FkBfosQU1FO9epX#auc0+3wE4gu zR#)h|x4L+Xb+Q}VfZRoeVIl7b;SB$D^>59uu;;VJi{ZK8Pw-7lJ} zgeDfQ54DZhTY{6el9;dkDCY3MK^fEXl!dR|+pa zV|TJPc3;Ot?ujI)g$n+MFWa79?lU`S^J!i@Bv0hRD^hPtJ=EXxY_6`o+Zhm;qEPUK zIG|IN_Yqgt82N_R)-nMzFm{eO<@xqm{^Wxu=vXS-6Q1fbU-rA3Xi>)bq7cJ+Nk?n; zC2~j$J3JfF_&52r?8ZoQMZT=DKqGsY&W`%ObRtm0x>X4a^q)7}R+4BP0u{kuw!^Qc$s z{uq3OX3>~ebf*5KTKiM!aA+!YtpcXp(qh@BQo#(pTw2cEvyn}Hks>zz^dw;q@z11@)nZqxlZx$Gd{ls_#B2T zPL6M_fUo&i&h7<^oxQ3~a8lqEITRyd!oN~GSit^v^18QY1AnliPqht??VF?S$;4BE zvG=Ze=kI!w?9TIcVViS%QbU`~I2g5*3BoVnv=K^7w zdwL5HVc?w76Ml0!4n`%{GO6Hvm6CHW&o5qvmRhtVyfb!Cwr(r^pj(WTTDt$#uDn}`CwwmU z=Y!Om9Rz{2d{=}$9kmrlF52v(@E!VYwt-8#i`4C_6F|X268;X zE4*o`<;_juyA2Lc-qd&V@Lh=K4|$$3AZ}LJtnl&hB91fe14?nW5~F>j@6Cw{hHCg4 zcFPp_!$<2VOXoeaX)*n<%i{4m*aY*G5ym(7Vf=)zxmfsIX`)eInUSd|~mz)!t^ zb+8`=Zb@>dzzGyGm89bv1U`rW`T{Hx1y;tPoIr3ZUj}d=3`PK4G>Q)cjAnHW0GUGf z^{2T~=)g6yCC%5BNMRg=0~gI;xHTn+0m$hGF${?tqDbU75d&X99MH>>2X2<(y1;Kh zBOScah_FaMnibX@-><0uUjS}gfP>)Q04o0qaHD(L0R0`|p8x@S0T+Tdd`JhwO{ru$ z_#lYoVJi^wo3EU}fT{j~?Wmt^{Huuo3yDGU@^$~A>ARZ=6b6Y5ya6L|KVW@_z=HX+ zkN)sC2yS6X03-4EAKqlS|2wCZGHAoRpM1@V$B(y21PIBBz7^aG2ilkrZlwZJVNrgP z_|abik^dWgKjE_a@AR=|{Ek3}M5nN#05_s|1yC4NSCXQIix>5%KV`$s8xaD*iT*AO zR^GBa57_x5ZCHT+y&fH3FYrvg@C_qU8HFOY!L}B3!su!68LShhbH!9rC3xrfg!@a3K{&c55ZQMwMpVj?HkUza* zM=<;GVF!uEVDb3xrvr7(AU~3;Cxroap}13hG@uI&cc5S@Sp#aTL_iSybSWNGqYxT} z7-DYi8sh1SBSSUuAazX=aHyat29f*}-8Q}u(ZLkDtA>=Wm6?GQiy=rg$lK2w$Ww5T zx0erHHAn-xA)*S5S!6gAyurfo)PUL%EWr$4UoTH8Pz^8~45^4jD}dc-ByUQfFU=E- zgkhn8N*dWs)e2Zkz9|HLX+S*~3_n#kJTNd27Kn!V(%j)l91aIZpx`K!BEX?Y5B6b@ zf)st|(!hKhK&Wn`Z1`!K48|wBo|+Qh6dE% zpGsC$A|aJgu1aJ@ii$Eu5s9Rb6%oLrNWx-W+{kEGlq(tcV>-W|VE$!3-~})t8t?-! zQUw-EvcD^ZrU5myGy@xY_|h5Q<_F_o2qh@|yZQeVDj+t0?*$;B-`$`N@Td}iWOfVI z1D1L`3V}o`A~1?56>B6`6@gY|{Zv*(Ak^Xi!U+T)5Y+{~5CUHe{|nKdIDZoLrC9?h zfp@3*y19V^C^R}N5=a;l2Sa_EaYO7ompYskqo2IcC3|mElFfZ`7W)7vtN&i^{4cRWFi{y9P8!kxX$T`Fk;-cpIM$Zt}Ni zcv11+1{-qlKXv_0tTsqMZ3AJ0|FLr5LEwMr`R5ewQ4C!>SU%;jB85(^F*?83Kb+L1Gc;jrxKj5Kw>(sKfuj@x2=4{;pp3{juu@ z(I{>p1Q>+?u@^^?-eT&{PnpUua4=WuS-nE1wb;1MIhd zr6CZkcJr?^v=SEBAOA|jA`yV&{)L9Y{344*D+9g8zwn_EKx_0bG$iJ4Xv)9PlvEJE zU`8vc{DMyji~5CzMWKGtheavf7pY6lhpG=x7eGiW5L7lj7={{t8aJp-)14ps@RkJLx1pm0h!eXNcy3Z;b6 e$Ny&zCsyl8XOL)&jl@tvsvtqKvicSVp#K4G_#7?( diff --git a/contrib/libzlib-ng/zlib.h b/contrib/libzlib-ng/zlib.h deleted file mode 100644 index 3a1cbb2f05b..00000000000 --- a/contrib/libzlib-ng/zlib.h +++ /dev/null @@ -1,1728 +0,0 @@ -#ifndef ZLIB_H_ -#define ZLIB_H_ -/* zlib.h -- interface of the 'zlib-ng' compression library - Forked from and compatible with zlib 1.2.8 - - Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 - (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). -*/ - -#include -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIBNG_VERSION "1.9.9" -#define ZLIBNG_VERNUM 0x1990 -#define ZLIBNG_VER_MAJOR 1 -#define ZLIBNG_VER_MINOR 9 -#define ZLIBNG_VER_REVISION 9 -#define ZLIBNG_VER_SUBREVISION 0 - -#define ZLIB_VERSION "1.2.8.zlib-ng" -#define ZLIB_VERNUM 0x128f -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 8 -#define ZLIB_VER_SUBREVISION 0 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed data. - This version of the library supports only one compression method (deflation) - but other algorithms will be added later and will have the same stream - interface. - - Compression can be done in a single step if the buffers are large enough, - or can be done by repeated calls of the compression function. In the latter - case, the application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip streams in memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never crash - even in case of corrupted input. -*/ - -typedef void *(*alloc_func) (void *opaque, unsigned int items, unsigned int size); -typedef void (*free_func) (void *opaque, void *address); - -struct internal_state; - -typedef struct z_stream_s { - const unsigned char *next_in; /* next input byte */ - uint32_t avail_in; /* number of bytes available at next_in */ - size_t total_in; /* total number of input bytes read so far */ - - unsigned char *next_out; /* next output byte should be put there */ - uint32_t avail_out; /* remaining free space at next_out */ - size_t total_out; /* total number of bytes output so far */ - - const char *msg; /* last error message, NULL if no error */ - struct internal_state *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - void *opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text */ - uint32_t adler; /* adler32 value of the uncompressed data */ - unsigned long reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream *z_streamp; // Obsolete type, retained for compatability only - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - unsigned long time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - unsigned char *extra; /* pointer to extra field or Z_NULL if none */ - unsigned int extra_len; /* extra field length (valid if extra != Z_NULL) */ - unsigned int extra_max; /* space at extra (only when reading header) */ - unsigned char *name; /* pointer to zero-terminated file name or Z_NULL */ - unsigned int name_max; /* space at name (only when reading header) */ - unsigned char *comment; /* pointer to zero-terminated comment or Z_NULL */ - unsigned int comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used when writing a gzip file) */ -} gz_header; - -typedef gz_header *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has dropped - to zero. It must update next_out and avail_out when avail_out has dropped - to zero. The application must initialize zalloc, zfree and opaque before - calling the init function. All other fields are set by the compression - library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. - - The fields total_in and total_out can be used for statistics or progress - reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use in the decompressor (particularly - if the decompressor wants to decompress everything in a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion(void); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is not - compatible with the zlib.h header file used by the application. This check - is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit (z_stream *strm, int level); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at all - (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION - requests a default compromise between speed and compression (currently - equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if level is not a valid compression level, or - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). msg is set to null - if there is no error message. deflateInit does not perform any compression: - this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate(z_stream *strm, int flush); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). Some - output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating avail_in or avail_out accordingly; avail_out should - never be zero before the call. The application can consume the compressed - output when it wants, for example when the output buffer is full (avail_out - == 0), or after each call of deflate(). If deflate returns Z_OK and with - zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumulate before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In - particular avail_in is zero after the call if enough output space has been - provided before the call.) Flushing may degrade compression for some - compression algorithms and so it should be used only when necessary. This - completes the current deflate block and follows it with an empty stored block - that is three bits plus filler bits to the next byte, followed by four bytes - (00 00 ff ff). - - If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the - output buffer, but the output is not aligned to a byte boundary. All of the - input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. - This completes the current deflate block and follows it with an empty fixed - codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed code - block. - - If flush is set to Z_BLOCK, a deflate block is completed and emitted, as - for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to - seven bits of the current block are held to be written as the next byte after - the next deflate block is completed. In this case, the decompressor may not - be provided enough bits at this point in order to complete decompression of - the data provided so far to the compressor. It may need to wait for the next - block to be emitted. This is for advanced applications that need to control - the emission of deflate blocks. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the stream - are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least the - value returned by deflateBound (see below). Then deflate is guaranteed to - return Z_STREAM_END. If not enough output space is provided, deflate will - not return Z_STREAM_END, and it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect the - compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not - fatal, and deflate() can be called again with more input and more output - space to continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd(z_stream *strm); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, msg - may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit (z_stream *strm); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the - exact value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit() does not process any header information -- that is deferred - until inflate() is called. -*/ - - -ZEXTERN int ZEXPORT inflate(z_stream *strm, int flush); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing will - resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there is - no more input data or no more space in the output buffer (see below about - the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. The - application can consume the uncompressed output when it wants, for example - when the output buffer is full (avail_out == 0), or after each call of - inflate(). If inflate returns Z_OK and with zero avail_out, it must be - called again after making room in the output buffer because there might be - more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, - Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() - stop if and when it gets to the next deflate block boundary. When decoding - the zlib or gzip format, this will cause inflate() to return immediately - after the header and before the first block. When doing a raw inflate, - inflate() will go ahead and process the first block, and will return when it - gets to the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - Also to assist in this, on return inflate() will set strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 if - inflate() is currently decoding the last block in the deflate stream, plus - 128 if inflate() returned immediately after decoding an end-of-block code or - decoding the complete header up to just before the first byte of the deflate - stream. The end-of-block will not be indicated until all of the uncompressed - data from that block has been written to strm->next_out. The number of - unused bits may in general be greater than seven, except when bit 7 of - data_type is set, in which case the number of unused bits will be less than - eight. data_type is set as noted here every time inflate() returns for all - flush options, and so can be used to determine the amount of currently - consumed input in bits. - - The Z_TREES option behaves as Z_BLOCK does, but it also returns when the - end of each deflate block header is reached, before any actual data in that - block is decoded. This allows the caller to determine the length of the - deflate block header for later use in random access within a deflate block. - 256 is added to the value of strm->data_type when inflate() returns - immediately after reaching the end of the deflate block header. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step (a - single call of inflate), the parameter flush should be set to Z_FINISH. In - this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all of the uncompressed data for the - operation to complete. (The size of the uncompressed data may have been - saved by the compressor for this purpose.) The use of Z_FINISH is not - required to perform an inflation in one step. However it may be used to - inform inflate that a faster approach can be used for the single inflate() - call. Z_FINISH also informs inflate to not maintain a sliding window if the - stream completes, which reduces inflate's memory footprint. If the stream - does not complete, either because not all of the stream is provided or not - enough output space is provided, then a sliding window will be allocated and - inflate() can be called again to continue the operation as if Z_NO_FLUSH had - been used. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the effects of the flush parameter in this implementation are - on the return value of inflate() as noted below, when inflate() returns early - when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of - memory for a sliding window when Z_FINISH is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the Adler-32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the Adler-32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() can decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically, if requested when - initializing with inflateInit2(). Any information contained in the gzip - header is not retained, so applications that need that information should - instead use raw inflate, see inflateInit2() below, or inflateBack() and - perform their own processing of the gzip header and trailer. When processing - gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output - producted so far. The CRC-32 is checked against the gzip trailer. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may - then call inflateSync() to look for a good compression block if a partial - recovery of the data is desired. -*/ - - -ZEXTERN int ZEXPORT inflateEnd(z_stream *strm); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 (z_stream *strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by the - caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - For the current implementation of deflate(), a windowBits value of 8 (a - window size of 256 bytes) is not supported. As a result, a request for 8 - will result in 9 (a 512-byte window). In that case, providing 8 to - inflateInit2() will result in an error when the zlib header with 9 is - checked against the initialization of inflate(). The remedy is to not use 8 - with deflateInit2() with this initialization, or at least in that case use 9 - with inflateInit2(). - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute an adler32 check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to 255 (unknown). If a - gzip stream is being written, strm->adler is a crc32 instead of an adler32. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but is - slow and reduces compression ratio; memLevel=9 uses maximum memory for - optimal speed. The default value is 8. See zconf.h for total memory usage - as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as - fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The - strategy parameter only affects the compression ratio but not the - correctness of the compressed output even if it is not set appropriately. - Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler - decoder for special applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid - method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is - incompatible with the version assumed by the caller (ZLIB_VERSION). msg is - set to null if there is no error message. deflateInit2 does not perform any - compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary(z_stream *strm, - const unsigned char *dictionary, - unsigned int dictLength); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. When using the zlib format, this - function must be called immediately after deflateInit, deflateInit2 or - deflateReset, and before any call of deflate. When doing raw deflate, this - function must be called either before any call of deflate, or immediately - after the completion of a deflate block, i.e. after all input has been - consumed and all output has been delivered when using any of the flush - options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The - compressor and decompressor must use exactly the same dictionary (see - inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size - provided in deflateInit or deflateInit2. Thus the strings most likely to be - useful should be put at the end of the dictionary, not at the front. In - addition, the current implementation of deflate will use at most the window - size minus 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - adler32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if not at a block boundary for raw deflate). deflateSetDictionary does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateCopy(z_stream *dest, z_stream *source); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and can - consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset(z_stream *strm); -/* - This function is equivalent to deflateEnd followed by deflateInit, but - does not free and reallocate the internal compression state. The stream - will leave the compression level and any other attributes that may have been - set unchanged. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams(z_stream *strm, int level, int strategy); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2(). This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression approach (which is a function of the level) or the - strategy is changed, then the input available so far is compressed with the - old level and strategy using deflate(strm, Z_BLOCK). There are three - approaches for the compression levels 0, 1..3, and 4..9 respectively. The - new level and strategy will take effect at the next call of deflate(). - - If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does - not have enough output space to complete, then the parameter change will - take effect at an undetermined location in the uncompressed data provided so - far. In order to assure a change in the parameters at a specific location - in the uncompressed data, the deflate stream should first be flushed with - Z_BLOCK or another flush parameter, and deflate() called until - strm.avail_out is not zero, before the call of deflateParams(). Then no - more input data should be provided before the deflateParams() call. If this - is done, the old level and strategy will be applied to the data compressed - before deflateParams(), and the new level and strategy will be applied to - the the data compressed after deflateParams(). - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source stream - state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if - there was not enough output space to complete the compression before the - parameters were changed. Note that in the case of a Z_BUF_ERROR, the - parameters are changed nevertheless, and will take effect at an undetermined - location in the previously supplied uncompressed data. Compression may - proceed after a Z_BUF_ERROR. -*/ - -ZEXTERN int ZEXPORT deflateTune(z_stream *strm, int good_length, int max_lazy, int nice_length, int max_chain); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN unsigned long ZEXPORT deflateBound(z_stream *strm, unsigned long sourceLen); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() or - deflateInit2(), and after deflateSetHeader(), if used. This would be used - to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). If that first deflate() call is provided the - sourceLen input bytes, an output buffer allocated to the size returned by - deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed - to return Z_STREAM_END. Note that it is possible for the compressed size to - be larger than the value returned by deflateBound() if flush options other - than Z_FINISH or Z_NO_FLUSH are used. -*/ - -ZEXTERN int ZEXPORT deflatePending(z_stream *strm, uint32_t *pending, int *bits); -/* - deflatePending() returns the number of bytes and bits of output that have - been generated, but not yet provided in the available output. The bytes not - provided would be due to the available output space having being consumed. - The number of bits of output not provided are between 0 and 7, where they - await more bits to join them in order to fill out a full byte. If pending - or bits are Z_NULL, then those values are not set. - - deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. - */ - -ZEXTERN int ZEXPORT deflatePrime(z_stream *strm, int bits, int value); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the bits - leftover from a previous deflate stream when appending to it. As such, this - function can only be used for raw deflate, and must be used before the first - deflate() call after a deflateInit2() or deflateReset(). bits must be less - than or equal to 16, and that many of the least significant bits of value - will be inserted in the output. - - deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough - room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader(z_stream *strm, gz_headerp head); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2(z_stream *strm, int windowBits); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be zero to request that inflate use the window size in - the zlib header of the compressed stream. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an adler32 or a crc32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - crc32 instead of an adler32. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit2 does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit2() does not process any header information -- that is - deferred until inflate() is called. -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary(z_stream *strm, const unsigned char *dictionary, unsigned int dictLength); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called at any - time to set the dictionary. If the provided dictionary is smaller than the - window and there is already data in the window, then the provided dictionary - will amend what's there. The application must insure that the dictionary - that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateGetDictionary(z_stream *strm, unsigned char *dictionary, unsigned int *dictLength); -/* - Returns the sliding dictionary being maintained by inflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If inflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similary, if dictLength is Z_NULL, then it is not set. - - inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateSync(z_stream *strm); -/* - Skips invalid compressed data until a possible full flush point (see above - for the description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync searches for a 00 00 FF FF pattern in the compressed data. - All full flush points have this pattern, but not all occurrences of this - pattern are full flush points. - - inflateSync returns Z_OK if a possible full flush point has been found, - Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point - has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy(z_stream *dest, z_stream *source); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset(z_stream *strm); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. The - stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT inflateReset2(z_stream *strm, int windowBits); -/* - This function is the same as inflateReset, but it also permits changing - the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. - - inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL), or if - the windowBits parameter is invalid. -*/ - -ZEXTERN int ZEXPORT inflatePrime(z_stream *strm, int bits, int value); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - If bits is negative, then the input stream bit buffer is emptied. Then - inflatePrime() can be called again to put bits in the buffer. This is used - to clear out bits leftover after feeding inflate a block description prior - to feeding inflate codes. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN long ZEXPORT inflateMark(z_stream *strm); -/* - This function returns two values, one in the lower 16 bits of the return - value, and the other in the remaining upper bits, obtained by shifting the - return value down 16 bits. If the upper value is -1 and the lower value is - zero, then inflate() is currently decoding information outside of a block. - If the upper value is -1 and the lower value is non-zero, then inflate is in - the middle of a stored block, with the lower value equaling the number of - bytes from the input remaining to copy. If the upper value is not -1, then - it is the number of bits back from the current bit position in the input of - the code (literal or length/distance pair) currently being processed. In - that case the lower value is the number of bytes already emitted for that - code. - - A code is being processed if inflate is waiting for more input to complete - decoding of the code, or if it has completed decoding but is waiting for - more output space to write the literal or match data. - - inflateMark() is used to mark locations in the input data for random - access, which may be at bit positions, and to note those cases where the - output of a code may span boundaries of random access blocks. The current - location in the input stream can be determined from avail_in and data_type - as noted in the description for the Z_BLOCK flush parameter for inflate. - - inflateMark returns the value noted above or -65536 if the provided - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader(z_stream *strm, gz_headerp head); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be - used to force inflate() to return immediately after header processing is - complete and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When any - of extra, name, or comment are not Z_NULL and the respective field is not - present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit (z_stream *strm, int windowBits, unsigned char *window); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the parameters are invalid, Z_MEM_ERROR if the internal state could not be - allocated, or Z_VERSION_ERROR if the version of the library does not match - the version of the header file. -*/ - -typedef uint32_t (*in_func) (void *, const unsigned char * *); -typedef int (*out_func) (void *, unsigned char *, uint32_t); - -ZEXTERN int ZEXPORT inflateBack(z_stream *strm, in_func in, void *in_desc, out_func out, void *out_desc); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is potentially more efficient than - inflate() for file i/o applications, in that it avoids copying between the - output and the sliding window by simply making the window itself the output - buffer. inflate() can be faster on modern CPUs when used with large - buffers. inflateBack() trusts the application to not change the output - buffer passed by the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free the - allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the normal - behavior of inflate(), which expects either a zlib or gzip header and - trailer around the deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero--buf is ignored in that - case--and inflateBack() will return a buffer error. inflateBack() will call - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() - should return zero on success, or non-zero on failure. If out() returns - non-zero, inflateBack() will return with an error. Neither in() nor out() - are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format error - in the deflate stream (in which case strm->msg is set to indicate the nature - of the error), or Z_STREAM_ERROR if the stream was not properly initialized. - In the case of Z_BUF_ERROR, an input or output error can be distinguished - using strm->next_in which will be Z_NULL only if in() returned an error. If - strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning - non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() - cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd(z_stream *strm); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN unsigned long ZEXPORT zlibCompileFlags(void); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of unsigned int - 3.2: size of unsigned long - 5.4: size of void * (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - - - /* utility functions */ - -/* - The following utility functions are implemented on top of the basic - stream-oriented functions. To simplify the interface, some default options - are assumed (compression level and memory usage, standard memory allocation - functions). The source code of these utility functions can be modified if - you need special options. -*/ - -ZEXTERN int ZEXPORT compress(unsigned char *dest, size_t *destLen, const unsigned char *source, size_t sourceLen); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. compress() is equivalent to compress2() with a level - parameter of Z_DEFAULT_COMPRESSION. - - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2(unsigned char *dest, size_t *destLen, const unsigned char *source, - size_t sourceLen, int level); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN size_t ZEXPORT compressBound(size_t sourceLen); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before a - compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress(unsigned char *dest, size_t *destLen, const unsigned char *source, size_t sourceLen); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, destLen - is the actual size of the uncompressed buffer. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In - the case where there is not enough room, uncompress() will fill the output - buffer with the uncompressed data up to that point. -*/ - -#ifdef WITH_GZFILEOP - /* gzip file access functions */ - -/* - This library supports reading and writing files in gzip (.gz) format with - an interface similar to that of stdio, using the functions that start with - "gz". The gzip format is different from the zlib format. gzip is a gzip - wrapper, documented in RFC 1952, wrapped around a deflate stream. -*/ - -typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ - -/* -ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode); - - Opens a gzip (.gz) file for reading or writing. The mode parameter is as - in fopen ("rb" or "wb") but can also include a compression level ("wb9") or - a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only - compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' - for fixed code compression as in "wb9F". (See the description of - deflateInit2 for more information about the strategy parameter.) 'T' will - request transparent writing or appending with no compression and not using - the gzip format. - - "a" can be used instead of "w" to request that the gzip stream that will - be written be appended to the file. "+" will result in an error, since - reading and writing to the same gzip file is not supported. The addition of - "x" when writing will create the file exclusively, which fails if the file - already exists. On systems that support it, the addition of "e" when - reading or writing will set the flag to close the file on an execve() call. - - These functions, as well as gzip, will read and decode a sequence of gzip - streams in a file. The append function of gzopen() can be used to create - such a file. (Also see gzflush() for another way to do this.) When - appending, gzopen does not test whether the file begins with a gzip stream, - nor does it look for the end of the gzip streams to begin appending. gzopen - will simply append a gzip stream to the existing file. - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. When - reading, this will be detected automatically by looking for the magic two- - byte gzip header. - - gzopen returns NULL if the file could not be opened, if there was - insufficient memory to allocate the gzFile state, or if an invalid mode was - specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). - errno can be checked to determine if the reason gzopen failed was that the - file could not be opened. -*/ - -ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode); -/* - gzdopen associates a gzFile with the file descriptor fd. File descriptors - are obtained from calls like open, dup, creat, pipe or fileno (if the file - has been previously opened with fopen). The mode parameter is as in gzopen. - - The next call of gzclose on the returned gzFile will also close the file - descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor - fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, - mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. If you are using fileno() to get the - file descriptor from a FILE *, then you will have to use dup() to avoid - double-close()ing the file descriptor. Both gzclose() and fclose() will - close the associated file descriptor, so they need to have different file - descriptors. - - gzdopen returns NULL if there was insufficient memory to allocate the - gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not - provided, or '+' was provided), or if fd is -1. The file descriptor is not - used until the next gz* read, write, seek, or close operation, so gzdopen - will not detect if fd is invalid (unless fd is -1). -*/ - -ZEXTERN int ZEXPORT gzbuffer(gzFile file, unsigned size); -/* - Set the internal buffer size used by this library's functions. The - default buffer size is 8192 bytes. This function must be called after - gzopen() or gzdopen(), and before any other calls that read or write the - file. The buffer memory allocation is always deferred to the first read or - write. Three times that size in buffer space is allocated. A larger buffer - size of, for example, 64K or 128K bytes will noticeably increase the speed - of decompression (reading). - - The new buffer size also affects the maximum length for gzprintf(). - - gzbuffer() returns 0 on success, or -1 on failure, such as being called - too late. -*/ - -ZEXTERN int ZEXPORT gzsetparams(gzFile file, int level, int strategy); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. - - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. -*/ - -ZEXTERN int ZEXPORT gzread(gzFile file, void *buf, unsigned len); -/* - Reads the given number of uncompressed bytes from the compressed file. If - the input file is not in gzip format, gzread copies the given number of - bytes into the buffer directly from the file. - - After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream. Any number of gzip streams may be - concatenated in the input file, and will all be decompressed by gzread(). - If something other than a gzip stream is encountered after a gzip stream, - that remaining trailing garbage is ignored (and no error is returned). - - gzread can be used to read a gzip file that is being concurrently written. - Upon reaching the end of the input, gzread will return with the available - data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then - gzclearerr can be used to clear the end of file indicator in order to permit - gzread to be tried again. Z_OK indicates that a gzip stream was completed - on the last gzread. Z_BUF_ERROR indicates that the input file ended in the - middle of a gzip stream. Note that gzread does not return -1 in the event - of an incomplete gzip stream. This error is deferred until gzclose(), which - will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip - stream. Alternatively, gzerror can be used before gzclose to detect this - case. - - gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. -*/ - -ZEXTERN int ZEXPORT gzwrite(gzFile file, void const *buf, unsigned len); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes written or 0 in case of - error. -*/ - -ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); -/* - Converts, formats, and writes the arguments to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or 0 in case of error. The number of - uncompressed bytes written is limited to 8191, or one less than the buffer - size given to gzbuffer(). The caller should assure that this limit is not - exceeded. If it is exceeded, then gzprintf() will return an error (0) with - nothing written. In this case, there may also be a buffer overflow with - unpredictable consequences, which is possible only if zlib was compiled with - the insecure functions sprintf() or vsprintf() because the secure snprintf() - or vsnprintf() functions were not available. This can be determined using - zlibCompileFlags(). -*/ - -ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); -/* - Reads bytes from the compressed file until len-1 characters are read, or a - newline character is read and transferred to buf, or an end-of-file - condition is encountered. If any characters are read or if len == 1, the - string is terminated with a null character. If no characters are read due - to an end-of-file or len < 1, then the buffer is left untouched. - - gzgets returns buf which is a null-terminated string, or it returns NULL - for end-of-file or in case of error. If there was an error, the contents at - buf are indeterminate. -*/ - -ZEXTERN int ZEXPORT gzputc(gzFile file, int c); -/* - Writes c, converted to an unsigned char, into the compressed file. gzputc - returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc(gzFile file); -/* - Reads one byte from the compressed file. gzgetc returns this byte or -1 - in case of end of file or error. This is implemented as a macro for speed. - As such, it does not do all of the checking the other functions do. I.e. - it does not check to see if file is NULL, nor whether the structure file - points to has been clobbered or not. -*/ - -ZEXTERN int ZEXPORT gzungetc(int c, gzFile file); -/* - Push one character back onto the stream to be read as the first character - on the next read. At least one character of push-back is allowed. - gzungetc() returns the character pushed, or -1 on failure. gzungetc() will - fail if c is -1, and may fail if a character has been pushed but not read - yet. If gzungetc is used immediately after gzopen or gzdopen, at least the - output buffer size of pushed characters is allowed. (See gzbuffer above.) - The pushed character will be discarded if the stream is repositioned with - gzseek() or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush(gzFile file, int flush); -/* - Flushes all pending output into the compressed file. The parameter flush - is as in the deflate() function. The return value is the zlib error number - (see function gzerror below). gzflush is only permitted when writing. - - If the flush parameter is Z_FINISH, the remaining data is written and the - gzip stream is completed in the output. If gzwrite() is called again, a new - gzip stream will be started in the output. gzread() is able to read such - concatented gzip streams. - - gzflush should be called only when strictly necessary because it will - degrade compression if called too often. -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzseek (gzFile file, z_off_t offset, int whence); - - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind(gzFile file); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gztell(gzFile file); - - Returns the starting position for the next gzread or gzwrite on the given - compressed file. This position represents a number of bytes in the - uncompressed data stream, and is zero when starting, even if appending or - reading a gzip stream from the middle of a file using gzdopen(). - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzoffset(gzFile file); - - Returns the current offset in the file being read or written. This offset - includes the count of bytes that precede the gzip stream, for example when - appending or when using gzdopen() for reading. When reading, the offset - does not include as yet unused buffered input. This information can be used - for a progress indicator. On error, gzoffset() returns -1. -*/ - -ZEXTERN int ZEXPORT gzeof(gzFile file); -/* - Returns true (1) if the end-of-file indicator has been set while reading, - false (0) otherwise. Note that the end-of-file indicator is set only if the - read tried to go past the end of the input, but came up short. Therefore, - just like feof(), gzeof() may return false even if there is no more data to - read, in the event that the last read request was for the exact number of - bytes remaining in the input file. This will happen if the input file size - is an exact multiple of the buffer size. - - If gzeof() returns true, then the read functions will return no more data, - unless the end-of-file indicator is reset by gzclearerr() and the input file - has grown since the previous end of file was detected. -*/ - -ZEXTERN int ZEXPORT gzdirect(gzFile file); -/* - Returns true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. - - If the input file is empty, gzdirect() will return true, since the input - does not contain a gzip stream. - - If gzdirect() is used immediately after gzopen() or gzdopen() it will - cause buffers to be allocated to allow reading the file to determine if it - is a gzip file. Therefore if gzbuffer() is used, it should be called before - gzdirect(). - - When writing, gzdirect() returns true (1) if transparent writing was - requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: - gzdirect() is not needed when writing. Transparent writing must be - explicitly requested, so the application already knows the answer. When - linking statically, using gzdirect() will include all of the zlib code for - gzip file reading and decompression, which may not be desired.) -*/ - -ZEXTERN int ZEXPORT gzclose(gzFile file); -/* - Flushes all pending output if necessary, closes the compressed file and - deallocates the (de)compression state. Note that once file is closed, you - cannot call gzerror with file, since its structures have been deallocated. - gzclose must not be called more than once on the same file, just as free - must not be called more than once on the same allocation. - - gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the - last read ended in the middle of a gzip stream, or Z_OK on success. -*/ - -ZEXTERN int ZEXPORT gzclose_r(gzFile file); -ZEXTERN int ZEXPORT gzclose_w(gzFile file); -/* - Same as gzclose(), but gzclose_r() is only for use when reading, and - gzclose_w() is only for use when writing or appending. The advantage to - using these instead of gzclose() is that they avoid linking in zlib - compression or decompression code that is not used when only reading or only - writing respectively. If gzclose() is used, then both compression and - decompression code will be included the application when linking to a static - zlib library. -*/ - -ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum); -/* - Returns the error message for the last error which occurred on the given - compressed file. errnum is set to zlib error number. If an error occurred - in the file system and not in the compression library, errnum is set to - Z_ERRNO and the application may consult errno to get the exact error code. - - The application must not modify the returned string. Future calls to - this function may invalidate the previously returned string. If file is - closed, then the string previously returned by gzerror will no longer be - available. - - gzerror() should be used to distinguish errors from end-of-file for those - functions above that do not distinguish those cases in their return values. -*/ - -ZEXTERN void ZEXPORT gzclearerr(gzFile file); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - -#endif /* WITH_GZFILEOP */ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the compression - library. -*/ - -ZEXTERN uint32_t ZEXPORT adler32(uint32_t adler, const unsigned char *buf, uint32_t len); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is Z_NULL, this function returns the - required initial value for the checksum. - - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. - - Usage example: - - uint32_t adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -/* -ZEXTERN uint32_t ZEXPORT adler32_combine(uint32_t adler1, uint32_t adler2, z_off_t len2); - - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note - that the z_off_t type (like off_t) is a signed integer. If len2 is - negative, the result has no meaning or utility. -*/ - -ZEXTERN uint32_t ZEXPORT crc32(uint32_t crc, const unsigned char *buf, z_off64_t len); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is Z_NULL, this function returns the required - initial value for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. - - Usage example: - - uint32_t crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -/* -ZEXTERN uint32_t ZEXPORT crc32_combine(uint32_t crc1, uint32_t crc2, z_off64_t len2); - - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_(z_stream *strm, int level, const char *version, int stream_size); -ZEXTERN int ZEXPORT inflateInit_(z_stream *strm, const char *version, int stream_size); -ZEXTERN int ZEXPORT deflateInit2_(z_stream *strm, int level, int method, int windowBits, int memLevel, - int strategy, const char *version, int stream_size); -ZEXTERN int ZEXPORT inflateInit2_(z_stream *strm, int windowBits, const char *version, int stream_size); -ZEXTERN int ZEXPORT inflateBackInit_(z_stream *strm, int windowBits, unsigned char *window, - const char *version, int stream_size); -#define deflateInit(strm, level) deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -#define inflateInit(strm) inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm), (level), (method), (windowBits), (memLevel), \ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -#define inflateInit2(strm, windowBits) inflateInit2_((strm), (windowBits), ZLIB_VERSION, (int)sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), ZLIB_VERSION, (int)sizeof(z_stream)) - -#ifdef WITH_GZFILEOP - -/* gzgetc() macro and its supporting function and exposed data structure. Note - * that the real internal state is much larger than the exposed structure. - * This abbreviated structure exposes just enough for the gzgetc() macro. The - * user should not mess with these exposed elements, since their names or - * behavior could change in the future, perhaps even capriciously. They can - * only be used by the gzgetc() macro. You have been warned. - */ -struct gzFile_s { - unsigned have; - unsigned char *next; - z_off64_t pos; -}; -ZEXTERN int ZEXPORT gzgetc_(gzFile file); /* backward compatibility */ -# define gzgetc(g) ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) - -/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or - * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if - * both are true, the application gets the *64 functions, and the regular - * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true - */ -#ifdef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); - ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); - ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); - ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); -#endif - -#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# ifndef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); - ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int); - ZEXTERN z_off_t ZEXPORT gztell64(gzFile); - ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile); -# endif -#else - ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *); - ZEXTERN z_off_t ZEXPORT gzseek(gzFile, z_off_t, int); - ZEXTERN z_off_t ZEXPORT gztell(gzFile); - ZEXTERN z_off_t ZEXPORT gzoffset(gzFile); -#endif -#endif /* WITH_GZFILEOP */ - - -/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or - * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if - * both are true, the application gets the *64 functions, and the regular - * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true - */ -#ifdef Z_LARGE64 - ZEXTERN uint32_t ZEXPORT adler32_combine64(uint32_t, uint32_t, z_off64_t); - ZEXTERN uint32_t ZEXPORT crc32_combine64(uint32_t, uint32_t, z_off64_t); -#endif - -#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# ifndef Z_LARGE64 - ZEXTERN uint32_t ZEXPORT adler32_combine64(uint32_t, uint32_t, z_off_t); - ZEXTERN uint32_t ZEXPORT crc32_combine64(uint32_t, uint32_t, z_off_t); -# endif -#else - ZEXTERN uint32_t ZEXPORT adler32_combine(uint32_t, uint32_t, z_off_t); - ZEXTERN uint32_t ZEXPORT crc32_combine(uint32_t, uint32_t, z_off_t); -#endif - - -/* undocumented functions */ -ZEXTERN const char * ZEXPORT zError (int); -ZEXTERN int ZEXPORT inflateSyncPoint (z_stream *); -ZEXTERN const uint32_t * ZEXPORT get_crc_table (void); -ZEXTERN int ZEXPORT inflateUndermine (z_stream *, int); -ZEXTERN int ZEXPORT inflateResetKeep (z_stream *); -ZEXTERN int ZEXPORT deflateResetKeep (z_stream *); - -#ifdef WITH_GZFILEOP -# if (defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW__)) - ZEXTERN gzFile ZEXPORT gzopen_w(const wchar_t *path, const char *mode); -# endif -ZEXTERN int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H_ */ diff --git a/contrib/libzlib-ng/zlib.map b/contrib/libzlib-ng/zlib.map deleted file mode 100644 index 55c6647eb46..00000000000 --- a/contrib/libzlib-ng/zlib.map +++ /dev/null @@ -1,83 +0,0 @@ -ZLIB_1.2.0 { - global: - compressBound; - deflateBound; - inflateBack; - inflateBackEnd; - inflateBackInit_; - inflateCopy; - local: - deflate_copyright; - inflate_copyright; - inflate_fast; - inflate_table; - zcalloc; - zcfree; - z_errmsg; - gz_error; - gz_intmax; - _*; -}; - -ZLIB_1.2.0.2 { - gzclearerr; - gzungetc; - zlibCompileFlags; -} ZLIB_1.2.0; - -ZLIB_1.2.0.8 { - deflatePrime; -} ZLIB_1.2.0.2; - -ZLIB_1.2.2 { - adler32_combine; - crc32_combine; - deflateSetHeader; - inflateGetHeader; -} ZLIB_1.2.0.8; - -ZLIB_1.2.2.3 { - deflateTune; - gzdirect; -} ZLIB_1.2.2; - -ZLIB_1.2.2.4 { - inflatePrime; -} ZLIB_1.2.2.3; - -ZLIB_1.2.3.3 { - adler32_combine64; - crc32_combine64; - gzopen64; - gzseek64; - gztell64; - inflateUndermine; -} ZLIB_1.2.2.4; - -ZLIB_1.2.3.4 { - inflateReset2; - inflateMark; -} ZLIB_1.2.3.3; - -ZLIB_1.2.3.5 { - gzbuffer; - gzoffset; - gzoffset64; - gzclose_r; - gzclose_w; -} ZLIB_1.2.3.4; - -ZLIB_1.2.5.1 { - deflatePending; -} ZLIB_1.2.3.5; - -ZLIB_1.2.5.2 { - deflateResetKeep; - gzgetc_; - inflateResetKeep; -} ZLIB_1.2.5.1; - -ZLIB_1.2.7.1 { - inflateGetDictionary; - gzvprintf; -} ZLIB_1.2.5.2; diff --git a/contrib/libzlib-ng/zlib.pc.cmakein b/contrib/libzlib-ng/zlib.pc.cmakein deleted file mode 100644 index a5e642938c6..00000000000 --- a/contrib/libzlib-ng/zlib.pc.cmakein +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@CMAKE_INSTALL_PREFIX@ -exec_prefix=@CMAKE_INSTALL_PREFIX@ -libdir=@INSTALL_LIB_DIR@ -sharedlibdir=@INSTALL_LIB_DIR@ -includedir=@INSTALL_INC_DIR@ - -Name: zlib -Description: zlib compression library -Version: @VERSION@ - -Requires: -Libs: -L${libdir} -L${sharedlibdir} -lz -Cflags: -I${includedir} diff --git a/contrib/libzlib-ng/zlib.pc.in b/contrib/libzlib-ng/zlib.pc.in deleted file mode 100644 index 7e5acf9c77e..00000000000 --- a/contrib/libzlib-ng/zlib.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -sharedlibdir=@sharedlibdir@ -includedir=@includedir@ - -Name: zlib -Description: zlib compression library -Version: @VERSION@ - -Requires: -Libs: -L${libdir} -L${sharedlibdir} -lz -Cflags: -I${includedir} diff --git a/contrib/libzlib-ng/zutil.c b/contrib/libzlib-ng/zutil.c deleted file mode 100644 index e46277b8786..00000000000 --- a/contrib/libzlib-ng/zutil.c +++ /dev/null @@ -1,124 +0,0 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" -#ifdef WITH_GZFILEOP -# include "gzguts.h" -#endif - -const char * const z_errmsg[10] = { -"need dictionary", /* Z_NEED_DICT 2 */ -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -"incompatible version",/* Z_VERSION_ERROR (-6) */ -""}; - -const char zlibng_string[] = - " zlib-ng 1.9.9 forked from zlib 1.2.8 "; - -const char * ZEXPORT zlibVersion(void) -{ - return ZLIB_VERSION; -} - -unsigned long ZEXPORT zlibCompileFlags(void) -{ - unsigned long flags; - - flags = 0; - switch ((int)(sizeof(unsigned int))) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch ((int)(sizeof(unsigned long))) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch ((int)(sizeof(void *))) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch ((int)(sizeof(z_off_t))) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef DEBUG - flags += 1 << 8; -#endif -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif - return flags; -} - -#ifdef DEBUG - -# ifndef verbose -# define verbose 0 -# endif -int ZLIB_INTERNAL z_verbose = verbose; - -void ZLIB_INTERNAL z_error (m) - char *m; -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError(int err) -{ - return ERR_MSG(err); -} - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -void ZLIB_INTERNAL *zcalloc (void *opaque, unsigned items, unsigned size) -{ - (void)opaque; - return sizeof(unsigned int) > 2 ? (void *)malloc(items * size) : - (void *)calloc(items, size); -} - -void ZLIB_INTERNAL zcfree (void *opaque, void *ptr) -{ - (void)opaque; - free(ptr); -} - -#endif /* MY_ZCALLOC */ diff --git a/contrib/libzlib-ng/zutil.h b/contrib/libzlib-ng/zutil.h deleted file mode 100644 index b6e858c9cd2..00000000000 --- a/contrib/libzlib-ng/zutil.h +++ /dev/null @@ -1,185 +0,0 @@ -#ifndef ZUTIL_H_ -#define ZUTIL_H_ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2013 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#if defined(HAVE_INTERNAL) -# define ZLIB_INTERNAL __attribute__((visibility ("internal"))) -#elif defined(HAVE_HIDDEN) -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include -#include -#include -#include -#include "zlib.h" - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -typedef unsigned char uch; /* Included for compatibility with external code only */ -typedef uint16_t ush; /* Included for compatibility with external code only */ -typedef unsigned long ulg; - -extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm, err) return (strm->msg = ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#ifdef WIN32 -# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ -# define OS_CODE 0x0b -# endif -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) -# define fdopen(fd, type) _fdopen(fd, type) -#endif - -/* provide prototypes for these when building zlib without LFS */ -#if !defined(WIN32) && !defined(__MSYS__) && (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) - ZEXTERN uint32_t ZEXPORT adler32_combine64(uint32_t, uint32_t, z_off_t); - ZEXTERN uint32_t ZEXPORT crc32_combine64(uint32_t, uint32_t, z_off_t); -#endif - -/* MS Visual Studio does not allow inline in C, only C++. - But it provides __inline instead, so use that. */ -#if defined(_MSC_VER) && !defined(inline) -# define inline __inline -#endif - - /* common defaults */ - -#ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ -#endif - -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -/* Diagnostic functions */ -#ifdef DEBUG -# include - extern int ZLIB_INTERNAL z_verbose; - extern void ZLIB_INTERNAL z_error(char *m); -# define Assert(cond, msg) {if(!(cond)) z_error(msg);} -# define Trace(x) {if (z_verbose >= 0) fprintf x;} -# define Tracev(x) {if (z_verbose > 0) fprintf x;} -# define Tracevv(x) {if (z_verbose > 1) fprintf x;} -# define Tracec(c, x) {if (z_verbose > 0 && (c)) fprintf x;} -# define Tracecv(c, x) {if (z_verbose > 1 && (c)) fprintf x;} -#else -# define Assert(cond, msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c, x) -# define Tracecv(c, x) -#endif - -void ZLIB_INTERNAL *zcalloc(void *opaque, unsigned items, unsigned size); -void ZLIB_INTERNAL zcfree(void *opaque, void *ptr); - -#define ZALLOC(strm, items, size) (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (void *)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -/* Reverse the bytes in a 32-bit value. Use compiler intrinsics when - possible to take advantage of hardware implementations. */ -#if defined(WIN32) && (_MSC_VER >= 1300) -# pragma intrinsic(_byteswap_ulong) -# define ZSWAP32(q) _byteswap_ulong(q) - -#elif defined(__Clang__) || (defined(__GNUC__) && \ - (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))) -# define ZSWAP32(q) __builtin_bswap32(q) - -#elif defined(__GNUC__) && (__GNUC__ >= 2) && defined(__linux__) -# include -# define ZSWAP32(q) bswap_32(q) - -#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) -# include -# define ZSWAP32(q) bswap32(q) - -#elif defined(__INTEL_COMPILER) -# define ZSWAP32(q) _bswap(q) - -#else -# define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) -#endif /* ZSWAP32 */ - -/* Only enable likely/unlikely if the compiler is known to support it */ -#if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__INTEL_COMPILER) || defined(__Clang__) -# ifndef likely -# define likely(x) __builtin_expect(!!(x), 1) -# endif -# ifndef unlikely -# define unlikely(x) __builtin_expect(!!(x), 0) -# endif -#else -# ifndef likely -# define likely(x) x -# endif -# ifndef unlikely -# define unlikely(x) x -# endif -#endif /* (un)likely */ - -#if defined(_MSC_VER) -#define ALIGNED_(x) __declspec(align(x)) -#else -#if defined(__GNUC__) -#define ALIGNED_(x) __attribute__ ((aligned(x))) -#endif -#endif - -#endif /* ZUTIL_H_ */ From b972516bfc2f8433ba6e00f572f278ca14158e34 Mon Sep 17 00:00:00 2001 From: proller Date: Wed, 22 Nov 2017 15:15:17 +0300 Subject: [PATCH 0009/1165] Zlib: remove unused test targets --- cmake/find_zlib.cmake | 1 + contrib/CMakeLists.txt | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/cmake/find_zlib.cmake b/cmake/find_zlib.cmake index 93e62497c25..3b41280f1c5 100644 --- a/cmake/find_zlib.cmake +++ b/cmake/find_zlib.cmake @@ -7,6 +7,7 @@ endif () if (NOT ZLIB_FOUND) set (USE_INTERNAL_ZLIB_LIBRARY 1) set (ZLIB_COMPAT 1) # for zlib-ng, also enables WITH_GZFILEOP + set (WITH_NATIVE_INSTRUCTIONS ${ARCHNATIVE}) set (ZLIB_INCLUDE_DIR "${ClickHouse_SOURCE_DIR}/contrib/libzlib-ng" "${ClickHouse_BINARY_DIR}/contrib/libzlib-ng") # generated zconf.h set (ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR}) # for poco set (ZLIB_FOUND 1) # for poco diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 137eea988bc..814e1c54c08 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -50,6 +50,10 @@ if (USE_INTERNAL_ZLIB_LIBRARY) # We should use same defines when including zlib.h as used when zlib compiled target_compile_definitions (zlib PUBLIC ZLIB_COMPAT WITH_GZFILEOP) target_compile_definitions (zlibstatic PUBLIC ZLIB_COMPAT WITH_GZFILEOP) + set_target_properties(example PROPERTIES EXCLUDE_FROM_ALL 1) + set_target_properties(example64 PROPERTIES EXCLUDE_FROM_ALL 1) + set_target_properties(minigzip PROPERTIES EXCLUDE_FROM_ALL 1) + set_target_properties(minigzip64 PROPERTIES EXCLUDE_FROM_ALL 1) endif () if (USE_INTERNAL_CCTZ_LIBRARY) From 5d21519d2762895ce02571962ff2ca25e742b590 Mon Sep 17 00:00:00 2001 From: proller Date: Wed, 22 Nov 2017 17:03:09 +0300 Subject: [PATCH 0010/1165] Freebsd: zlib: dont use optimizations (broken asm) --- cmake/find_zlib.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/find_zlib.cmake b/cmake/find_zlib.cmake index 3b41280f1c5..d38ef13a5e9 100644 --- a/cmake/find_zlib.cmake +++ b/cmake/find_zlib.cmake @@ -8,6 +8,9 @@ if (NOT ZLIB_FOUND) set (USE_INTERNAL_ZLIB_LIBRARY 1) set (ZLIB_COMPAT 1) # for zlib-ng, also enables WITH_GZFILEOP set (WITH_NATIVE_INSTRUCTIONS ${ARCHNATIVE}) + if (CMAKE_SYSTEM MATCHES "FreeBSD") + set (WITH_OPTIM 0 CACHE INTERNAL "") # Bug in assembler + endif () set (ZLIB_INCLUDE_DIR "${ClickHouse_SOURCE_DIR}/contrib/libzlib-ng" "${ClickHouse_BINARY_DIR}/contrib/libzlib-ng") # generated zconf.h set (ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR}) # for poco set (ZLIB_FOUND 1) # for poco From 2ea3e6c67fe468a6b69263a0a15cdbee3d4f432e Mon Sep 17 00:00:00 2001 From: proller Date: Wed, 22 Nov 2017 22:15:17 +0300 Subject: [PATCH 0011/1165] Fix include path contrib/zlib-ng --- cmake/find_poco.cmake | 4 ++-- cmake/find_zlib.cmake | 2 +- utils/check_include.sh | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmake/find_poco.cmake b/cmake/find_poco.cmake index c63cbc3da13..19b0cf3ffca 100644 --- a/cmake/find_poco.cmake +++ b/cmake/find_poco.cmake @@ -62,8 +62,8 @@ else () if (USE_STATIC_LIBRARIES AND USE_INTERNAL_ZLIB_LIBRARY) list (APPEND Poco_INCLUDE_DIRS - "${ClickHouse_SOURCE_DIR}/contrib/libzlib-ng/" - "${ClickHouse_BINARY_DIR}/contrib/libzlib-ng/" + "${ClickHouse_SOURCE_DIR}/contrib/zlib-ng/" + "${ClickHouse_BINARY_DIR}/contrib/zlib-ng/" ) endif () diff --git a/cmake/find_zlib.cmake b/cmake/find_zlib.cmake index d38ef13a5e9..db26c0ad2de 100644 --- a/cmake/find_zlib.cmake +++ b/cmake/find_zlib.cmake @@ -11,7 +11,7 @@ if (NOT ZLIB_FOUND) if (CMAKE_SYSTEM MATCHES "FreeBSD") set (WITH_OPTIM 0 CACHE INTERNAL "") # Bug in assembler endif () - set (ZLIB_INCLUDE_DIR "${ClickHouse_SOURCE_DIR}/contrib/libzlib-ng" "${ClickHouse_BINARY_DIR}/contrib/libzlib-ng") # generated zconf.h + set (ZLIB_INCLUDE_DIR "${ClickHouse_SOURCE_DIR}/contrib/zlib-ng" "${ClickHouse_BINARY_DIR}/contrib/zlib-ng") # generated zconf.h set (ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR}) # for poco set (ZLIB_FOUND 1) # for poco if (USE_STATIC_LIBRARIES) diff --git a/utils/check_include.sh b/utils/check_include.sh index 22429d16a40..80c39ddff0c 100755 --- a/utils/check_include.sh +++ b/utils/check_include.sh @@ -15,8 +15,8 @@ inc="-I. \ -I./contrib/zookeeper/src/c/include \ -I./contrib/zookeeper/src/c/generated \ -I./contrib/libtcmalloc/include \ --I./build/contrib/libzlib-ng \ --I./contrib/libzlib-ng \ +-I./build/contrib/zlib-ng \ +-I./contrib/zlib-ng \ -I./contrib/poco/MongoDB/include \ -I./contrib/poco/XML/include \ -I./contrib/poco/Crypto/include \ From c0dab866d9be60d88e5c3f860e76bfe4da6faef3 Mon Sep 17 00:00:00 2001 From: proller Date: Fri, 17 Nov 2017 16:14:13 +0300 Subject: [PATCH 0012/1165] Update build_debian.sh --- utils/build/build_debian.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/build/build_debian.sh b/utils/build/build_debian.sh index 6124c1b482d..6d9594049b4 100755 --- a/utils/build/build_debian.sh +++ b/utils/build/build_debian.sh @@ -6,9 +6,9 @@ # curl https://raw.githubusercontent.com/yandex/ClickHouse/master/utils/build/build_debian.sh | sh # install compiler and libs -sudo apt install -y git bash cmake gcc-6 g++-6 libicu-dev libreadline-dev libmysqlclient-dev unixodbc-dev libltdl-dev libssl-dev +sudo apt install -y git bash cmake gcc-7 g++-7 libicu-dev libreadline-dev libmysqlclient-dev unixodbc-dev libltdl-dev libssl-dev # for -DUNBUNDLED=1 mode: -#sudo apt install -y libboost-dev zlib1g-dev liblz4-dev libdouble-conversion-dev libzstd-dev libre2-dev libzookeeper-mt-dev libsparsehash-dev # libpoco-dev +#sudo apt install -y libboost-dev zlib1g-dev liblz4-dev libdouble-conversion-dev libzstd-dev libre2-dev libzookeeper-mt-dev libsparsehash-dev librdkafka-dev libpoco-dev libsparsehash-dev libgoogle-perftools-dev libunwind-dev libzstd-dev # install testing only stuff if you want: sudo apt install -y python python-lxml python-termcolor curl perl @@ -19,7 +19,7 @@ git clone --recursive https://github.com/yandex/ClickHouse.git # Build! mkdir -p ClickHouse/build cd ClickHouse/build -cmake .. -DCMAKE_CXX_COMPILER=`which g++-6` -DCMAKE_C_COMPILER=`which gcc-6` +cmake .. -DCMAKE_CXX_COMPILER=`which g++-7` -DCMAKE_C_COMPILER=`which gcc-7` make -j $(nproc || sysctl -n hw.ncpu || echo 2) cd .. From 33faccbfd325908fb70d9445be43a18d04136ab3 Mon Sep 17 00:00:00 2001 From: Vitaliy Lyudvichenko Date: Wed, 29 Nov 2017 15:37:55 +0300 Subject: [PATCH 0013/1165] Update compiler version. [#CLICKHOUSE-2] --- release | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release b/release index 255f973eb91..ed622de6487 100755 --- a/release +++ b/release @@ -7,8 +7,8 @@ cd $CURDIR source "./release_lib.sh" -DEB_CC=gcc-6 -DEB_CXX=g++-6 +DEB_CC=gcc-7 +DEB_CXX=g++-7 CONTROL=debian/control DEBUILD_NOSIGN_OPTIONS="-us -uc" From 9b7f75940a852273e46d1e4559a87bb9e9756668 Mon Sep 17 00:00:00 2001 From: Vitaliy Lyudvichenko Date: Thu, 30 Nov 2017 16:34:07 +0300 Subject: [PATCH 0014/1165] Added missing include dirs for dynamic compilation. [#CLICKHOUSE-2] --- dbms/src/Interpreters/Compiler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dbms/src/Interpreters/Compiler.cpp b/dbms/src/Interpreters/Compiler.cpp index fde9e717690..e791ac7457a 100644 --- a/dbms/src/Interpreters/Compiler.cpp +++ b/dbms/src/Interpreters/Compiler.cpp @@ -215,7 +215,7 @@ void Compiler::compile( std::stringstream command; - /// Slightly unconvenient. + /// Slightly inconvenient. command << "LD_LIBRARY_PATH=" PATH_SHARE "/clickhouse/bin/" " " INTERNAL_COMPILER_EXECUTABLE @@ -224,6 +224,7 @@ void Compiler::compile( #if INTERNAL_COMPILER_CUSTOM_ROOT " -isystem " INTERNAL_COMPILER_HEADERS_ROOT "/usr/local/include/" " -isystem " INTERNAL_COMPILER_HEADERS_ROOT "/usr/include/" + " -isystem " INTERNAL_COMPILER_HEADERS_ROOT "/usr/local/include/c++/*/" " -isystem " INTERNAL_COMPILER_HEADERS_ROOT "/usr/include/c++/*/" " -isystem " INTERNAL_COMPILER_HEADERS_ROOT "/usr/include/x86_64-linux-gnu/" " -isystem " INTERNAL_COMPILER_HEADERS_ROOT "/usr/include/x86_64-linux-gnu/c++/*/" From 902c9374b62bcbdd2fcb787665312643b6145a29 Mon Sep 17 00:00:00 2001 From: proller Date: Thu, 30 Nov 2017 20:09:33 +0300 Subject: [PATCH 0015/1165] zlib fix flags in headers --- contrib/CMakeLists.txt | 5 +++ dbms/src/IO/ZlibDeflatingWriteBuffer.cpp | 2 +- dbms/src/IO/ZlibInflatingReadBuffer.cpp | 2 +- .../0_stateless/00302_http_compression.sh | 36 ++++++++++--------- 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 814e1c54c08..3f46ccfaaca 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -50,6 +50,11 @@ if (USE_INTERNAL_ZLIB_LIBRARY) # We should use same defines when including zlib.h as used when zlib compiled target_compile_definitions (zlib PUBLIC ZLIB_COMPAT WITH_GZFILEOP) target_compile_definitions (zlibstatic PUBLIC ZLIB_COMPAT WITH_GZFILEOP) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64") + target_compile_definitions (zlib PUBLIC X86_64) + target_compile_definitions (zlibstatic PUBLIC X86_64) + endif () + set_target_properties(example PROPERTIES EXCLUDE_FROM_ALL 1) set_target_properties(example64 PROPERTIES EXCLUDE_FROM_ALL 1) set_target_properties(minigzip PROPERTIES EXCLUDE_FROM_ALL 1) diff --git a/dbms/src/IO/ZlibDeflatingWriteBuffer.cpp b/dbms/src/IO/ZlibDeflatingWriteBuffer.cpp index c2165c382a9..61450e19db4 100644 --- a/dbms/src/IO/ZlibDeflatingWriteBuffer.cpp +++ b/dbms/src/IO/ZlibDeflatingWriteBuffer.cpp @@ -34,7 +34,7 @@ ZlibDeflatingWriteBuffer::ZlibDeflatingWriteBuffer( #pragma GCC diagnostic pop if (rc != Z_OK) - throw Exception(std::string("deflateInit2 failed: ") + zError(rc), ErrorCodes::ZLIB_DEFLATE_FAILED); + throw Exception(std::string("deflateInit2 failed: ") + zError(rc) + "; zlib version: " + ZLIB_VERSION, ErrorCodes::ZLIB_DEFLATE_FAILED); } ZlibDeflatingWriteBuffer::~ZlibDeflatingWriteBuffer() diff --git a/dbms/src/IO/ZlibInflatingReadBuffer.cpp b/dbms/src/IO/ZlibInflatingReadBuffer.cpp index 869108515d3..8100cf88de7 100644 --- a/dbms/src/IO/ZlibInflatingReadBuffer.cpp +++ b/dbms/src/IO/ZlibInflatingReadBuffer.cpp @@ -34,7 +34,7 @@ ZlibInflatingReadBuffer::ZlibInflatingReadBuffer( #pragma GCC diagnostic pop if (rc != Z_OK) - throw Exception(std::string("inflateInit2 failed: ") + zError(rc), ErrorCodes::ZLIB_INFLATE_FAILED); + throw Exception(std::string("inflateInit2 failed: ") + zError(rc) + "; zlib version: " + ZLIB_VERSION, ErrorCodes::ZLIB_INFLATE_FAILED); } ZlibInflatingReadBuffer::~ZlibInflatingReadBuffer() diff --git a/dbms/tests/queries/0_stateless/00302_http_compression.sh b/dbms/tests/queries/0_stateless/00302_http_compression.sh index f71b8975fd0..013f3988d0e 100755 --- a/dbms/tests/queries/0_stateless/00302_http_compression.sh +++ b/dbms/tests/queries/0_stateless/00302_http_compression.sh @@ -1,24 +1,28 @@ #!/usr/bin/env bash -curl -sS 'http://localhost:8123/?enable_http_compression=1' -d 'SELECT number FROM system.numbers LIMIT 10'; -curl -sS 'http://localhost:8123/?enable_http_compression=0' -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 10'; -curl -sS 'http://localhost:8123/?enable_http_compression=1' -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 10' | gzip -d; -curl -sS 'http://localhost:8123/?enable_http_compression=1' -H 'Accept-Encoding: gzip, deflate' -d 'SELECT number FROM system.numbers LIMIT 10' | gzip -d; -curl -sS 'http://localhost:8123/?enable_http_compression=1' -H 'Accept-Encoding: zip, eflate' -d 'SELECT number FROM system.numbers LIMIT 10'; +CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +. $CURDIR/../shell_config.sh -curl -vsS 'http://localhost:8123/?enable_http_compression=1' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; -curl -vsS 'http://localhost:8123/?enable_http_compression=1' -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; -curl -vsS 'http://localhost:8123/?enable_http_compression=1' -H 'Accept-Encoding: deflate' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; -curl -vsS 'http://localhost:8123/?enable_http_compression=1' -H 'Accept-Encoding: gzip, deflate' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; -curl -vsS 'http://localhost:8123/?enable_http_compression=1' -H 'Accept-Encoding: zip, eflate' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; -echo "SELECT 1" | curl -sS --data-binary @- 'http://localhost:8123/'; -echo "SELECT 1" | gzip -c | curl -sS --data-binary @- -H 'Content-Encoding: gzip' 'http://localhost:8123/'; +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}?enable_http_compression=1" -d 'SELECT number FROM system.numbers LIMIT 10'; +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}?enable_http_compression=0" -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 10'; +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}?enable_http_compression=1" -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 10' | gzip -d; +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}?enable_http_compression=1" -H 'Accept-Encoding: gzip, deflate' -d 'SELECT number FROM system.numbers LIMIT 10' | gzip -d; +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}?enable_http_compression=1" -H 'Accept-Encoding: zip, eflate' -d 'SELECT number FROM system.numbers LIMIT 10'; -echo "'Hello, world'" | curl -sS --data-binary @- 'http://localhost:8123/?query=SELECT'; -echo "'Hello, world'" | gzip -c | curl -sS --data-binary @- -H 'Content-Encoding: gzip' 'http://localhost:8123/?query=SELECT'; +${CLICKHOUSE_CURL} -vsS "${CLICKHOUSE_URL}?enable_http_compression=1" -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; +${CLICKHOUSE_CURL} -vsS "${CLICKHOUSE_URL}?enable_http_compression=1" -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; +${CLICKHOUSE_CURL} -vsS "${CLICKHOUSE_URL}?enable_http_compression=1" -H 'Accept-Encoding: deflate' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; +${CLICKHOUSE_CURL} -vsS "${CLICKHOUSE_URL}?enable_http_compression=1" -H 'Accept-Encoding: gzip, deflate' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; + -vsS '${CLICKHOUSE_URL}?enable_http_compression=1' -H 'Accept-Encoding: zip, eflate' -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep --text '< Content-Encoding'; -curl -sS 'http://localhost:8123/?enable_http_compression=1' -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 0' | wc -c; +echo "SELECT 1" | ${CLICKHOUSE_CURL} -sS --data-binary @- ${CLICKHOUSE_URL}; +echo "SELECT 1" | gzip -c | ${CLICKHOUSE_CURL} -sS --data-binary @- -H 'Content-Encoding: gzip' ${CLICKHOUSE_URL}; + +echo "'Hello, world'" | ${CLICKHOUSE_CURL} -sS --data-binary @- "${CLICKHOUSE_URL}?query=SELECT"; +echo "'Hello, world'" | gzip -c | ${CLICKHOUSE_CURL} -sS --data-binary @- -H 'Content-Encoding: gzip' "${CLICKHOUSE_URL}?query=SELECT"; + +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}?enable_http_compression=1" -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 0' | wc -c; # POST multiple concatenated gzip streams. -(echo -n "SELECT 'Part1" | gzip -c; echo " Part2'" | gzip -c) | curl -sS -H 'Content-Encoding: gzip' 'http://localhost:8123/?' --data-binary @- +(echo -n "SELECT 'Part1" | gzip -c; echo " Part2'" | gzip -c) | ${CLICKHOUSE_CURL} -sS -H 'Content-Encoding: gzip' "${CLICKHOUSE_URL}?" --data-binary @- From 89e633d0649c94b160f8b6afe94f67f072b19d4a Mon Sep 17 00:00:00 2001 From: proller Date: Thu, 30 Nov 2017 20:21:03 +0300 Subject: [PATCH 0016/1165] Fix compile (missing boost libs) --- .../boost/archive/archive_exception.hpp | 100 + .../boost/archive/basic_archive.hpp | 304 +++ .../boost/archive/basic_binary_iarchive.hpp | 204 ++ .../boost/archive/basic_binary_iprimitive.hpp | 198 ++ .../boost/archive/basic_binary_oarchive.hpp | 185 ++ .../boost/archive/basic_binary_oprimitive.hpp | 188 ++ .../archive/basic_streambuf_locale_saver.hpp | 108 ++ .../boost/archive/basic_text_iarchive.hpp | 96 + .../boost/archive/basic_text_iprimitive.hpp | 142 ++ .../boost/archive/basic_text_oarchive.hpp | 119 ++ .../boost/archive/basic_text_oprimitive.hpp | 209 ++ .../boost/archive/basic_xml_archive.hpp | 67 + .../boost/archive/basic_xml_iarchive.hpp | 119 ++ .../boost/archive/basic_xml_oarchive.hpp | 138 ++ .../boost/archive/binary_iarchive.hpp | 64 + .../boost/archive/binary_iarchive_impl.hpp | 105 + .../boost/archive/binary_oarchive.hpp | 64 + .../boost/archive/binary_oarchive_impl.hpp | 106 + .../boost/archive/binary_wiarchive.hpp | 56 + .../boost/archive/binary_woarchive.hpp | 59 + .../boost/archive/codecvt_null.hpp | 109 ++ .../boost/archive/detail/abi_prefix.hpp | 16 + .../boost/archive/detail/abi_suffix.hpp | 15 + .../archive/detail/archive_serializer_map.hpp | 54 + .../archive/detail/auto_link_archive.hpp | 48 + .../archive/detail/auto_link_warchive.hpp | 47 + .../boost/archive/detail/basic_iarchive.hpp | 105 + .../archive/detail/basic_iserializer.hpp | 91 + .../boost/archive/detail/basic_oarchive.hpp | 94 + .../archive/detail/basic_oserializer.hpp | 89 + .../detail/basic_pointer_iserializer.hpp | 70 + .../detail/basic_pointer_oserializer.hpp | 68 + .../boost/archive/detail/basic_serializer.hpp | 77 + .../archive/detail/basic_serializer_map.hpp | 69 + .../boost/archive/detail/check.hpp | 169 ++ .../boost/archive/detail/common_iarchive.hpp | 88 + .../boost/archive/detail/common_oarchive.hpp | 88 + .../boost/archive/detail/decl.hpp | 57 + .../archive/detail/helper_collection.hpp | 99 + .../archive/detail/interface_iarchive.hpp | 85 + .../archive/detail/interface_oarchive.hpp | 87 + .../boost/archive/detail/iserializer.hpp | 631 ++++++ .../boost/archive/detail/oserializer.hpp | 540 ++++++ .../detail/polymorphic_iarchive_route.hpp | 218 +++ .../detail/polymorphic_oarchive_route.hpp | 209 ++ .../boost/archive/detail/register_archive.hpp | 91 + .../archive/detail/utf8_codecvt_facet.hpp | 39 + .../boost_1_65_0/boost/archive/dinkumware.hpp | 224 +++ .../archive/impl/archive_serializer_map.ipp | 75 + .../archive/impl/basic_binary_iarchive.ipp | 134 ++ .../archive/impl/basic_binary_iprimitive.ipp | 171 ++ .../archive/impl/basic_binary_oarchive.ipp | 42 + .../archive/impl/basic_binary_oprimitive.ipp | 126 ++ .../archive/impl/basic_text_iarchive.ipp | 76 + .../archive/impl/basic_text_iprimitive.ipp | 137 ++ .../archive/impl/basic_text_oarchive.ipp | 62 + .../archive/impl/basic_text_oprimitive.ipp | 115 ++ .../boost/archive/impl/basic_xml_grammar.hpp | 173 ++ .../boost/archive/impl/basic_xml_iarchive.ipp | 115 ++ .../boost/archive/impl/basic_xml_oarchive.ipp | 272 +++ .../boost/archive/impl/text_iarchive_impl.ipp | 128 ++ .../boost/archive/impl/text_oarchive_impl.ipp | 122 ++ .../archive/impl/text_wiarchive_impl.ipp | 118 ++ .../archive/impl/text_woarchive_impl.ipp | 85 + .../boost/archive/impl/xml_iarchive_impl.ipp | 199 ++ .../boost/archive/impl/xml_oarchive_impl.ipp | 142 ++ .../boost/archive/impl/xml_wiarchive_impl.ipp | 189 ++ .../boost/archive/impl/xml_woarchive_impl.ipp | 171 ++ .../archive/iterators/base64_exception.hpp | 68 + .../archive/iterators/base64_from_binary.hpp | 109 ++ .../archive/iterators/binary_from_base64.hpp | 118 ++ .../boost/archive/iterators/dataflow.hpp | 102 + .../archive/iterators/dataflow_exception.hpp | 80 + .../boost/archive/iterators/escape.hpp | 115 ++ .../archive/iterators/insert_linebreaks.hpp | 99 + .../archive/iterators/istream_iterator.hpp | 92 + .../boost/archive/iterators/mb_from_wchar.hpp | 139 ++ .../archive/iterators/ostream_iterator.hpp | 83 + .../archive/iterators/remove_whitespace.hpp | 167 ++ .../archive/iterators/transform_width.hpp | 177 ++ .../boost/archive/iterators/unescape.hpp | 89 + .../boost/archive/iterators/wchar_from_mb.hpp | 194 ++ .../boost/archive/iterators/xml_escape.hpp | 121 ++ .../boost/archive/iterators/xml_unescape.hpp | 125 ++ .../iterators/xml_unescape_exception.hpp | 49 + .../archive/polymorphic_binary_iarchive.hpp | 54 + .../archive/polymorphic_binary_oarchive.hpp | 43 + .../boost/archive/polymorphic_iarchive.hpp | 168 ++ .../boost/archive/polymorphic_oarchive.hpp | 154 ++ .../archive/polymorphic_text_iarchive.hpp | 54 + .../archive/polymorphic_text_oarchive.hpp | 39 + .../archive/polymorphic_text_wiarchive.hpp | 59 + .../archive/polymorphic_text_woarchive.hpp | 44 + .../archive/polymorphic_xml_iarchive.hpp | 54 + .../archive/polymorphic_xml_oarchive.hpp | 39 + .../archive/polymorphic_xml_wiarchive.hpp | 50 + .../archive/polymorphic_xml_woarchive.hpp | 44 + .../boost/archive/text_iarchive.hpp | 132 ++ .../boost/archive/text_oarchive.hpp | 121 ++ .../boost/archive/text_wiarchive.hpp | 137 ++ .../boost/archive/text_woarchive.hpp | 155 ++ .../boost_1_65_0/boost/archive/tmpdir.hpp | 50 + .../boost_1_65_0/boost/archive/wcslen.hpp | 58 + .../boost/archive/xml_archive_exception.hpp | 57 + .../boost/archive/xml_iarchive.hpp | 142 ++ .../boost/archive/xml_oarchive.hpp | 137 ++ .../boost/archive/xml_wiarchive.hpp | 149 ++ .../boost/archive/xml_woarchive.hpp | 134 ++ .../boost_1_65_0/boost/foreach_fwd.hpp | 51 + .../boost/multi_index/composite_key.hpp | 1513 +++++++++++++++ .../multi_index/detail/access_specifier.hpp | 54 + .../boost/multi_index/detail/adl_swap.hpp | 44 + .../detail/archive_constructed.hpp | 83 + .../boost/multi_index/detail/auto_space.hpp | 91 + .../boost/multi_index/detail/base_type.hpp | 74 + .../detail/bidir_node_iterator.hpp | 114 ++ .../boost/multi_index/detail/bucket_array.hpp | 243 +++ .../multi_index/detail/cons_stdtuple.hpp | 93 + .../boost/multi_index/detail/converter.hpp | 52 + .../boost/multi_index/detail/copy_map.hpp | 142 ++ .../detail/do_not_copy_elements_tag.hpp | 34 + .../detail/duplicates_iterator.hpp | 120 ++ .../boost/multi_index/detail/has_tag.hpp | 42 + .../multi_index/detail/hash_index_args.hpp | 105 + .../detail/hash_index_iterator.hpp | 166 ++ .../multi_index/detail/hash_index_node.hpp | 778 ++++++++ .../multi_index/detail/header_holder.hpp | 50 + .../detail/ignore_wstrict_aliasing.hpp | 18 + .../boost/multi_index/detail/index_base.hpp | 293 +++ .../boost/multi_index/detail/index_loader.hpp | 139 ++ .../multi_index/detail/index_matcher.hpp | 249 +++ .../multi_index/detail/index_node_base.hpp | 135 ++ .../boost/multi_index/detail/index_saver.hpp | 135 ++ .../multi_index/detail/invariant_assert.hpp | 21 + .../multi_index/detail/is_index_list.hpp | 40 + .../multi_index/detail/is_transparent.hpp | 135 ++ .../boost/multi_index/detail/iter_adaptor.hpp | 321 +++ .../multi_index/detail/modify_key_adaptor.hpp | 49 + .../multi_index/detail/no_duplicate_tags.hpp | 97 + .../boost/multi_index/detail/node_type.hpp | 66 + .../multi_index/detail/ord_index_args.hpp | 83 + .../multi_index/detail/ord_index_impl.hpp | 1567 +++++++++++++++ .../multi_index/detail/ord_index_impl_fwd.hpp | 128 ++ .../multi_index/detail/ord_index_node.hpp | 658 +++++++ .../multi_index/detail/ord_index_ops.hpp | 266 +++ .../boost/multi_index/detail/promotes_arg.hpp | 83 + .../boost/multi_index/detail/raw_ptr.hpp | 52 + .../detail/restore_wstrict_aliasing.hpp | 11 + .../multi_index/detail/rnd_index_loader.hpp | 173 ++ .../multi_index/detail/rnd_index_node.hpp | 273 +++ .../multi_index/detail/rnd_index_ops.hpp | 203 ++ .../detail/rnd_index_ptr_array.hpp | 144 ++ .../multi_index/detail/rnd_node_iterator.hpp | 140 ++ .../multi_index/detail/rnk_index_ops.hpp | 300 +++ .../boost/multi_index/detail/safe_mode.hpp | 588 ++++++ .../boost/multi_index/detail/scope_guard.hpp | 453 +++++ .../multi_index/detail/seq_index_node.hpp | 217 +++ .../multi_index/detail/seq_index_ops.hpp | 203 ++ .../detail/serialization_version.hpp | 73 + .../boost/multi_index/detail/uintptr_type.hpp | 76 + .../boost/multi_index/detail/unbounded.hpp | 66 + .../multi_index/detail/value_compare.hpp | 56 + .../multi_index/detail/vartempl_support.hpp | 247 +++ .../boost/multi_index/global_fun.hpp | 185 ++ .../boost/multi_index/hashed_index.hpp | 1725 +++++++++++++++++ .../boost/multi_index/hashed_index_fwd.hpp | 74 + .../boost/multi_index/identity.hpp | 145 ++ .../boost/multi_index/identity_fwd.hpp | 26 + .../boost/multi_index/indexed_by.hpp | 68 + .../boost/multi_index/key_extractors.hpp | 22 + .../boost/multi_index/mem_fun.hpp | 205 ++ .../boost_1_65_0/boost/multi_index/member.hpp | 262 +++ .../boost/multi_index/ordered_index.hpp | 114 ++ .../boost/multi_index/ordered_index_fwd.hpp | 35 + .../boost/multi_index/random_access_index.hpp | 1167 +++++++++++ .../multi_index/random_access_index_fwd.hpp | 91 + .../boost/multi_index/ranked_index.hpp | 382 ++++ .../boost/multi_index/ranked_index_fwd.hpp | 35 + .../boost/multi_index/safe_mode_errors.hpp | 48 + .../boost/multi_index/sequenced_index.hpp | 1062 ++++++++++ .../boost/multi_index/sequenced_index_fwd.hpp | 91 + .../boost_1_65_0/boost/multi_index/tag.hpp | 88 + .../boost/multi_index_container.hpp | 1362 +++++++++++++ .../boost/multi_index_container_fwd.hpp | 121 ++ .../boost/serialization/access.hpp | 145 ++ .../archive_input_unordered_map.hpp | 85 + .../archive_input_unordered_set.hpp | 72 + .../boost/serialization/array.hpp | 48 + .../serialization/array_optimization.hpp | 37 + .../boost/serialization/array_wrapper.hpp | 121 ++ .../boost/serialization/assume_abstract.hpp | 60 + .../boost/serialization/base_object.hpp | 100 + .../boost/serialization/binary_object.hpp | 79 + .../boost/serialization/bitset.hpp | 75 + .../boost/serialization/boost_array.hpp | 33 + .../serialization/boost_unordered_map.hpp | 154 ++ .../serialization/boost_unordered_set.hpp | 150 ++ .../serialization/collection_size_type.hpp | 62 + .../boost/serialization/collection_traits.hpp | 79 + .../serialization/collections_load_imp.hpp | 106 + .../serialization/collections_save_imp.hpp | 82 + .../boost/serialization/complex.hpp | 81 + .../boost/serialization/config.hpp | 74 + .../boost/serialization/deque.hpp | 80 + .../detail/is_default_constructible.hpp | 54 + .../serialization/detail/shared_count_132.hpp | 551 ++++++ .../serialization/detail/shared_ptr_132.hpp | 443 +++++ .../detail/shared_ptr_nmt_132.hpp | 182 ++ .../detail/stack_constructor.hpp | 66 + .../boost/serialization/ephemeral.hpp | 72 + .../boost/serialization/export.hpp | 225 +++ .../serialization/extended_type_info.hpp | 116 ++ .../extended_type_info_no_rtti.hpp | 182 ++ .../extended_type_info_typeid.hpp | 167 ++ .../boost/serialization/factory.hpp | 102 + .../boost/serialization/force_include.hpp | 55 + .../boost/serialization/forward_list.hpp | 124 ++ .../hash_collections_load_imp.hpp | 77 + .../hash_collections_save_imp.hpp | 97 + .../boost/serialization/hash_map.hpp | 232 +++ .../boost/serialization/hash_set.hpp | 222 +++ .../serialization/is_bitwise_serializable.hpp | 46 + .../boost/serialization/item_version_type.hpp | 68 + .../boost/serialization/level.hpp | 116 ++ .../boost/serialization/level_enum.hpp | 55 + .../boost_1_65_0/boost/serialization/list.hpp | 85 + .../boost_1_65_0/boost/serialization/map.hpp | 139 ++ .../boost_1_65_0/boost/serialization/nvp.hpp | 123 ++ .../boost/serialization/optional.hpp | 107 + .../boost/serialization/priority_queue.hpp | 76 + .../boost/serialization/queue.hpp | 76 + .../boost/serialization/scoped_ptr.hpp | 58 + .../boost/serialization/serialization.hpp | 154 ++ .../boost_1_65_0/boost/serialization/set.hpp | 137 ++ .../boost/serialization/shared_ptr.hpp | 281 +++ .../boost/serialization/shared_ptr_132.hpp | 222 +++ .../boost/serialization/shared_ptr_helper.hpp | 209 ++ .../boost/serialization/singleton.hpp | 166 ++ .../boost/serialization/slist.hpp | 145 ++ .../boost/serialization/smart_cast.hpp | 275 +++ .../boost/serialization/split_free.hpp | 93 + .../boost/serialization/split_member.hpp | 86 + .../boost/serialization/stack.hpp | 76 + .../boost/serialization/state_saver.hpp | 96 + .../boost/serialization/static_warning.hpp | 103 + .../boost/serialization/string.hpp | 30 + .../boost/serialization/strong_typedef.hpp | 50 + .../boost/serialization/throw_exception.hpp | 44 + .../boost/serialization/tracking.hpp | 118 ++ .../boost/serialization/tracking_enum.hpp | 41 + .../boost/serialization/traits.hpp | 65 + .../type_info_implementation.hpp | 73 + .../boost/serialization/unique_ptr.hpp | 68 + .../unordered_collections_load_imp.hpp | 73 + .../unordered_collections_save_imp.hpp | 86 + .../boost/serialization/unordered_map.hpp | 160 ++ .../boost/serialization/unordered_set.hpp | 162 ++ .../boost/serialization/utility.hpp | 56 + .../boost/serialization/valarray.hpp | 86 + .../boost/serialization/variant.hpp | 158 ++ .../boost/serialization/vector.hpp | 233 +++ .../boost/serialization/vector_135.hpp | 26 + .../boost/serialization/version.hpp | 107 + .../boost/serialization/void_cast.hpp | 298 +++ .../boost/serialization/void_cast_fwd.hpp | 37 + .../boost/serialization/weak_ptr.hpp | 99 + .../boost/serialization/wrapper.hpp | 60 + 267 files changed, 41588 insertions(+) create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/archive_exception.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_archive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iprimitive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oprimitive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_streambuf_locale_saver.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_text_iarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_text_iprimitive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_text_oarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_text_oprimitive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_xml_archive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_xml_iarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_xml_oarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive_impl.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive_impl.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/binary_wiarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/binary_woarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/codecvt_null.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/abi_prefix.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/abi_suffix.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/archive_serializer_map.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_archive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_warchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iserializer.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oserializer.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_iserializer.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_oserializer.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer_map.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/check.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/common_iarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/common_oarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/decl.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/helper_collection.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/interface_iarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/interface_oarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/iserializer.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/oserializer.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_iarchive_route.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_oarchive_route.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/register_archive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/utf8_codecvt_facet.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/dinkumware.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/archive_serializer_map.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iarchive.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iprimitive.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oarchive.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oprimitive.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iarchive.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iprimitive.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oarchive.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oprimitive.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_grammar.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_iarchive.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_oarchive.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/text_iarchive_impl.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/text_oarchive_impl.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/text_wiarchive_impl.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/text_woarchive_impl.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/xml_iarchive_impl.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/xml_oarchive_impl.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/xml_wiarchive_impl.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/xml_woarchive_impl.ipp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_exception.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_from_binary.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/binary_from_base64.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow_exception.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/escape.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/insert_linebreaks.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/istream_iterator.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/mb_from_wchar.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/ostream_iterator.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/remove_whitespace.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/transform_width.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/unescape.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/wchar_from_mb.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_escape.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape_exception.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_iarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_oarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_iarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_oarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_iarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_oarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_wiarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_woarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_iarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_oarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_wiarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_woarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/text_iarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/text_oarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/text_wiarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/text_woarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/tmpdir.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/wcslen.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/xml_archive_exception.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/xml_iarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/xml_oarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/xml_wiarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/archive/xml_woarchive.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/foreach_fwd.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/composite_key.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/access_specifier.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/adl_swap.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/archive_constructed.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/auto_space.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/base_type.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/bidir_node_iterator.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/bucket_array.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/cons_stdtuple.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/converter.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/copy_map.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/do_not_copy_elements_tag.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/duplicates_iterator.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/has_tag.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_args.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_iterator.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_node.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/header_holder.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/ignore_wstrict_aliasing.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_base.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_loader.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_matcher.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_node_base.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_saver.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/invariant_assert.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_index_list.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_transparent.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/iter_adaptor.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/modify_key_adaptor.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/no_duplicate_tags.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/node_type.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_args.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl_fwd.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_node.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_ops.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/promotes_arg.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/raw_ptr.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/restore_wstrict_aliasing.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_loader.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_node.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ops.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ptr_array.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_node_iterator.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnk_index_ops.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/safe_mode.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/scope_guard.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_node.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_ops.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/serialization_version.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/uintptr_type.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/unbounded.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/value_compare.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/vartempl_support.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/global_fun.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index_fwd.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/identity.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/identity_fwd.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/indexed_by.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/key_extractors.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/mem_fun.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/member.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index_fwd.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index_fwd.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index_fwd.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/safe_mode_errors.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index_fwd.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/tag.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index_container.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index_container_fwd.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/access.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_map.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_set.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/array.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/array_optimization.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/array_wrapper.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/assume_abstract.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/base_object.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/binary_object.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/bitset.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/boost_array.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_map.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_set.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/collection_size_type.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/collection_traits.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/collections_load_imp.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/collections_save_imp.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/complex.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/config.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/deque.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/detail/is_default_constructible.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_count_132.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_132.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_nmt_132.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/detail/stack_constructor.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/ephemeral.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/export.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_no_rtti.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_typeid.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/factory.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/force_include.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/forward_list.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_load_imp.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_save_imp.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/hash_map.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/hash_set.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/is_bitwise_serializable.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/item_version_type.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/level.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/level_enum.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/list.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/map.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/nvp.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/optional.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/priority_queue.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/queue.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/scoped_ptr.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/serialization.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/set.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_132.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_helper.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/singleton.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/slist.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/smart_cast.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/split_free.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/split_member.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/stack.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/state_saver.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/static_warning.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/string.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/strong_typedef.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/throw_exception.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/tracking.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/tracking_enum.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/traits.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/type_info_implementation.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/unique_ptr.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_load_imp.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_save_imp.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/unordered_map.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/unordered_set.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/utility.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/valarray.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/variant.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/vector.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/vector_135.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/version.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/void_cast.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/void_cast_fwd.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/weak_ptr.hpp create mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/wrapper.hpp diff --git a/contrib/libboost/boost_1_65_0/boost/archive/archive_exception.hpp b/contrib/libboost/boost_1_65_0/boost/archive/archive_exception.hpp new file mode 100644 index 00000000000..fabcdb5fa71 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/archive_exception.hpp @@ -0,0 +1,100 @@ +#ifndef BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP +#define BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// archive/archive_exception.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +#include +#include + +// note: the only reason this is in here is that windows header +// includes #define exception_code _exception_code (arrrgghhhh!). +// the most expedient way to address this is be sure that this +// header is always included whenever this header file is included. +#if defined(BOOST_WINDOWS) +#include +#endif + +#include // must be the last header + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// exceptions thrown by archives +// +class BOOST_SYMBOL_VISIBLE archive_exception : + public virtual std::exception +{ +private: + char m_buffer[128]; +protected: + BOOST_ARCHIVE_DECL unsigned int + append(unsigned int l, const char * a); + BOOST_ARCHIVE_DECL + archive_exception() BOOST_NOEXCEPT; +public: + typedef enum { + no_exception, // initialized without code + other_exception, // any excepton not listed below + unregistered_class, // attempt to serialize a pointer of + // an unregistered class + invalid_signature, // first line of archive does not contain + // expected string + unsupported_version,// archive created with library version + // subsequent to this one + pointer_conflict, // an attempt has been made to directly + // serialize an object which has + // already been serialized through a pointer. + // Were this permitted, the archive load would result + // in the creation of an extra copy of the obect. + incompatible_native_format, // attempt to read native binary format + // on incompatible platform + array_size_too_short,// array being loaded doesn't fit in array allocated + input_stream_error, // error on input stream + invalid_class_name, // class name greater than the maximum permitted. + // most likely a corrupted archive or an attempt + // to insert virus via buffer overrun method. + unregistered_cast, // base - derived relationship not registered with + // void_cast_register + unsupported_class_version, // type saved with a version # greater than the + // one used by the program. This indicates that the program + // needs to be rebuilt. + multiple_code_instantiation, // code for implementing serialization for some + // type has been instantiated in more than one module. + output_stream_error // error on input stream + } exception_code; + exception_code code; + + BOOST_ARCHIVE_DECL archive_exception( + exception_code c, + const char * e1 = NULL, + const char * e2 = NULL + ) BOOST_NOEXCEPT; + BOOST_ARCHIVE_DECL archive_exception(archive_exception const &) BOOST_NOEXCEPT ; + virtual BOOST_ARCHIVE_DECL ~archive_exception() BOOST_NOEXCEPT_OR_NOTHROW ; + virtual BOOST_ARCHIVE_DECL const char * what() const BOOST_NOEXCEPT_OR_NOTHROW ; +}; + +}// namespace archive +}// namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif //BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_archive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_archive.hpp new file mode 100644 index 00000000000..ce7ac99a6dd --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_archive.hpp @@ -0,0 +1,304 @@ +#ifndef BOOST_ARCHIVE_BASIC_ARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_ARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_archive.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include // count +#include +#include +#include // size_t +#include +#include + +#include +#include // must be the last header + +namespace boost { +namespace archive { + +#if defined(_MSC_VER) +#pragma warning( push ) +#pragma warning( disable : 4244 4267 ) +#endif + +/* NOTE : Warning : Warning : Warning : Warning : Warning + * Don't ever changes this. If you do, they previously created + * binary archives won't be readable !!! + */ +class library_version_type { +private: + typedef uint_least16_t base_type; + base_type t; +public: + library_version_type(): t(0) {}; + explicit library_version_type(const unsigned int & t_) : t(t_){ + BOOST_ASSERT(t_ <= boost::integer_traits::const_max); + } + library_version_type(const library_version_type & t_) : + t(t_.t) + {} + library_version_type & operator=(const library_version_type & rhs){ + t = rhs.t; + return *this; + } + // used for text output + operator base_type () const { + return t; + } + // used for text input + operator base_type & (){ + return t; + } + bool operator==(const library_version_type & rhs) const { + return t == rhs.t; + } + bool operator<(const library_version_type & rhs) const { + return t < rhs.t; + } +}; + +BOOST_ARCHIVE_DECL library_version_type +BOOST_ARCHIVE_VERSION(); + +class version_type { +private: + typedef uint_least32_t base_type; + base_type t; +public: + // should be private - but MPI fails if it's not!!! + version_type(): t(0) {}; + explicit version_type(const unsigned int & t_) : t(t_){ + BOOST_ASSERT(t_ <= boost::integer_traits::const_max); + } + version_type(const version_type & t_) : + t(t_.t) + {} + version_type & operator=(const version_type & rhs){ + t = rhs.t; + return *this; + } + // used for text output + operator base_type () const { + return t; + } + // used for text intput + operator base_type & (){ + return t; + } + bool operator==(const version_type & rhs) const { + return t == rhs.t; + } + bool operator<(const version_type & rhs) const { + return t < rhs.t; + } +}; + +class class_id_type { +private: + typedef int_least16_t base_type; + base_type t; +public: + // should be private - but then can't use BOOST_STRONG_TYPE below + class_id_type() : t(0) {}; + explicit class_id_type(const int t_) : t(t_){ + BOOST_ASSERT(t_ <= boost::integer_traits::const_max); + } + explicit class_id_type(const std::size_t t_) : t(t_){ + // BOOST_ASSERT(t_ <= boost::integer_traits::const_max); + } + class_id_type(const class_id_type & t_) : + t(t_.t) + {} + class_id_type & operator=(const class_id_type & rhs){ + t = rhs.t; + return *this; + } + + // used for text output + operator int () const { + return t; + } + // used for text input + operator int_least16_t &() { + return t; + } + bool operator==(const class_id_type & rhs) const { + return t == rhs.t; + } + bool operator<(const class_id_type & rhs) const { + return t < rhs.t; + } +}; + +#define NULL_POINTER_TAG boost::archive::class_id_type(-1) + +class object_id_type { +private: + typedef uint_least32_t base_type; + base_type t; +public: + object_id_type(): t(0) {}; + // note: presumes that size_t >= unsigned int. + explicit object_id_type(const std::size_t & t_) : t(t_){ + BOOST_ASSERT(t_ <= boost::integer_traits::const_max); + } + object_id_type(const object_id_type & t_) : + t(t_.t) + {} + object_id_type & operator=(const object_id_type & rhs){ + t = rhs.t; + return *this; + } + // used for text output + operator uint_least32_t () const { + return t; + } + // used for text input + operator uint_least32_t & () { + return t; + } + bool operator==(const object_id_type & rhs) const { + return t == rhs.t; + } + bool operator<(const object_id_type & rhs) const { + return t < rhs.t; + } +}; + +#if defined(_MSC_VER) +#pragma warning( pop ) +#endif + +struct tracking_type { + bool t; + explicit tracking_type(const bool t_ = false) + : t(t_) + {}; + tracking_type(const tracking_type & t_) + : t(t_.t) + {} + operator bool () const { + return t; + }; + operator bool & () { + return t; + }; + tracking_type & operator=(const bool t_){ + t = t_; + return *this; + } + bool operator==(const tracking_type & rhs) const { + return t == rhs.t; + } + bool operator==(const bool & rhs) const { + return t == rhs; + } + tracking_type & operator=(const tracking_type & rhs){ + t = rhs.t; + return *this; + } +}; + +struct class_name_type : + private boost::noncopyable +{ + char *t; + operator const char * & () const { + return const_cast(t); + } + operator char * () { + return t; + } + std::size_t size() const { + return std::strlen(t); + } + explicit class_name_type(const char *key_) + : t(const_cast(key_)){} + explicit class_name_type(char *key_) + : t(key_){} + class_name_type & operator=(const class_name_type & rhs){ + t = rhs.t; + return *this; + } +}; + +enum archive_flags { + no_header = 1, // suppress archive header info + no_codecvt = 2, // suppress alteration of codecvt facet + no_xml_tag_checking = 4, // suppress checking of xml tags + no_tracking = 8, // suppress ALL tracking + flags_last = 8 +}; + +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_SIGNATURE(); + +/* NOTE : Warning : Warning : Warning : Warning : Warning + * If any of these are changed to different sized types, + * binary_iarchive won't be able to read older archives + * unless you rev the library version and include conditional + * code based on the library version. There is nothing + * inherently wrong in doing this - but you have to be super + * careful because it's easy to get wrong and start breaking + * old archives !!! + */ + +#define BOOST_ARCHIVE_STRONG_TYPEDEF(T, D) \ + class D : public T { \ + public: \ + explicit D(const T tt) : T(tt){} \ + }; \ +/**/ + +BOOST_ARCHIVE_STRONG_TYPEDEF(class_id_type, class_id_reference_type) +BOOST_ARCHIVE_STRONG_TYPEDEF(class_id_type, class_id_optional_type) +BOOST_ARCHIVE_STRONG_TYPEDEF(object_id_type, object_reference_type) + +}// namespace archive +}// namespace boost + +#include // pops abi_suffix.hpp pragmas + +#include + +// set implementation level to primitive for all types +// used internally by the serialization library + +BOOST_CLASS_IMPLEMENTATION(boost::archive::library_version_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::version_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::class_id_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::class_id_reference_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::class_id_optional_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::class_name_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::object_id_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::object_reference_type, primitive_type) +BOOST_CLASS_IMPLEMENTATION(boost::archive::tracking_type, primitive_type) + +#include + +// set types used internally by the serialization library +// to be bitwise serializable + +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::library_version_type) +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::version_type) +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::class_id_type) +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::class_id_reference_type) +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::class_id_optional_type) +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::class_name_type) +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::object_id_type) +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::object_reference_type) +BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::tracking_type) + +#endif //BOOST_ARCHIVE_BASIC_ARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iarchive.hpp new file mode 100644 index 00000000000..c0cc655c997 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iarchive.hpp @@ -0,0 +1,204 @@ +#ifndef BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_iarchive.hpp +// +// archives stored as native binary - this should be the fastest way +// to archive the state of a group of obects. It makes no attempt to +// convert to any canonical form. + +// IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE +// ON PLATFORM APART FROM THE ONE THEY ARE CREATED ON + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +#include // must be the last header + +namespace boost { +namespace archive { + +namespace detail { + template class interface_iarchive; +} // namespace detail + +///////////////////////////////////////////////////////////////////////// +// class basic_binary_iarchive - read serialized objects from a input binary stream +template +class BOOST_SYMBOL_VISIBLE basic_binary_iarchive : + public detail::common_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_iarchive; + #else + friend class detail::interface_iarchive; + #endif +#endif + // intermediate level to support override of operators + // fot templates in the absence of partial function + // template ordering. If we get here pass to base class + // note extra nonsense to sneak it pass the borland compiers + typedef detail::common_iarchive detail_common_iarchive; + template + void load_override(T & t){ + this->detail_common_iarchive::load_override(t); + } + + // include these to trap a change in binary format which + // isn't specifically handled + // upto 32K classes + BOOST_STATIC_ASSERT(sizeof(class_id_type) == sizeof(int_least16_t)); + BOOST_STATIC_ASSERT(sizeof(class_id_reference_type) == sizeof(int_least16_t)); + // upto 2G objects + BOOST_STATIC_ASSERT(sizeof(object_id_type) == sizeof(uint_least32_t)); + BOOST_STATIC_ASSERT(sizeof(object_reference_type) == sizeof(uint_least32_t)); + + // binary files don't include the optional information + void load_override(class_id_optional_type & /* t */){} + + void load_override(tracking_type & t, int /*version*/){ + library_version_type lvt = this->get_library_version(); + if(boost::archive::library_version_type(6) < lvt){ + int_least8_t x=0; + * this->This() >> x; + t = boost::archive::tracking_type(x); + } + else{ + bool x=0; + * this->This() >> x; + t = boost::archive::tracking_type(x); + } + } + void load_override(class_id_type & t){ + library_version_type lvt = this->get_library_version(); + if(boost::archive::library_version_type(7) < lvt){ + this->detail_common_iarchive::load_override(t); + } + else + if(boost::archive::library_version_type(6) < lvt){ + int_least16_t x=0; + * this->This() >> x; + t = boost::archive::class_id_type(x); + } + else{ + int x=0; + * this->This() >> x; + t = boost::archive::class_id_type(x); + } + } + void load_override(class_id_reference_type & t){ + load_override(static_cast(t)); + } + + void load_override(version_type & t){ + library_version_type lvt = this->get_library_version(); + if(boost::archive::library_version_type(7) < lvt){ + this->detail_common_iarchive::load_override(t); + } + else + if(boost::archive::library_version_type(6) < lvt){ + uint_least8_t x=0; + * this->This() >> x; + t = boost::archive::version_type(x); + } + else + if(boost::archive::library_version_type(5) < lvt){ + uint_least16_t x=0; + * this->This() >> x; + t = boost::archive::version_type(x); + } + else + if(boost::archive::library_version_type(2) < lvt){ + // upto 255 versions + unsigned char x=0; + * this->This() >> x; + t = version_type(x); + } + else{ + unsigned int x=0; + * this->This() >> x; + t = boost::archive::version_type(x); + } + } + + void load_override(boost::serialization::item_version_type & t){ + library_version_type lvt = this->get_library_version(); +// if(boost::archive::library_version_type(7) < lvt){ + if(boost::archive::library_version_type(6) < lvt){ + this->detail_common_iarchive::load_override(t); + } + else + if(boost::archive::library_version_type(6) < lvt){ + uint_least16_t x=0; + * this->This() >> x; + t = boost::serialization::item_version_type(x); + } + else{ + unsigned int x=0; + * this->This() >> x; + t = boost::serialization::item_version_type(x); + } + } + + void load_override(serialization::collection_size_type & t){ + if(boost::archive::library_version_type(5) < this->get_library_version()){ + this->detail_common_iarchive::load_override(t); + } + else{ + unsigned int x=0; + * this->This() >> x; + t = serialization::collection_size_type(x); + } + } + + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_override(class_name_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + init(); + + basic_binary_iarchive(unsigned int flags) : + detail::common_iarchive(flags) + {} +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iprimitive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iprimitive.hpp new file mode 100644 index 00000000000..665d3e81e1f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iprimitive.hpp @@ -0,0 +1,198 @@ +#ifndef BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP +#define BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +#if defined(_MSC_VER) +#pragma warning( disable : 4800 ) +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_iprimitive.hpp +// +// archives stored as native binary - this should be the fastest way +// to archive the state of a group of obects. It makes no attempt to +// convert to any canonical form. + +// IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE +// ON PLATFORM APART FROM THE ONE THEY ARE CREATED ON + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include // std::memcpy +#include // std::size_t +#include // basic_streambuf +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include + +//#include +#include +#include + +#include +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace archive { + +///////////////////////////////////////////////////////////////////////////// +// class binary_iarchive - read serialized objects from a input binary stream +template +class BOOST_SYMBOL_VISIBLE basic_binary_iprimitive { +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + friend class load_access; +protected: +#else +public: +#endif + std::basic_streambuf & m_sb; + // return a pointer to the most derived class + Archive * This(){ + return static_cast(this); + } + + #ifndef BOOST_NO_STD_LOCALE + // note order! - if you change this, libstd++ will fail! + // a) create new locale with new codecvt facet + // b) save current locale + // c) change locale to new one + // d) use stream buffer + // e) change locale back to original + // f) destroy new codecvt facet + boost::archive::codecvt_null codecvt_null_facet; + basic_streambuf_locale_saver locale_saver; + std::locale archive_locale; + #endif + + // main template for serilization of primitive types + template + void load(T & t){ + load_binary(& t, sizeof(T)); + } + + ///////////////////////////////////////////////////////// + // fundamental types that need special treatment + + // trap usage of invalid uninitialized boolean + void load(bool & t){ + load_binary(& t, sizeof(t)); + int i = t; + BOOST_ASSERT(0 == i || 1 == i); + (void)i; // warning suppression for release builds. + } + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load(std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load(std::wstring &ws); + #endif + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load(char * t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load(wchar_t * t); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + init(); + BOOST_ARCHIVE_OR_WARCHIVE_DECL + basic_binary_iprimitive( + std::basic_streambuf & sb, + bool no_codecvt + ); + BOOST_ARCHIVE_OR_WARCHIVE_DECL + ~basic_binary_iprimitive(); +public: + // we provide an optimized load for all fundamental types + // typedef serialization::is_bitwise_serializable + // use_array_optimization; + struct use_array_optimization { + template + #if defined(BOOST_NO_DEPENDENT_NESTED_DERIVATIONS) + struct apply { + typedef typename boost::serialization::is_bitwise_serializable< T >::type type; + }; + #else + struct apply : public boost::serialization::is_bitwise_serializable< T > {}; + #endif + }; + + // the optimized load_array dispatches to load_binary + template + void load_array(serialization::array_wrapper& a, unsigned int) + { + load_binary(a.address(),a.count()*sizeof(ValueType)); + } + + void + load_binary(void *address, std::size_t count); +}; + +template +inline void +basic_binary_iprimitive::load_binary( + void *address, + std::size_t count +){ + // note: an optimizer should eliminate the following for char files + BOOST_ASSERT( + static_cast(count / sizeof(Elem)) + <= boost::integer_traits::const_max + ); + std::streamsize s = static_cast(count / sizeof(Elem)); + std::streamsize scount = m_sb.sgetn( + static_cast(address), + s + ); + if(scount != s) + boost::serialization::throw_exception( + archive_exception(archive_exception::input_stream_error) + ); + // note: an optimizer should eliminate the following for char files + BOOST_ASSERT(count % sizeof(Elem) <= boost::integer_traits::const_max); + s = static_cast(count % sizeof(Elem)); + if(0 < s){ +// if(is.fail()) +// boost::serialization::throw_exception( +// archive_exception(archive_exception::stream_error) +// ); + Elem t; + scount = m_sb.sgetn(& t, 1); + if(scount != 1) + boost::serialization::throw_exception( + archive_exception(archive_exception::input_stream_error) + ); + std::memcpy(static_cast(address) + (count - s), &t, static_cast(s)); + } +} + +} // namespace archive +} // namespace boost + +#include // pop pragmas + +#endif // BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oarchive.hpp new file mode 100644 index 00000000000..f05f2f86d55 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oarchive.hpp @@ -0,0 +1,185 @@ +#ifndef BOOST_ARCHIVE_BASIC_BINARY_OARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_BINARY_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as native binary - this should be the fastest way +// to archive the state of a group of obects. It makes no attempt to +// convert to any canonical form. + +// IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE +// ON PLATFORM APART FROM THE ONE THEY ARE CREATE ON + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_oarchive; +} // namespace detail + +////////////////////////////////////////////////////////////////////// +// class basic_binary_oarchive - write serialized objects to a binary output stream +// note: this archive has no pretensions to portability. Archive format +// may vary across machine architectures and compilers. About the only +// guarentee is that an archive created with this code will be readable +// by a program built with the same tools for the same machne. This class +// does have the virtue of buiding the smalles archive in the minimum amount +// of time. So under some circumstances it may be he right choice. +template +class BOOST_SYMBOL_VISIBLE basic_binary_oarchive : + public detail::common_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_oarchive; + #else + friend class detail::interface_oarchive; + #endif +#endif + // any datatype not specifed below will be handled by base class + typedef detail::common_oarchive detail_common_oarchive; + template + void save_override(const T & t){ + this->detail_common_oarchive::save_override(t); + } + + // include these to trap a change in binary format which + // isn't specifically handled + BOOST_STATIC_ASSERT(sizeof(tracking_type) == sizeof(bool)); + // upto 32K classes + BOOST_STATIC_ASSERT(sizeof(class_id_type) == sizeof(int_least16_t)); + BOOST_STATIC_ASSERT(sizeof(class_id_reference_type) == sizeof(int_least16_t)); + // upto 2G objects + BOOST_STATIC_ASSERT(sizeof(object_id_type) == sizeof(uint_least32_t)); + BOOST_STATIC_ASSERT(sizeof(object_reference_type) == sizeof(uint_least32_t)); + + // binary files don't include the optional information + void save_override(const class_id_optional_type & /* t */){} + + // enable this if we decide to support generation of previous versions + #if 0 + void save_override(const boost::archive::version_type & t){ + library_version_type lvt = this->get_library_version(); + if(boost::archive::library_version_type(7) < lvt){ + this->detail_common_oarchive::save_override(t); + } + else + if(boost::archive::library_version_type(6) < lvt){ + const boost::uint_least16_t x = t; + * this->This() << x; + } + else{ + const unsigned int x = t; + * this->This() << x; + } + } + void save_override(const boost::serialization::item_version_type & t){ + library_version_type lvt = this->get_library_version(); + if(boost::archive::library_version_type(7) < lvt){ + this->detail_common_oarchive::save_override(t); + } + else + if(boost::archive::library_version_type(6) < lvt){ + const boost::uint_least16_t x = t; + * this->This() << x; + } + else{ + const unsigned int x = t; + * this->This() << x; + } + } + + void save_override(class_id_type & t){ + library_version_type lvt = this->get_library_version(); + if(boost::archive::library_version_type(7) < lvt){ + this->detail_common_oarchive::save_override(t); + } + else + if(boost::archive::library_version_type(6) < lvt){ + const boost::int_least16_t x = t; + * this->This() << x; + } + else{ + const int x = t; + * this->This() << x; + } + } + void save_override(class_id_reference_type & t){ + save_override(static_cast(t)); + } + + #endif + + // explicitly convert to char * to avoid compile ambiguities + void save_override(const class_name_type & t){ + const std::string s(t); + * this->This() << s; + } + + #if 0 + void save_override(const serialization::collection_size_type & t){ + if (get_library_version() < boost::archive::library_version_type(6)){ + unsigned int x=0; + * this->This() >> x; + t = serialization::collection_size_type(x); + } + else{ + * this->This() >> t; + } + } + #endif + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + init(); + + basic_binary_oarchive(unsigned int flags) : + detail::common_oarchive(flags) + {} +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_BINARY_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oprimitive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oprimitive.hpp new file mode 100644 index 00000000000..6dc770c60e8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oprimitive.hpp @@ -0,0 +1,188 @@ +#ifndef BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP +#define BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_oprimitive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as native binary - this should be the fastest way +// to archive the state of a group of obects. It makes no attempt to +// convert to any canonical form. + +// IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE +// ON PLATFORM APART FROM THE ONE THEY ARE CREATE ON + +#include +#include +#include +#include // basic_streambuf +#include +#include // size_t + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include +#include + +//#include +#include +#include + +#include +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace archive { + +///////////////////////////////////////////////////////////////////////// +// class basic_binary_oprimitive - binary output of prmitives + +template +class BOOST_SYMBOL_VISIBLE basic_binary_oprimitive { +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + friend class save_access; +protected: +#else +public: +#endif + std::basic_streambuf & m_sb; + // return a pointer to the most derived class + Archive * This(){ + return static_cast(this); + } + #ifndef BOOST_NO_STD_LOCALE + // note order! - if you change this, libstd++ will fail! + // a) create new locale with new codecvt facet + // b) save current locale + // c) change locale to new one + // d) use stream buffer + // e) change locale back to original + // f) destroy new codecvt facet + boost::archive::codecvt_null codecvt_null_facet; + basic_streambuf_locale_saver locale_saver; + std::locale archive_locale; + #endif + // default saving of primitives. + template + void save(const T & t) + { + save_binary(& t, sizeof(T)); + } + + ///////////////////////////////////////////////////////// + // fundamental types that need special treatment + + // trap usage of invalid uninitialized boolean which would + // otherwise crash on load. + void save(const bool t){ + BOOST_ASSERT(0 == static_cast(t) || 1 == static_cast(t)); + save_binary(& t, sizeof(t)); + } + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save(const std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save(const std::wstring &ws); + #endif + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save(const char * t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save(const wchar_t * t); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + init(); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL + basic_binary_oprimitive( + std::basic_streambuf & sb, + bool no_codecvt + ); + BOOST_ARCHIVE_OR_WARCHIVE_DECL + ~basic_binary_oprimitive(); +public: + + // we provide an optimized save for all fundamental types + // typedef serialization::is_bitwise_serializable + // use_array_optimization; + // workaround without using mpl lambdas + struct use_array_optimization { + template + #if defined(BOOST_NO_DEPENDENT_NESTED_DERIVATIONS) + struct apply { + typedef typename boost::serialization::is_bitwise_serializable< T >::type type; + }; + #else + struct apply : public boost::serialization::is_bitwise_serializable< T > {}; + #endif + }; + + // the optimized save_array dispatches to save_binary + template + void save_array(boost::serialization::array_wrapper const& a, unsigned int) + { + save_binary(a.address(),a.count()*sizeof(ValueType)); + } + + void save_binary(const void *address, std::size_t count); +}; + +template +inline void +basic_binary_oprimitive::save_binary( + const void *address, + std::size_t count +){ + // BOOST_ASSERT(count <= std::size_t(boost::integer_traits::const_max)); + // note: if the following assertions fail + // a likely cause is that the output stream is set to "text" + // mode where by cr characters recieve special treatment. + // be sure that the output stream is opened with ios::binary + //if(os.fail()) + // boost::serialization::throw_exception( + // archive_exception(archive_exception::output_stream_error) + // ); + // figure number of elements to output - round up + count = ( count + sizeof(Elem) - 1) / sizeof(Elem); + std::streamsize scount = m_sb.sputn( + static_cast(address), + static_cast(count) + ); + if(count != static_cast(scount)) + boost::serialization::throw_exception( + archive_exception(archive_exception::output_stream_error) + ); + //os.write( + // static_cast(address), + // count + //); + //BOOST_ASSERT(os.good()); +} + +} //namespace boost +} //namespace archive + +#include // pop pragmas + +#endif // BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_streambuf_locale_saver.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_streambuf_locale_saver.hpp new file mode 100644 index 00000000000..5cd4b36f081 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_streambuf_locale_saver.hpp @@ -0,0 +1,108 @@ +#ifndef BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_HPP +#define BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_streambuf_locale_saver.hpp + +// (C) Copyright 2005 Robert Ramey - http://www.rrsd.com + +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// note derived from boost/io/ios_state.hpp +// Copyright 2002, 2005 Daryle Walker. Use, modification, and distribution +// are subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or a copy at .) + +// See for the library's home page. + +#ifndef BOOST_NO_STD_LOCALE + +#include // for std::locale +#include +#include // for std::basic_streambuf + +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost{ +namespace archive{ + +template < typename Ch, class Tr > +class basic_streambuf_locale_saver : + private boost::noncopyable +{ +public: + explicit basic_streambuf_locale_saver(std::basic_streambuf &s) : + m_streambuf(s), + m_locale(s.getloc()) + {} + ~basic_streambuf_locale_saver(){ + m_streambuf.pubsync(); + m_streambuf.pubimbue(m_locale); + } +private: + std::basic_streambuf & m_streambuf; + std::locale const m_locale; +}; + +template < typename Ch, class Tr > +class basic_istream_locale_saver : + private boost::noncopyable +{ +public: + explicit basic_istream_locale_saver(std::basic_istream &s) : + m_istream(s), + m_locale(s.getloc()) + {} + ~basic_istream_locale_saver(){ + // libstdc++ crashes without this + m_istream.sync(); + m_istream.imbue(m_locale); + } +private: + std::basic_istream & m_istream; + std::locale const m_locale; +}; + +template < typename Ch, class Tr > +class basic_ostream_locale_saver : + private boost::noncopyable +{ +public: + explicit basic_ostream_locale_saver(std::basic_ostream &s) : + m_ostream(s), + m_locale(s.getloc()) + {} + ~basic_ostream_locale_saver(){ + m_ostream.flush(); + m_ostream.imbue(m_locale); + } +private: + std::basic_ostream & m_ostream; + std::locale const m_locale; +}; + + +} // archive +} // boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_NO_STD_LOCALE +#endif // BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iarchive.hpp new file mode 100644 index 00000000000..48a646cc1f7 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iarchive.hpp @@ -0,0 +1,96 @@ +#ifndef BOOST_ARCHIVE_BASIC_TEXT_IARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_TEXT_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as text - note these ar templated on the basic +// stream templates to accommodate wide (and other?) kind of characters +// +// note the fact that on libraries without wide characters, ostream is +// is not a specialization of basic_ostream which in fact is not defined +// in such cases. So we can't use basic_istream but rather +// use two template parameters + +#include +#include + +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_iarchive; +} // namespace detail + +///////////////////////////////////////////////////////////////////////// +// class basic_text_iarchive - read serialized objects from a input text stream +template +class BOOST_SYMBOL_VISIBLE basic_text_iarchive : + public detail::common_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_iarchive; + #else + friend class detail::interface_iarchive; + #endif +#endif + // intermediate level to support override of operators + // fot templates in the absence of partial function + // template ordering + typedef detail::common_iarchive detail_common_iarchive; + template + void load_override(T & t){ + this->detail_common_iarchive::load_override(t); + } + // text file don't include the optional information + void load_override(class_id_optional_type & /*t*/){} + + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_override(class_name_type & t); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + init(void); + + basic_text_iarchive(unsigned int flags) : + detail::common_iarchive(flags) + {} + ~basic_text_iarchive(){} +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_TEXT_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iprimitive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iprimitive.hpp new file mode 100644 index 00000000000..bf936b55546 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iprimitive.hpp @@ -0,0 +1,142 @@ +#ifndef BOOST_ARCHIVE_BASIC_TEXT_IPRIMITIVE_HPP +#define BOOST_ARCHIVE_BASIC_TEXT_IPRIMITIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_iprimitive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as text - note these are templated on the basic +// stream templates to accommodate wide (and other?) kind of characters +// +// Note the fact that on libraries without wide characters, ostream is +// not a specialization of basic_ostream which in fact is not defined +// in such cases. So we can't use basic_ostream but rather +// use two template parameters + +#include +#include // size_t + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; + #if ! defined(BOOST_DINKUMWARE_STDLIB) && ! defined(__SGI_STL_PORT) + using ::locale; + #endif +} // namespace std +#endif + +#include +#include + +#include +#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) +#include +#endif +#include +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace archive { + +///////////////////////////////////////////////////////////////////////// +// class basic_text_iarchive - load serialized objects from a input text stream +#if defined(_MSC_VER) +#pragma warning( push ) +#pragma warning( disable : 4244 4267 ) +#endif + +template +class BOOST_SYMBOL_VISIBLE basic_text_iprimitive { +protected: + IStream &is; + io::ios_flags_saver flags_saver; + io::ios_precision_saver precision_saver; + + #ifndef BOOST_NO_STD_LOCALE + // note order! - if you change this, libstd++ will fail! + // a) create new locale with new codecvt facet + // b) save current locale + // c) change locale to new one + // d) use stream buffer + // e) change locale back to original + // f) destroy new codecvt facet + boost::archive::codecvt_null codecvt_null_facet; + std::locale archive_locale; + basic_istream_locale_saver< + typename IStream::char_type, + typename IStream::traits_type + > locale_saver; + #endif + + template + void load(T & t) + { + if(is >> t) + return; + boost::serialization::throw_exception( + archive_exception(archive_exception::input_stream_error) + ); + } + + void load(char & t) + { + short int i; + load(i); + t = i; + } + void load(signed char & t) + { + short int i; + load(i); + t = i; + } + void load(unsigned char & t) + { + unsigned short int i; + load(i); + t = i; + } + + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + void load(wchar_t & t) + { + BOOST_STATIC_ASSERT(sizeof(wchar_t) <= sizeof(int)); + int i; + load(i); + t = i; + } + #endif + BOOST_ARCHIVE_OR_WARCHIVE_DECL + basic_text_iprimitive(IStream &is, bool no_codecvt); + BOOST_ARCHIVE_OR_WARCHIVE_DECL + ~basic_text_iprimitive(); +public: + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_binary(void *address, std::size_t count); +}; + +#if defined(_MSC_VER) +#pragma warning( pop ) +#endif + +} // namespace archive +} // namespace boost + +#include // pop pragmas + +#endif // BOOST_ARCHIVE_BASIC_TEXT_IPRIMITIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oarchive.hpp new file mode 100644 index 00000000000..6f7f8fb167d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oarchive.hpp @@ -0,0 +1,119 @@ +#ifndef BOOST_ARCHIVE_BASIC_TEXT_OARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_TEXT_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as text - note these ar templated on the basic +// stream templates to accommodate wide (and other?) kind of characters +// +// note the fact that on libraries without wide characters, ostream is +// is not a specialization of basic_ostream which in fact is not defined +// in such cases. So we can't use basic_ostream but rather +// use two template parameters + +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_oarchive; +} // namespace detail + +///////////////////////////////////////////////////////////////////////// +// class basic_text_oarchive +template +class BOOST_SYMBOL_VISIBLE basic_text_oarchive : + public detail::common_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_oarchive; + #else + friend class detail::interface_oarchive; + #endif +#endif + + enum { + none, + eol, + space + } delimiter; + + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + newtoken(); + + void newline(){ + delimiter = eol; + } + + // default processing - kick back to base class. Note the + // extra stuff to get it passed borland compilers + typedef detail::common_oarchive detail_common_oarchive; + template + void save_override(T & t){ + this->detail_common_oarchive::save_override(t); + } + + // start new objects on a new line + void save_override(const object_id_type & t){ + this->This()->newline(); + this->detail_common_oarchive::save_override(t); + } + + // text file don't include the optional information + void save_override(const class_id_optional_type & /* t */){} + + void save_override(const class_name_type & t){ + const std::string s(t); + * this->This() << s; + } + + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + init(); + + basic_text_oarchive(unsigned int flags) : + detail::common_oarchive(flags), + delimiter(none) + {} + ~basic_text_oarchive(){} +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_TEXT_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oprimitive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oprimitive.hpp new file mode 100644 index 00000000000..45f09358ece --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oprimitive.hpp @@ -0,0 +1,209 @@ +#ifndef BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP +#define BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_oprimitive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// archives stored as text - note these ar templated on the basic +// stream templates to accommodate wide (and other?) kind of characters +// +// note the fact that on libraries without wide characters, ostream is +// is not a specialization of basic_ostream which in fact is not defined +// in such cases. So we can't use basic_ostream but rather +// use two template parameters + +#include +#include +#include // size_t + +#include +#include +#include + +#include +#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) +#include +#endif + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; + #if ! defined(BOOST_DINKUMWARE_STDLIB) && ! defined(__SGI_STL_PORT) + using ::locale; + #endif +} // namespace std +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace archive { + +///////////////////////////////////////////////////////////////////////// +// class basic_text_oprimitive - output of prmitives to stream +template +class BOOST_SYMBOL_VISIBLE basic_text_oprimitive +{ +protected: + OStream &os; + io::ios_flags_saver flags_saver; + io::ios_precision_saver precision_saver; + + #ifndef BOOST_NO_STD_LOCALE + // note order! - if you change this, libstd++ will fail! + // a) create new locale with new codecvt facet + // b) save current locale + // c) change locale to new one + // d) use stream buffer + // e) change locale back to original + // f) destroy new codecvt facet + boost::archive::codecvt_null codecvt_null_facet; + std::locale archive_locale; + basic_ostream_locale_saver< + typename OStream::char_type, + typename OStream::traits_type + > locale_saver; + #endif + + ///////////////////////////////////////////////////////// + // fundamental types that need special treatment + void save(const bool t){ + // trap usage of invalid uninitialized boolean which would + // otherwise crash on load. + BOOST_ASSERT(0 == static_cast(t) || 1 == static_cast(t)); + if(os.fail()) + boost::serialization::throw_exception( + archive_exception(archive_exception::output_stream_error) + ); + os << t; + } + void save(const signed char t) + { + save(static_cast(t)); + } + void save(const unsigned char t) + { + save(static_cast(t)); + } + void save(const char t) + { + save(static_cast(t)); + } + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + void save(const wchar_t t) + { + BOOST_STATIC_ASSERT(sizeof(wchar_t) <= sizeof(int)); + save(static_cast(t)); + } + #endif + + ///////////////////////////////////////////////////////// + // saving of any types not listed above + + template + void save_impl(const T &t, boost::mpl::bool_ &){ + if(os.fail()) + boost::serialization::throw_exception( + archive_exception(archive_exception::output_stream_error) + ); + os << t; + } + + ///////////////////////////////////////////////////////// + // floating point types need even more special treatment + // the following determines whether the type T is some sort + // of floating point type. Note that we then assume that + // the stream << operator is defined on that type - if not + // we'll get a compile time error. This is meant to automatically + // support synthesized types which support floating point + // operations. Also it should handle compiler dependent types + // such long double. Due to John Maddock. + + template + struct is_float { + typedef typename mpl::bool_< + boost::is_floating_point::value + || (std::numeric_limits::is_specialized + && !std::numeric_limits::is_integer + && !std::numeric_limits::is_exact + && std::numeric_limits::max_exponent) + >::type type; + }; + + template + void save_impl(const T &t, boost::mpl::bool_ &){ + // must be a user mistake - can't serialize un-initialized data + if(os.fail()) + boost::serialization::throw_exception( + archive_exception(archive_exception::output_stream_error) + ); + // The formulae for the number of decimla digits required is given in + // http://www2.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1822.pdf + // which is derived from Kahan's paper: + // www.eecs.berkeley.edu/~wkahan/ieee754status/ieee754.ps + // const unsigned int digits = (std::numeric_limits::digits * 3010) / 10000; + // note: I've commented out the above because I didn't get good results. e.g. + // in one case I got a difference of 19 units. + #ifndef BOOST_NO_CXX11_NUMERIC_LIMITS + const unsigned int digits = std::numeric_limits::max_digits10; + #else + const unsigned int digits = std::numeric_limits::digits10 + 2; + #endif + os << std::setprecision(digits) << std::scientific << t; + } + + template + void save(const T & t){ + typename is_float::type tf; + save_impl(t, tf); + } + + BOOST_ARCHIVE_OR_WARCHIVE_DECL + basic_text_oprimitive(OStream & os, bool no_codecvt); + BOOST_ARCHIVE_OR_WARCHIVE_DECL + ~basic_text_oprimitive(); +public: + // unformatted append of one character + void put(typename OStream::char_type c){ + if(os.fail()) + boost::serialization::throw_exception( + archive_exception(archive_exception::output_stream_error) + ); + os.put(c); + } + // unformatted append of null terminated string + void put(const char * s){ + while('\0' != *s) + os.put(*s++); + } + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_binary(const void *address, std::size_t count); +}; + +} //namespace boost +} //namespace archive + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_archive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_archive.hpp new file mode 100644 index 00000000000..bef368b973b --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_archive.hpp @@ -0,0 +1,67 @@ +#ifndef BOOST_ARCHIVE_BASIC_XML_TEXT_ARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_XML_TEXT_ARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_archive.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include // must be the last header + +namespace boost { +namespace archive { + +// constant strings used in xml i/o + +extern +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_XML_OBJECT_ID(); + +extern +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_XML_OBJECT_REFERENCE(); + +extern +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_XML_CLASS_ID(); + +extern +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_XML_CLASS_ID_REFERENCE(); + +extern +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_XML_CLASS_NAME(); + +extern +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_XML_TRACKING(); + +extern +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_XML_VERSION(); + +extern +BOOST_ARCHIVE_DECL const char * +BOOST_ARCHIVE_XML_SIGNATURE(); + +}// namespace archive +}// namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_XML_TEXT_ARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_iarchive.hpp new file mode 100644 index 00000000000..e9f7482f744 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_iarchive.hpp @@ -0,0 +1,119 @@ +#ifndef BOOST_ARCHIVE_BASIC_XML_IARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_XML_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_iarchive; +} // namespace detail + +///////////////////////////////////////////////////////////////////////// +// class basic_xml_iarchive - read serialized objects from a input text stream +template +class BOOST_SYMBOL_VISIBLE basic_xml_iarchive : + public detail::common_iarchive +{ + unsigned int depth; +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + friend class detail::interface_iarchive; +#endif + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_start(const char *name); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_end(const char *name); + + // Anything not an attribute and not a name-value pair is an + // should be trapped here. + template + void load_override(T & t) + { + // If your program fails to compile here, its most likely due to + // not specifying an nvp wrapper around the variable to + // be serialized. + BOOST_MPL_ASSERT((serialization::is_wrapper< T >)); + this->detail_common_iarchive::load_override(t); + } + + // Anything not an attribute - see below - should be a name value + // pair and be processed here + typedef detail::common_iarchive detail_common_iarchive; + template + void load_override( + const boost::serialization::nvp< T > & t + ){ + this->This()->load_start(t.name()); + this->detail_common_iarchive::load_override(t.value()); + this->This()->load_end(t.name()); + } + + // specific overrides for attributes - handle as + // primitives. These are not name-value pairs + // so they have to be intercepted here and passed on to load. + // although the class_id is included in the xml text file in order + // to make the file self describing, it isn't used when loading + // an xml archive. So we can skip it here. Note: we MUST override + // it otherwise it will be loaded as a normal primitive w/o tag and + // leaving the archive in an undetermined state + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_override(class_id_type & t); + void load_override(class_id_optional_type & /* t */){} + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_override(object_id_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_override(version_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + load_override(tracking_type & t); + // class_name_type can't be handled here as it depends upon the + // char type used by the stream. So require the derived implementation + // handle this. + // void load_override(class_name_type & t); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL + basic_xml_iarchive(unsigned int flags); + BOOST_ARCHIVE_OR_WARCHIVE_DECL + ~basic_xml_iarchive(); +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_XML_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_oarchive.hpp new file mode 100644 index 00000000000..107fca4ec65 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_oarchive.hpp @@ -0,0 +1,138 @@ +#ifndef BOOST_ARCHIVE_BASIC_XML_OARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_XML_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_oarchive; +} // namespace detail + +////////////////////////////////////////////////////////////////////// +// class basic_xml_oarchive - write serialized objects to a xml output stream +template +class BOOST_SYMBOL_VISIBLE basic_xml_oarchive : + public detail::common_oarchive +{ + // special stuff for xml output + unsigned int depth; + bool pending_preamble; +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + friend class detail::interface_oarchive; +#endif + bool indent_next; + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + indent(); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + init(); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + windup(); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + write_attribute( + const char *attribute_name, + int t, + const char *conjunction = "=\"" + ); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + write_attribute( + const char *attribute_name, + const char *key + ); + // helpers used below + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_start(const char *name); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_end(const char *name); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + end_preamble(); + + // Anything not an attribute and not a name-value pair is an + // error and should be trapped here. + template + void save_override(T & t) + { + // If your program fails to compile here, its most likely due to + // not specifying an nvp wrapper around the variable to + // be serialized. + BOOST_MPL_ASSERT((serialization::is_wrapper< T >)); + this->detail_common_oarchive::save_override(t); + } + + // special treatment for name-value pairs. + typedef detail::common_oarchive detail_common_oarchive; + template + void save_override( + const ::boost::serialization::nvp< T > & t + ){ + this->This()->save_start(t.name()); + this->detail_common_oarchive::save_override(t.const_value()); + this->This()->save_end(t.name()); + } + + // specific overrides for attributes - not name value pairs so we + // want to trap them before the above "fall through" + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_override(const class_id_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_override(const class_id_optional_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_override(const class_id_reference_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_override(const object_id_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_override(const object_reference_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_override(const version_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_override(const class_name_type & t); + BOOST_ARCHIVE_OR_WARCHIVE_DECL void + save_override(const tracking_type & t); + + BOOST_ARCHIVE_OR_WARCHIVE_DECL + basic_xml_oarchive(unsigned int flags); + BOOST_ARCHIVE_OR_WARCHIVE_DECL + ~basic_xml_oarchive(); +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_XML_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive.hpp new file mode 100644 index 00000000000..785ce7610b1 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive.hpp @@ -0,0 +1,64 @@ +#ifndef BOOST_ARCHIVE_BINARY_IARCHIVE_HPP +#define BOOST_ARCHIVE_BINARY_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from binary_iarchive_impl instead. This will +// preserve correct static polymorphism. +class BOOST_SYMBOL_VISIBLE binary_iarchive : + public binary_iarchive_impl< + boost::archive::binary_iarchive, + std::istream::char_type, + std::istream::traits_type + >{ +public: + binary_iarchive(std::istream & is, unsigned int flags = 0) : + binary_iarchive_impl< + binary_iarchive, std::istream::char_type, std::istream::traits_type + >(is, flags) + {} + binary_iarchive(std::streambuf & bsb, unsigned int flags = 0) : + binary_iarchive_impl< + binary_iarchive, std::istream::char_type, std::istream::traits_type + >(bsb, flags) + {} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_iarchive) +BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::archive::binary_iarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_BINARY_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive_impl.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive_impl.hpp new file mode 100644 index 00000000000..b4747c98ece --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive_impl.hpp @@ -0,0 +1,105 @@ +#ifndef BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_HPP +#define BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_iarchive_impl.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_iarchive; +} // namespace detail + +template +class BOOST_SYMBOL_VISIBLE binary_iarchive_impl : + public basic_binary_iprimitive, + public basic_binary_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_iarchive; + friend basic_binary_iarchive; + friend load_access; + #else + friend class detail::interface_iarchive; + friend class basic_binary_iarchive; + friend class load_access; + #endif +#endif + template + void load_override(T & t){ + this->basic_binary_iarchive::load_override(t); + } + void init(unsigned int flags){ + if(0 != (flags & no_header)){ + return; + } + #if ! defined(__MWERKS__) + this->basic_binary_iarchive::init(); + this->basic_binary_iprimitive::init(); + #else + basic_binary_iarchive::init(); + basic_binary_iprimitive::init(); + #endif + } + binary_iarchive_impl( + std::basic_streambuf & bsb, + unsigned int flags + ) : + basic_binary_iprimitive( + bsb, + 0 != (flags & no_codecvt) + ), + basic_binary_iarchive(flags) + { + init(flags); + } + binary_iarchive_impl( + std::basic_istream & is, + unsigned int flags + ) : + basic_binary_iprimitive( + * is.rdbuf(), + 0 != (flags & no_codecvt) + ), + basic_binary_iarchive(flags) + { + init(flags); + } +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive.hpp new file mode 100644 index 00000000000..e8313fd7c95 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive.hpp @@ -0,0 +1,64 @@ +#ifndef BOOST_ARCHIVE_BINARY_OARCHIVE_HPP +#define BOOST_ARCHIVE_BINARY_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from binary_oarchive_impl instead. This will +// preserve correct static polymorphism. +class BOOST_SYMBOL_VISIBLE binary_oarchive : + public binary_oarchive_impl< + binary_oarchive, std::ostream::char_type, std::ostream::traits_type + > +{ +public: + binary_oarchive(std::ostream & os, unsigned int flags = 0) : + binary_oarchive_impl< + binary_oarchive, std::ostream::char_type, std::ostream::traits_type + >(os, flags) + {} + binary_oarchive(std::streambuf & bsb, unsigned int flags = 0) : + binary_oarchive_impl< + binary_oarchive, std::ostream::char_type, std::ostream::traits_type + >(bsb, flags) + {} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_oarchive) +BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::archive::binary_oarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_BINARY_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive_impl.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive_impl.hpp new file mode 100644 index 00000000000..6b4d018a564 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive_impl.hpp @@ -0,0 +1,106 @@ +#ifndef BOOST_ARCHIVE_BINARY_OARCHIVE_IMPL_HPP +#define BOOST_ARCHIVE_BINARY_OARCHIVE_IMPL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_oarchive_impl.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_oarchive; +} // namespace detail + +template +class BOOST_SYMBOL_VISIBLE binary_oarchive_impl : + public basic_binary_oprimitive, + public basic_binary_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_oarchive; + friend basic_binary_oarchive; + friend save_access; + #else + friend class detail::interface_oarchive; + friend class basic_binary_oarchive; + friend class save_access; + #endif +#endif + template + void save_override(T & t){ + this->basic_binary_oarchive::save_override(t); + } + void init(unsigned int flags) { + if(0 != (flags & no_header)){ + return; + } + #if ! defined(__MWERKS__) + this->basic_binary_oarchive::init(); + this->basic_binary_oprimitive::init(); + #else + basic_binary_oarchive::init(); + basic_binary_oprimitive::init(); + #endif + } + binary_oarchive_impl( + std::basic_streambuf & bsb, + unsigned int flags + ) : + basic_binary_oprimitive( + bsb, + 0 != (flags & no_codecvt) + ), + basic_binary_oarchive(flags) + { + init(flags); + } + binary_oarchive_impl( + std::basic_ostream & os, + unsigned int flags + ) : + basic_binary_oprimitive( + * os.rdbuf(), + 0 != (flags & no_codecvt) + ), + basic_binary_oarchive(flags) + { + init(flags); + } +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_BINARY_OARCHIVE_IMPL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_wiarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_wiarchive.hpp new file mode 100644 index 00000000000..775d8f82726 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/binary_wiarchive.hpp @@ -0,0 +1,56 @@ +#ifndef BOOST_ARCHIVE_BINARY_WIARCHIVE_HPP +#define BOOST_ARCHIVE_BINARY_WIARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_wiarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include // wistream +#include +#include + +namespace boost { +namespace archive { + +class binary_wiarchive : + public binary_iarchive_impl< + binary_wiarchive, std::wistream::char_type, std::wistream::traits_type + > +{ +public: + binary_wiarchive(std::wistream & is, unsigned int flags = 0) : + binary_iarchive_impl< + binary_wiarchive, std::wistream::char_type, std::wistream::traits_type + >(is, flags) + {} + binary_wiarchive(std::wstreambuf & bsb, unsigned int flags = 0) : + binary_iarchive_impl< + binary_wiarchive, std::wistream::char_type, std::wistream::traits_type + >(bsb, flags) + {} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_wiarchive) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_BINARY_WIARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_woarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_woarchive.hpp new file mode 100644 index 00000000000..a8817d6f8b4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/binary_woarchive.hpp @@ -0,0 +1,59 @@ +#ifndef BOOST_ARCHIVE_BINARY_WOARCHIVE_HPP +#define BOOST_ARCHIVE_BINARY_WOARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_woarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include +#include + +namespace boost { +namespace archive { + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from binary_oarchive_impl instead. This will +// preserve correct static polymorphism. +class binary_woarchive : + public binary_oarchive_impl< + binary_woarchive, std::wostream::char_type, std::wostream::traits_type + > +{ +public: + binary_woarchive(std::wostream & os, unsigned int flags = 0) : + binary_oarchive_impl< + binary_woarchive, std::wostream::char_type, std::wostream::traits_type + >(os, flags) + {} + binary_woarchive(std::wstreambuf & bsb, unsigned int flags = 0) : + binary_oarchive_impl< + binary_woarchive, std::wostream::char_type, std::wostream::traits_type + >(bsb, flags) + {} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_woarchive) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_BINARY_WOARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/codecvt_null.hpp b/contrib/libboost/boost_1_65_0/boost/archive/codecvt_null.hpp new file mode 100644 index 00000000000..7bce2b9b329 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/codecvt_null.hpp @@ -0,0 +1,109 @@ +#ifndef BOOST_ARCHIVE_CODECVT_NULL_HPP +#define BOOST_ARCHIVE_CODECVT_NULL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// codecvt_null.hpp: + +// (C) Copyright 2004 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // NULL, size_t +#ifndef BOOST_NO_CWCHAR +#include // for mbstate_t +#endif +#include +#include +#include +#include // must be the last header + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std { +// For STLport on WinCE, BOOST_NO_STDC_NAMESPACE can get defined if STLport is putting symbols in its own namespace. +// In the case of codecvt, however, this does not mean that codecvt is in the global namespace (it will be in STLport's namespace) +# if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) + using ::codecvt; +# endif + using ::mbstate_t; + using ::size_t; +} // namespace +#endif + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +template +class codecvt_null; + +template<> +class codecvt_null : public std::codecvt +{ + virtual bool do_always_noconv() const throw() { + return true; + } +public: + explicit codecvt_null(std::size_t no_locale_manage = 0) : + std::codecvt(no_locale_manage) + {} + virtual ~codecvt_null(){}; +}; + +template<> +class BOOST_SYMBOL_VISIBLE codecvt_null : public std::codecvt +{ + virtual BOOST_WARCHIVE_DECL BOOST_DLLEXPORT std::codecvt_base::result + do_out( + std::mbstate_t & state, + const wchar_t * first1, + const wchar_t * last1, + const wchar_t * & next1, + char * first2, + char * last2, + char * & next2 + ) const BOOST_USED; + virtual BOOST_WARCHIVE_DECL BOOST_DLLEXPORT std::codecvt_base::result + do_in( + std::mbstate_t & state, + const char * first1, + const char * last1, + const char * & next1, + wchar_t * first2, + wchar_t * last2, + wchar_t * & next2 + ) const BOOST_USED; + virtual int do_encoding( ) const throw( ){ + return sizeof(wchar_t) / sizeof(char); + } + virtual int do_max_length( ) const throw( ){ + return do_encoding(); + } +public: + BOOST_DLLEXPORT explicit codecvt_null(std::size_t no_locale_manage = 0) : + std::codecvt(no_locale_manage) + {} + virtual ~codecvt_null(){}; +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif +#include // pop pragmas + +#endif //BOOST_ARCHIVE_CODECVT_NULL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_prefix.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_prefix.hpp new file mode 100644 index 00000000000..debf79e9f0b --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_prefix.hpp @@ -0,0 +1,16 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// abi_prefix.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // must be the last header +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4251 4231 4660 4275) +#endif + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_suffix.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_suffix.hpp new file mode 100644 index 00000000000..4e054d66214 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_suffix.hpp @@ -0,0 +1,15 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// abi_suffix.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif +#include // pops abi_suffix.hpp pragmas + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/archive_serializer_map.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/archive_serializer_map.hpp new file mode 100644 index 00000000000..5432bfc73e7 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/archive_serializer_map.hpp @@ -0,0 +1,54 @@ +#ifndef BOOST_ARCHIVE_SERIALIZER_MAP_HPP +#define BOOST_ARCHIVE_SERIALIZER_MAP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// archive_serializer_map.hpp: extenstion of type_info required for +// serialization. + +// (C) Copyright 2009 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// note: this is nothing more than the thinest of wrappers around +// basic_serializer_map so we can have a one map / archive type. + +#include +#include +#include // must be the last header + +namespace boost { + +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { +namespace detail { + +class basic_serializer; + +template +class BOOST_SYMBOL_VISIBLE archive_serializer_map { +public: + static BOOST_ARCHIVE_OR_WARCHIVE_DECL bool insert(const basic_serializer * bs); + static BOOST_ARCHIVE_OR_WARCHIVE_DECL void erase(const basic_serializer * bs); + static BOOST_ARCHIVE_OR_WARCHIVE_DECL const basic_serializer * find( + const boost::serialization::extended_type_info & type_ + ); +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // must be the last header + +#endif //BOOST_ARCHIVE_SERIALIZER_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_archive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_archive.hpp new file mode 100644 index 00000000000..79b0e490d65 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_archive.hpp @@ -0,0 +1,48 @@ +#ifndef BOOST_ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// auto_link_archive.hpp +// +// (c) Copyright Robert Ramey 2004 +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/serialization + +//----------------------------------------------------------------------------// + +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html + +// enable automatic library variant selection ------------------------------// + +#include + +#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) \ +&& !defined(BOOST_ARCHIVE_SOURCE) && !defined(BOOST_WARCHIVE_SOURCE) \ +&& !defined(BOOST_SERIALIZATION_SOURCE) + + // Set the name of our library, this will get undef'ed by auto_link.hpp + // once it's done with it: + // + #define BOOST_LIB_NAME boost_serialization + // + // If we're importing code from a dll, then tell auto_link.hpp about it: + // + #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) + # define BOOST_DYN_LINK + #endif + // + // And include the header that does the work: + // + #include +#endif // auto-linking disabled + +#endif // BOOST_ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_warchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_warchive.hpp new file mode 100644 index 00000000000..683d191c20d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_warchive.hpp @@ -0,0 +1,47 @@ +#ifndef BOOST_ARCHIVE_DETAIL_AUTO_LINK_WARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_AUTO_LINK_WARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// auto_link_warchive.hpp +// +// (c) Copyright Robert Ramey 2004 +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/serialization + +//----------------------------------------------------------------------------// + +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html + +// enable automatic library variant selection ------------------------------// + +#include + +#if !defined(BOOST_WARCHIVE_SOURCE) \ +&& !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) + +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_wserialization +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include +#endif // auto-linking disabled + +#endif // ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iarchive.hpp new file mode 100644 index 00000000000..1f5a8bf63bf --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iarchive.hpp @@ -0,0 +1,105 @@ +#ifndef BOOST_ARCHIVE_DETAIL_BASIC_IARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_BASIC_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_iarchive.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// can't use this - much as I'd like to as borland doesn't support it + +#include +#include +#include + +#include +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { +namespace detail { + +class basic_iarchive_impl; +class basic_iserializer; +class basic_pointer_iserializer; + +////////////////////////////////////////////////////////////////////// +// class basic_iarchive - read serialized objects from a input stream +class BOOST_SYMBOL_VISIBLE basic_iarchive : + private boost::noncopyable, + public boost::archive::detail::helper_collection +{ + friend class basic_iarchive_impl; + // hide implementation of this class to minimize header conclusion + boost::scoped_ptr pimpl; + + virtual void vload(version_type &t) = 0; + virtual void vload(object_id_type &t) = 0; + virtual void vload(class_id_type &t) = 0; + virtual void vload(class_id_optional_type &t) = 0; + virtual void vload(class_name_type &t) = 0; + virtual void vload(tracking_type &t) = 0; +protected: + BOOST_ARCHIVE_DECL basic_iarchive(unsigned int flags); + boost::archive::detail::helper_collection & + get_helper_collection(){ + return *this; + } +public: + // some msvc versions require that the following function be public + // otherwise it should really protected. + virtual BOOST_ARCHIVE_DECL ~basic_iarchive(); + // note: NOT part of the public API. + BOOST_ARCHIVE_DECL void next_object_pointer(void *t); + BOOST_ARCHIVE_DECL void register_basic_serializer( + const basic_iserializer & bis + ); + BOOST_ARCHIVE_DECL void load_object( + void *t, + const basic_iserializer & bis + ); + BOOST_ARCHIVE_DECL const basic_pointer_iserializer * + load_pointer( + void * & t, + const basic_pointer_iserializer * bpis_ptr, + const basic_pointer_iserializer * (*finder)( + const boost::serialization::extended_type_info & eti + ) + ); + // real public API starts here + BOOST_ARCHIVE_DECL void + set_library_version(library_version_type archive_library_version); + BOOST_ARCHIVE_DECL library_version_type + get_library_version() const; + BOOST_ARCHIVE_DECL unsigned int + get_flags() const; + BOOST_ARCHIVE_DECL void + reset_object_address(const void * new_address, const void * old_address); + BOOST_ARCHIVE_DECL void + delete_created_pointers(); +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif //BOOST_ARCHIVE_DETAIL_BASIC_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iserializer.hpp new file mode 100644 index 00000000000..0d66674c349 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iserializer.hpp @@ -0,0 +1,91 @@ +#ifndef BOOST_ARCHIVE_DETAIL_BASIC_ISERIALIZER_HPP +#define BOOST_ARCHIVE_DETAIL_BASIC_ISERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_iserializer.hpp: extenstion of type_info required for serialization. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // NULL +#include + +#include +#include +#include +#include +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization + +// forward declarations +namespace archive { +namespace detail { + +class basic_iarchive; +class basic_pointer_iserializer; + +class BOOST_SYMBOL_VISIBLE basic_iserializer : + public basic_serializer +{ +private: + basic_pointer_iserializer *m_bpis; +protected: + explicit BOOST_ARCHIVE_DECL basic_iserializer( + const boost::serialization::extended_type_info & type + ); + virtual BOOST_ARCHIVE_DECL ~basic_iserializer(); +public: + bool serialized_as_pointer() const { + return m_bpis != NULL; + } + void set_bpis(basic_pointer_iserializer *bpis){ + m_bpis = bpis; + } + const basic_pointer_iserializer * get_bpis_ptr() const { + return m_bpis; + } + virtual void load_object_data( + basic_iarchive & ar, + void *x, + const unsigned int file_version + ) const = 0; + // returns true if class_info should be saved + virtual bool class_info() const = 0 ; + // returns true if objects should be tracked + virtual bool tracking(const unsigned int) const = 0 ; + // returns class version + virtual version_type version() const = 0 ; + // returns true if this class is polymorphic + virtual bool is_polymorphic() const = 0; + virtual void destroy(/*const*/ void *address) const = 0 ; +}; + +} // namespae detail +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_DETAIL_BASIC_ISERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oarchive.hpp new file mode 100644 index 00000000000..c379108d584 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oarchive.hpp @@ -0,0 +1,94 @@ +#ifndef BOOST_ARCHIVE_BASIC_OARCHIVE_HPP +#define BOOST_ARCHIVE_BASIC_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_oarchive.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // NULL +#include +#include +#include + +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { +namespace detail { + +class basic_oarchive_impl; +class basic_oserializer; +class basic_pointer_oserializer; + +////////////////////////////////////////////////////////////////////// +// class basic_oarchive - write serialized objects to an output stream +class BOOST_SYMBOL_VISIBLE basic_oarchive : + private boost::noncopyable, + public boost::archive::detail::helper_collection +{ + friend class basic_oarchive_impl; + // hide implementation of this class to minimize header conclusion + boost::scoped_ptr pimpl; + + // overload these to bracket object attributes. Used to implement + // xml archives + virtual void vsave(const version_type t) = 0; + virtual void vsave(const object_id_type t) = 0; + virtual void vsave(const object_reference_type t) = 0; + virtual void vsave(const class_id_type t) = 0; + virtual void vsave(const class_id_optional_type t) = 0; + virtual void vsave(const class_id_reference_type t) = 0; + virtual void vsave(const class_name_type & t) = 0; + virtual void vsave(const tracking_type t) = 0; +protected: + BOOST_ARCHIVE_DECL basic_oarchive(unsigned int flags = 0); + BOOST_ARCHIVE_DECL boost::archive::detail::helper_collection & + get_helper_collection(); + virtual BOOST_ARCHIVE_DECL ~basic_oarchive(); +public: + // note: NOT part of the public interface + BOOST_ARCHIVE_DECL void register_basic_serializer( + const basic_oserializer & bos + ); + BOOST_ARCHIVE_DECL void save_object( + const void *x, + const basic_oserializer & bos + ); + BOOST_ARCHIVE_DECL void save_pointer( + const void * t, + const basic_pointer_oserializer * bpos_ptr + ); + void save_null_pointer(){ + vsave(NULL_POINTER_TAG); + } + // real public interface starts here + BOOST_ARCHIVE_DECL void end_preamble(); // default implementation does nothing + BOOST_ARCHIVE_DECL library_version_type get_library_version() const; + BOOST_ARCHIVE_DECL unsigned int get_flags() const; +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif //BOOST_ARCHIVE_BASIC_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oserializer.hpp new file mode 100644 index 00000000000..94247e90056 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oserializer.hpp @@ -0,0 +1,89 @@ +#ifndef BOOST_SERIALIZATION_BASIC_OSERIALIZER_HPP +#define BOOST_SERIALIZATION_BASIC_OSERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_oserializer.hpp: extenstion of type_info required for serialization. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // NULL +#include +#include + +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization + +// forward declarations +namespace archive { +namespace detail { + +class basic_oarchive; +class basic_pointer_oserializer; + +class BOOST_SYMBOL_VISIBLE basic_oserializer : + public basic_serializer +{ +private: + basic_pointer_oserializer *m_bpos; +protected: + explicit BOOST_ARCHIVE_DECL basic_oserializer( + const boost::serialization::extended_type_info & type_ + ); + virtual BOOST_ARCHIVE_DECL ~basic_oserializer(); +public: + bool serialized_as_pointer() const { + return m_bpos != NULL; + } + void set_bpos(basic_pointer_oserializer *bpos){ + m_bpos = bpos; + } + const basic_pointer_oserializer * get_bpos() const { + return m_bpos; + } + virtual void save_object_data( + basic_oarchive & ar, const void * x + ) const = 0; + // returns true if class_info should be saved + virtual bool class_info() const = 0; + // returns true if objects should be tracked + virtual bool tracking(const unsigned int flags) const = 0; + // returns class version + virtual version_type version() const = 0; + // returns true if this class is polymorphic + virtual bool is_polymorphic() const = 0; +}; + +} // namespace detail +} // namespace serialization +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_SERIALIZATION_BASIC_OSERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_iserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_iserializer.hpp new file mode 100644 index 00000000000..1fc4b14d6e9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_iserializer.hpp @@ -0,0 +1,70 @@ +#ifndef BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP +#define BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_pointer_oserializer.hpp: extenstion of type_info required for +// serialization. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization + +// forward declarations +namespace archive { +namespace detail { + +class basic_iarchive; +class basic_iserializer; + +class BOOST_SYMBOL_VISIBLE basic_pointer_iserializer + : public basic_serializer { +protected: + explicit BOOST_ARCHIVE_DECL basic_pointer_iserializer( + const boost::serialization::extended_type_info & type_ + ); + virtual BOOST_ARCHIVE_DECL ~basic_pointer_iserializer(); +public: + virtual void * heap_allocation() const = 0; + virtual const basic_iserializer & get_basic_serializer() const = 0; + virtual void load_object_ptr( + basic_iarchive & ar, + void * x, + const unsigned int file_version + ) const = 0; +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_oserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_oserializer.hpp new file mode 100644 index 00000000000..1a5d9549eab --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_oserializer.hpp @@ -0,0 +1,68 @@ +#ifndef BOOST_ARCHIVE_BASIC_POINTER_OSERIALIZER_HPP +#define BOOST_ARCHIVE_BASIC_POINTER_OSERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_pointer_oserializer.hpp: extenstion of type_info required for +// serialization. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { +namespace detail { + +class basic_oarchive; +class basic_oserializer; + +class BOOST_SYMBOL_VISIBLE basic_pointer_oserializer : + public basic_serializer +{ +protected: + explicit BOOST_ARCHIVE_DECL basic_pointer_oserializer( + const boost::serialization::extended_type_info & type_ + ); +public: + virtual BOOST_ARCHIVE_DECL ~basic_pointer_oserializer(); + virtual const basic_oserializer & get_basic_serializer() const = 0; + virtual void save_object_ptr( + basic_oarchive & ar, + const void * x + ) const = 0; +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_BASIC_POINTER_OSERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer.hpp new file mode 100644 index 00000000000..f9c4203f862 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer.hpp @@ -0,0 +1,77 @@ +#ifndef BOOST_ARCHIVE_BASIC_SERIALIZER_HPP +#define BOOST_ARCHIVE_BASIC_SERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_serializer.hpp: extenstion of type_info required for serialization. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // NULL + +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { +namespace detail { + +class basic_serializer : + private boost::noncopyable +{ + const boost::serialization::extended_type_info * m_eti; +protected: + explicit basic_serializer( + const boost::serialization::extended_type_info & eti + ) : + m_eti(& eti) + {} +public: + inline bool + operator<(const basic_serializer & rhs) const { + // can't compare address since there can be multiple eti records + // for the same type in different execution modules (that is, DLLS) + // leave this here as a reminder not to do this! + // return & lhs.get_eti() < & rhs.get_eti(); + return get_eti() < rhs.get_eti(); + } + const char * get_debug_info() const { + return m_eti->get_debug_info(); + } + const boost::serialization::extended_type_info & get_eti() const { + return * m_eti; + } +}; + +class basic_serializer_arg : public basic_serializer { +public: + basic_serializer_arg(const serialization::extended_type_info & eti) : + basic_serializer(eti) + {} +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_BASIC_SERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer_map.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer_map.hpp new file mode 100644 index 00000000000..79341803367 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer_map.hpp @@ -0,0 +1,69 @@ +#ifndef BOOST_SERIALIZER_MAP_HPP +#define BOOST_SERIALIZER_MAP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_serializer_map.hpp: extenstion of type_info required for serialization. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include +#include + +#include // must be the last header + +namespace boost { +namespace serialization { + class extended_type_info; +} + +namespace archive { +namespace detail { + +class basic_serializer; + +class BOOST_SYMBOL_VISIBLE +basic_serializer_map : public + boost::noncopyable +{ + struct type_info_pointer_compare + { + bool operator()( + const basic_serializer * lhs, const basic_serializer * rhs + ) const ; + }; + typedef std::set< + const basic_serializer *, + type_info_pointer_compare + > map_type; + map_type m_map; +public: + BOOST_ARCHIVE_DECL bool insert(const basic_serializer * bs); + BOOST_ARCHIVE_DECL void erase(const basic_serializer * bs); + BOOST_ARCHIVE_DECL const basic_serializer * find( + const boost::serialization::extended_type_info & type_ + ) const; +private: + // cw 8.3 requires this + basic_serializer_map& operator=(basic_serializer_map const&); +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // must be the last header + +#endif // BOOST_SERIALIZER_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/check.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/check.hpp new file mode 100644 index 00000000000..10034e7d101 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/check.hpp @@ -0,0 +1,169 @@ +#ifndef BOOST_ARCHIVE_DETAIL_CHECK_HPP +#define BOOST_ARCHIVE_DETAIL_CHECK_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#pragma inline_depth(511) +#pragma inline_recursion(on) +#endif + +#if defined(__MWERKS__) +#pragma inline_depth(511) +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// check.hpp: interface for serialization system. + +// (C) Copyright 2009 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace archive { +namespace detail { + +// checks for objects + +template +inline void check_object_level(){ + typedef + typename mpl::greater_equal< + serialization::implementation_level< T >, + mpl::int_ + >::type typex; + + // trap attempts to serialize objects marked + // not_serializable + BOOST_STATIC_ASSERT(typex::value); +} + +template +inline void check_object_versioning(){ + typedef + typename mpl::or_< + typename mpl::greater< + serialization::implementation_level< T >, + mpl::int_ + >, + typename mpl::equal_to< + serialization::version< T >, + mpl::int_<0> + > + > typex; + // trap attempts to serialize with objects that don't + // save class information in the archive with versioning. + BOOST_STATIC_ASSERT(typex::value); +} + +template +inline void check_object_tracking(){ + // presume it has already been determined that + // T is not a const + BOOST_STATIC_ASSERT(! boost::is_const< T >::value); + typedef typename mpl::equal_to< + serialization::tracking_level< T >, + mpl::int_ + >::type typex; + // saving an non-const object of a type not marked "track_never) + + // may be an indicator of an error usage of the + // serialization library and should be double checked. + // See documentation on object tracking. Also, see the + // "rationale" section of the documenation + // for motivation for this checking. + + BOOST_STATIC_WARNING(typex::value); +} + +// checks for pointers + +template +inline void check_pointer_level(){ + // we should only invoke this once we KNOW that T + // has been used as a pointer!! + typedef + typename mpl::or_< + typename mpl::greater< + serialization::implementation_level< T >, + mpl::int_ + >, + typename mpl::not_< + typename mpl::equal_to< + serialization::tracking_level< T >, + mpl::int_ + > + > + > typex; + // Address the following when serializing to a pointer: + + // a) This type doesn't save class information in the + // archive. That is, the serialization trait implementation + // level <= object_serializable. + // b) Tracking for this type is set to "track selectively" + + // in this case, indication that an object is tracked is + // not stored in the archive itself - see level == object_serializable + // but rather the existence of the operation ar >> T * is used to + // infer that an object of this type should be tracked. So, if + // you save via a pointer but don't load via a pointer the operation + // will fail on load without given any valid reason for the failure. + + // So if your program traps here, consider changing the + // tracking or implementation level traits - or not + // serializing via a pointer. + BOOST_STATIC_WARNING(typex::value); +} + +template +void inline check_pointer_tracking(){ + typedef typename mpl::greater< + serialization::tracking_level< T >, + mpl::int_ + >::type typex; + // serializing an object of a type marked "track_never" through a pointer + // could result in creating more objects than were saved! + BOOST_STATIC_WARNING(typex::value); +} + +template +inline void check_const_loading(){ + typedef + typename mpl::or_< + typename boost::serialization::is_wrapper< T >, + typename mpl::not_< + typename boost::is_const< T > + > + >::type typex; + // cannot load data into a "const" object unless it's a + // wrapper around some other non-const object. + BOOST_STATIC_ASSERT(typex::value); +} + +} // detail +} // archive +} // boost + +#endif // BOOST_ARCHIVE_DETAIL_CHECK_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/common_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/common_iarchive.hpp new file mode 100644 index 00000000000..82304f1e5ac --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/common_iarchive.hpp @@ -0,0 +1,88 @@ +#ifndef BOOST_ARCHIVE_DETAIL_COMMON_IARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_COMMON_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// common_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { +namespace detail { + +class extended_type_info; + +// note: referred to as Curiously Recurring Template Patter (CRTP) +template +class BOOST_SYMBOL_VISIBLE common_iarchive : + public basic_iarchive, + public interface_iarchive +{ + friend class interface_iarchive; +private: + virtual void vload(version_type & t){ + * this->This() >> t; + } + virtual void vload(object_id_type & t){ + * this->This() >> t; + } + virtual void vload(class_id_type & t){ + * this->This() >> t; + } + virtual void vload(class_id_optional_type & t){ + * this->This() >> t; + } + virtual void vload(tracking_type & t){ + * this->This() >> t; + } + virtual void vload(class_name_type &s){ + * this->This() >> s; + } +protected: + // default processing - invoke serialization library + template + void load_override(T & t){ + archive::load(* this->This(), t); + } + // default implementations of functions which emit start/end tags for + // archive types that require them. + void load_start(const char * /*name*/){} + void load_end(const char * /*name*/){} + // default archive initialization + common_iarchive(unsigned int flags = 0) : + basic_iarchive(flags), + interface_iarchive() + {} +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_DETAIL_COMMON_IARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/common_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/common_oarchive.hpp new file mode 100644 index 00000000000..ee42bbe5976 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/common_oarchive.hpp @@ -0,0 +1,88 @@ +#ifndef BOOST_ARCHIVE_DETAIL_COMMON_OARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_COMMON_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// common_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { +namespace detail { + +// note: referred to as Curiously Recurring Template Patter (CRTP) +template + +class BOOST_SYMBOL_VISIBLE common_oarchive : + public basic_oarchive, + public interface_oarchive +{ + friend class interface_oarchive; +private: + virtual void vsave(const version_type t){ + * this->This() << t; + } + virtual void vsave(const object_id_type t){ + * this->This() << t; + } + virtual void vsave(const object_reference_type t){ + * this->This() << t; + } + virtual void vsave(const class_id_type t){ + * this->This() << t; + } + virtual void vsave(const class_id_reference_type t){ + * this->This() << t; + } + virtual void vsave(const class_id_optional_type t){ + * this->This() << t; + } + virtual void vsave(const class_name_type & t){ + * this->This() << t; + } + virtual void vsave(const tracking_type t){ + * this->This() << t; + } +protected: + // default processing - invoke serialization library + template + void save_override(T & t){ + archive::save(* this->This(), t); + } + void save_start(const char * /*name*/){} + void save_end(const char * /*name*/){} + common_oarchive(unsigned int flags = 0) : + basic_oarchive(flags), + interface_oarchive() + {} +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_DETAIL_COMMON_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/decl.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/decl.hpp new file mode 100644 index 00000000000..4f731cded37 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/decl.hpp @@ -0,0 +1,57 @@ +#ifndef BOOST_ARCHIVE_DETAIL_DECL_HPP +#define BOOST_ARCHIVE_DETAIL_DECL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2///////// 3/////////4/////////5/////////6/////////7/////////8 +// decl.hpp +// +// (c) Copyright Robert Ramey 2004 +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/serialization + +//----------------------------------------------------------------------------// + +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html + +#include + +#if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK)) + #if defined(BOOST_ARCHIVE_SOURCE) + #define BOOST_ARCHIVE_DECL BOOST_SYMBOL_EXPORT + #else + #define BOOST_ARCHIVE_DECL BOOST_SYMBOL_IMPORT + #endif + + #if defined(BOOST_WARCHIVE_SOURCE) + #define BOOST_WARCHIVE_DECL BOOST_SYMBOL_EXPORT + #else + #define BOOST_WARCHIVE_DECL BOOST_SYMBOL_IMPORT + #endif + + #if defined(BOOST_WARCHIVE_SOURCE) || defined(BOOST_ARCHIVE_SOURCE) + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL BOOST_SYMBOL_EXPORT + #else + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL BOOST_SYMBOL_IMPORT + #endif + +#endif + +#if ! defined(BOOST_ARCHIVE_DECL) + #define BOOST_ARCHIVE_DECL +#endif +#if ! defined(BOOST_WARCHIVE_DECL) + #define BOOST_WARCHIVE_DECL +#endif +#if ! defined(BOOST_ARCHIVE_OR_WARCHIVE_DECL) + #define BOOST_ARCHIVE_OR_WARCHIVE_DECL +#endif + +#endif // BOOST_ARCHIVE_DETAIL_DECL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/helper_collection.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/helper_collection.hpp new file mode 100644 index 00000000000..edb4125e308 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/helper_collection.hpp @@ -0,0 +1,99 @@ +#ifndef BOOST_ARCHIVE_DETAIL_HELPER_COLLECTION_HPP +#define BOOST_ARCHIVE_DETAIL_HELPER_COLLECTION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// helper_collection.hpp: archive support for run-time helpers + +// (C) Copyright 2002-2008 Robert Ramey and Joaquin M Lopez Munoz +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // NULL +#include +#include +#include +#include + +#include + +#include +#include + +namespace boost { + +namespace archive { +namespace detail { + +class helper_collection +{ + helper_collection(const helper_collection&); // non-copyable + helper_collection& operator = (const helper_collection&); // non-copyable + + // note: we dont' actually "share" the function object pointer + // we only use shared_ptr to make sure that it get's deleted + + typedef std::pair< + const void *, + boost::shared_ptr + > helper_value_type; + template + boost::shared_ptr make_helper_ptr(){ + // use boost::shared_ptr rather than std::shared_ptr to maintain + // c++03 compatibility + return boost::make_shared(); + } + + typedef std::vector collection; + collection m_collection; + + struct predicate { + BOOST_DELETED_FUNCTION(predicate & operator=(const predicate & rhs)) + public: + const void * const m_ti; + bool operator()(helper_value_type const &rhs) const { + return m_ti == rhs.first; + } + predicate(const void * ti) : + m_ti(ti) + {} + }; +protected: + helper_collection(){} + ~helper_collection(){} +public: + template + Helper& find_helper(void * const id = 0) { + collection::const_iterator it = + std::find_if( + m_collection.begin(), + m_collection.end(), + predicate(id) + ); + + void * rval = 0; + if(it == m_collection.end()){ + m_collection.push_back( + std::make_pair(id, make_helper_ptr()) + ); + rval = m_collection.back().second.get(); + } + else{ + rval = it->second.get(); + } + return *static_cast(rval); + } +}; + +} // namespace detail +} // namespace serialization +} // namespace boost + +#endif // BOOST_ARCHIVE_DETAIL_HELPER_COLLECTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_iarchive.hpp new file mode 100644 index 00000000000..4a99e28b59f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_iarchive.hpp @@ -0,0 +1,85 @@ +#ifndef BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// interface_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include // NULL +#include +#include +#include +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace archive { +namespace detail { + +class basic_pointer_iserializer; + +template +class interface_iarchive +{ +protected: + interface_iarchive(){}; +public: + ///////////////////////////////////////////////////////// + // archive public interface + typedef mpl::bool_ is_loading; + typedef mpl::bool_ is_saving; + + // return a pointer to the most derived class + Archive * This(){ + return static_cast(this); + } + + template + const basic_pointer_iserializer * + register_type(T * = NULL){ + const basic_pointer_iserializer & bpis = + boost::serialization::singleton< + pointer_iserializer + >::get_const_instance(); + this->This()->register_basic_serializer(bpis.get_basic_serializer()); + return & bpis; + } + template + Helper & + get_helper(void * const id = 0){ + helper_collection & hc = this->This()->get_helper_collection(); + return hc.template find_helper(id); + } + + template + Archive & operator>>(T & t){ + this->This()->load_override(t); + return * this->This(); + } + + // the & operator + template + Archive & operator&(T & t){ + return *(this->This()) >> t; + } +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_oarchive.hpp new file mode 100644 index 00000000000..359463ed9d8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_oarchive.hpp @@ -0,0 +1,87 @@ +#ifndef BOOST_ARCHIVE_DETAIL_INTERFACE_OARCHIVE_HPP +#define BOOST_ARCHIVE_DETAIL_INTERFACE_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// interface_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include // NULL +#include +#include + +#include +#include +#include // must be the last header + +#include + +namespace boost { +namespace archive { +namespace detail { + +class basic_pointer_oserializer; + +template +class interface_oarchive +{ +protected: + interface_oarchive(){}; +public: + ///////////////////////////////////////////////////////// + // archive public interface + typedef mpl::bool_ is_loading; + typedef mpl::bool_ is_saving; + + // return a pointer to the most derived class + Archive * This(){ + return static_cast(this); + } + + template + const basic_pointer_oserializer * + register_type(const T * = NULL){ + const basic_pointer_oserializer & bpos = + boost::serialization::singleton< + pointer_oserializer + >::get_const_instance(); + this->This()->register_basic_serializer(bpos.get_basic_serializer()); + return & bpos; + } + + template + Helper & + get_helper(void * const id = 0){ + helper_collection & hc = this->This()->get_helper_collection(); + return hc.template find_helper(id); + } + + template + Archive & operator<<(const T & t){ + this->This()->save_override(t); + return * this->This(); + } + + // the & operator + template + Archive & operator&(const T & t){ + return * this ->This() << t; + } +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/iserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/iserializer.hpp new file mode 100644 index 00000000000..193e98a82e4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/iserializer.hpp @@ -0,0 +1,631 @@ +#ifndef BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP +#define BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#pragma inline_depth(511) +#pragma inline_recursion(on) +#endif + +#if defined(__MWERKS__) +#pragma inline_depth(511) +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// iserializer.hpp: interface for serialization system. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // for placement new +#include // size_t, NULL + +#include +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include + +#include +#include +#include +#include +#include + +#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO + #include +#endif +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#ifndef BOOST_MSVC + #define DONT_USE_HAS_NEW_OPERATOR ( \ + BOOST_WORKAROUND(__IBMCPP__, < 1210) \ + || defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x590) \ + ) +#else + #define DONT_USE_HAS_NEW_OPERATOR 0 +#endif + +#if ! DONT_USE_HAS_NEW_OPERATOR +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// the following is need only for dynamic cast of polymorphic pointers +#include +#include +#include +#include +#include +#include + +namespace boost { + +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { + +// an accessor to permit friend access to archives. Needed because +// some compilers don't handle friend templates completely +class load_access { +public: + template + static void load_primitive(Archive &ar, T &t){ + ar.load(t); + } +}; + +namespace detail { + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +template +class iserializer : public basic_iserializer +{ +private: + virtual void destroy(/*const*/ void *address) const { + boost::serialization::access::destroy(static_cast(address)); + } +protected: + // protected constructor since it's always created by singleton + explicit iserializer() : + basic_iserializer( + boost::serialization::singleton< + typename + boost::serialization::type_info_implementation< T >::type + >::get_const_instance() + ) + {} +public: + virtual BOOST_DLLEXPORT void load_object_data( + basic_iarchive & ar, + void *x, + const unsigned int file_version + ) const BOOST_USED; + virtual bool class_info() const { + return boost::serialization::implementation_level< T >::value + >= boost::serialization::object_class_info; + } + virtual bool tracking(const unsigned int /* flags */) const { + return boost::serialization::tracking_level< T >::value + == boost::serialization::track_always + || ( boost::serialization::tracking_level< T >::value + == boost::serialization::track_selectively + && serialized_as_pointer()); + } + virtual version_type version() const { + return version_type(::boost::serialization::version< T >::value); + } + virtual bool is_polymorphic() const { + return boost::is_polymorphic< T >::value; + } + virtual ~iserializer(){}; +}; + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +template +BOOST_DLLEXPORT void iserializer::load_object_data( + basic_iarchive & ar, + void *x, + const unsigned int file_version +) const { + // note: we now comment this out. Before we permited archive + // version # to be very large. Now we don't. To permit + // readers of these old archives, we have to suppress this + // code. Perhaps in the future we might re-enable it but + // permit its suppression with a runtime switch. + #if 0 + // trap case where the program cannot handle the current version + if(file_version > static_cast(version())) + boost::serialization::throw_exception( + archive::archive_exception( + boost::archive::archive_exception::unsupported_class_version, + get_debug_info() + ) + ); + #endif + // make sure call is routed through the higest interface that might + // be specialized by the user. + boost::serialization::serialize_adl( + boost::serialization::smart_cast_reference(ar), + * static_cast(x), + file_version + ); +} + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +// the purpose of this code is to allocate memory for an object +// without requiring the constructor to be called. Presumably +// the allocated object will be subsequently initialized with +// "placement new". +// note: we have the boost type trait has_new_operator but we +// have no corresponding has_delete_operator. So we presume +// that the former being true would imply that the a delete +// operator is also defined for the class T. + +template +struct heap_allocation { + // boost::has_new_operator< T > doesn't work on these compilers + #if DONT_USE_HAS_NEW_OPERATOR + // This doesn't handle operator new overload for class T + static T * invoke_new(){ + return static_cast(operator new(sizeof(T))); + } + static void invoke_delete(T *t){ + (operator delete(t)); + } + #else + // note: we presume that a true value for has_new_operator + // implies the existence of a class specific delete operator as well + // as a class specific new operator. + struct has_new_operator { + static T * invoke_new() { + return static_cast((T::operator new)(sizeof(T))); + } + static void invoke_delete(T * t) { + // if compilation fails here, the likely cause that the class + // T has a class specific new operator but no class specific + // delete operator which matches the following signature. + // note that this solution addresses the issue that two + // possible signatures. But it doesn't address the possibility + // that the class might have class specific new with NO + // class specific delete at all. Patches (compatible with + // C++03) welcome! + delete t; + } + }; + struct doesnt_have_new_operator { + static T* invoke_new() { + return static_cast(operator new(sizeof(T))); + } + static void invoke_delete(T * t) { + // Note: I'm reliance upon automatic conversion from T * to void * here + delete t; + } + }; + static T * invoke_new() { + typedef typename + mpl::eval_if< + boost::has_new_operator< T >, + mpl::identity, + mpl::identity + >::type typex; + return typex::invoke_new(); + } + static void invoke_delete(T *t) { + typedef typename + mpl::eval_if< + boost::has_new_operator< T >, + mpl::identity, + mpl::identity + >::type typex; + typex::invoke_delete(t); + } + #endif + explicit heap_allocation(){ + m_p = invoke_new(); + } + ~heap_allocation(){ + if (0 != m_p) + invoke_delete(m_p); + } + T* get() const { + return m_p; + } + + T* release() { + T* p = m_p; + m_p = 0; + return p; + } +private: + T* m_p; +}; + +template +class pointer_iserializer : + public basic_pointer_iserializer +{ +private: + virtual void * heap_allocation() const { + detail::heap_allocation h; + T * t = h.get(); + h.release(); + return t; + } + virtual const basic_iserializer & get_basic_serializer() const { + return boost::serialization::singleton< + iserializer + >::get_const_instance(); + } + BOOST_DLLEXPORT virtual void load_object_ptr( + basic_iarchive & ar, + void * x, + const unsigned int file_version + ) const BOOST_USED; +protected: + // this should alway be a singleton so make the constructor protected + pointer_iserializer(); + ~pointer_iserializer(); +}; + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +// note: BOOST_DLLEXPORT is so that code for polymorphic class +// serialized only through base class won't get optimized out +template +BOOST_DLLEXPORT void pointer_iserializer::load_object_ptr( + basic_iarchive & ar, + void * t, + const unsigned int file_version +) const +{ + Archive & ar_impl = + boost::serialization::smart_cast_reference(ar); + + // note that the above will throw std::bad_alloc if the allocation + // fails so we don't have to address this contingency here. + + // catch exception during load_construct_data so that we don't + // automatically delete the t which is most likely not fully + // constructed + BOOST_TRY { + // this addresses an obscure situation that occurs when + // load_constructor de-serializes something through a pointer. + ar.next_object_pointer(t); + boost::serialization::load_construct_data_adl( + ar_impl, + static_cast(t), + file_version + ); + } + BOOST_CATCH(...){ + // if we get here the load_construct failed. The heap_allocation + // will be automatically deleted so we don't have to do anything + // special here. + BOOST_RETHROW; + } + BOOST_CATCH_END + + ar_impl >> boost::serialization::make_nvp(NULL, * static_cast(t)); +} + +template +pointer_iserializer::pointer_iserializer() : + basic_pointer_iserializer( + boost::serialization::singleton< + typename + boost::serialization::type_info_implementation< T >::type + >::get_const_instance() + ) +{ + boost::serialization::singleton< + iserializer + >::get_mutable_instance().set_bpis(this); + archive_serializer_map::insert(this); +} + +template +pointer_iserializer::~pointer_iserializer(){ + archive_serializer_map::erase(this); +} + +template +struct load_non_pointer_type { + // note this bounces the call right back to the archive + // with no runtime overhead + struct load_primitive { + template + static void invoke(Archive & ar, T & t){ + load_access::load_primitive(ar, t); + } + }; + // note this bounces the call right back to the archive + // with no runtime overhead + struct load_only { + template + static void invoke(Archive & ar, const T & t){ + // short cut to user's serializer + // make sure call is routed through the higest interface that might + // be specialized by the user. + boost::serialization::serialize_adl( + ar, + const_cast(t), + boost::serialization::version< T >::value + ); + } + }; + + // note this save class information including version + // and serialization level to the archive + struct load_standard { + template + static void invoke(Archive &ar, const T & t){ + void * x = & const_cast(t); + ar.load_object( + x, + boost::serialization::singleton< + iserializer + >::get_const_instance() + ); + } + }; + + struct load_conditional { + template + static void invoke(Archive &ar, T &t){ + //if(0 == (ar.get_flags() & no_tracking)) + load_standard::invoke(ar, t); + //else + // load_only::invoke(ar, t); + } + }; + + template + static void invoke(Archive & ar, T &t){ + typedef typename mpl::eval_if< + // if its primitive + mpl::equal_to< + boost::serialization::implementation_level< T >, + mpl::int_ + >, + mpl::identity, + // else + typename mpl::eval_if< + // class info / version + mpl::greater_equal< + boost::serialization::implementation_level< T >, + mpl::int_ + >, + // do standard load + mpl::identity, + // else + typename mpl::eval_if< + // no tracking + mpl::equal_to< + boost::serialization::tracking_level< T >, + mpl::int_ + >, + // do a fast load + mpl::identity, + // else + // do a fast load only tracking is turned off + mpl::identity + > > >::type typex; + check_object_versioning< T >(); + check_object_level< T >(); + typex::invoke(ar, t); + } +}; + +template +struct load_pointer_type { + struct abstract + { + template + static const basic_pointer_iserializer * register_type(Archive & /* ar */){ + // it has? to be polymorphic + BOOST_STATIC_ASSERT(boost::is_polymorphic< T >::value); + return static_cast(NULL); + } + }; + + struct non_abstract + { + template + static const basic_pointer_iserializer * register_type(Archive & ar){ + return ar.register_type(static_cast(NULL)); + } + }; + + template + static const basic_pointer_iserializer * register_type(Archive &ar, const T & /*t*/){ + // there should never be any need to load an abstract polymorphic + // class pointer. Inhibiting code generation for this + // permits abstract base classes to be used - note: exception + // virtual serialize functions used for plug-ins + typedef typename + mpl::eval_if< + boost::serialization::is_abstract, + boost::mpl::identity, + boost::mpl::identity + >::type typex; + return typex::template register_type< T >(ar); + } + + template + static T * pointer_tweak( + const boost::serialization::extended_type_info & eti, + void const * const t, + const T & + ) { + // tweak the pointer back to the base class + void * upcast = const_cast( + boost::serialization::void_upcast( + eti, + boost::serialization::singleton< + typename + boost::serialization::type_info_implementation< T >::type + >::get_const_instance(), + t + ) + ); + if(NULL == upcast) + boost::serialization::throw_exception( + archive_exception(archive_exception::unregistered_class) + ); + return static_cast(upcast); + } + + template + static void check_load(T & /* t */){ + check_pointer_level< T >(); + check_pointer_tracking< T >(); + } + + static const basic_pointer_iserializer * + find(const boost::serialization::extended_type_info & type){ + return static_cast( + archive_serializer_map::find(type) + ); + } + + template + static void invoke(Archive & ar, Tptr & t){ + check_load(*t); + const basic_pointer_iserializer * bpis_ptr = register_type(ar, *t); + const basic_pointer_iserializer * newbpis_ptr = ar.load_pointer( + // note major hack here !!! + // I tried every way to convert Tptr &t (where Tptr might + // include const) to void * &. This is the only way + // I could make it work. RR + (void * & )t, + bpis_ptr, + find + ); + // if the pointer isn't that of the base class + if(newbpis_ptr != bpis_ptr){ + t = pointer_tweak(newbpis_ptr->get_eti(), t, *t); + } + } +}; + +template +struct load_enum_type { + template + static void invoke(Archive &ar, T &t){ + // convert integers to correct enum to load + int i; + ar >> boost::serialization::make_nvp(NULL, i); + t = static_cast< T >(i); + } +}; + +template +struct load_array_type { + template + static void invoke(Archive &ar, T &t){ + typedef typename remove_extent< T >::type value_type; + + // convert integers to correct enum to load + // determine number of elements in the array. Consider the + // fact that some machines will align elements on boundries + // other than characters. + std::size_t current_count = sizeof(t) / ( + static_cast(static_cast(&t[1])) + - static_cast(static_cast(&t[0])) + ); + boost::serialization::collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(static_cast(count) > current_count) + boost::serialization::throw_exception( + archive::archive_exception( + boost::archive::archive_exception::array_size_too_short + ) + ); + // explict template arguments to pass intel C++ compiler + ar >> serialization::make_array< + value_type, + boost::serialization::collection_size_type + >( + static_cast(&t[0]), + count + ); + } +}; + +} // detail + +template +inline void load(Archive & ar, T &t){ + // if this assertion trips. It means we're trying to load a + // const object with a compiler that doesn't have correct + // function template ordering. On other compilers, this is + // handled below. + detail::check_const_loading< T >(); + typedef + typename mpl::eval_if, + mpl::identity > + ,//else + typename mpl::eval_if, + mpl::identity > + ,//else + typename mpl::eval_if, + mpl::identity > + ,//else + mpl::identity > + > + > + >::type typex; + typex::invoke(ar, t); +} + +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/oserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/oserializer.hpp new file mode 100644 index 00000000000..c120ec55073 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/oserializer.hpp @@ -0,0 +1,540 @@ +#ifndef BOOST_ARCHIVE_OSERIALIZER_HPP +#define BOOST_ARCHIVE_OSERIALIZER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#pragma inline_depth(511) +#pragma inline_recursion(on) +#endif + +#if defined(__MWERKS__) +#pragma inline_depth(511) +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// oserializer.hpp: interface for serialization system. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // NULL + +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO + #include +#endif +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { + +namespace serialization { + class extended_type_info; +} // namespace serialization + +namespace archive { + +// an accessor to permit friend access to archives. Needed because +// some compilers don't handle friend templates completely +class save_access { +public: + template + static void end_preamble(Archive & ar){ + ar.end_preamble(); + } + template + static void save_primitive(Archive & ar, const T & t){ + ar.end_preamble(); + ar.save(t); + } +}; + +namespace detail { + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +template +class oserializer : public basic_oserializer +{ +private: + // private constructor to inhibit any existence other than the + // static one +public: + explicit BOOST_DLLEXPORT oserializer() : + basic_oserializer( + boost::serialization::singleton< + typename + boost::serialization::type_info_implementation< T >::type + >::get_const_instance() + ) + {} + virtual BOOST_DLLEXPORT void save_object_data( + basic_oarchive & ar, + const void *x + ) const BOOST_USED; + virtual bool class_info() const { + return boost::serialization::implementation_level< T >::value + >= boost::serialization::object_class_info; + } + virtual bool tracking(const unsigned int /* flags */) const { + return boost::serialization::tracking_level< T >::value == boost::serialization::track_always + || (boost::serialization::tracking_level< T >::value == boost::serialization::track_selectively + && serialized_as_pointer()); + } + virtual version_type version() const { + return version_type(::boost::serialization::version< T >::value); + } + virtual bool is_polymorphic() const { + return boost::is_polymorphic< T >::value; + } + virtual ~oserializer(){} +}; + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +template +BOOST_DLLEXPORT void oserializer::save_object_data( + basic_oarchive & ar, + const void *x +) const { + // make sure call is routed through the highest interface that might + // be specialized by the user. + BOOST_STATIC_ASSERT(boost::is_const< T >::value == false); + boost::serialization::serialize_adl( + boost::serialization::smart_cast_reference(ar), + * static_cast(const_cast(x)), + version() + ); +} + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +template +class pointer_oserializer : + public basic_pointer_oserializer +{ +private: + const basic_oserializer & + get_basic_serializer() const { + return boost::serialization::singleton< + oserializer + >::get_const_instance(); + } + virtual BOOST_DLLEXPORT void save_object_ptr( + basic_oarchive & ar, + const void * x + ) const BOOST_USED; +public: + pointer_oserializer(); + ~pointer_oserializer(); +}; + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +template +BOOST_DLLEXPORT void pointer_oserializer::save_object_ptr( + basic_oarchive & ar, + const void * x +) const { + BOOST_ASSERT(NULL != x); + // make sure call is routed through the highest interface that might + // be specialized by the user. + T * t = static_cast(const_cast(x)); + const unsigned int file_version = boost::serialization::version< T >::value; + Archive & ar_impl + = boost::serialization::smart_cast_reference(ar); + boost::serialization::save_construct_data_adl( + ar_impl, + t, + file_version + ); + ar_impl << boost::serialization::make_nvp(NULL, * t); +} + +template +pointer_oserializer::pointer_oserializer() : + basic_pointer_oserializer( + boost::serialization::singleton< + typename + boost::serialization::type_info_implementation< T >::type + >::get_const_instance() + ) +{ + // make sure appropriate member function is instantiated + boost::serialization::singleton< + oserializer + >::get_mutable_instance().set_bpos(this); + archive_serializer_map::insert(this); +} + +template +pointer_oserializer::~pointer_oserializer(){ + archive_serializer_map::erase(this); +} + +template +struct save_non_pointer_type { + // note this bounces the call right back to the archive + // with no runtime overhead + struct save_primitive { + template + static void invoke(Archive & ar, const T & t){ + save_access::save_primitive(ar, t); + } + }; + // same as above but passes through serialization + struct save_only { + template + static void invoke(Archive & ar, const T & t){ + // make sure call is routed through the highest interface that might + // be specialized by the user. + boost::serialization::serialize_adl( + ar, + const_cast(t), + ::boost::serialization::version< T >::value + ); + } + }; + // adds class information to the archive. This includes + // serialization level and class version + struct save_standard { + template + static void invoke(Archive &ar, const T & t){ + ar.save_object( + & t, + boost::serialization::singleton< + oserializer + >::get_const_instance() + ); + } + }; + + // adds class information to the archive. This includes + // serialization level and class version + struct save_conditional { + template + static void invoke(Archive &ar, const T &t){ + //if(0 == (ar.get_flags() & no_tracking)) + save_standard::invoke(ar, t); + //else + // save_only::invoke(ar, t); + } + }; + + + template + static void invoke(Archive & ar, const T & t){ + typedef + typename mpl::eval_if< + // if its primitive + mpl::equal_to< + boost::serialization::implementation_level< T >, + mpl::int_ + >, + mpl::identity, + // else + typename mpl::eval_if< + // class info / version + mpl::greater_equal< + boost::serialization::implementation_level< T >, + mpl::int_ + >, + // do standard save + mpl::identity, + // else + typename mpl::eval_if< + // no tracking + mpl::equal_to< + boost::serialization::tracking_level< T >, + mpl::int_ + >, + // do a fast save + mpl::identity, + // else + // do a fast save only tracking is turned off + mpl::identity + > > >::type typex; + check_object_versioning< T >(); + typex::invoke(ar, t); + } + template + static void invoke(Archive & ar, T & t){ + check_object_level< T >(); + check_object_tracking< T >(); + invoke(ar, const_cast(t)); + } +}; + +template +struct save_pointer_type { + struct abstract + { + template + static const basic_pointer_oserializer * register_type(Archive & /* ar */){ + // it has? to be polymorphic + BOOST_STATIC_ASSERT(boost::is_polymorphic< T >::value); + return NULL; + } + }; + + struct non_abstract + { + template + static const basic_pointer_oserializer * register_type(Archive & ar){ + return ar.register_type(static_cast(NULL)); + } + }; + + template + static const basic_pointer_oserializer * register_type(Archive &ar, T & /*t*/){ + // there should never be any need to save an abstract polymorphic + // class pointer. Inhibiting code generation for this + // permits abstract base classes to be used - note: exception + // virtual serialize functions used for plug-ins + typedef + typename mpl::eval_if< + boost::serialization::is_abstract< T >, + mpl::identity, + mpl::identity + >::type typex; + return typex::template register_type< T >(ar); + } + + struct non_polymorphic + { + template + static void save( + Archive &ar, + T & t + ){ + const basic_pointer_oserializer & bpos = + boost::serialization::singleton< + pointer_oserializer + >::get_const_instance(); + // save the requested pointer type + ar.save_pointer(& t, & bpos); + } + }; + + struct polymorphic + { + template + static void save( + Archive &ar, + T & t + ){ + typename + boost::serialization::type_info_implementation< T >::type const + & i = boost::serialization::singleton< + typename + boost::serialization::type_info_implementation< T >::type + >::get_const_instance(); + + boost::serialization::extended_type_info const * const this_type = & i; + + // retrieve the true type of the object pointed to + // if this assertion fails its an error in this library + BOOST_ASSERT(NULL != this_type); + + const boost::serialization::extended_type_info * true_type = + i.get_derived_extended_type_info(t); + + // note:if this exception is thrown, be sure that derived pointer + // is either registered or exported. + if(NULL == true_type){ + boost::serialization::throw_exception( + archive_exception( + archive_exception::unregistered_class, + "derived class not registered or exported" + ) + ); + } + + // if its not a pointer to a more derived type + const void *vp = static_cast(&t); + if(*this_type == *true_type){ + const basic_pointer_oserializer * bpos = register_type(ar, t); + ar.save_pointer(vp, bpos); + return; + } + // convert pointer to more derived type. if this is thrown + // it means that the base/derived relationship hasn't be registered + vp = serialization::void_downcast( + *true_type, + *this_type, + static_cast(&t) + ); + if(NULL == vp){ + boost::serialization::throw_exception( + archive_exception( + archive_exception::unregistered_cast, + true_type->get_debug_info(), + this_type->get_debug_info() + ) + ); + } + + // since true_type is valid, and this only gets made if the + // pointer oserializer object has been created, this should never + // fail + const basic_pointer_oserializer * bpos + = static_cast( + boost::serialization::singleton< + archive_serializer_map + >::get_const_instance().find(*true_type) + ); + BOOST_ASSERT(NULL != bpos); + if(NULL == bpos) + boost::serialization::throw_exception( + archive_exception( + archive_exception::unregistered_class, + "derived class not registered or exported" + ) + ); + ar.save_pointer(vp, bpos); + } + }; + + template + static void save( + Archive & ar, + const T & t + ){ + check_pointer_level< T >(); + check_pointer_tracking< T >(); + typedef typename mpl::eval_if< + is_polymorphic< T >, + mpl::identity, + mpl::identity + >::type type; + type::save(ar, const_cast(t)); + } + + template + static void invoke(Archive &ar, const TPtr t){ + register_type(ar, * t); + if(NULL == t){ + basic_oarchive & boa + = boost::serialization::smart_cast_reference(ar); + boa.save_null_pointer(); + save_access::end_preamble(ar); + return; + } + save(ar, * t); + } +}; + +template +struct save_enum_type +{ + template + static void invoke(Archive &ar, const T &t){ + // convert enum to integers on save + const int i = static_cast(t); + ar << boost::serialization::make_nvp(NULL, i); + } +}; + +template +struct save_array_type +{ + template + static void invoke(Archive &ar, const T &t){ + typedef typename boost::remove_extent< T >::type value_type; + + save_access::end_preamble(ar); + // consider alignment + std::size_t c = sizeof(t) / ( + static_cast(static_cast(&t[1])) + - static_cast(static_cast(&t[0])) + ); + boost::serialization::collection_size_type count(c); + ar << BOOST_SERIALIZATION_NVP(count); + // explict template arguments to pass intel C++ compiler + ar << serialization::make_array< + const value_type, + boost::serialization::collection_size_type + >( + static_cast(&t[0]), + count + ); + } +}; + +} // detail + +template +inline void save(Archive & ar, /*const*/ T &t){ + typedef + typename mpl::eval_if, + mpl::identity >, + //else + typename mpl::eval_if, + mpl::identity >, + //else + typename mpl::eval_if, + mpl::identity >, + //else + mpl::identity > + > + > + >::type typex; + typex::invoke(ar, t); +} + +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_OSERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_iarchive_route.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_iarchive_route.hpp new file mode 100644 index 00000000000..105685ebbd8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_iarchive_route.hpp @@ -0,0 +1,218 @@ +#ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_ROUTE_HPP +#define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_ROUTE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_iarchive_route.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization +namespace archive { +namespace detail{ + +class basic_iserializer; +class basic_pointer_iserializer; + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +template +class polymorphic_iarchive_route : + public polymorphic_iarchive, + // note: gcc dynamic cross cast fails if the the derivation below is + // not public. I think this is a mistake. + public /*protected*/ ArchiveImplementation +{ +private: + // these are used by the serialization library. + virtual void load_object( + void *t, + const basic_iserializer & bis + ){ + ArchiveImplementation::load_object(t, bis); + } + virtual const basic_pointer_iserializer * load_pointer( + void * & t, + const basic_pointer_iserializer * bpis_ptr, + const basic_pointer_iserializer * (*finder)( + const boost::serialization::extended_type_info & type + ) + ){ + return ArchiveImplementation::load_pointer(t, bpis_ptr, finder); + } + virtual void set_library_version(library_version_type archive_library_version){ + ArchiveImplementation::set_library_version(archive_library_version); + } + virtual library_version_type get_library_version() const{ + return ArchiveImplementation::get_library_version(); + } + virtual unsigned int get_flags() const { + return ArchiveImplementation::get_flags(); + } + virtual void delete_created_pointers(){ + ArchiveImplementation::delete_created_pointers(); + } + virtual void reset_object_address( + const void * new_address, + const void * old_address + ){ + ArchiveImplementation::reset_object_address(new_address, old_address); + } + virtual void load_binary(void * t, std::size_t size){ + ArchiveImplementation::load_binary(t, size); + } + // primitive types the only ones permitted by polymorphic archives + virtual void load(bool & t){ + ArchiveImplementation::load(t); + } + virtual void load(char & t){ + ArchiveImplementation::load(t); + } + virtual void load(signed char & t){ + ArchiveImplementation::load(t); + } + virtual void load(unsigned char & t){ + ArchiveImplementation::load(t); + } + #ifndef BOOST_NO_CWCHAR + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + virtual void load(wchar_t & t){ + ArchiveImplementation::load(t); + } + #endif + #endif + virtual void load(short & t){ + ArchiveImplementation::load(t); + } + virtual void load(unsigned short & t){ + ArchiveImplementation::load(t); + } + virtual void load(int & t){ + ArchiveImplementation::load(t); + } + virtual void load(unsigned int & t){ + ArchiveImplementation::load(t); + } + virtual void load(long & t){ + ArchiveImplementation::load(t); + } + virtual void load(unsigned long & t){ + ArchiveImplementation::load(t); + } + #if defined(BOOST_HAS_LONG_LONG) + virtual void load(boost::long_long_type & t){ + ArchiveImplementation::load(t); + } + virtual void load(boost::ulong_long_type & t){ + ArchiveImplementation::load(t); + } + #elif defined(BOOST_HAS_MS_INT64) + virtual void load(__int64 & t){ + ArchiveImplementation::load(t); + } + virtual void load(unsigned __int64 & t){ + ArchiveImplementation::load(t); + } + #endif + virtual void load(float & t){ + ArchiveImplementation::load(t); + } + virtual void load(double & t){ + ArchiveImplementation::load(t); + } + virtual void load(std::string & t){ + ArchiveImplementation::load(t); + } + #ifndef BOOST_NO_STD_WSTRING + virtual void load(std::wstring & t){ + ArchiveImplementation::load(t); + } + #endif + // used for xml and other tagged formats default does nothing + virtual void load_start(const char * name){ + ArchiveImplementation::load_start(name); + } + virtual void load_end(const char * name){ + ArchiveImplementation::load_end(name); + } + virtual void register_basic_serializer(const basic_iserializer & bis){ + ArchiveImplementation::register_basic_serializer(bis); + } + virtual helper_collection & + get_helper_collection(){ + return ArchiveImplementation::get_helper_collection(); + } +public: + // this can't be inheriteded because they appear in mulitple + // parents + typedef mpl::bool_ is_loading; + typedef mpl::bool_ is_saving; + // the >> operator + template + polymorphic_iarchive & operator>>(T & t){ + return polymorphic_iarchive::operator>>(t); + } + // the & operator + template + polymorphic_iarchive & operator&(T & t){ + return polymorphic_iarchive::operator&(t); + } + // register type function + template + const basic_pointer_iserializer * + register_type(T * t = NULL){ + return ArchiveImplementation::register_type(t); + } + // all current archives take a stream as constructor argument + template + polymorphic_iarchive_route( + std::basic_istream<_Elem, _Tr> & is, + unsigned int flags = 0 + ) : + ArchiveImplementation(is, flags) + {} + virtual ~polymorphic_iarchive_route(){}; +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_DISPATCH_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_oarchive_route.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_oarchive_route.hpp new file mode 100644 index 00000000000..b23fd6bf39d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_oarchive_route.hpp @@ -0,0 +1,209 @@ +#ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_ROUTE_HPP +#define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_ROUTE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_oarchive_route.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include // size_t + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include // must be the last header + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization +namespace archive { +namespace detail{ + +class basic_oserializer; +class basic_pointer_oserializer; + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +template +class polymorphic_oarchive_route : + public polymorphic_oarchive, + // note: gcc dynamic cross cast fails if the the derivation below is + // not public. I think this is a mistake. + public /*protected*/ ArchiveImplementation +{ +private: + // these are used by the serialization library. + virtual void save_object( + const void *x, + const detail::basic_oserializer & bos + ){ + ArchiveImplementation::save_object(x, bos); + } + virtual void save_pointer( + const void * t, + const detail::basic_pointer_oserializer * bpos_ptr + ){ + ArchiveImplementation::save_pointer(t, bpos_ptr); + } + virtual void save_null_pointer(){ + ArchiveImplementation::save_null_pointer(); + } + // primitive types the only ones permitted by polymorphic archives + virtual void save(const bool t){ + ArchiveImplementation::save(t); + } + virtual void save(const char t){ + ArchiveImplementation::save(t); + } + virtual void save(const signed char t){ + ArchiveImplementation::save(t); + } + virtual void save(const unsigned char t){ + ArchiveImplementation::save(t); + } + #ifndef BOOST_NO_CWCHAR + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + virtual void save(const wchar_t t){ + ArchiveImplementation::save(t); + } + #endif + #endif + virtual void save(const short t){ + ArchiveImplementation::save(t); + } + virtual void save(const unsigned short t){ + ArchiveImplementation::save(t); + } + virtual void save(const int t){ + ArchiveImplementation::save(t); + } + virtual void save(const unsigned int t){ + ArchiveImplementation::save(t); + } + virtual void save(const long t){ + ArchiveImplementation::save(t); + } + virtual void save(const unsigned long t){ + ArchiveImplementation::save(t); + } + #if defined(BOOST_HAS_LONG_LONG) + virtual void save(const boost::long_long_type t){ + ArchiveImplementation::save(t); + } + virtual void save(const boost::ulong_long_type t){ + ArchiveImplementation::save(t); + } + #elif defined(BOOST_HAS_MS_INT64) + virtual void save(const boost::int64_t t){ + ArchiveImplementation::save(t); + } + virtual void save(const boost::uint64_t t){ + ArchiveImplementation::save(t); + } + #endif + virtual void save(const float t){ + ArchiveImplementation::save(t); + } + virtual void save(const double t){ + ArchiveImplementation::save(t); + } + virtual void save(const std::string & t){ + ArchiveImplementation::save(t); + } + #ifndef BOOST_NO_STD_WSTRING + virtual void save(const std::wstring & t){ + ArchiveImplementation::save(t); + } + #endif + virtual library_version_type get_library_version() const{ + return ArchiveImplementation::get_library_version(); + } + virtual unsigned int get_flags() const { + return ArchiveImplementation::get_flags(); + } + virtual void save_binary(const void * t, std::size_t size){ + ArchiveImplementation::save_binary(t, size); + } + // used for xml and other tagged formats default does nothing + virtual void save_start(const char * name){ + ArchiveImplementation::save_start(name); + } + virtual void save_end(const char * name){ + ArchiveImplementation::save_end(name); + } + virtual void end_preamble(){ + ArchiveImplementation::end_preamble(); + } + virtual void register_basic_serializer(const detail::basic_oserializer & bos){ + ArchiveImplementation::register_basic_serializer(bos); + } + virtual helper_collection & + get_helper_collection(){ + return ArchiveImplementation::get_helper_collection(); + } +public: + // this can't be inheriteded because they appear in mulitple + // parents + typedef mpl::bool_ is_loading; + typedef mpl::bool_ is_saving; + // the << operator + template + polymorphic_oarchive & operator<<(T & t){ + return polymorphic_oarchive::operator<<(t); + } + // the & operator + template + polymorphic_oarchive & operator&(T & t){ + return polymorphic_oarchive::operator&(t); + } + // register type function + template + const basic_pointer_oserializer * + register_type(T * t = NULL){ + return ArchiveImplementation::register_type(t); + } + // all current archives take a stream as constructor argument + template + polymorphic_oarchive_route( + std::basic_ostream<_Elem, _Tr> & os, + unsigned int flags = 0 + ) : + ArchiveImplementation(os, flags) + {} + virtual ~polymorphic_oarchive_route(){}; +}; + +} // namespace detail +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_DISPATCH_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/register_archive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/register_archive.hpp new file mode 100644 index 00000000000..5ffecc702ce --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/register_archive.hpp @@ -0,0 +1,91 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_ARCHIVE_DETAIL_REGISTER_ARCHIVE_DWA2006521_HPP +# define BOOST_ARCHIVE_DETAIL_REGISTER_ARCHIVE_DWA2006521_HPP + +namespace boost { namespace archive { namespace detail { + +// No instantiate_ptr_serialization overloads generated by +// BOOST_SERIALIZATION_REGISTER_ARCHIVE that lexically follow the call +// will be seen *unless* they are in an associated namespace of one of +// the arguments, so we pass one of these along to make sure this +// namespace is considered. See temp.dep.candidate (14.6.4.2) in the +// standard. +struct adl_tag {}; + +template +struct ptr_serialization_support; + +// We could've just used ptr_serialization_support, above, but using +// it with only a forward declaration causes vc6/7 to complain about a +// missing instantiate member, even if it has one. This is just a +// friendly layer of indirection. +template +struct _ptr_serialization_support + : ptr_serialization_support +{ + typedef int type; +}; + +#if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5130) + +template +struct counter : counter {}; +template<> +struct counter<0> {}; + +template +void instantiate_ptr_serialization(Serializable* s, int, adl_tag) { + instantiate_ptr_serialization(s, counter<20>()); +} + +template +struct get_counter { + static const int value = sizeof(adjust_counter(counter<20>())); + typedef counter type; + typedef counter prior; + typedef char (&next)[value+1]; +}; + +char adjust_counter(counter<0>); +template +void instantiate_ptr_serialization(Serializable*, counter<0>) {} + +#define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive) \ +namespace boost { namespace archive { namespace detail { \ + get_counter::next adjust_counter(get_counter::type);\ + template \ + void instantiate_ptr_serialization(Serializable* s, \ + get_counter::type) { \ + ptr_serialization_support x; \ + instantiate_ptr_serialization(s, get_counter::prior()); \ + }\ +}}} + + +#else + +// This function gets called, but its only purpose is to participate +// in overload resolution with the functions declared by +// BOOST_SERIALIZATION_REGISTER_ARCHIVE, below. +template +void instantiate_ptr_serialization(Serializable*, int, adl_tag ) {} + +// The function declaration generated by this macro never actually +// gets called, but its return type gets instantiated, and that's +// enough to cause registration of serialization functions between +// Archive and any exported Serializable type. See also: +// boost/serialization/export.hpp +# define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive) \ +namespace boost { namespace archive { namespace detail { \ + \ +template \ +typename _ptr_serialization_support::type \ +instantiate_ptr_serialization( Serializable*, Archive*, adl_tag ); \ + \ +}}} +#endif +}}} // namespace boost::archive::detail + +#endif // BOOST_ARCHIVE_DETAIL_INSTANTIATE_SERIALIZE_DWA2006521_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/utf8_codecvt_facet.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/utf8_codecvt_facet.hpp new file mode 100644 index 00000000000..a40104abea6 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/detail/utf8_codecvt_facet.hpp @@ -0,0 +1,39 @@ +// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu) +// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP +#define BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP + +#include + +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#endif + +// std::codecvt_utf8 doesn't seem to work for any versions of msvc + +#if defined(_MSC_VER) || defined(BOOST_NO_CXX11_HDR_CODECVT) + // use boost's utf8 codecvt facet + #include + #define BOOST_UTF8_BEGIN_NAMESPACE \ + namespace boost { namespace archive { namespace detail { + #define BOOST_UTF8_DECL BOOST_ARCHIVE_DECL + #define BOOST_UTF8_END_NAMESPACE }}} + + #include + + #undef BOOST_UTF8_END_NAMESPACE + #undef BOOST_UTF8_DECL + #undef BOOST_UTF8_BEGIN_NAMESPACE +#else + // use the standard vendor supplied facet + #include + namespace boost { namespace archive { namespace detail { + typedef std::codecvt_utf8 utf8_codecvt_facet; + } } } +#endif + +#endif // BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/dinkumware.hpp b/contrib/libboost/boost_1_65_0/boost/archive/dinkumware.hpp new file mode 100644 index 00000000000..90ba6271cdd --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/dinkumware.hpp @@ -0,0 +1,224 @@ +#ifndef BOOST_ARCHIVE_DINKUMWARE_HPP +#define BOOST_ARCHIVE_DINKUMWARE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// dinkumware.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// this file adds a couple of things that are missing from the dinkumware +// implementation of the standard library. + +#include +#include + +#include +#include + +namespace std { + +// define i/o operators for 64 bit integers +template +basic_ostream & +operator<<(basic_ostream & os, boost::uint64_t t){ + // octal rendering of 64 bit number would be 22 octets + eos + CharType d[23]; + unsigned int radix; + + if(os.flags() & (int)std::ios_base::hex) + radix = 16; + else + if(os.flags() & (int)std::ios_base::oct) + radix = 8; + else + //if(s.flags() & (int)std::ios_base::dec) + radix = 10; + unsigned int i = 0; + do{ + unsigned int j = t % radix; + d[i++] = j + ((j < 10) ? '0' : ('a' - 10)); + t /= radix; + } + while(t > 0); + d[i--] = '\0'; + + // reverse digits + unsigned int j = 0; + while(j < i){ + CharType k = d[i]; + d[i] = d[j]; + d[j] = k; + --i;++j; + } + os << d; + return os; + +} + +template +basic_ostream & +operator<<(basic_ostream &os, boost::int64_t t){ + if(0 <= t){ + os << static_cast(t); + } + else{ + os.put('-'); + os << -t; + } + return os; +} + +template +basic_istream & +operator>>(basic_istream &is, boost::int64_t & t){ + CharType d; + do{ + d = is.get(); + } + while(::isspace(d)); + bool negative = (d == '-'); + if(negative) + d = is.get(); + unsigned int radix; + if(is.flags() & (int)std::ios_base::hex) + radix = 16; + else + if(is.flags() & (int)std::ios_base::oct) + radix = 8; + else + //if(s.flags() & (int)std::ios_base::dec) + radix = 10; + t = 0; + do{ + if('0' <= d && d <= '9') + t = t * radix + (d - '0'); + else + if('a' <= d && d <= 'f') + t = t * radix + (d - 'a' + 10); + else + break; + d = is.get(); + } + while(!is.fail()); + // restore the delimiter + is.putback(d); + is.clear(); + if(negative) + t = -t; + return is; +} + +template +basic_istream & +operator>>(basic_istream &is, boost::uint64_t & t){ + boost::int64_t it; + is >> it; + t = it; + return is; +} + +//#endif + +template<> +class back_insert_iterator > : public + iterator +{ +public: + typedef basic_string container_type; + typedef container_type::reference reference; + + explicit back_insert_iterator(container_type & s) + : container(& s) + {} // construct with container + + back_insert_iterator & operator=( + container_type::const_reference Val_ + ){ // push value into container + //container->push_back(Val_); + *container += Val_; + return (*this); + } + + back_insert_iterator & operator*(){ + return (*this); + } + + back_insert_iterator & operator++(){ + // pretend to preincrement + return (*this); + } + + back_insert_iterator operator++(int){ + // pretend to postincrement + return (*this); + } + +protected: + container_type *container; // pointer to container +}; + +template +inline back_insert_iterator > back_inserter( + basic_string & s +){ + return (std::back_insert_iterator >(s)); +} + +template<> +class back_insert_iterator > : public + iterator +{ +public: + typedef basic_string container_type; + typedef container_type::reference reference; + + explicit back_insert_iterator(container_type & s) + : container(& s) + {} // construct with container + + back_insert_iterator & operator=( + container_type::const_reference Val_ + ){ // push value into container + //container->push_back(Val_); + *container += Val_; + return (*this); + } + + back_insert_iterator & operator*(){ + return (*this); + } + + back_insert_iterator & operator++(){ + // pretend to preincrement + return (*this); + } + + back_insert_iterator operator++(int){ + // pretend to postincrement + return (*this); + } + +protected: + container_type *container; // pointer to container +}; + +template +inline back_insert_iterator > back_inserter( + basic_string & s +){ + return (std::back_insert_iterator >(s)); +} + +} // namespace std + +#endif //BOOST_ARCHIVE_DINKUMWARE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/archive_serializer_map.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/archive_serializer_map.ipp new file mode 100644 index 00000000000..7f163ec4076 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/archive_serializer_map.ipp @@ -0,0 +1,75 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// archive_serializer_map.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +////////////////////////////////////////////////////////////////////// +// implementation of basic_text_iprimitive overrides for the combination +// of template parameters used to implement a text_iprimitive + +#include +#include +#include +#include + +namespace boost { +namespace archive { +namespace detail { + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace extra_detail { // anon + template + class map : public basic_serializer_map + {}; +} + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL bool +archive_serializer_map::insert(const basic_serializer * bs){ + return boost::serialization::singleton< + extra_detail::map + >::get_mutable_instance().insert(bs); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +archive_serializer_map::erase(const basic_serializer * bs){ + BOOST_ASSERT(! boost::serialization::singleton< + extra_detail::map + >::is_destroyed() + ); + if(boost::serialization::singleton< + extra_detail::map + >::is_destroyed()) + return; + boost::serialization::singleton< + extra_detail::map + >::get_mutable_instance().erase(bs); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL const basic_serializer * +archive_serializer_map::find( + const boost::serialization::extended_type_info & eti +) { + return boost::serialization::singleton< + extra_detail::map + >::get_const_instance().find(eti); +} + +} // namespace detail +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iarchive.ipp new file mode 100644 index 00000000000..d5619ab6cf3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iarchive.ipp @@ -0,0 +1,134 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_iarchive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include +#include +#include +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; + using ::strlen; + using ::size_t; +} +#endif + +#include +#include + +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation of binary_binary_archive +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_iarchive::load_override(class_name_type & t){ + std::string cn; + cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE); + load_override(cn); + if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)) + boost::serialization::throw_exception( + archive_exception(archive_exception::invalid_class_name) + ); + std::memcpy(t, cn.data(), cn.size()); + // borland tweak + t.t[cn.size()] = '\0'; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_iarchive::init(void){ + // read signature in an archive version independent manner + std::string file_signature; + + #if 0 // commented out since it interfers with derivation + BOOST_TRY { + std::size_t l; + this->This()->load(l); + if(l == std::strlen(BOOST_ARCHIVE_SIGNATURE())) { + // borland de-allocator fixup + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != file_signature.data()) + #endif + file_signature.resize(l); + // note breaking a rule here - could be a problem on some platform + if(0 < l) + this->This()->load_binary(&(*file_signature.begin()), l); + } + } + BOOST_CATCH(archive_exception const &) { // catch stream_error archive exceptions + // will cause invalid_signature archive exception to be thrown below + file_signature = ""; + } + BOOST_CATCH_END + #else + // https://svn.boost.org/trac/boost/ticket/7301 + * this->This() >> file_signature; + #endif + + if(file_signature != BOOST_ARCHIVE_SIGNATURE()) + boost::serialization::throw_exception( + archive_exception(archive_exception::invalid_signature) + ); + + // make sure the version of the reading archive library can + // support the format of the archive being read + library_version_type input_library_version; + //* this->This() >> input_library_version; + { + int v = 0; + v = this->This()->m_sb.sbumpc(); + #if defined(BOOST_LITTLE_ENDIAN) + if(v < 6){ + ; + } + else + if(v < 7){ + // version 6 - next byte should be zero + this->This()->m_sb.sbumpc(); + } + else + if(v < 8){ + int x1; + // version 7 = might be followed by zero or some other byte + x1 = this->This()->m_sb.sgetc(); + // it's =a zero, push it back + if(0 == x1) + this->This()->m_sb.sbumpc(); + } + else{ + // version 8+ followed by a zero + this->This()->m_sb.sbumpc(); + } + #elif defined(BOOST_BIG_ENDIAN) + if(v == 0) + v = this->This()->m_sb.sbumpc(); + #endif + input_library_version = static_cast(v); + } + + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + this->set_library_version(input_library_version); + #else + detail::basic_iarchive::set_library_version(input_library_version); + #endif + + if(BOOST_ARCHIVE_VERSION() < input_library_version) + boost::serialization::throw_exception( + archive_exception(archive_exception::unsupported_version) + ); +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iprimitive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iprimitive.ipp new file mode 100644 index 00000000000..bbe933ccf63 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iprimitive.ipp @@ -0,0 +1,171 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_iprimitive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // size_t, NULL +#include // memcpy + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; + using ::memcpy; +} // namespace std +#endif + +#include +#include +#include +#include + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// implementation of basic_binary_iprimitive + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_iprimitive::init() +{ + // Detect attempts to pass native binary archives across + // incompatible platforms. This is not fool proof but its + // better than nothing. + unsigned char size; + this->This()->load(size); + if(sizeof(int) != size) + boost::serialization::throw_exception( + archive_exception( + archive_exception::incompatible_native_format, + "size of int" + ) + ); + this->This()->load(size); + if(sizeof(long) != size) + boost::serialization::throw_exception( + archive_exception( + archive_exception::incompatible_native_format, + "size of long" + ) + ); + this->This()->load(size); + if(sizeof(float) != size) + boost::serialization::throw_exception( + archive_exception( + archive_exception::incompatible_native_format, + "size of float" + ) + ); + this->This()->load(size); + if(sizeof(double) != size) + boost::serialization::throw_exception( + archive_exception( + archive_exception::incompatible_native_format, + "size of double" + ) + ); + + // for checking endian + int i; + this->This()->load(i); + if(1 != i) + boost::serialization::throw_exception( + archive_exception( + archive_exception::incompatible_native_format, + "endian setting" + ) + ); +} + +#ifndef BOOST_NO_CWCHAR +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_iprimitive::load(wchar_t * ws) +{ + std::size_t l; // number of wchar_t !!! + this->This()->load(l); + load_binary(ws, l * sizeof(wchar_t) / sizeof(char)); + ws[l] = L'\0'; +} +#endif + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_iprimitive::load(std::string & s) +{ + std::size_t l; + this->This()->load(l); + // borland de-allocator fixup + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != s.data()) + #endif + s.resize(l); + // note breaking a rule here - could be a problem on some platform + if(0 < l) + load_binary(&(*s.begin()), l); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_iprimitive::load(char * s) +{ + std::size_t l; + this->This()->load(l); + load_binary(s, l); + s[l] = '\0'; +} + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_iprimitive::load(std::wstring & ws) +{ + std::size_t l; + this->This()->load(l); + // borland de-allocator fixup + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != ws.data()) + #endif + ws.resize(l); + // note breaking a rule here - is could be a problem on some platform + load_binary(const_cast(ws.data()), l * sizeof(wchar_t) / sizeof(char)); +} +#endif + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_binary_iprimitive::basic_binary_iprimitive( + std::basic_streambuf & sb, + bool no_codecvt +) : +#ifndef BOOST_NO_STD_LOCALE + m_sb(sb), + codecvt_null_facet(1), + locale_saver(m_sb), + archive_locale(sb.getloc(), & codecvt_null_facet) +{ + if(! no_codecvt){ + m_sb.pubsync(); + m_sb.pubimbue(archive_locale); + } +} +#else + m_sb(sb) +{} +#endif + +// scoped_ptr requires that g be a complete type at time of +// destruction so define destructor here rather than in the header +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_binary_iprimitive::~basic_binary_iprimitive(){} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oarchive.ipp new file mode 100644 index 00000000000..d5a019d32bc --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oarchive.ipp @@ -0,0 +1,42 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_oarchive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include +#include +#include +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; +} +#endif + +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation of binary_binary_oarchive + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_oarchive::init(){ + // write signature in an archive version independent manner + const std::string file_signature(BOOST_ARCHIVE_SIGNATURE()); + * this->This() << file_signature; + // write library version + const library_version_type v(BOOST_ARCHIVE_VERSION()); + * this->This() << v; +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oprimitive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oprimitive.ipp new file mode 100644 index 00000000000..7b042173a48 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oprimitive.ipp @@ -0,0 +1,126 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_binary_oprimitive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // NULL +#include + +#include + +#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__) +namespace std{ + using ::strlen; +} // namespace std +#endif + +#ifndef BOOST_NO_CWCHAR +#include +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ using ::wcslen; } +#endif +#endif + +#include +#include + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// implementation of basic_binary_oprimitive + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_oprimitive::init() +{ + // record native sizes of fundamental types + // this is to permit detection of attempts to pass + // native binary archives accross incompatible machines. + // This is not foolproof but its better than nothing. + this->This()->save(static_cast(sizeof(int))); + this->This()->save(static_cast(sizeof(long))); + this->This()->save(static_cast(sizeof(float))); + this->This()->save(static_cast(sizeof(double))); + // for checking endianness + this->This()->save(int(1)); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_oprimitive::save(const char * s) +{ + std::size_t l = std::strlen(s); + this->This()->save(l); + save_binary(s, l); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_oprimitive::save(const std::string &s) +{ + std::size_t l = static_cast(s.size()); + this->This()->save(l); + save_binary(s.data(), l); +} + +#ifndef BOOST_NO_CWCHAR +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_oprimitive::save(const wchar_t * ws) +{ + std::size_t l = std::wcslen(ws); + this->This()->save(l); + save_binary(ws, l * sizeof(wchar_t) / sizeof(char)); +} +#endif + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_binary_oprimitive::save(const std::wstring &ws) +{ + std::size_t l = ws.size(); + this->This()->save(l); + save_binary(ws.data(), l * sizeof(wchar_t) / sizeof(char)); +} +#endif +#endif // BOOST_NO_CWCHAR + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_binary_oprimitive::basic_binary_oprimitive( + std::basic_streambuf & sb, + bool no_codecvt +) : +#ifndef BOOST_NO_STD_LOCALE + m_sb(sb), + codecvt_null_facet(1), + locale_saver(m_sb), + archive_locale(sb.getloc(), & codecvt_null_facet) +{ + if(! no_codecvt){ + m_sb.pubsync(); + m_sb.pubimbue(archive_locale); + } +} +#else + m_sb(sb) +{} +#endif + +// scoped_ptr requires that g be a complete type at time of +// destruction so define destructor here rather than in the header +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_binary_oprimitive::~basic_binary_oprimitive(){} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iarchive.ipp new file mode 100644 index 00000000000..9ec8c6588c8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iarchive.ipp @@ -0,0 +1,76 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_iarchive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include +#include +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; +} +#endif + +#include +#include +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation of text_text_archive + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_text_iarchive::load_override(class_name_type & t){ + std::string cn; + cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE); + load_override(cn); + if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)) + boost::serialization::throw_exception( + archive_exception(archive_exception::invalid_class_name) + ); + std::memcpy(t, cn.data(), cn.size()); + // borland tweak + t.t[cn.size()] = '\0'; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_text_iarchive::init(void){ + // read signature in an archive version independent manner + std::string file_signature; + * this->This() >> file_signature; + if(file_signature != BOOST_ARCHIVE_SIGNATURE()) + boost::serialization::throw_exception( + archive_exception(archive_exception::invalid_signature) + ); + + // make sure the version of the reading archive library can + // support the format of the archive being read + library_version_type input_library_version; + * this->This() >> input_library_version; + + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + this->set_library_version(input_library_version); + #else + detail::basic_iarchive::set_library_version(input_library_version); + #endif + + // extra little .t is to get around borland quirk + if(BOOST_ARCHIVE_VERSION() < input_library_version) + boost::serialization::throw_exception( + archive_exception(archive_exception::unsupported_version) + ); +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iprimitive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iprimitive.ipp new file mode 100644 index 00000000000..4e44728068d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iprimitive.ipp @@ -0,0 +1,137 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_iprimitive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // size_t, NULL +#include // NULL + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include + +#include + +#include +#include +#include +#include + +namespace boost { +namespace archive { + +namespace detail { + template + static inline bool is_whitespace(CharType c); + + template<> + inline bool is_whitespace(char t){ + return 0 != std::isspace(t); + } + + #ifndef BOOST_NO_CWCHAR + template<> + inline bool is_whitespace(wchar_t t){ + return 0 != std::iswspace(t); + } + #endif +} // detail + +// translate base64 text into binary and copy into buffer +// until buffer is full. +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_text_iprimitive::load_binary( + void *address, + std::size_t count +){ + typedef typename IStream::char_type CharType; + + if(0 == count) + return; + + BOOST_ASSERT( + static_cast((std::numeric_limits::max)()) + > (count + sizeof(CharType) - 1)/sizeof(CharType) + ); + + if(is.fail()) + boost::serialization::throw_exception( + archive_exception(archive_exception::input_stream_error) + ); + // convert from base64 to binary + typedef typename + iterators::transform_width< + iterators::binary_from_base64< + iterators::remove_whitespace< + iterators::istream_iterator + > + ,typename IStream::int_type + > + ,8 + ,6 + ,CharType + > + binary; + + binary i = binary(iterators::istream_iterator(is)); + + char * caddr = static_cast(address); + + // take care that we don't increment anymore than necessary + while(count-- > 0){ + *caddr++ = static_cast(*i++); + } + + // skip over any excess input + for(;;){ + typename IStream::int_type r; + r = is.get(); + if(is.eof()) + break; + if(detail::is_whitespace(static_cast(r))) + break; + } +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_text_iprimitive::basic_text_iprimitive( + IStream &is_, + bool no_codecvt +) : + is(is_), + flags_saver(is_), + precision_saver(is_), +#ifndef BOOST_NO_STD_LOCALE + codecvt_null_facet(1), + archive_locale(is.getloc(), & codecvt_null_facet), + locale_saver(is) +{ + if(! no_codecvt){ + is_.sync(); + is_.imbue(archive_locale); + } + is_ >> std::noboolalpha; +} +#else +{} +#endif + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_text_iprimitive::~basic_text_iprimitive(){ +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oarchive.ipp new file mode 100644 index 00000000000..44bc1401fd6 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oarchive.ipp @@ -0,0 +1,62 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_oarchive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include +#include +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; +} +#endif + +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation of basic_text_oarchive + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_text_oarchive::newtoken() +{ + switch(delimiter){ + default: + BOOST_ASSERT(false); + break; + case eol: + this->This()->put('\n'); + delimiter = space; + break; + case space: + this->This()->put(' '); + break; + case none: + delimiter = space; + break; + } +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_text_oarchive::init(){ + // write signature in an archive version independent manner + const std::string file_signature(BOOST_ARCHIVE_SIGNATURE()); + * this->This() << file_signature; + // write library version + const library_version_type v(BOOST_ARCHIVE_VERSION()); + * this->This() << v; +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oprimitive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oprimitive.ipp new file mode 100644 index 00000000000..6030fd44c57 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oprimitive.ipp @@ -0,0 +1,115 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_text_oprimitive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // NULL +#include // std::copy +#include // std::uncaught_exception +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include + +#include +#include +#include +#include + +namespace boost { +namespace archive { + +// translate to base64 and copy in to buffer. +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_text_oprimitive::save_binary( + const void *address, + std::size_t count +){ + typedef typename OStream::char_type CharType; + + if(0 == count) + return; + + if(os.fail()) + boost::serialization::throw_exception( + archive_exception(archive_exception::output_stream_error) + ); + + os.put('\n'); + + typedef + boost::archive::iterators::insert_linebreaks< + boost::archive::iterators::base64_from_binary< + boost::archive::iterators::transform_width< + const char *, + 6, + 8 + > + > + ,76 + ,const char // cwpro8 needs this + > + base64_text; + + boost::archive::iterators::ostream_iterator oi(os); + std::copy( + base64_text(static_cast(address)), + base64_text( + static_cast(address) + count + ), + oi + ); + + std::size_t tail = count % 3; + if(tail > 0){ + *oi++ = '='; + if(tail < 2) + *oi = '='; + } +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_text_oprimitive::basic_text_oprimitive( + OStream & os_, + bool no_codecvt +) : + os(os_), + flags_saver(os_), + precision_saver(os_), +#ifndef BOOST_NO_STD_LOCALE + codecvt_null_facet(1), + archive_locale(os.getloc(), & codecvt_null_facet), + locale_saver(os) +{ + if(! no_codecvt){ + os_.flush(); + os_.imbue(archive_locale); + } + os_ << std::noboolalpha; +} +#else +{} +#endif + + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_text_oprimitive::~basic_text_oprimitive(){ + if(std::uncaught_exception()) + return; + os << std::endl; +} + +} //namespace boost +} //namespace archive diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_grammar.hpp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_grammar.hpp new file mode 100644 index 00000000000..6d4e4683f6a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_grammar.hpp @@ -0,0 +1,173 @@ +#ifndef BOOST_ARCHIVE_BASIC_XML_GRAMMAR_HPP +#define BOOST_ARCHIVE_BASIC_XML_GRAMMAR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_grammar.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// this module is derived from simplexml.cpp - an example shipped as part of +// the spirit parser. This example contains the following notice: +/*============================================================================= + simplexml.cpp + + Spirit V1.3 + URL: http://spirit.sourceforge.net/ + + Copyright (c) 2001, Daniel C. Nuffer + + This software is provided 'as-is', without any express or implied + warranty. In no event will the copyright holder be held liable for + any damages arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute + it freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product documentation + would be appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +=============================================================================*/ +#include + +#include +#include + +#include +#include + +#include +#include +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// XML grammar parsing + +template +class basic_xml_grammar { +public: + // The following is not necessary according to DR45, but at least + // one compiler (Compaq C++ 6.5 in strict_ansi mode) chokes otherwise. + struct return_values; + friend struct return_values; + +private: + typedef typename std::basic_istream IStream; + typedef typename std::basic_string StringType; + typedef typename boost::spirit::classic::chset chset_t; + typedef typename boost::spirit::classic::chlit chlit_t; + typedef typename boost::spirit::classic::scanner< + typename std::basic_string::iterator + > scanner_t; + typedef typename boost::spirit::classic::rule rule_t; + // Start grammar definition + rule_t + Reference, + Eq, + STag, + ETag, + LetterOrUnderscoreOrColon, + AttValue, + CharRef1, + CharRef2, + CharRef, + AmpRef, + LTRef, + GTRef, + AposRef, + QuoteRef, + CharData, + CharDataChars, + content, + AmpName, + LTName, + GTName, + ClassNameChar, + ClassName, + Name, + XMLDecl, + XMLDeclChars, + DocTypeDecl, + DocTypeDeclChars, + ClassIDAttribute, + ObjectIDAttribute, + ClassNameAttribute, + TrackingAttribute, + VersionAttribute, + UnusedAttribute, + Attribute, + SignatureAttribute, + SerializationWrapper, + NameHead, + NameTail, + AttributeList, + S; + + // XML Character classes + chset_t + BaseChar, + Ideographic, + Char, + Letter, + Digit, + CombiningChar, + Extender, + Sch, + NameChar; + + void init_chset(); + + bool my_parse( + IStream & is, + const rule_t &rule_, + const CharType delimiter = L'>' + ) const ; +public: + struct return_values { + StringType object_name; + StringType contents; + //class_id_type class_id; + int_least16_t class_id; + //object_id_type object_id; + uint_least32_t object_id; + //version_type version; + unsigned int version; + tracking_type tracking_level; + StringType class_name; + return_values() : + version(0), + tracking_level(false) + {} + } rv; + bool parse_start_tag(IStream & is) /*const*/; + bool parse_end_tag(IStream & is) const; + bool parse_string(IStream & is, StringType & s) /*const*/; + void init(IStream & is); + bool windup(IStream & is); + basic_xml_grammar(); +}; + +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_BASIC_XML_GRAMMAR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_iarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_iarchive.ipp new file mode 100644 index 00000000000..625458b9eb5 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_iarchive.ipp @@ -0,0 +1,115 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_iarchive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // NULL +#include + +#include +#include +#include +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation of xml_text_archive + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_iarchive::load_start(const char *name){ + // if there's no name + if(NULL == name) + return; + bool result = this->This()->gimpl->parse_start_tag(this->This()->get_is()); + if(true != result){ + boost::serialization::throw_exception( + archive_exception(archive_exception::input_stream_error) + ); + } + // don't check start tag at highest level + ++depth; + return; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_iarchive::load_end(const char *name){ + // if there's no name + if(NULL == name) + return; + bool result = this->This()->gimpl->parse_end_tag(this->This()->get_is()); + if(true != result){ + boost::serialization::throw_exception( + archive_exception(archive_exception::input_stream_error) + ); + } + + // don't check start tag at highest level + if(0 == --depth) + return; + + if(0 == (this->get_flags() & no_xml_tag_checking)){ + // double check that the tag matches what is expected - useful for debug + if(0 != name[this->This()->gimpl->rv.object_name.size()] + || ! std::equal( + this->This()->gimpl->rv.object_name.begin(), + this->This()->gimpl->rv.object_name.end(), + name + ) + ){ + boost::serialization::throw_exception( + xml_archive_exception( + xml_archive_exception::xml_archive_tag_mismatch, + name + ) + ); + } + } +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_iarchive::load_override(object_id_type & t){ + t = object_id_type(this->This()->gimpl->rv.object_id); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_iarchive::load_override(version_type & t){ + t = version_type(this->This()->gimpl->rv.version); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_iarchive::load_override(class_id_type & t){ + t = class_id_type(this->This()->gimpl->rv.class_id); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_iarchive::load_override(tracking_type & t){ + t = this->This()->gimpl->rv.tracking_level; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_xml_iarchive::basic_xml_iarchive(unsigned int flags) : + detail::common_iarchive(flags), + depth(0) +{} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_xml_iarchive::~basic_xml_iarchive(){ +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_oarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_oarchive.ipp new file mode 100644 index 00000000000..3184413f382 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_oarchive.ipp @@ -0,0 +1,272 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// basic_xml_oarchive.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // NULL +#include +#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__) +namespace std{ + using ::strlen; +} // namespace std +#endif + +#include +#include +#include +#include + +namespace boost { +namespace archive { + +namespace detail { +template +struct XML_name { + void operator()(CharType t) const{ + const unsigned char lookup_table[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0, // -. + 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 0-9 + 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // A- + 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, // -Z _ + 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // a- + 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, // -z + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + }; + if((unsigned)t > 127) + return; + if(0 == lookup_table[(unsigned)t]) + boost::serialization::throw_exception( + xml_archive_exception( + xml_archive_exception::xml_archive_tag_name_error + ) + ); + } +}; + +} // namespace detail + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implemenations of functions common to both types of xml output + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::write_attribute( + const char *attribute_name, + int t, + const char *conjunction +){ + this->This()->put(' '); + this->This()->put(attribute_name); + this->This()->put(conjunction); + this->This()->save(t); + this->This()->put('"'); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::write_attribute( + const char *attribute_name, + const char *key +){ + this->This()->put(' '); + this->This()->put(attribute_name); + this->This()->put("=\""); + this->This()->save(key); + this->This()->put('"'); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::indent(){ + int i; + for(i = depth; i-- > 0;) + this->This()->put('\t'); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_start(const char *name) +{ + if(NULL == name) + return; + + // be sure name has no invalid characters + std::for_each(name, name + std::strlen(name), detail::XML_name()); + + end_preamble(); + if(depth > 0){ + this->This()->put('\n'); + indent(); + } + ++depth; + this->This()->put('<'); + this->This()->save(name); + pending_preamble = true; + indent_next = false; +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_end(const char *name) +{ + if(NULL == name) + return; + + // be sure name has no invalid characters + std::for_each(name, name + std::strlen(name), detail::XML_name()); + + end_preamble(); + --depth; + if(indent_next){ + this->This()->put('\n'); + indent(); + } + indent_next = true; + this->This()->put("This()->save(name); + this->This()->put('>'); + if(0 == depth) + this->This()->put('\n'); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::end_preamble(){ + if(pending_preamble){ + this->This()->put('>'); + pending_preamble = false; + } +} +#if 0 +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override(const object_id_type & t) +{ + int i = t.t; // extra .t is for borland + write_attribute(BOOST_ARCHIVE_XML_OBJECT_ID(), i, "=\"_"); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override( + const object_reference_type & t, + int +){ + int i = t.t; // extra .t is for borland + write_attribute(BOOST_ARCHIVE_XML_OBJECT_REFERENCE(), i, "=\"_"); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override(const version_type & t) +{ + int i = t.t; // extra .t is for borland + write_attribute(BOOST_ARCHIVE_XML_VERSION(), i); +} +#endif + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override(const object_id_type & t) +{ + // borland doesn't do conversion of STRONG_TYPEDEFs very well + const unsigned int i = t; + write_attribute(BOOST_ARCHIVE_XML_OBJECT_ID(), i, "=\"_"); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override( + const object_reference_type & t +){ + const unsigned int i = t; + write_attribute(BOOST_ARCHIVE_XML_OBJECT_REFERENCE(), i, "=\"_"); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override(const version_type & t) +{ + const unsigned int i = t; + write_attribute(BOOST_ARCHIVE_XML_VERSION(), i); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override(const class_id_type & t) +{ + write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override( + const class_id_reference_type & t +){ + write_attribute(BOOST_ARCHIVE_XML_CLASS_ID_REFERENCE(), t); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override( + const class_id_optional_type & t +){ + write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t); +} +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override(const class_name_type & t) +{ + const char * key = t; + if(NULL == key) + return; + write_attribute(BOOST_ARCHIVE_XML_CLASS_NAME(), key); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::save_override(const tracking_type & t) +{ + write_attribute(BOOST_ARCHIVE_XML_TRACKING(), t.t); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::init(){ + // xml header + this->This()->put("\n"); + this->This()->put("\n"); + // xml document wrapper - outer root + this->This()->put("This()->put(">\n"); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL void +basic_xml_oarchive::windup(){ + // xml_trailer + this->This()->put("\n"); +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_xml_oarchive::basic_xml_oarchive(unsigned int flags) : + detail::common_oarchive(flags), + depth(0), + pending_preamble(false), + indent_next(false) +{ +} + +template +BOOST_ARCHIVE_OR_WARCHIVE_DECL +basic_xml_oarchive::~basic_xml_oarchive(){ +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/text_iarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_iarchive_impl.ipp new file mode 100644 index 00000000000..ae4e2750ce8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_iarchive_impl.ipp @@ -0,0 +1,128 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_iarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +////////////////////////////////////////////////////////////////////// +// implementation of basic_text_iprimitive overrides for the combination +// of template parameters used to implement a text_iprimitive + +#include // size_t, NULL +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include // RogueWave + +#include + +namespace boost { +namespace archive { + +template +BOOST_ARCHIVE_DECL void +text_iarchive_impl::load(char *s) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + // Works on all tested platforms + is.read(s, size); + s[size] = '\0'; +} + +template +BOOST_ARCHIVE_DECL void +text_iarchive_impl::load(std::string &s) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + // borland de-allocator fixup + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != s.data()) + #endif + s.resize(size); + if(0 < size) + is.read(&(*s.begin()), size); +} + +#ifndef BOOST_NO_CWCHAR +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_ARCHIVE_DECL void +text_iarchive_impl::load(wchar_t *ws) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + is.read((char *)ws, size * sizeof(wchar_t)/sizeof(char)); + ws[size] = L'\0'; +} +#endif // BOOST_NO_INTRINSIC_WCHAR_T + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_DECL void +text_iarchive_impl::load(std::wstring &ws) +{ + std::size_t size; + * this->This() >> size; + // borland de-allocator fixup + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != ws.data()) + #endif + ws.resize(size); + // skip separating space + is.get(); + is.read((char *)ws.data(), size * sizeof(wchar_t)/sizeof(char)); +} + +#endif // BOOST_NO_STD_WSTRING +#endif // BOOST_NO_CWCHAR + +template +BOOST_ARCHIVE_DECL void +text_iarchive_impl::load_override(class_name_type & t){ + basic_text_iarchive::load_override(t); +} + +template +BOOST_ARCHIVE_DECL void +text_iarchive_impl::init(){ + basic_text_iarchive::init(); +} + +template +BOOST_ARCHIVE_DECL +text_iarchive_impl::text_iarchive_impl( + std::istream & is, + unsigned int flags +) : + basic_text_iprimitive( + is, + 0 != (flags & no_codecvt) + ), + basic_text_iarchive(flags) +{ + if(0 == (flags & no_header)) + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + this->init(); + #else + this->basic_text_iarchive::init(); + #endif +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/text_oarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_oarchive_impl.ipp new file mode 100644 index 00000000000..37d8664a98c --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_oarchive_impl.ipp @@ -0,0 +1,122 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_oarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include // size_t + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#ifndef BOOST_NO_CWCHAR +#include +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ using ::wcslen; } +#endif +#endif + +#include + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// implementation of basic_text_oprimitive overrides for the combination +// of template parameters used to create a text_oprimitive + +template +BOOST_ARCHIVE_DECL void +text_oarchive_impl::save(const char * s) +{ + const std::size_t len = std::ostream::traits_type::length(s); + *this->This() << len; + this->This()->newtoken(); + os << s; +} + +template +BOOST_ARCHIVE_DECL void +text_oarchive_impl::save(const std::string &s) +{ + const std::size_t size = s.size(); + *this->This() << size; + this->This()->newtoken(); + os << s; +} + +#ifndef BOOST_NO_CWCHAR +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_ARCHIVE_DECL void +text_oarchive_impl::save(const wchar_t * ws) +{ + const std::size_t l = std::wcslen(ws); + * this->This() << l; + this->This()->newtoken(); + os.write((const char *)ws, l * sizeof(wchar_t)/sizeof(char)); +} +#endif + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_DECL void +text_oarchive_impl::save(const std::wstring &ws) +{ + const std::size_t l = ws.size(); + * this->This() << l; + this->This()->newtoken(); + os.write((const char *)(ws.data()), l * sizeof(wchar_t)/sizeof(char)); +} +#endif +#endif // BOOST_NO_CWCHAR + +template +BOOST_ARCHIVE_DECL +text_oarchive_impl::text_oarchive_impl( + std::ostream & os, + unsigned int flags +) : + basic_text_oprimitive( + os, + 0 != (flags & no_codecvt) + ), + basic_text_oarchive(flags) +{ + if(0 == (flags & no_header)) + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + this->init(); + #else + this->basic_text_oarchive::init(); + #endif +} + +template +BOOST_ARCHIVE_DECL void +text_oarchive_impl::save_binary(const void *address, std::size_t count){ + put('\n'); + this->end_preamble(); + #if ! defined(__MWERKS__) + this->basic_text_oprimitive::save_binary( + #else + this->basic_text_oprimitive::save_binary( + #endif + address, + count + ); + this->delimiter = this->eol; +} + +} // namespace archive +} // namespace boost + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/text_wiarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_wiarchive_impl.ipp new file mode 100644 index 00000000000..e85625ac326 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_wiarchive_impl.ipp @@ -0,0 +1,118 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_text_wiarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // size_t, NULL + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include // fixup for RogueWave + +#ifndef BOOST_NO_STD_WSTREAMBUF +#include + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// implementation of wiprimtives functions +// +template +BOOST_WARCHIVE_DECL void +text_wiarchive_impl::load(char *s) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + while(size-- > 0){ + *s++ = is.narrow(is.get(), '\0'); + } + *s = '\0'; +} + +template +BOOST_WARCHIVE_DECL void +text_wiarchive_impl::load(std::string &s) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != s.data()) + #endif + s.resize(0); + s.reserve(size); + while(size-- > 0){ + char x = is.narrow(is.get(), '\0'); + s += x; + } +} + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_WARCHIVE_DECL void +text_wiarchive_impl::load(wchar_t *s) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + // Works on all tested platforms + is.read(s, size); + s[size] = L'\0'; +} +#endif + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_WARCHIVE_DECL void +text_wiarchive_impl::load(std::wstring &ws) +{ + std::size_t size; + * this->This() >> size; + // skip separating space + is.get(); + // borland complains about resize + // borland de-allocator fixup + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != ws.data()) + #endif + ws.resize(size); + // note breaking a rule here - is this a problem on some platform + is.read(const_cast(ws.data()), size); +} +#endif + +template +BOOST_WARCHIVE_DECL +text_wiarchive_impl::text_wiarchive_impl( + std::wistream & is, + unsigned int flags +) : + basic_text_iprimitive( + is, + 0 != (flags & no_codecvt) + ), + basic_text_iarchive(flags) +{ + if(0 == (flags & no_header)) + basic_text_iarchive::init(); +} + +} // archive +} // boost + +#endif // BOOST_NO_STD_WSTREAMBUF diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/text_woarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_woarchive_impl.ipp new file mode 100644 index 00000000000..2b6d427cd3a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_woarchive_impl.ipp @@ -0,0 +1,85 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_woarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifndef BOOST_NO_STD_WSTREAMBUF + +#include +#include // size_t +#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__) +namespace std{ + using ::strlen; + using ::size_t; +} // namespace std +#endif + +#include + +#include + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// implementation of woarchive functions +// +template +BOOST_WARCHIVE_DECL void +text_woarchive_impl::save(const char *s) +{ + // note: superfluous local variable fixes borland warning + const std::size_t size = std::strlen(s); + * this->This() << size; + this->This()->newtoken(); + while(*s != '\0') + os.put(os.widen(*s++)); +} + +template +BOOST_WARCHIVE_DECL void +text_woarchive_impl::save(const std::string &s) +{ + const std::size_t size = s.size(); + * this->This() << size; + this->This()->newtoken(); + const char * cptr = s.data(); + for(std::size_t i = size; i-- > 0;) + os.put(os.widen(*cptr++)); +} + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_WARCHIVE_DECL void +text_woarchive_impl::save(const wchar_t *ws) +{ + const std::size_t size = std::wostream::traits_type::length(ws); + * this->This() << size; + this->This()->newtoken(); + os.write(ws, size); +} +#endif + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_WARCHIVE_DECL void +text_woarchive_impl::save(const std::wstring &ws) +{ + const std::size_t size = ws.length(); + * this->This() << size; + this->This()->newtoken(); + os.write(ws.data(), size); +} +#endif + +} // namespace archive +} // namespace boost + +#endif + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_iarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_iarchive_impl.ipp new file mode 100644 index 00000000000..efc32e01632 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_iarchive_impl.ipp @@ -0,0 +1,199 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_iarchive_impl.cpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // memcpy +#include // NULL +#include + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; +} // namespace std +#endif + +#ifndef BOOST_NO_CWCHAR +#include // mbstate_t and mbrtowc +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::mbstate_t; + using ::mbrtowc; + } // namespace std +#endif +#endif // BOOST_NO_CWCHAR + +#include // RogueWave and Dinkumware +#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) +#include +#endif + +#include + +#include +#include +#include +#include + +#include "basic_xml_grammar.hpp" + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implemenations of functions specific to char archives + +// wide char stuff used by char archives + +#ifndef BOOST_NO_CWCHAR +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_DECL void +xml_iarchive_impl::load(std::wstring &ws){ + std::string s; + bool result = gimpl->parse_string(is, s); + if(! result) + boost::serialization::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != ws.data()) + #endif + ws.resize(0); + std::mbstate_t mbs = std::mbstate_t(); + const char * start = s.data(); + const char * end = start + s.size(); + while(start < end){ + wchar_t wc; + std::size_t count = std::mbrtowc(&wc, start, end - start, &mbs); + if(count == static_cast(-1)) + boost::serialization::throw_exception( + iterators::dataflow_exception( + iterators::dataflow_exception::invalid_conversion + ) + ); + if(count == static_cast(-2)) + continue; + start += count; + ws += wc; + } +} +#endif // BOOST_NO_STD_WSTRING + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_ARCHIVE_DECL void +xml_iarchive_impl::load(wchar_t * ws){ + std::string s; + bool result = gimpl->parse_string(is, s); + if(! result) + boost::serialization::throw_exception( + xml_archive_exception( + xml_archive_exception::xml_archive_parsing_error + ) + ); + + std::mbstate_t mbs = std::mbstate_t(); + const char * start = s.data(); + const char * end = start + s.size(); + while(start < end){ + wchar_t wc; + std::size_t length = std::mbrtowc(&wc, start, end - start, &mbs); + if(static_cast(-1) == length) + boost::serialization::throw_exception( + iterators::dataflow_exception( + iterators::dataflow_exception::invalid_conversion + ) + ); + if(static_cast(-2) == length) + continue; + + start += length; + *ws++ = wc; + } + *ws = L'\0'; +} +#endif // BOOST_NO_INTRINSIC_WCHAR_T + +#endif // BOOST_NO_CWCHAR + +template +BOOST_ARCHIVE_DECL void +xml_iarchive_impl::load(std::string &s){ + bool result = gimpl->parse_string(is, s); + if(! result) + boost::serialization::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); +} + +template +BOOST_ARCHIVE_DECL void +xml_iarchive_impl::load(char * s){ + std::string tstring; + bool result = gimpl->parse_string(is, tstring); + if(! result) + boost::serialization::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + std::memcpy(s, tstring.data(), tstring.size()); + s[tstring.size()] = 0; +} + +template +BOOST_ARCHIVE_DECL void +xml_iarchive_impl::load_override(class_name_type & t){ + const std::string & s = gimpl->rv.class_name; + if(s.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1) + boost::serialization::throw_exception( + archive_exception(archive_exception::invalid_class_name) + ); + char * tptr = t; + std::memcpy(tptr, s.data(), s.size()); + tptr[s.size()] = '\0'; +} + +template +BOOST_ARCHIVE_DECL void +xml_iarchive_impl::init(){ + gimpl->init(is); + this->set_library_version( + library_version_type(gimpl->rv.version) + ); +} + +template +BOOST_ARCHIVE_DECL +xml_iarchive_impl::xml_iarchive_impl( + std::istream &is_, + unsigned int flags +) : + basic_text_iprimitive( + is_, + 0 != (flags & no_codecvt) + ), + basic_xml_iarchive(flags), + gimpl(new xml_grammar()) +{ + if(0 == (flags & no_header)) + init(); +} + +template +BOOST_ARCHIVE_DECL +xml_iarchive_impl::~xml_iarchive_impl(){ + if(std::uncaught_exception()) + return; + if(0 == (this->get_flags() & no_header)){ + gimpl->windup(is); + } +} +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_oarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_oarchive_impl.ipp new file mode 100644 index 00000000000..5ebd454e722 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_oarchive_impl.ipp @@ -0,0 +1,142 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_oarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include // std::copy +#include +#include + +#include // strlen +#include // msvc 6.0 needs this to suppress warnings +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::strlen; +} // namespace std +#endif + +#include +#include + +#ifndef BOOST_NO_CWCHAR +#include +#include +#endif + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implemenations of functions specific to char archives + +// wide char stuff used by char archives +#ifndef BOOST_NO_CWCHAR +// copy chars to output escaping to xml and translating wide chars to mb chars +template +void save_iterator(std::ostream &os, InputIterator begin, InputIterator end){ + typedef boost::archive::iterators::mb_from_wchar< + boost::archive::iterators::xml_escape + > translator; + std::copy( + translator(begin), + translator(end), + boost::archive::iterators::ostream_iterator(os) + ); +} + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_ARCHIVE_DECL void +xml_oarchive_impl::save(const std::wstring & ws){ +// at least one library doesn't typedef value_type for strings +// so rather than using string directly make a pointer iterator out of it +// save_iterator(os, ws.data(), ws.data() + std::wcslen(ws.data())); + save_iterator(os, ws.data(), ws.data() + ws.size()); +} +#endif + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_ARCHIVE_DECL void +xml_oarchive_impl::save(const wchar_t * ws){ + save_iterator(os, ws, ws + std::wcslen(ws)); +} +#endif + +#endif // BOOST_NO_CWCHAR + +template +BOOST_ARCHIVE_DECL void +xml_oarchive_impl::save(const std::string & s){ +// at least one library doesn't typedef value_type for strings +// so rather than using string directly make a pointer iterator out of it + typedef boost::archive::iterators::xml_escape< + const char * + > xml_escape_translator; + std::copy( + xml_escape_translator(s.data()), + xml_escape_translator(s.data()+ s.size()), + boost::archive::iterators::ostream_iterator(os) + ); +} + +template +BOOST_ARCHIVE_DECL void +xml_oarchive_impl::save(const char * s){ + typedef boost::archive::iterators::xml_escape< + const char * + > xml_escape_translator; + std::copy( + xml_escape_translator(s), + xml_escape_translator(s + std::strlen(s)), + boost::archive::iterators::ostream_iterator(os) + ); +} + +template +BOOST_ARCHIVE_DECL +xml_oarchive_impl::xml_oarchive_impl( + std::ostream & os_, + unsigned int flags +) : + basic_text_oprimitive( + os_, + 0 != (flags & no_codecvt) + ), + basic_xml_oarchive(flags) +{ + if(0 == (flags & no_header)) + this->init(); +} + +template +BOOST_ARCHIVE_DECL void +xml_oarchive_impl::save_binary(const void *address, std::size_t count){ + this->end_preamble(); + #if ! defined(__MWERKS__) + this->basic_text_oprimitive::save_binary( + #else + this->basic_text_oprimitive::save_binary( + #endif + address, + count + ); + this->indent_next = true; +} + +template +BOOST_ARCHIVE_DECL +xml_oarchive_impl::~xml_oarchive_impl(){ + if(std::uncaught_exception()) + return; + if(0 == (this->get_flags() & no_header)) + this->windup(); +} + +} // namespace archive +} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_wiarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_wiarchive_impl.ipp new file mode 100644 index 00000000000..ee66c1263e6 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_wiarchive_impl.ipp @@ -0,0 +1,189 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_wiarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::memcpy; +} //std +#endif + +#include // msvc 6.0 needs this to suppress warnings +#ifndef BOOST_NO_STD_WSTREAMBUF + +#include +#include // std::copy +#include // uncaught exception +#include // Dinkumware and RogueWave +#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) +#include +#endif + +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include "basic_xml_grammar.hpp" + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implemenations of functions specific to wide char archives + +namespace { // anonymous + +void copy_to_ptr(char * s, const std::wstring & ws){ + std::copy( + iterators::mb_from_wchar( + ws.begin() + ), + iterators::mb_from_wchar( + ws.end() + ), + s + ); + s[ws.size()] = 0; +} + +} // anonymous + +template +BOOST_WARCHIVE_DECL void +xml_wiarchive_impl::load(std::string & s){ + std::wstring ws; + bool result = gimpl->parse_string(is, ws); + if(! result) + boost::serialization::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) + if(NULL != s.data()) + #endif + s.resize(0); + s.reserve(ws.size()); + std::copy( + iterators::mb_from_wchar( + ws.begin() + ), + iterators::mb_from_wchar( + ws.end() + ), + std::back_inserter(s) + ); +} + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_WARCHIVE_DECL void +xml_wiarchive_impl::load(std::wstring & ws){ + bool result = gimpl->parse_string(is, ws); + if(! result) + boost::serialization::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); +} +#endif + +template +BOOST_WARCHIVE_DECL void +xml_wiarchive_impl::load(char * s){ + std::wstring ws; + bool result = gimpl->parse_string(is, ws); + if(! result) + boost::serialization::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + copy_to_ptr(s, ws); +} + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_WARCHIVE_DECL void +xml_wiarchive_impl::load(wchar_t * ws){ + std::wstring twstring; + bool result = gimpl->parse_string(is, twstring); + if(! result) + boost::serialization::throw_exception( + xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) + ); + std::memcpy(ws, twstring.c_str(), twstring.size()); + ws[twstring.size()] = L'\0'; +} +#endif + +template +BOOST_WARCHIVE_DECL void +xml_wiarchive_impl::load_override(class_name_type & t){ + const std::wstring & ws = gimpl->rv.class_name; + if(ws.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1) + boost::serialization::throw_exception( + archive_exception(archive_exception::invalid_class_name) + ); + copy_to_ptr(t, ws); +} + +template +BOOST_WARCHIVE_DECL void +xml_wiarchive_impl::init(){ + gimpl->init(is); + this->set_library_version( + library_version_type(gimpl->rv.version) + ); +} + +template +BOOST_WARCHIVE_DECL +xml_wiarchive_impl::xml_wiarchive_impl( + std::wistream &is_, + unsigned int flags +) : + basic_text_iprimitive( + is_, + true // don't change the codecvt - use the one below + ), + basic_xml_iarchive(flags), + gimpl(new xml_wgrammar()) +{ + if(0 == (flags & no_codecvt)){ + std::locale l = std::locale( + is_.getloc(), + new boost::archive::detail::utf8_codecvt_facet + ); + // libstdc++ crashes without this + is_.sync(); + is_.imbue(l); + } + if(0 == (flags & no_header)) + init(); +} + +template +BOOST_WARCHIVE_DECL +xml_wiarchive_impl::~xml_wiarchive_impl(){ + if(std::uncaught_exception()) + return; + if(0 == (this->get_flags() & no_header)){ + gimpl->windup(is); + } +} + +} // namespace archive +} // namespace boost + +#endif // BOOST_NO_STD_WSTREAMBUF diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_woarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_woarchive_impl.ipp new file mode 100644 index 00000000000..01b1a052d51 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_woarchive_impl.ipp @@ -0,0 +1,171 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_woarchive_impl.ipp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#ifndef BOOST_NO_STD_WSTREAMBUF + +#include +#include +#include // std::copy +#include +#include + +#include // strlen +#include // mbtowc +#ifndef BOOST_NO_CWCHAR +#include // wcslen +#endif + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::strlen; + #if ! defined(BOOST_NO_INTRINSIC_WCHAR_T) + using ::mbtowc; + using ::wcslen; + #endif +} // namespace std +#endif + +#include +#include + +#include + +#include +#include +#include +#include + +namespace boost { +namespace archive { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implemenations of functions specific to wide char archives + +// copy chars to output escaping to xml and widening characters as we go +template +void save_iterator(std::wostream &os, InputIterator begin, InputIterator end){ + typedef iterators::wchar_from_mb< + iterators::xml_escape + > xmbtows; + std::copy( + xmbtows(begin), + xmbtows(end), + boost::archive::iterators::ostream_iterator(os) + ); +} + +template +BOOST_WARCHIVE_DECL void +xml_woarchive_impl::save(const std::string & s){ + // note: we don't use s.begin() and s.end() because dinkumware + // doesn't have string::value_type defined. So use a wrapper + // around these values to implement the definitions. + const char * begin = s.data(); + const char * end = begin + s.size(); + save_iterator(os, begin, end); +} + +#ifndef BOOST_NO_STD_WSTRING +template +BOOST_WARCHIVE_DECL void +xml_woarchive_impl::save(const std::wstring & ws){ +#if 0 + typedef iterators::xml_escape xmbtows; + std::copy( + xmbtows(ws.begin()), + xmbtows(ws.end()), + boost::archive::iterators::ostream_iterator(os) + ); +#endif + typedef iterators::xml_escape xmbtows; + std::copy( + xmbtows(ws.data()), + xmbtows(ws.data() + ws.size()), + boost::archive::iterators::ostream_iterator(os) + ); +} +#endif //BOOST_NO_STD_WSTRING + +template +BOOST_WARCHIVE_DECL void +xml_woarchive_impl::save(const char * s){ + save_iterator(os, s, s + std::strlen(s)); +} + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template +BOOST_WARCHIVE_DECL void +xml_woarchive_impl::save(const wchar_t * ws){ + os << ws; + typedef iterators::xml_escape xmbtows; + std::copy( + xmbtows(ws), + xmbtows(ws + std::wcslen(ws)), + boost::archive::iterators::ostream_iterator(os) + ); +} +#endif + +template +BOOST_WARCHIVE_DECL +xml_woarchive_impl::xml_woarchive_impl( + std::wostream & os_, + unsigned int flags +) : + basic_text_oprimitive( + os_, + true // don't change the codecvt - use the one below + ), + basic_xml_oarchive(flags) +{ + if(0 == (flags & no_codecvt)){ + std::locale l = std::locale( + os_.getloc(), + new boost::archive::detail::utf8_codecvt_facet + ); + os_.flush(); + os_.imbue(l); + } + if(0 == (flags & no_header)) + this->init(); +} + +template +BOOST_WARCHIVE_DECL +xml_woarchive_impl::~xml_woarchive_impl(){ + if(std::uncaught_exception()) + return; + if(0 == (this->get_flags() & no_header)){ + save(L"\n"); + } +} + +template +BOOST_WARCHIVE_DECL void +xml_woarchive_impl::save_binary( + const void *address, + std::size_t count +){ + this->end_preamble(); + #if ! defined(__MWERKS__) + this->basic_text_oprimitive::save_binary( + #else + this->basic_text_oprimitive::save_binary( + #endif + address, + count + ); + this->indent_next = true; +} + +} // namespace archive +} // namespace boost + +#endif //BOOST_NO_STD_WSTREAMBUF diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_exception.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_exception.hpp new file mode 100644 index 00000000000..8f9208b60ea --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_exception.hpp @@ -0,0 +1,68 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_BASE64_EXCEPTION_HPP +#define BOOST_ARCHIVE_ITERATORS_BASE64_EXCEPTION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// base64_exception.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifndef BOOST_NO_EXCEPTIONS +#include + +#include + +namespace boost { +namespace archive { +namespace iterators { + +////////////////////////////////////////////////////////////////////// +// exceptions thrown by base64s +// +class base64_exception : public std::exception +{ +public: + typedef enum { + invalid_code, // attempt to encode a value > 6 bits + invalid_character, // decode a value not in base64 char set + other_exception + } exception_code; + exception_code code; + + base64_exception(exception_code c = other_exception) : code(c) + {} + + virtual const char *what( ) const throw( ) + { + const char *msg = "unknown exception code"; + switch(code){ + case invalid_code: + msg = "attempt to encode a value > 6 bits"; + break; + case invalid_character: + msg = "attempt to decode a value not in base64 char set"; + break; + default: + BOOST_ASSERT(false); + break; + } + return msg; + } +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif //BOOST_NO_EXCEPTIONS +#endif //BOOST_ARCHIVE_ITERATORS_ARCHIVE_EXCEPTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_from_binary.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_from_binary.hpp new file mode 100644 index 00000000000..ee849944397 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_from_binary.hpp @@ -0,0 +1,109 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_BASE64_FROM_BINARY_HPP +#define BOOST_ARCHIVE_ITERATORS_BASE64_FROM_BINARY_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// base64_from_binary.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include // size_t +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// convert binary integers to base64 characters + +namespace detail { + +template +struct from_6_bit { + typedef CharType result_type; + CharType operator()(CharType t) const{ + static const char * lookup_table = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "+/"; + BOOST_ASSERT(t < 64); + return lookup_table[static_cast(t)]; + } +}; + +} // namespace detail + +// note: what we would like to do is +// template +// typedef transform_iterator< +// from_6_bit, +// transform_width +// > base64_from_binary; +// but C++ won't accept this. Rather than using a "type generator" and +// using a different syntax, make a derivation which should be equivalent. +// +// Another issue addressed here is that the transform_iterator doesn't have +// a templated constructor. This makes it incompatible with the dataflow +// ideal. This is also addressed here. + +//template +template< + class Base, + class CharType = typename boost::iterator_value::type +> +class base64_from_binary : + public transform_iterator< + detail::from_6_bit, + Base + > +{ + friend class boost::iterator_core_access; + typedef transform_iterator< + typename detail::from_6_bit, + Base + > super_t; + +public: + // make composible buy using templated constructor + template + base64_from_binary(T start) : + super_t( + Base(static_cast< T >(start)), + detail::from_6_bit() + ) + {} + // intel 7.1 doesn't like default copy constructor + base64_from_binary(const base64_from_binary & rhs) : + super_t( + Base(rhs.base_reference()), + detail::from_6_bit() + ) + {} +// base64_from_binary(){}; +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_BASE64_FROM_BINARY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/binary_from_base64.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/binary_from_base64.hpp new file mode 100644 index 00000000000..89b8f889da3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/binary_from_base64.hpp @@ -0,0 +1,118 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP +#define BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// binary_from_base64.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// convert base64 characters to binary data + +namespace detail { + +template +struct to_6_bit { + typedef CharType result_type; + CharType operator()(CharType t) const{ + static const signed char lookup_table[] = { + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, + 52,53,54,55,56,57,58,59,60,61,-1,-1,-1, 0,-1,-1, // render '=' as 0 + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, + 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, + -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, + 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1 + }; + // metrowerks trips this assertion - how come? + #if ! defined(__MWERKS__) + BOOST_STATIC_ASSERT(128 == sizeof(lookup_table)); + #endif + signed char value = -1; + if((unsigned)t <= 127) + value = lookup_table[(unsigned)t]; + if(-1 == value) + boost::serialization::throw_exception( + dataflow_exception(dataflow_exception::invalid_base64_character) + ); + return value; + } +}; + +} // namespace detail + +// note: what we would like to do is +// template +// typedef transform_iterator< +// from_6_bit, +// transform_width +// > base64_from_binary; +// but C++ won't accept this. Rather than using a "type generator" and +// using a different syntax, make a derivation which should be equivalent. +// +// Another issue addressed here is that the transform_iterator doesn't have +// a templated constructor. This makes it incompatible with the dataflow +// ideal. This is also addressed here. + +template< + class Base, + class CharType = typename boost::iterator_value::type +> +class binary_from_base64 : public + transform_iterator< + detail::to_6_bit, + Base + > +{ + friend class boost::iterator_core_access; + typedef transform_iterator< + detail::to_6_bit, + Base + > super_t; +public: + // make composible buy using templated constructor + template + binary_from_base64(T start) : + super_t( + Base(static_cast< T >(start)), + detail::to_6_bit() + ) + {} + // intel 7.1 doesn't like default copy constructor + binary_from_base64(const binary_from_base64 & rhs) : + super_t( + Base(rhs.base_reference()), + detail::to_6_bit() + ) + {} +// binary_from_base64(){}; +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow.hpp new file mode 100644 index 00000000000..07733d5fd62 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow.hpp @@ -0,0 +1,102 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_DATAFLOW_HPP +#define BOOST_ARCHIVE_ITERATORS_DATAFLOW_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// dataflow.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +// poor man's tri-state +struct tri_state { + enum state_enum { + is_false = false, + is_true = true, + is_indeterminant + } m_state; + // convert to bool + operator bool (){ + BOOST_ASSERT(is_indeterminant != m_state); + return is_true == m_state ? true : false; + } + // assign from bool + tri_state & operator=(bool rhs) { + m_state = rhs ? is_true : is_false; + return *this; + } + tri_state(bool rhs) : + m_state(rhs ? is_true : is_false) + {} + tri_state(state_enum state) : + m_state(state) + {} + bool operator==(const tri_state & rhs) const { + return m_state == rhs.m_state; + } + bool operator!=(const tri_state & rhs) const { + return m_state != rhs.m_state; + } +}; + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implement functions common to dataflow iterators +template +class dataflow { + bool m_eoi; +protected: + // test for iterator equality + tri_state equal(const Derived & rhs) const { + if(m_eoi && rhs.m_eoi) + return true; + if(m_eoi || rhs.m_eoi) + return false; + return tri_state(tri_state::is_indeterminant); + } + void eoi(bool tf){ + m_eoi = tf; + } + bool eoi() const { + return m_eoi; + } +public: + dataflow(bool tf) : + m_eoi(tf) + {} + dataflow() : // used for iterator end + m_eoi(true) + {} +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_DATAFLOW_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow_exception.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow_exception.hpp new file mode 100644 index 00000000000..e3e18605b38 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow_exception.hpp @@ -0,0 +1,80 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_DATAFLOW_EXCEPTION_HPP +#define BOOST_ARCHIVE_ITERATORS_DATAFLOW_EXCEPTION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// dataflow_exception.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifndef BOOST_NO_EXCEPTIONS +#include +#endif //BOOST_NO_EXCEPTIONS + +#include + +namespace boost { +namespace archive { +namespace iterators { + +////////////////////////////////////////////////////////////////////// +// exceptions thrown by dataflows +// +class dataflow_exception : public std::exception +{ +public: + typedef enum { + invalid_6_bitcode, + invalid_base64_character, + invalid_xml_escape_sequence, + comparison_not_permitted, + invalid_conversion, + other_exception + } exception_code; + exception_code code; + + dataflow_exception(exception_code c = other_exception) : code(c) + {} + + virtual const char *what( ) const throw( ) + { + const char *msg = "unknown exception code"; + switch(code){ + case invalid_6_bitcode: + msg = "attempt to encode a value > 6 bits"; + break; + case invalid_base64_character: + msg = "attempt to decode a value not in base64 char set"; + break; + case invalid_xml_escape_sequence: + msg = "invalid xml escape_sequence"; + break; + case comparison_not_permitted: + msg = "cannot invoke iterator comparison now"; + break; + case invalid_conversion: + msg = "invalid multbyte/wide char conversion"; + break; + default: + BOOST_ASSERT(false); + break; + } + return msg; + } +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif //BOOST_ARCHIVE_ITERATORS_DATAFLOW_EXCEPTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/escape.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/escape.hpp new file mode 100644 index 00000000000..103b31e0fef --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/escape.hpp @@ -0,0 +1,115 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_ESCAPE_HPP +#define BOOST_ARCHIVE_ITERATORS_ESCAPE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// escape.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // NULL + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// insert escapes into text + +template +class escape : + public boost::iterator_adaptor< + Derived, + Base, + typename boost::iterator_value::type, + single_pass_traversal_tag, + typename boost::iterator_value::type + > +{ + typedef typename boost::iterator_value::type base_value_type; + typedef typename boost::iterator_reference::type reference_type; + friend class boost::iterator_core_access; + + typedef typename boost::iterator_adaptor< + Derived, + Base, + base_value_type, + single_pass_traversal_tag, + base_value_type + > super_t; + + typedef escape this_t; + + void dereference_impl() { + m_current_value = static_cast(this)->fill(m_bnext, m_bend); + m_full = true; + } + + //Access the value referred to + reference_type dereference() const { + if(!m_full) + const_cast(this)->dereference_impl(); + return m_current_value; + } + + bool equal(const this_t & rhs) const { + if(m_full){ + if(! rhs.m_full) + const_cast(& rhs)->dereference_impl(); + } + else{ + if(rhs.m_full) + const_cast(this)->dereference_impl(); + } + if(m_bnext != rhs.m_bnext) + return false; + if(this->base_reference() != rhs.base_reference()) + return false; + return true; + } + + void increment(){ + if(++m_bnext < m_bend){ + m_current_value = *m_bnext; + return; + } + ++(this->base_reference()); + m_bnext = NULL; + m_bend = NULL; + m_full = false; + } + + // buffer to handle pending characters + const base_value_type *m_bnext; + const base_value_type *m_bend; + bool m_full; + base_value_type m_current_value; +public: + escape(Base base) : + super_t(base), + m_bnext(NULL), + m_bend(NULL), + m_full(false), + m_current_value(0) + { + } +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_ESCAPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/insert_linebreaks.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/insert_linebreaks.hpp new file mode 100644 index 00000000000..2504b030db1 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/insert_linebreaks.hpp @@ -0,0 +1,99 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_INSERT_LINEBREAKS_HPP +#define BOOST_ARCHIVE_ITERATORS_INSERT_LINEBREAKS_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// insert_linebreaks.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ using ::memcpy; } +#endif + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// insert line break every N characters +template< + class Base, + int N, + class CharType = typename boost::iterator_value::type +> +class insert_linebreaks : + public iterator_adaptor< + insert_linebreaks, + Base, + CharType, + single_pass_traversal_tag, + CharType + > +{ +private: + friend class boost::iterator_core_access; + typedef iterator_adaptor< + insert_linebreaks, + Base, + CharType, + single_pass_traversal_tag, + CharType + > super_t; + + bool equal(const insert_linebreaks & rhs) const { + return +// m_count == rhs.m_count +// && base_reference() == rhs.base_reference() + this->base_reference() == rhs.base_reference() + ; + } + + void increment() { + if(m_count == N){ + m_count = 0; + return; + } + ++m_count; + ++(this->base_reference()); + } + CharType dereference() const { + if(m_count == N) + return '\n'; + return * (this->base_reference()); + } + unsigned int m_count; +public: + // make composible buy using templated constructor + template + insert_linebreaks(T start) : + super_t(Base(static_cast< T >(start))), + m_count(0) + {} + // intel 7.1 doesn't like default copy constructor + insert_linebreaks(const insert_linebreaks & rhs) : + super_t(rhs.base_reference()), + m_count(rhs.m_count) + {} +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_INSERT_LINEBREAKS_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/istream_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/istream_iterator.hpp new file mode 100644 index 00000000000..a187f605e69 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/istream_iterator.hpp @@ -0,0 +1,92 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_ISTREAM_ITERATOR_HPP +#define BOOST_ARCHIVE_ITERATORS_ISTREAM_ITERATOR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// istream_iterator.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// note: this is a custom version of the standard istream_iterator. +// This is necessary as the standard version doesn't work as expected +// for wchar_t based streams on systems for which wchar_t not a true +// type but rather a synonym for some integer type. + +#include // NULL +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +// given a type, make an input iterator based on a pointer to that type +template +class istream_iterator : + public boost::iterator_facade< + istream_iterator, + Elem, + std::input_iterator_tag, + Elem + > +{ + friend class boost::iterator_core_access; + typedef istream_iterator this_t ; + typedef typename boost::iterator_facade< + istream_iterator, + Elem, + std::input_iterator_tag, + Elem + > super_t; + typedef typename std::basic_istream istream_type; + + bool equal(const this_t & rhs) const { + // note: only works for comparison against end of stream + return m_istream == rhs.m_istream; + } + + //Access the value referred to + Elem dereference() const { + return static_cast(m_istream->peek()); + } + + void increment(){ + if(NULL != m_istream){ + m_istream->ignore(1); + } + } + + istream_type *m_istream; + Elem m_current_value; +public: + istream_iterator(istream_type & is) : + m_istream(& is) + { + //increment(); + } + + istream_iterator() : + m_istream(NULL), + m_current_value(NULL) + {} + + istream_iterator(const istream_iterator & rhs) : + m_istream(rhs.m_istream), + m_current_value(rhs.m_current_value) + {} +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_ISTREAM_ITERATOR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/mb_from_wchar.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/mb_from_wchar.hpp new file mode 100644 index 00000000000..05df71c258e --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/mb_from_wchar.hpp @@ -0,0 +1,139 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP +#define BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// mb_from_wchar.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // size_t +#ifndef BOOST_NO_CWCHAR +#include // mbstate_t +#endif +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::mbstate_t; +} // namespace std +#endif + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// class used by text archives to translate wide strings and to char +// strings of the currently selected locale +template // the input iterator +class mb_from_wchar + : public boost::iterator_adaptor< + mb_from_wchar, + Base, + wchar_t, + single_pass_traversal_tag, + char + > +{ + friend class boost::iterator_core_access; + + typedef typename boost::iterator_adaptor< + mb_from_wchar, + Base, + wchar_t, + single_pass_traversal_tag, + char + > super_t; + + typedef mb_from_wchar this_t; + + char dereference_impl() { + if(! m_full){ + fill(); + m_full = true; + } + return m_buffer[m_bnext]; + } + + char dereference() const { + return (const_cast(this))->dereference_impl(); + } + // test for iterator equality + bool equal(const mb_from_wchar & rhs) const { + // once the value is filled, the base_reference has been incremented + // so don't permit comparison anymore. + return + 0 == m_bend + && 0 == m_bnext + && this->base_reference() == rhs.base_reference() + ; + } + + void fill(){ + wchar_t value = * this->base_reference(); + const wchar_t *wend; + char *bend; + std::codecvt_base::result r = m_codecvt_facet.out( + m_mbs, + & value, & value + 1, wend, + m_buffer, m_buffer + sizeof(m_buffer), bend + ); + BOOST_ASSERT(std::codecvt_base::ok == r); + m_bnext = 0; + m_bend = bend - m_buffer; + } + + void increment(){ + if(++m_bnext < m_bend) + return; + m_bend = + m_bnext = 0; + ++(this->base_reference()); + m_full = false; + } + + boost::archive::detail::utf8_codecvt_facet m_codecvt_facet; + std::mbstate_t m_mbs; + // buffer to handle pending characters + char m_buffer[9 /* MB_CUR_MAX */]; + std::size_t m_bend; + std::size_t m_bnext; + bool m_full; + +public: + // make composible buy using templated constructor + template + mb_from_wchar(T start) : + super_t(Base(static_cast< T >(start))), + m_mbs(std::mbstate_t()), + m_bend(0), + m_bnext(0), + m_full(false) + {} + // intel 7.1 doesn't like default copy constructor + mb_from_wchar(const mb_from_wchar & rhs) : + super_t(rhs.base_reference()), + m_bend(rhs.m_bend), + m_bnext(rhs.m_bnext), + m_full(rhs.m_full) + {} +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/ostream_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/ostream_iterator.hpp new file mode 100644 index 00000000000..49a9b99034b --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/ostream_iterator.hpp @@ -0,0 +1,83 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_OSTREAM_ITERATOR_HPP +#define BOOST_ARCHIVE_ITERATORS_OSTREAM_ITERATOR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// ostream_iterator.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// note: this is a custom version of the standard ostream_iterator. +// This is necessary as the standard version doesn't work as expected +// for wchar_t based streams on systems for which wchar_t not a true +// type but rather a synonym for some integer type. + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +// given a type, make an input iterator based on a pointer to that type +template +class ostream_iterator : + public boost::iterator_facade< + ostream_iterator, + Elem, + std::output_iterator_tag, + ostream_iterator & + > +{ + friend class boost::iterator_core_access; + typedef ostream_iterator this_t ; + typedef Elem char_type; + typedef std::basic_ostream ostream_type; + + //emulate the behavior of std::ostream + ostream_iterator & dereference() const { + return const_cast(*this); + } + bool equal(const this_t & rhs) const { + return m_ostream == rhs.m_ostream; + } + void increment(){} +protected: + ostream_type *m_ostream; + void put_val(char_type e){ + if(NULL != m_ostream){ + m_ostream->put(e); + if(! m_ostream->good()) + m_ostream = NULL; + } + } +public: + this_t & operator=(char_type c){ + put_val(c); + return *this; + } + ostream_iterator(ostream_type & os) : + m_ostream (& os) + {} + ostream_iterator() : + m_ostream (NULL) + {} + ostream_iterator(const ostream_iterator & rhs) : + m_ostream (rhs.m_ostream) + {} +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_OSTREAM_ITERATOR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/remove_whitespace.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/remove_whitespace.hpp new file mode 100644 index 00000000000..c3580ab258a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/remove_whitespace.hpp @@ -0,0 +1,167 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_REMOVE_WHITESPACE_HPP +#define BOOST_ARCHIVE_ITERATORS_REMOVE_WHITESPACE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// remove_whitespace.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include +#include + +// here is the default standard implementation of the functor used +// by the filter iterator to remove spaces. Unfortunately usage +// of this implementation in combination with spirit trips a bug +// VC 6.5. The only way I can find to work around it is to +// implement a special non-standard version for this platform + +#ifndef BOOST_NO_CWCTYPE +#include // iswspace +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ using ::iswspace; } +#endif +#endif + +#include // isspace +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ using ::isspace; } +#endif + +#if defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER) +// this is required for the RW STL on Linux and Tru64. +#undef isspace +#undef iswspace +#endif + +namespace { // anonymous + +template +struct remove_whitespace_predicate; + +template<> +struct remove_whitespace_predicate +{ + bool operator()(unsigned char t){ + return ! std::isspace(t); + } +}; + +#ifndef BOOST_NO_CWCHAR +template<> +struct remove_whitespace_predicate +{ + bool operator()(wchar_t t){ + return ! std::iswspace(t); + } +}; +#endif + +} // namespace anonymous + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// convert base64 file data (including whitespace and padding) to binary + +namespace boost { +namespace archive { +namespace iterators { + +// custom version of filter iterator which doesn't look ahead further than +// necessary + +template +class filter_iterator + : public boost::iterator_adaptor< + filter_iterator, + Base, + use_default, + single_pass_traversal_tag + > +{ + friend class boost::iterator_core_access; + typedef typename boost::iterator_adaptor< + filter_iterator, + Base, + use_default, + single_pass_traversal_tag + > super_t; + typedef filter_iterator this_t; + typedef typename super_t::reference reference_type; + + reference_type dereference_impl(){ + if(! m_full){ + while(! m_predicate(* this->base_reference())) + ++(this->base_reference()); + m_full = true; + } + return * this->base_reference(); + } + + reference_type dereference() const { + return const_cast(this)->dereference_impl(); + } + + Predicate m_predicate; + bool m_full; +public: + // note: this function is public only because comeau compiler complained + // I don't know if this is because the compiler is wrong or what + void increment(){ + m_full = false; + ++(this->base_reference()); + } + filter_iterator(Base start) : + super_t(start), + m_full(false) + {} + filter_iterator(){} +}; + +template +class remove_whitespace : + public filter_iterator< + remove_whitespace_predicate< + typename boost::iterator_value::type + //typename Base::value_type + >, + Base + > +{ + friend class boost::iterator_core_access; + typedef filter_iterator< + remove_whitespace_predicate< + typename boost::iterator_value::type + //typename Base::value_type + >, + Base + > super_t; +public: +// remove_whitespace(){} // why is this needed? + // make composible buy using templated constructor + template + remove_whitespace(T start) : + super_t(Base(static_cast< T >(start))) + {} + // intel 7.1 doesn't like default copy constructor + remove_whitespace(const remove_whitespace & rhs) : + super_t(rhs.base_reference()) + {} +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_REMOVE_WHITESPACE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/transform_width.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/transform_width.hpp new file mode 100644 index 00000000000..09c050a9274 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/transform_width.hpp @@ -0,0 +1,177 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP +#define BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// transform_width.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// iterator which takes elements of x bits and returns elements of y bits. +// used to change streams of 8 bit characters into streams of 6 bit characters. +// and vice-versa for implementing base64 encodeing/decoding. Be very careful +// when using and end iterator. end is only reliable detected when the input +// stream length is some common multiple of x and y. E.G. Base64 6 bit +// character and 8 bit bytes. Lowest common multiple is 24 => 4 6 bit characters +// or 3 8 bit characters + +#include +#include + +#include // std::min + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// class used by text archives to translate char strings to wchar_t +// strings of the currently selected locale +template< + class Base, + int BitsOut, + int BitsIn, + class CharType = typename boost::iterator_value::type // output character +> +class transform_width : + public boost::iterator_adaptor< + transform_width, + Base, + CharType, + single_pass_traversal_tag, + CharType + > +{ + friend class boost::iterator_core_access; + typedef typename boost::iterator_adaptor< + transform_width, + Base, + CharType, + single_pass_traversal_tag, + CharType + > super_t; + + typedef transform_width this_t; + typedef typename iterator_value::type base_value_type; + + void fill(); + + CharType dereference() const { + if(!m_buffer_out_full) + const_cast(this)->fill(); + return m_buffer_out; + } + + bool equal_impl(const this_t & rhs){ + if(BitsIn < BitsOut) // discard any left over bits + return this->base_reference() == rhs.base_reference(); + else{ + // BitsIn > BitsOut // zero fill + if(this->base_reference() == rhs.base_reference()){ + m_end_of_sequence = true; + return 0 == m_remaining_bits; + } + return false; + } + } + + // standard iterator interface + bool equal(const this_t & rhs) const { + return const_cast(this)->equal_impl(rhs); + } + + void increment(){ + m_buffer_out_full = false; + } + + bool m_buffer_out_full; + CharType m_buffer_out; + + // last read element from input + base_value_type m_buffer_in; + + // number of bits to left in the input buffer. + unsigned int m_remaining_bits; + + // flag to indicate we've reached end of data. + bool m_end_of_sequence; + +public: + // make composible buy using templated constructor + template + transform_width(T start) : + super_t(Base(static_cast< T >(start))), + m_buffer_out_full(false), + m_buffer_out(0), + // To disable GCC warning, but not truly necessary + //(m_buffer_in will be initialized later before being + //used because m_remaining_bits == 0) + m_buffer_in(0), + m_remaining_bits(0), + m_end_of_sequence(false) + {} + // intel 7.1 doesn't like default copy constructor + transform_width(const transform_width & rhs) : + super_t(rhs.base_reference()), + m_buffer_out_full(rhs.m_buffer_out_full), + m_buffer_out(rhs.m_buffer_out), + m_buffer_in(rhs.m_buffer_in), + m_remaining_bits(rhs.m_remaining_bits), + m_end_of_sequence(false) + {} +}; + +template< + class Base, + int BitsOut, + int BitsIn, + class CharType +> +void transform_width::fill() { + unsigned int missing_bits = BitsOut; + m_buffer_out = 0; + do{ + if(0 == m_remaining_bits){ + if(m_end_of_sequence){ + m_buffer_in = 0; + m_remaining_bits = missing_bits; + } + else{ + m_buffer_in = * this->base_reference()++; + m_remaining_bits = BitsIn; + } + } + + // append these bits to the next output + // up to the size of the output + unsigned int i = (std::min)(missing_bits, m_remaining_bits); + // shift interesting bits to least significant position + base_value_type j = m_buffer_in >> (m_remaining_bits - i); + // and mask off the un interesting higher bits + // note presumption of twos complement notation + j &= (1 << i) - 1; + // append then interesting bits to the output value + m_buffer_out <<= i; + m_buffer_out |= j; + + // and update counters + missing_bits -= i; + m_remaining_bits -= i; + }while(0 < missing_bits); + m_buffer_out_full = true; +} + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/unescape.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/unescape.hpp new file mode 100644 index 00000000000..abf62406088 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/unescape.hpp @@ -0,0 +1,89 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_UNESCAPE_HPP +#define BOOST_ARCHIVE_ITERATORS_UNESCAPE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// unescape.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// class used by text archives to translate char strings to wchar_t +// strings of the currently selected locale +template +class unescape + : public boost::iterator_adaptor< + unescape, + Base, + typename pointee::type, + single_pass_traversal_tag, + typename pointee::type + > +{ + friend class boost::iterator_core_access; + typedef typename boost::iterator_adaptor< + unescape, + Base, + typename pointee::type, + single_pass_traversal_tag, + typename pointee::type + > super_t; + + typedef unescape this_t; +public: + typedef typename this_t::value_type value_type; + typedef typename this_t::reference reference; +private: + value_type dereference_impl() { + if(! m_full){ + m_current_value = static_cast(this)->drain(); + m_full = true; + } + return m_current_value; + } + + reference dereference() const { + return const_cast(this)->dereference_impl(); + } + + value_type m_current_value; + bool m_full; + + void increment(){ + ++(this->base_reference()); + dereference_impl(); + m_full = false; + }; + +public: + + unescape(Base base) : + super_t(base), + m_full(false) + {} + +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_UNESCAPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/wchar_from_mb.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/wchar_from_mb.hpp new file mode 100644 index 00000000000..2af8f6401f2 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/wchar_from_mb.hpp @@ -0,0 +1,194 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP +#define BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// wchar_from_mb.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include // size_t +#ifndef BOOST_NO_CWCHAR +#include // mbstate_t +#endif +#include // copy + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::mbstate_t; +} // namespace std +#endif +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// class used by text archives to translate char strings to wchar_t +// strings of the currently selected locale +template +class wchar_from_mb + : public boost::iterator_adaptor< + wchar_from_mb, + Base, + wchar_t, + single_pass_traversal_tag, + wchar_t + > +{ + friend class boost::iterator_core_access; + typedef typename boost::iterator_adaptor< + wchar_from_mb, + Base, + wchar_t, + single_pass_traversal_tag, + wchar_t + > super_t; + + typedef wchar_from_mb this_t; + + void drain(); + + wchar_t dereference() const { + if(m_output.m_next == m_output.m_next_available) + return static_cast(0); + return * m_output.m_next; + } + + void increment(){ + if(m_output.m_next == m_output.m_next_available) + return; + if(++m_output.m_next == m_output.m_next_available){ + if(m_input.m_done) + return; + drain(); + } + } + + bool equal(this_t const & rhs) const { + return dereference() == rhs.dereference(); + } + + boost::archive::detail::utf8_codecvt_facet m_codecvt_facet; + std::mbstate_t m_mbs; + + template + struct sliding_buffer { + boost::array m_buffer; + typename boost::array::const_iterator m_next_available; + typename boost::array::iterator m_next; + bool m_done; + // default ctor + sliding_buffer() : + m_next_available(m_buffer.begin()), + m_next(m_buffer.begin()), + m_done(false) + {} + // copy ctor + sliding_buffer(const sliding_buffer & rhs) : + m_next_available( + std::copy( + rhs.m_buffer.begin(), + rhs.m_next_available, + m_buffer.begin() + ) + ), + m_next( + m_buffer.begin() + (rhs.m_next - rhs.m_buffer.begin()) + ), + m_done(rhs.m_done) + {} + }; + + sliding_buffer::type> m_input; + sliding_buffer::type> m_output; + +public: + // make composible buy using templated constructor + template + wchar_from_mb(T start) : + super_t(Base(static_cast< T >(start))), + m_mbs(std::mbstate_t()) + { + BOOST_ASSERT(std::mbsinit(&m_mbs)); + drain(); + } + // default constructor used as an end iterator + wchar_from_mb(){} + + // copy ctor + wchar_from_mb(const wchar_from_mb & rhs) : + super_t(rhs.base_reference()), + m_mbs(rhs.m_mbs), + m_input(rhs.m_input), + m_output(rhs.m_output) + {} +}; + +template +void wchar_from_mb::drain(){ + BOOST_ASSERT(! m_input.m_done); + for(;;){ + typename boost::iterators::iterator_reference::type c = *(this->base_reference()); + // a null character in a multibyte stream is takes as end of string + if(0 == c){ + m_input.m_done = true; + break; + } + ++(this->base_reference()); + * const_cast::type *>( + (m_input.m_next_available++) + ) = c; + // if input buffer is full - we're done for now + if(m_input.m_buffer.end() == m_input.m_next_available) + break; + } + const typename boost::iterators::iterator_value::type * input_new_start; + typename iterator_value::type * next_available; + + std::codecvt_base::result r = m_codecvt_facet.in( + m_mbs, + m_input.m_buffer.begin(), + m_input.m_next_available, + input_new_start, + m_output.m_buffer.begin(), + m_output.m_buffer.end(), + next_available + ); + BOOST_ASSERT(std::codecvt_base::ok == r); + m_output.m_next_available = next_available; + m_output.m_next = m_output.m_buffer.begin(); + + // we're done with some of the input so shift left. + m_input.m_next_available = std::copy( + input_new_start, + m_input.m_next_available, + m_input.m_buffer.begin() + ); + m_input.m_next = m_input.m_buffer.begin(); +} + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_escape.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_escape.hpp new file mode 100644 index 00000000000..c838a73b864 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_escape.hpp @@ -0,0 +1,121 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_XML_ESCAPE_HPP +#define BOOST_ARCHIVE_ITERATORS_XML_ESCAPE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_escape.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// insert escapes into xml text + +template +class xml_escape + : public escape, Base> +{ + friend class boost::iterator_core_access; + + typedef escape, Base> super_t; + +public: + char fill(const char * & bstart, const char * & bend); + wchar_t fill(const wchar_t * & bstart, const wchar_t * & bend); + + template + xml_escape(T start) : + super_t(Base(static_cast< T >(start))) + {} + // intel 7.1 doesn't like default copy constructor + xml_escape(const xml_escape & rhs) : + super_t(rhs.base_reference()) + {} +}; + +template +char xml_escape::fill( + const char * & bstart, + const char * & bend +){ + char current_value = * this->base_reference(); + switch(current_value){ + case '<': + bstart = "<"; + bend = bstart + 4; + break; + case '>': + bstart = ">"; + bend = bstart + 4; + break; + case '&': + bstart = "&"; + bend = bstart + 5; + break; + case '"': + bstart = """; + bend = bstart + 6; + break; + case '\'': + bstart = "'"; + bend = bstart + 6; + break; + default: + return current_value; + } + return *bstart; +} + +template +wchar_t xml_escape::fill( + const wchar_t * & bstart, + const wchar_t * & bend +){ + wchar_t current_value = * this->base_reference(); + switch(current_value){ + case '<': + bstart = L"<"; + bend = bstart + 4; + break; + case '>': + bstart = L">"; + bend = bstart + 4; + break; + case '&': + bstart = L"&"; + bend = bstart + 5; + break; + case '"': + bstart = L"""; + bend = bstart + 6; + break; + case '\'': + bstart = L"'"; + bend = bstart + 6; + break; + default: + return current_value; + } + return *bstart; +} + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_XML_ESCAPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape.hpp new file mode 100644 index 00000000000..69977404567 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape.hpp @@ -0,0 +1,125 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP +#define BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_unescape.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include + +#include +#include + +namespace boost { +namespace archive { +namespace iterators { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// replace &??? xml escape sequences with the corresponding characters +template +class xml_unescape + : public unescape, Base> +{ + friend class boost::iterator_core_access; + typedef xml_unescape this_t; + typedef unescape super_t; + typedef typename boost::iterator_reference reference_type; + + reference_type dereference() const { + return unescape, Base>::dereference(); + } +public: + // workaround msvc 7.1 ICU crash + #if defined(BOOST_MSVC) + typedef int value_type; + #else + typedef typename this_t::value_type value_type; + #endif + + void drain_residue(const char *literal); + value_type drain(); + + template + xml_unescape(T start) : + super_t(Base(static_cast< T >(start))) + {} + // intel 7.1 doesn't like default copy constructor + xml_unescape(const xml_unescape & rhs) : + super_t(rhs.base_reference()) + {} +}; + +template +void xml_unescape::drain_residue(const char * literal){ + do{ + if(* literal != * ++(this->base_reference())) + boost::serialization::throw_exception( + dataflow_exception( + dataflow_exception::invalid_xml_escape_sequence + ) + ); + } + while('\0' != * ++literal); +} + +// note key constraint on this function is that can't "look ahead" any +// more than necessary into base iterator. Doing so would alter the base +// iterator refenence which would make subsequent iterator comparisons +// incorrect and thereby break the composiblity of iterators. +template +typename xml_unescape::value_type +//int +xml_unescape::drain(){ + value_type retval = * this->base_reference(); + if('&' != retval){ + return retval; + } + retval = * ++(this->base_reference()); + switch(retval){ + case 'l': // < + drain_residue("t;"); + retval = '<'; + break; + case 'g': // > + drain_residue("t;"); + retval = '>'; + break; + case 'a': + retval = * ++(this->base_reference()); + switch(retval){ + case 'p': // ' + drain_residue("os;"); + retval = '\''; + break; + case 'm': // & + drain_residue("p;"); + retval = '&'; + break; + } + break; + case 'q': + drain_residue("uot;"); + retval = '"'; + break; + } + return retval; +} + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif // BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape_exception.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape_exception.hpp new file mode 100644 index 00000000000..71a64378c20 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape_exception.hpp @@ -0,0 +1,49 @@ +#ifndef BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_EXCEPTION_HPP +#define BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_EXCEPTION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_unescape_exception.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifndef BOOST_NO_EXCEPTIONS +#include + +#include + +namespace boost { +namespace archive { +namespace iterators { + +////////////////////////////////////////////////////////////////////// +// exceptions thrown by xml_unescapes +// +class xml_unescape_exception : public std::exception +{ +public: + xml_unescape_exception() + {} + + virtual const char *what( ) const throw( ) + { + return "xml contained un-recognized escape code"; + } +}; + +} // namespace iterators +} // namespace archive +} // namespace boost + +#endif //BOOST_NO_EXCEPTIONS +#endif //BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_EXCEPTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_iarchive.hpp new file mode 100644 index 00000000000..4a898a8ad16 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_iarchive.hpp @@ -0,0 +1,54 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_binary_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +class polymorphic_binary_iarchive : + public detail::polymorphic_iarchive_route +{ +public: + polymorphic_binary_iarchive(std::istream & is, unsigned int flags = 0) : + detail::polymorphic_iarchive_route(is, flags) + {} + ~polymorphic_binary_iarchive(){} +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_binary_iarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_oarchive.hpp new file mode 100644 index 00000000000..931b243feb8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_oarchive.hpp @@ -0,0 +1,43 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_binary_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +namespace boost { +namespace archive { + +typedef detail::polymorphic_oarchive_route< + binary_oarchive_impl< + binary_oarchive, + std::ostream::char_type, + std::ostream::traits_type + > + > polymorphic_binary_oarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_binary_oarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_iarchive.hpp new file mode 100644 index 00000000000..d3c59a9f0f4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_iarchive.hpp @@ -0,0 +1,168 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_IARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // std::size_t +#include // ULONG_MAX +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include + +#include +#include +#include +#include + +#include +#include // must be the last header + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization +namespace archive { +namespace detail { + class basic_iarchive; + class basic_iserializer; +} + +class polymorphic_iarchive; + +class BOOST_SYMBOL_VISIBLE polymorphic_iarchive_impl : + public detail::interface_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class detail::interface_iarchive; + friend class load_access; +#endif + // primitive types the only ones permitted by polymorphic archives + virtual void load(bool & t) = 0; + + virtual void load(char & t) = 0; + virtual void load(signed char & t) = 0; + virtual void load(unsigned char & t) = 0; + #ifndef BOOST_NO_CWCHAR + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + virtual void load(wchar_t & t) = 0; + #endif + #endif + virtual void load(short & t) = 0; + virtual void load(unsigned short & t) = 0; + virtual void load(int & t) = 0; + virtual void load(unsigned int & t) = 0; + virtual void load(long & t) = 0; + virtual void load(unsigned long & t) = 0; + + #if defined(BOOST_HAS_LONG_LONG) + virtual void load(boost::long_long_type & t) = 0; + virtual void load(boost::ulong_long_type & t) = 0; + #elif defined(BOOST_HAS_MS_INT64) + virtual void load(__int64 & t) = 0; + virtual void load(unsigned __int64 & t) = 0; + #endif + + virtual void load(float & t) = 0; + virtual void load(double & t) = 0; + + // string types are treated as primitives + virtual void load(std::string & t) = 0; + #ifndef BOOST_NO_STD_WSTRING + virtual void load(std::wstring & t) = 0; + #endif + + // used for xml and other tagged formats + virtual void load_start(const char * name) = 0; + virtual void load_end(const char * name) = 0; + virtual void register_basic_serializer(const detail::basic_iserializer & bis) = 0; + virtual detail::helper_collection & get_helper_collection() = 0; + + // msvc and borland won't automatically pass these to the base class so + // make it explicit here + template + void load_override(T & t) + { + archive::load(* this->This(), t); + } + // special treatment for name-value pairs. + template + void load_override( + const boost::serialization::nvp< T > & t + ){ + load_start(t.name()); + archive::load(* this->This(), t.value()); + load_end(t.name()); + } +protected: + virtual ~polymorphic_iarchive_impl(){}; +public: + // utility function implemented by all legal archives + virtual void set_library_version(library_version_type archive_library_version) = 0; + virtual library_version_type get_library_version() const = 0; + virtual unsigned int get_flags() const = 0; + virtual void delete_created_pointers() = 0; + virtual void reset_object_address( + const void * new_address, + const void * old_address + ) = 0; + + virtual void load_binary(void * t, std::size_t size) = 0; + + // these are used by the serialization library implementation. + virtual void load_object( + void *t, + const detail::basic_iserializer & bis + ) = 0; + virtual const detail::basic_pointer_iserializer * load_pointer( + void * & t, + const detail::basic_pointer_iserializer * bpis_ptr, + const detail::basic_pointer_iserializer * (*finder)( + const boost::serialization::extended_type_info & type + ) + ) = 0; +}; + +} // namespace archive +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +namespace boost { +namespace archive { + +class BOOST_SYMBOL_VISIBLE polymorphic_iarchive : + public polymorphic_iarchive_impl +{ +public: + virtual ~polymorphic_iarchive(){}; +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::polymorphic_iarchive) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_oarchive.hpp new file mode 100644 index 00000000000..edac4edb1e8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_oarchive.hpp @@ -0,0 +1,154 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_OARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // size_t +#include // ULONG_MAX +#include + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include +#include + +#include +#include // must be the last header + +namespace boost { +namespace serialization { + class extended_type_info; +} // namespace serialization +namespace archive { +namespace detail { + class basic_oarchive; + class basic_oserializer; +} + +class polymorphic_oarchive; + +class BOOST_SYMBOL_VISIBLE polymorphic_oarchive_impl : + public detail::interface_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + friend class detail::interface_oarchive; + friend class save_access; +#endif + // primitive types the only ones permitted by polymorphic archives + virtual void save(const bool t) = 0; + + virtual void save(const char t) = 0; + virtual void save(const signed char t) = 0; + virtual void save(const unsigned char t) = 0; + #ifndef BOOST_NO_CWCHAR + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + virtual void save(const wchar_t t) = 0; + #endif + #endif + virtual void save(const short t) = 0; + virtual void save(const unsigned short t) = 0; + virtual void save(const int t) = 0; + virtual void save(const unsigned int t) = 0; + virtual void save(const long t) = 0; + virtual void save(const unsigned long t) = 0; + + #if defined(BOOST_HAS_LONG_LONG) + virtual void save(const boost::long_long_type t) = 0; + virtual void save(const boost::ulong_long_type t) = 0; + #elif defined(BOOST_HAS_MS_INT64) + virtual void save(const __int64 t) = 0; + virtual void save(const unsigned __int64 t) = 0; + #endif + + virtual void save(const float t) = 0; + virtual void save(const double t) = 0; + + // string types are treated as primitives + virtual void save(const std::string & t) = 0; + #ifndef BOOST_NO_STD_WSTRING + virtual void save(const std::wstring & t) = 0; + #endif + + virtual void save_null_pointer() = 0; + // used for xml and other tagged formats + virtual void save_start(const char * name) = 0; + virtual void save_end(const char * name) = 0; + virtual void register_basic_serializer(const detail::basic_oserializer & bos) = 0; + virtual detail::helper_collection & get_helper_collection() = 0; + + virtual void end_preamble() = 0; + + // msvc and borland won't automatically pass these to the base class so + // make it explicit here + template + void save_override(T & t) + { + archive::save(* this->This(), t); + } + // special treatment for name-value pairs. + template + void save_override( + const ::boost::serialization::nvp< T > & t + ){ + save_start(t.name()); + archive::save(* this->This(), t.const_value()); + save_end(t.name()); + } +protected: + virtual ~polymorphic_oarchive_impl(){}; +public: + // utility functions implemented by all legal archives + virtual unsigned int get_flags() const = 0; + virtual library_version_type get_library_version() const = 0; + virtual void save_binary(const void * t, std::size_t size) = 0; + + virtual void save_object( + const void *x, + const detail::basic_oserializer & bos + ) = 0; + virtual void save_pointer( + const void * t, + const detail::basic_pointer_oserializer * bpos_ptr + ) = 0; +}; + +// note: preserve naming symmetry +class BOOST_SYMBOL_VISIBLE polymorphic_oarchive : + public polymorphic_oarchive_impl +{ +public: + virtual ~polymorphic_oarchive(){}; +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::polymorphic_oarchive) + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_POLYMORPHIC_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_iarchive.hpp new file mode 100644 index 00000000000..7bef2927865 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_iarchive.hpp @@ -0,0 +1,54 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_text_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +class polymorphic_text_iarchive : + public detail::polymorphic_iarchive_route +{ +public: + polymorphic_text_iarchive(std::istream & is, unsigned int flags = 0) : + detail::polymorphic_iarchive_route(is, flags) + {} + ~polymorphic_text_iarchive(){} +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_text_iarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_oarchive.hpp new file mode 100644 index 00000000000..457aad9fd75 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_oarchive.hpp @@ -0,0 +1,39 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_text_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +namespace boost { +namespace archive { + +typedef detail::polymorphic_oarchive_route< + text_oarchive_impl +> polymorphic_text_oarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_text_oarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_wiarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_wiarchive.hpp new file mode 100644 index 00000000000..8466f05d6a6 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_wiarchive.hpp @@ -0,0 +1,59 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_text_wiarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +class polymorphic_text_wiarchive : + public detail::polymorphic_iarchive_route +{ +public: + polymorphic_text_wiarchive(std::wistream & is, unsigned int flags = 0) : + detail::polymorphic_iarchive_route(is, flags) + {} + ~polymorphic_text_wiarchive(){} +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_text_wiarchive +) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_woarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_woarchive.hpp new file mode 100644 index 00000000000..295625d1bcf --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_woarchive.hpp @@ -0,0 +1,44 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_text_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include + +namespace boost { +namespace archive { + +typedef detail::polymorphic_oarchive_route< + text_woarchive_impl +> polymorphic_text_woarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_text_woarchive +) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_iarchive.hpp new file mode 100644 index 00000000000..4dc3f894b38 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_iarchive.hpp @@ -0,0 +1,54 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_xml_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +class polymorphic_xml_iarchive : + public detail::polymorphic_iarchive_route +{ +public: + polymorphic_xml_iarchive(std::istream & is, unsigned int flags = 0) : + detail::polymorphic_iarchive_route(is, flags) + {} + ~polymorphic_xml_iarchive(){} +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_xml_iarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_oarchive.hpp new file mode 100644 index 00000000000..514f9e530a8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_oarchive.hpp @@ -0,0 +1,39 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_xml_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +namespace boost { +namespace archive { + +typedef detail::polymorphic_oarchive_route< + xml_oarchive_impl +> polymorphic_xml_oarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_xml_oarchive +) + +#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_wiarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_wiarchive.hpp new file mode 100644 index 00000000000..d4ab731267f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_wiarchive.hpp @@ -0,0 +1,50 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_xml_wiarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include + +namespace boost { +namespace archive { + +class polymorphic_xml_wiarchive : + public detail::polymorphic_iarchive_route +{ +public: + polymorphic_xml_wiarchive(std::wistream & is, unsigned int flags = 0) : + detail::polymorphic_iarchive_route(is, flags) + {} + ~polymorphic_xml_wiarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_xml_wiarchive +) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_woarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_woarchive.hpp new file mode 100644 index 00000000000..dd8963fbb14 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_woarchive.hpp @@ -0,0 +1,44 @@ +#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP +#define BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// polymorphic_xml_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include + +namespace boost { +namespace archive { + +typedef detail::polymorphic_oarchive_route< + xml_woarchive_impl +> polymorphic_xml_woarchive; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE( + boost::archive::polymorphic_xml_woarchive +) + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/archive/text_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/text_iarchive.hpp new file mode 100644 index 00000000000..d9d60adf0b8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/text_iarchive.hpp @@ -0,0 +1,132 @@ +#ifndef BOOST_ARCHIVE_TEXT_IARCHIVE_HPP +#define BOOST_ARCHIVE_TEXT_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_iarchive; +} // namespace detail + +template +class BOOST_SYMBOL_VISIBLE text_iarchive_impl : + public basic_text_iprimitive, + public basic_text_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + friend class detail::interface_iarchive; + friend class load_access; +#endif + template + void load(T & t){ + basic_text_iprimitive::load(t); + } + void load(version_type & t){ + unsigned int v; + load(v); + t = version_type(v); + } + void load(boost::serialization::item_version_type & t){ + unsigned int v; + load(v); + t = boost::serialization::item_version_type(v); + } + BOOST_ARCHIVE_DECL void + load(char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_ARCHIVE_DECL void + load(wchar_t * t); + #endif + BOOST_ARCHIVE_DECL void + load(std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_DECL void + load(std::wstring &ws); + #endif + template + void load_override(T & t){ + basic_text_iarchive::load_override(t); + } + BOOST_ARCHIVE_DECL void + load_override(class_name_type & t); + BOOST_ARCHIVE_DECL void + init(); + BOOST_ARCHIVE_DECL + text_iarchive_impl(std::istream & is, unsigned int flags); + // don't import inline definitions! leave this as a reminder. + //BOOST_ARCHIVE_DECL + ~text_iarchive_impl(){}; +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +class BOOST_SYMBOL_VISIBLE text_iarchive : + public text_iarchive_impl{ +public: + text_iarchive(std::istream & is_, unsigned int flags = 0) : + // note: added _ to suppress useless gcc warning + text_iarchive_impl(is_, flags) + {} + ~text_iarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_iarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_TEXT_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/text_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/text_oarchive.hpp new file mode 100644 index 00000000000..9ba0dafffb4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/text_oarchive.hpp @@ -0,0 +1,121 @@ +#ifndef BOOST_ARCHIVE_TEXT_OARCHIVE_HPP +#define BOOST_ARCHIVE_TEXT_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include // std::size_t + +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_oarchive; +} // namespace detail + +template +class BOOST_SYMBOL_VISIBLE text_oarchive_impl : + /* protected ? */ public basic_text_oprimitive, + public basic_text_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + friend class detail::interface_oarchive; + friend class basic_text_oarchive; + friend class save_access; +#endif + template + void save(const T & t){ + this->newtoken(); + basic_text_oprimitive::save(t); + } + void save(const version_type & t){ + save(static_cast(t)); + } + void save(const boost::serialization::item_version_type & t){ + save(static_cast(t)); + } + BOOST_ARCHIVE_DECL void + save(const char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_ARCHIVE_DECL void + save(const wchar_t * t); + #endif + BOOST_ARCHIVE_DECL void + save(const std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_DECL void + save(const std::wstring &ws); + #endif + BOOST_ARCHIVE_DECL + text_oarchive_impl(std::ostream & os, unsigned int flags); + // don't import inline definitions! leave this as a reminder. + //BOOST_ARCHIVE_DECL + ~text_oarchive_impl(){}; +public: + BOOST_ARCHIVE_DECL void + save_binary(const void *address, std::size_t count); +}; + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from text_oarchive_impl instead. This will +// preserve correct static polymorphism. +class BOOST_SYMBOL_VISIBLE text_oarchive : + public text_oarchive_impl +{ +public: + text_oarchive(std::ostream & os_, unsigned int flags = 0) : + // note: added _ to suppress useless gcc warning + text_oarchive_impl(os_, flags) + {} + ~text_oarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_oarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_ARCHIVE_TEXT_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/text_wiarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/text_wiarchive.hpp new file mode 100644 index 00000000000..3adf068a51a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/text_wiarchive.hpp @@ -0,0 +1,137 @@ +#ifndef BOOST_ARCHIVE_TEXT_WIARCHIVE_HPP +#define BOOST_ARCHIVE_TEXT_WIARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_wiarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include + +#include +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_iarchive; +} // namespace detail + +template +class BOOST_SYMBOL_VISIBLE text_wiarchive_impl : + public basic_text_iprimitive, + public basic_text_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_iarchive; + friend load_access; + #else + friend class detail::interface_iarchive; + friend class load_access; + #endif +#endif + template + void load(T & t){ + basic_text_iprimitive::load(t); + } + void load(version_type & t){ + unsigned int v; + load(v); + t = version_type(v); + } + void load(boost::serialization::item_version_type & t){ + unsigned int v; + load(v); + t = boost::serialization::item_version_type(v); + } + BOOST_WARCHIVE_DECL void + load(char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_WARCHIVE_DECL void + load(wchar_t * t); + #endif + BOOST_WARCHIVE_DECL void + load(std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_WARCHIVE_DECL void + load(std::wstring &ws); + #endif + template + void load_override(T & t){ + basic_text_iarchive::load_override(t); + } + BOOST_WARCHIVE_DECL + text_wiarchive_impl(std::wistream & is, unsigned int flags); + ~text_wiarchive_impl(){}; +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +class BOOST_SYMBOL_VISIBLE text_wiarchive : + public text_wiarchive_impl{ +public: + text_wiarchive(std::wistream & is, unsigned int flags = 0) : + text_wiarchive_impl(is, flags) + {} + ~text_wiarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_wiarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_TEXT_WIARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/text_woarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/text_woarchive.hpp new file mode 100644 index 00000000000..b6b4f8ed59a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/text_woarchive.hpp @@ -0,0 +1,155 @@ +#ifndef BOOST_ARCHIVE_TEXT_WOARCHIVE_HPP +#define BOOST_ARCHIVE_TEXT_WOARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// text_woarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include +#include // size_t + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_oarchive; +} // namespace detail + +template +class BOOST_SYMBOL_VISIBLE text_woarchive_impl : + public basic_text_oprimitive, + public basic_text_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) + // for some inexplicable reason insertion of "class" generates compile erro + // on msvc 7.1 + friend detail::interface_oarchive; + friend basic_text_oarchive; + friend save_access; + #else + friend class detail::interface_oarchive; + friend class basic_text_oarchive; + friend class save_access; + #endif +#endif + template + void save(const T & t){ + this->newtoken(); + basic_text_oprimitive::save(t); + } + void save(const version_type & t){ + save(static_cast(t)); + } + void save(const boost::serialization::item_version_type & t){ + save(static_cast(t)); + } + BOOST_WARCHIVE_DECL void + save(const char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_WARCHIVE_DECL void + save(const wchar_t * t); + #endif + BOOST_WARCHIVE_DECL void + save(const std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_WARCHIVE_DECL void + save(const std::wstring &ws); + #endif + text_woarchive_impl(std::wostream & os, unsigned int flags) : + basic_text_oprimitive( + os, + 0 != (flags & no_codecvt) + ), + basic_text_oarchive(flags) + { + if(0 == (flags & no_header)) + basic_text_oarchive::init(); + } +public: + void save_binary(const void *address, std::size_t count){ + put(static_cast('\n')); + this->end_preamble(); + #if ! defined(__MWERKS__) + this->basic_text_oprimitive::save_binary( + #else + this->basic_text_oprimitive::save_binary( + #endif + address, + count + ); + put(static_cast('\n')); + this->delimiter = this->none; + } + +}; + +// we use the following because we can't use +// typedef text_oarchive_impl > text_oarchive; + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from text_oarchive_impl instead. This will +// preserve correct static polymorphism. +class BOOST_SYMBOL_VISIBLE text_woarchive : + public text_woarchive_impl +{ +public: + text_woarchive(std::wostream & os, unsigned int flags = 0) : + text_woarchive_impl(os, flags) + {} + ~text_woarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_woarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_TEXT_WOARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/tmpdir.hpp b/contrib/libboost/boost_1_65_0/boost/archive/tmpdir.hpp new file mode 100644 index 00000000000..400d23b9f68 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/tmpdir.hpp @@ -0,0 +1,50 @@ +#ifndef BOOST_ARCHIVE_TMPDIR_HPP +#define BOOST_ARCHIVE_TMPDIR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// tmpdir.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // getenv +#include // NULL +//#include + +#include +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { + using ::getenv; +} +#endif + +namespace boost { +namespace archive { + +inline const char * tmpdir(){ + const char *dirname; + dirname = std::getenv("TMP"); + if(NULL == dirname) + dirname = std::getenv("TMPDIR"); + if(NULL == dirname) + dirname = std::getenv("TEMP"); + if(NULL == dirname){ + //BOOST_ASSERT(false); // no temp directory found + dirname = "."; + } + return dirname; +} + +} // archive +} // boost + +#endif // BOOST_ARCHIVE_TMPDIR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/wcslen.hpp b/contrib/libboost/boost_1_65_0/boost/archive/wcslen.hpp new file mode 100644 index 00000000000..0b60004f095 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/wcslen.hpp @@ -0,0 +1,58 @@ +#ifndef BOOST_ARCHIVE_WCSLEN_HPP +#define BOOST_ARCHIVE_WCSLEN_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// wcslen.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // size_t +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#ifndef BOOST_NO_CWCHAR + +// a couple of libraries which include wchar_t don't include +// wcslen + +#if defined(BOOST_DINKUMWARE_STDLIB) && BOOST_DINKUMWARE_STDLIB < 306 \ +|| defined(__LIBCOMO__) + +namespace std { +inline std::size_t wcslen(const wchar_t * ws) +{ + const wchar_t * eows = ws; + while(* eows != 0) + ++eows; + return eows - ws; +} +} // namespace std + +#else + +#ifndef BOOST_NO_CWCHAR +#include +#endif +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ using ::wcslen; } +#endif + +#endif // wcslen + +#endif //BOOST_NO_CWCHAR + +#endif //BOOST_ARCHIVE_WCSLEN_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/xml_archive_exception.hpp b/contrib/libboost/boost_1_65_0/boost/archive/xml_archive_exception.hpp new file mode 100644 index 00000000000..82c53ef5d3e --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/xml_archive_exception.hpp @@ -0,0 +1,57 @@ +#ifndef BOOST_ARCHIVE_XML_ARCHIVE_EXCEPTION_HPP +#define BOOST_ARCHIVE_XML_ARCHIVE_EXCEPTION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_archive_exception.hpp: + +// (C) Copyright 2007 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include +#include +#include + +#include // must be the last header + +namespace boost { +namespace archive { + +////////////////////////////////////////////////////////////////////// +// exceptions thrown by xml archives +// +class BOOST_SYMBOL_VISIBLE xml_archive_exception : + public virtual boost::archive::archive_exception +{ +public: + typedef enum { + xml_archive_parsing_error, // see save_register + xml_archive_tag_mismatch, + xml_archive_tag_name_error + } exception_code; + BOOST_ARCHIVE_DECL xml_archive_exception( + exception_code c, + const char * e1 = NULL, + const char * e2 = NULL + ); + BOOST_ARCHIVE_DECL xml_archive_exception(xml_archive_exception const &) ; + virtual BOOST_ARCHIVE_DECL ~xml_archive_exception() BOOST_NOEXCEPT_OR_NOTHROW ; +}; + +}// namespace archive +}// namespace boost + +#include // pops abi_suffix.hpp pragmas + +#endif //BOOST_XML_ARCHIVE_ARCHIVE_EXCEPTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/xml_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/xml_iarchive.hpp new file mode 100644 index 00000000000..abd2f9fc4e3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/xml_iarchive.hpp @@ -0,0 +1,142 @@ +#ifndef BOOST_ARCHIVE_XML_IARCHIVE_HPP +#define BOOST_ARCHIVE_XML_IARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_iarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_iarchive; +} // namespace detail + +template +class basic_xml_grammar; +typedef basic_xml_grammar xml_grammar; + +template +class BOOST_SYMBOL_VISIBLE xml_iarchive_impl : + public basic_text_iprimitive, + public basic_xml_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + friend class detail::interface_iarchive; + friend class basic_xml_iarchive; + friend class load_access; +#endif + // use boost:scoped_ptr to implement automatic deletion; + boost::scoped_ptr gimpl; + + std::istream & get_is(){ + return is; + } + template + void load(T & t){ + basic_text_iprimitive::load(t); + } + void + load(version_type & t){ + unsigned int v; + load(v); + t = version_type(v); + } + void + load(boost::serialization::item_version_type & t){ + unsigned int v; + load(v); + t = boost::serialization::item_version_type(v); + } + BOOST_ARCHIVE_DECL void + load(char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_ARCHIVE_DECL void + load(wchar_t * t); + #endif + BOOST_ARCHIVE_DECL void + load(std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_DECL void + load(std::wstring &ws); + #endif + template + void load_override(T & t){ + basic_xml_iarchive::load_override(t); + } + BOOST_ARCHIVE_DECL void + load_override(class_name_type & t); + BOOST_ARCHIVE_DECL void + init(); + BOOST_ARCHIVE_DECL + xml_iarchive_impl(std::istream & is, unsigned int flags); + BOOST_ARCHIVE_DECL + ~xml_iarchive_impl(); +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +class BOOST_SYMBOL_VISIBLE xml_iarchive : + public xml_iarchive_impl{ +public: + xml_iarchive(std::istream & is, unsigned int flags = 0) : + xml_iarchive_impl(is, flags) + {} + ~xml_iarchive(){}; +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_iarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_XML_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/xml_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/xml_oarchive.hpp new file mode 100644 index 00000000000..eea12680372 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/xml_oarchive.hpp @@ -0,0 +1,137 @@ +#ifndef BOOST_ARCHIVE_XML_OARCHIVE_HPP +#define BOOST_ARCHIVE_XML_OARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_oarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include // size_t +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_oarchive; +} // namespace detail + +template +class BOOST_SYMBOL_VISIBLE xml_oarchive_impl : + public basic_text_oprimitive, + public basic_xml_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + friend class detail::interface_oarchive; + friend class basic_xml_oarchive; + friend class save_access; +#endif + template + void save(const T & t){ + basic_text_oprimitive::save(t); + } + void + save(const version_type & t){ + save(static_cast(t)); + } + void + save(const boost::serialization::item_version_type & t){ + save(static_cast(t)); + } + BOOST_ARCHIVE_DECL void + save(const char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_ARCHIVE_DECL void + save(const wchar_t * t); + #endif + BOOST_ARCHIVE_DECL void + save(const std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_ARCHIVE_DECL void + save(const std::wstring &ws); + #endif + BOOST_ARCHIVE_DECL + xml_oarchive_impl(std::ostream & os, unsigned int flags); + BOOST_ARCHIVE_DECL + ~xml_oarchive_impl(); +public: + BOOST_ARCHIVE_DECL + void save_binary(const void *address, std::size_t count); +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +// we use the following because we can't use +// typedef xml_oarchive_impl > xml_oarchive; + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from xml_oarchive_impl instead. This will +// preserve correct static polymorphism. +class BOOST_SYMBOL_VISIBLE xml_oarchive : + public xml_oarchive_impl +{ +public: + xml_oarchive(std::ostream & os, unsigned int flags = 0) : + xml_oarchive_impl(os, flags) + {} + ~xml_oarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_oarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_ARCHIVE_XML_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/xml_wiarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/xml_wiarchive.hpp new file mode 100644 index 00000000000..ac24289ac11 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/xml_wiarchive.hpp @@ -0,0 +1,149 @@ +#ifndef BOOST_ARCHIVE_XML_WIARCHIVE_HPP +#define BOOST_ARCHIVE_XML_WIARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_wiarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else + +#include + +#include +#include +#include +#include +#include +#include +// #include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_iarchive; +} // namespace detail + +template +class basic_xml_grammar; +typedef basic_xml_grammar xml_wgrammar; + +template +class BOOST_SYMBOL_VISIBLE xml_wiarchive_impl : + public basic_text_iprimitive, + public basic_xml_iarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + friend class detail::interface_iarchive; + friend class basic_xml_iarchive; + friend class load_access; +#endif + boost::scoped_ptr gimpl; + std::wistream & get_is(){ + return is; + } + template + void + load(T & t){ + basic_text_iprimitive::load(t); + } + void + load(version_type & t){ + unsigned int v; + load(v); + t = version_type(v); + } + void + load(boost::serialization::item_version_type & t){ + unsigned int v; + load(v); + t = boost::serialization::item_version_type(v); + } + BOOST_WARCHIVE_DECL void + load(char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_WARCHIVE_DECL void + load(wchar_t * t); + #endif + BOOST_WARCHIVE_DECL void + load(std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_WARCHIVE_DECL void + load(std::wstring &ws); + #endif + template + void load_override(T & t){ + basic_xml_iarchive::load_override(t); + } + BOOST_WARCHIVE_DECL void + load_override(class_name_type & t); + BOOST_WARCHIVE_DECL void + init(); + BOOST_WARCHIVE_DECL + xml_wiarchive_impl(std::wistream & is, unsigned int flags) ; + BOOST_WARCHIVE_DECL + ~xml_wiarchive_impl(); +}; + +} // namespace archive +} // namespace boost + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +class BOOST_SYMBOL_VISIBLE xml_wiarchive : + public xml_wiarchive_impl{ +public: + xml_wiarchive(std::wistream & is, unsigned int flags = 0) : + xml_wiarchive_impl(is, flags) + {} + ~xml_wiarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_wiarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_XML_WIARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/xml_woarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/xml_woarchive.hpp new file mode 100644 index 00000000000..cb7ce68cb6f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/archive/xml_woarchive.hpp @@ -0,0 +1,134 @@ +#ifndef BOOST_ARCHIVE_XML_WOARCHIVE_HPP +#define BOOST_ARCHIVE_XML_WOARCHIVE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// xml_woarchive.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_NO_STD_WSTREAMBUF +#error "wide char i/o not supported on this platform" +#else +#include // size_t +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include + +//#include +#include +#include +#include +#include +#include +//#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace archive { + +namespace detail { + template class interface_oarchive; +} // namespace detail + +template +class BOOST_SYMBOL_VISIBLE xml_woarchive_impl : + public basic_text_oprimitive, + public basic_xml_oarchive +{ +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else +protected: + friend class detail::interface_oarchive; + friend class basic_xml_oarchive; + friend class save_access; +#endif + //void end_preamble(){ + // basic_xml_oarchive::end_preamble(); + //} + template + void + save(const T & t){ + basic_text_oprimitive::save(t); + } + void + save(const version_type & t){ + save(static_cast(t)); + } + void + save(const boost::serialization::item_version_type & t){ + save(static_cast(t)); + } + BOOST_WARCHIVE_DECL void + save(const char * t); + #ifndef BOOST_NO_INTRINSIC_WCHAR_T + BOOST_WARCHIVE_DECL void + save(const wchar_t * t); + #endif + BOOST_WARCHIVE_DECL void + save(const std::string &s); + #ifndef BOOST_NO_STD_WSTRING + BOOST_WARCHIVE_DECL void + save(const std::wstring &ws); + #endif + BOOST_WARCHIVE_DECL + xml_woarchive_impl(std::wostream & os, unsigned int flags); + BOOST_WARCHIVE_DECL + ~xml_woarchive_impl(); +public: + BOOST_WARCHIVE_DECL void + save_binary(const void *address, std::size_t count); + +}; + +// we use the following because we can't use +// typedef xml_woarchive_impl > xml_woarchive; + +// do not derive from this class. If you want to extend this functionality +// via inhertance, derived from xml_woarchive_impl instead. This will +// preserve correct static polymorphism. +class BOOST_SYMBOL_VISIBLE xml_woarchive : + public xml_woarchive_impl +{ +public: + xml_woarchive(std::wostream & os, unsigned int flags = 0) : + xml_woarchive_impl(os, flags) + {} + ~xml_woarchive(){} +}; + +} // namespace archive +} // namespace boost + +// required by export +BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_woarchive) + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_NO_STD_WSTREAMBUF +#endif // BOOST_ARCHIVE_XML_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/foreach_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/foreach_fwd.hpp new file mode 100644 index 00000000000..4e0bb370c2f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/foreach_fwd.hpp @@ -0,0 +1,51 @@ +/////////////////////////////////////////////////////////////////////////////// +// foreach.hpp header file +// +// Copyright 2010 Eric Niebler. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// See http://www.boost.org/libs/foreach for documentation +// +// Credits: +// Kazutoshi Satoda: for suggesting the need for a _fwd header for foreach's +// customization points. + +#ifndef BOOST_FOREACH_FWD_HPP +#define BOOST_FOREACH_FWD_HPP + +// This must be at global scope, hence the uglified name +enum boost_foreach_argument_dependent_lookup_hack +{ + boost_foreach_argument_dependent_lookup_hack_value +}; + +namespace boost +{ + +namespace foreach +{ + /////////////////////////////////////////////////////////////////////////////// + // boost::foreach::tag + // + typedef boost_foreach_argument_dependent_lookup_hack tag; + + /////////////////////////////////////////////////////////////////////////////// + // boost::foreach::is_lightweight_proxy + // Specialize this for user-defined collection types if they are inexpensive to copy. + // This tells BOOST_FOREACH it can avoid the rvalue/lvalue detection stuff. + template + struct is_lightweight_proxy; + + /////////////////////////////////////////////////////////////////////////////// + // boost::foreach::is_noncopyable + // Specialize this for user-defined collection types if they cannot be copied. + // This also tells BOOST_FOREACH to avoid the rvalue/lvalue detection stuff. + template + struct is_noncopyable; + +} // namespace foreach + +} // namespace boost + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/composite_key.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/composite_key.hpp new file mode 100644 index 00000000000..787cdf83195 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/composite_key.hpp @@ -0,0 +1,1513 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP +#define BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) +#include +#endif + +#if !defined(BOOST_NO_SFINAE) +#include +#endif + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif + +/* A composite key stores n key extractors and "computes" the + * result on a given value as a packed reference to the value and + * the composite key itself. Actual invocations to the component + * key extractors are lazily performed when executing an operation + * on composite_key results (equality, comparison, hashing.) + * As the other key extractors in Boost.MultiIndex, composite_key + * is overloaded to work on chained pointers to T and reference_wrappers + * of T. + */ + +/* This user_definable macro limits the number of elements of a composite + * key; useful for shortening resulting symbol names (MSVC++ 6.0, for + * instance has problems coping with very long symbol names.) + * NB: This cannot exceed the maximum number of arguments of + * boost::tuple. In Boost 1.32, the limit is 10. + */ + +#if !defined(BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE) +#define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 10 +#endif + +/* maximum number of key extractors in a composite key */ + +#if BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE<10 /* max length of a tuple */ +#define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE \ + BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE +#else +#define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE 10 +#endif + +/* BOOST_PP_ENUM of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */ + +#define BOOST_MULTI_INDEX_CK_ENUM(macro,data) \ + BOOST_PP_ENUM(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,macro,data) + +/* BOOST_PP_ENUM_PARAMS of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */ + +#define BOOST_MULTI_INDEX_CK_ENUM_PARAMS(param) \ + BOOST_PP_ENUM_PARAMS(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,param) + +/* if n==0 -> text0 + * otherwise -> textn=tuples::null_type + */ + +#define BOOST_MULTI_INDEX_CK_TEMPLATE_PARM(z,n,text) \ + typename BOOST_PP_CAT(text,n) BOOST_PP_EXPR_IF(n,=tuples::null_type) + +/* const textn& kn=textn() */ + +#define BOOST_MULTI_INDEX_CK_CTOR_ARG(z,n,text) \ + const BOOST_PP_CAT(text,n)& BOOST_PP_CAT(k,n) = BOOST_PP_CAT(text,n)() + +/* typename list(0)::type */ + +#define BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N(z,n,list) \ + BOOST_DEDUCED_TYPENAME BOOST_PP_LIST_AT(list,0)< \ + BOOST_PP_LIST_AT(list,1),n \ + >::type + +namespace boost{ + +template class reference_wrapper; /* fwd decl. */ + +namespace multi_index{ + +namespace detail{ + +/* n-th key extractor of a composite key */ + +template +struct nth_key_from_value +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename mpl::eval_if_c< + N::value, + tuples::element, + mpl::identity + >::type type; +}; + +/* nth_composite_key_##name::type yields + * functor >, or tuples::null_type + * if N exceeds the length of the composite key. + */ + +#define BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(name,functor) \ +template \ +struct BOOST_PP_CAT(key_,name) \ +{ \ + typedef functor type; \ +}; \ + \ +template<> \ +struct BOOST_PP_CAT(key_,name) \ +{ \ + typedef tuples::null_type type; \ +}; \ + \ +template \ +struct BOOST_PP_CAT(nth_composite_key_,name) \ +{ \ + typedef typename nth_key_from_value::type key_from_value; \ + typedef typename BOOST_PP_CAT(key_,name)::type type; \ +}; + +/* nth_composite_key_equal_to + * nth_composite_key_less + * nth_composite_key_greater + * nth_composite_key_hash + */ + +BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(equal_to,std::equal_to) +BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(less,std::less) +BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(greater,std::greater) +BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(hash,boost::hash) + +/* used for defining equality and comparison ops of composite_key_result */ + +#define BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO(z,n,text) text + +struct generic_operator_equal +{ + template + bool operator()(const T& x,const Q& y)const{return x==y;} +}; + +typedef tuple< + BOOST_MULTI_INDEX_CK_ENUM( + BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO, + detail::generic_operator_equal)> generic_operator_equal_tuple; + +struct generic_operator_less +{ + template + bool operator()(const T& x,const Q& y)const{return x generic_operator_less_tuple; + +/* Metaprogramming machinery for implementing equality, comparison and + * hashing operations of composite_key_result. + * + * equal_* checks for equality between composite_key_results and + * between those and tuples, accepting a tuple of basic equality functors. + * compare_* does lexicographical comparison. + * hash_* computes a combination of elementwise hash values. + */ + +template +< + typename KeyCons1,typename Value1, + typename KeyCons2, typename Value2, + typename EqualCons +> +struct equal_ckey_ckey; /* fwd decl. */ + +template +< + typename KeyCons1,typename Value1, + typename KeyCons2, typename Value2, + typename EqualCons +> +struct equal_ckey_ckey_terminal +{ + static bool compare( + const KeyCons1&,const Value1&, + const KeyCons2&,const Value2&, + const EqualCons&) + { + return true; + } +}; + +template +< + typename KeyCons1,typename Value1, + typename KeyCons2, typename Value2, + typename EqualCons +> +struct equal_ckey_ckey_normal +{ + static bool compare( + const KeyCons1& c0,const Value1& v0, + const KeyCons2& c1,const Value2& v1, + const EqualCons& eq) + { + if(!eq.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return false; + return equal_ckey_ckey< + BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1, + BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2, + BOOST_DEDUCED_TYPENAME EqualCons::tail_type + >::compare(c0.get_tail(),v0,c1.get_tail(),v1,eq.get_tail()); + } +}; + +template +< + typename KeyCons1,typename Value1, + typename KeyCons2, typename Value2, + typename EqualCons +> +struct equal_ckey_ckey: + mpl::if_< + mpl::or_< + is_same, + is_same + >, + equal_ckey_ckey_terminal, + equal_ckey_ckey_normal + >::type +{ +}; + +template +< + typename KeyCons,typename Value, + typename ValCons,typename EqualCons +> +struct equal_ckey_cval; /* fwd decl. */ + +template +< + typename KeyCons,typename Value, + typename ValCons,typename EqualCons +> +struct equal_ckey_cval_terminal +{ + static bool compare( + const KeyCons&,const Value&,const ValCons&,const EqualCons&) + { + return true; + } + + static bool compare( + const ValCons&,const KeyCons&,const Value&,const EqualCons&) + { + return true; + } +}; + +template +< + typename KeyCons,typename Value, + typename ValCons,typename EqualCons +> +struct equal_ckey_cval_normal +{ + static bool compare( + const KeyCons& c,const Value& v,const ValCons& vc, + const EqualCons& eq) + { + if(!eq.get_head()(c.get_head()(v),vc.get_head()))return false; + return equal_ckey_cval< + BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, + BOOST_DEDUCED_TYPENAME ValCons::tail_type, + BOOST_DEDUCED_TYPENAME EqualCons::tail_type + >::compare(c.get_tail(),v,vc.get_tail(),eq.get_tail()); + } + + static bool compare( + const ValCons& vc,const KeyCons& c,const Value& v, + const EqualCons& eq) + { + if(!eq.get_head()(vc.get_head(),c.get_head()(v)))return false; + return equal_ckey_cval< + BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, + BOOST_DEDUCED_TYPENAME ValCons::tail_type, + BOOST_DEDUCED_TYPENAME EqualCons::tail_type + >::compare(vc.get_tail(),c.get_tail(),v,eq.get_tail()); + } +}; + +template +< + typename KeyCons,typename Value, + typename ValCons,typename EqualCons +> +struct equal_ckey_cval: + mpl::if_< + mpl::or_< + is_same, + is_same + >, + equal_ckey_cval_terminal, + equal_ckey_cval_normal + >::type +{ +}; + +template +< + typename KeyCons1,typename Value1, + typename KeyCons2, typename Value2, + typename CompareCons +> +struct compare_ckey_ckey; /* fwd decl. */ + +template +< + typename KeyCons1,typename Value1, + typename KeyCons2, typename Value2, + typename CompareCons +> +struct compare_ckey_ckey_terminal +{ + static bool compare( + const KeyCons1&,const Value1&, + const KeyCons2&,const Value2&, + const CompareCons&) + { + return false; + } +}; + +template +< + typename KeyCons1,typename Value1, + typename KeyCons2, typename Value2, + typename CompareCons +> +struct compare_ckey_ckey_normal +{ + static bool compare( + const KeyCons1& c0,const Value1& v0, + const KeyCons2& c1,const Value2& v1, + const CompareCons& comp) + { + if(comp.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return true; + if(comp.get_head()(c1.get_head()(v1),c0.get_head()(v0)))return false; + return compare_ckey_ckey< + BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1, + BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2, + BOOST_DEDUCED_TYPENAME CompareCons::tail_type + >::compare(c0.get_tail(),v0,c1.get_tail(),v1,comp.get_tail()); + } +}; + +template +< + typename KeyCons1,typename Value1, + typename KeyCons2, typename Value2, + typename CompareCons +> +struct compare_ckey_ckey: + mpl::if_< + mpl::or_< + is_same, + is_same + >, + compare_ckey_ckey_terminal, + compare_ckey_ckey_normal + >::type +{ +}; + +template +< + typename KeyCons,typename Value, + typename ValCons,typename CompareCons +> +struct compare_ckey_cval; /* fwd decl. */ + +template +< + typename KeyCons,typename Value, + typename ValCons,typename CompareCons +> +struct compare_ckey_cval_terminal +{ + static bool compare( + const KeyCons&,const Value&,const ValCons&,const CompareCons&) + { + return false; + } + + static bool compare( + const ValCons&,const KeyCons&,const Value&,const CompareCons&) + { + return false; + } +}; + +template +< + typename KeyCons,typename Value, + typename ValCons,typename CompareCons +> +struct compare_ckey_cval_normal +{ + static bool compare( + const KeyCons& c,const Value& v,const ValCons& vc, + const CompareCons& comp) + { + if(comp.get_head()(c.get_head()(v),vc.get_head()))return true; + if(comp.get_head()(vc.get_head(),c.get_head()(v)))return false; + return compare_ckey_cval< + BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, + BOOST_DEDUCED_TYPENAME ValCons::tail_type, + BOOST_DEDUCED_TYPENAME CompareCons::tail_type + >::compare(c.get_tail(),v,vc.get_tail(),comp.get_tail()); + } + + static bool compare( + const ValCons& vc,const KeyCons& c,const Value& v, + const CompareCons& comp) + { + if(comp.get_head()(vc.get_head(),c.get_head()(v)))return true; + if(comp.get_head()(c.get_head()(v),vc.get_head()))return false; + return compare_ckey_cval< + BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, + BOOST_DEDUCED_TYPENAME ValCons::tail_type, + BOOST_DEDUCED_TYPENAME CompareCons::tail_type + >::compare(vc.get_tail(),c.get_tail(),v,comp.get_tail()); + } +}; + +template +< + typename KeyCons,typename Value, + typename ValCons,typename CompareCons +> +struct compare_ckey_cval: + mpl::if_< + mpl::or_< + is_same, + is_same + >, + compare_ckey_cval_terminal, + compare_ckey_cval_normal + >::type +{ +}; + +template +struct hash_ckey; /* fwd decl. */ + +template +struct hash_ckey_terminal +{ + static std::size_t hash( + const KeyCons&,const Value&,const HashCons&,std::size_t carry) + { + return carry; + } +}; + +template +struct hash_ckey_normal +{ + static std::size_t hash( + const KeyCons& c,const Value& v,const HashCons& h,std::size_t carry=0) + { + /* same hashing formula as boost::hash_combine */ + + carry^=h.get_head()(c.get_head()(v))+0x9e3779b9+(carry<<6)+(carry>>2); + return hash_ckey< + BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, + BOOST_DEDUCED_TYPENAME HashCons::tail_type + >::hash(c.get_tail(),v,h.get_tail(),carry); + } +}; + +template +struct hash_ckey: + mpl::if_< + is_same, + hash_ckey_terminal, + hash_ckey_normal + >::type +{ +}; + +template +struct hash_cval; /* fwd decl. */ + +template +struct hash_cval_terminal +{ + static std::size_t hash(const ValCons&,const HashCons&,std::size_t carry) + { + return carry; + } +}; + +template +struct hash_cval_normal +{ + static std::size_t hash( + const ValCons& vc,const HashCons& h,std::size_t carry=0) + { + carry^=h.get_head()(vc.get_head())+0x9e3779b9+(carry<<6)+(carry>>2); + return hash_cval< + BOOST_DEDUCED_TYPENAME ValCons::tail_type, + BOOST_DEDUCED_TYPENAME HashCons::tail_type + >::hash(vc.get_tail(),h.get_tail(),carry); + } +}; + +template +struct hash_cval: + mpl::if_< + is_same, + hash_cval_terminal, + hash_cval_normal + >::type +{ +}; + +} /* namespace multi_index::detail */ + +/* composite_key_result */ + +#if defined(BOOST_MSVC) +#pragma warning(push) +#pragma warning(disable:4512) +#endif + +template +struct composite_key_result +{ + typedef CompositeKey composite_key_type; + typedef typename composite_key_type::value_type value_type; + + composite_key_result( + const composite_key_type& composite_key_,const value_type& value_): + composite_key(composite_key_),value(value_) + {} + + const composite_key_type& composite_key; + const value_type& value; +}; + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +/* composite_key */ + +template< + typename Value, + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,KeyFromValue) +> +struct composite_key: + private tuple +{ +private: + typedef tuple super; + +public: + typedef super key_extractor_tuple; + typedef Value value_type; + typedef composite_key_result result_type; + + composite_key( + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,KeyFromValue)): + super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) + {} + + composite_key(const key_extractor_tuple& x):super(x){} + + const key_extractor_tuple& key_extractors()const{return *this;} + key_extractor_tuple& key_extractors(){return *this;} + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,result_type>::type +#else + result_type +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + result_type operator()(const value_type& x)const + { + return result_type(*this,x); + } + + result_type operator()(const reference_wrapper& x)const + { + return result_type(*this,x.get()); + } + + result_type operator()(const reference_wrapper& x)const + { + return result_type(*this,x.get()); + } +}; + +/* comparison operators */ + +/* == */ + +template +inline bool operator==( + const composite_key_result& x, + const composite_key_result& y) +{ + typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; + typedef typename CompositeKey1::value_type value_type1; + typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; + typedef typename CompositeKey2::value_type value_type2; + + BOOST_STATIC_ASSERT( + tuples::length::value== + tuples::length::value); + + return detail::equal_ckey_ckey< + key_extractor_tuple1,value_type1, + key_extractor_tuple2,value_type2, + detail::generic_operator_equal_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + y.composite_key.key_extractors(),y.value, + detail::generic_operator_equal_tuple()); +} + +template< + typename CompositeKey, + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) +> +inline bool operator==( + const composite_key_result& x, + const tuple& y) +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef tuple key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value== + tuples::length::value); + + return detail::equal_ckey_cval< + key_extractor_tuple,value_type, + key_tuple,detail::generic_operator_equal_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + y,detail::generic_operator_equal_tuple()); +} + +template +< + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), + typename CompositeKey +> +inline bool operator==( + const tuple& x, + const composite_key_result& y) +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef tuple key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value== + tuples::length::value); + + return detail::equal_ckey_cval< + key_extractor_tuple,value_type, + key_tuple,detail::generic_operator_equal_tuple + >::compare( + x,y.composite_key.key_extractors(), + y.value,detail::generic_operator_equal_tuple()); +} + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template +inline bool operator==( + const composite_key_result& x, + const std::tuple& y) +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + BOOST_STATIC_ASSERT( + static_cast(tuples::length::value)== + std::tuple_size::value); + + return detail::equal_ckey_cval< + key_extractor_tuple,value_type, + cons_key_tuple,detail::generic_operator_equal_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + detail::make_cons_stdtuple(y),detail::generic_operator_equal_tuple()); +} + +template +inline bool operator==( + const std::tuple& x, + const composite_key_result& y) +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + BOOST_STATIC_ASSERT( + static_cast(tuples::length::value)== + std::tuple_size::value); + + return detail::equal_ckey_cval< + key_extractor_tuple,value_type, + cons_key_tuple,detail::generic_operator_equal_tuple + >::compare( + detail::make_cons_stdtuple(x),y.composite_key.key_extractors(), + y.value,detail::generic_operator_equal_tuple()); +} +#endif + +/* < */ + +template +inline bool operator<( + const composite_key_result& x, + const composite_key_result& y) +{ + typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; + typedef typename CompositeKey1::value_type value_type1; + typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; + typedef typename CompositeKey2::value_type value_type2; + + return detail::compare_ckey_ckey< + key_extractor_tuple1,value_type1, + key_extractor_tuple2,value_type2, + detail::generic_operator_less_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + y.composite_key.key_extractors(),y.value, + detail::generic_operator_less_tuple()); +} + +template +< + typename CompositeKey, + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) +> +inline bool operator<( + const composite_key_result& x, + const tuple& y) +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef tuple key_tuple; + + return detail::compare_ckey_cval< + key_extractor_tuple,value_type, + key_tuple,detail::generic_operator_less_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + y,detail::generic_operator_less_tuple()); +} + +template +< + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), + typename CompositeKey +> +inline bool operator<( + const tuple& x, + const composite_key_result& y) +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef tuple key_tuple; + + return detail::compare_ckey_cval< + key_extractor_tuple,value_type, + key_tuple,detail::generic_operator_less_tuple + >::compare( + x,y.composite_key.key_extractors(), + y.value,detail::generic_operator_less_tuple()); +} + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +template +inline bool operator<( + const composite_key_result& x, + const std::tuple& y) +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + return detail::compare_ckey_cval< + key_extractor_tuple,value_type, + cons_key_tuple,detail::generic_operator_less_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + detail::make_cons_stdtuple(y),detail::generic_operator_less_tuple()); +} + +template +inline bool operator<( + const std::tuple& x, + const composite_key_result& y) +{ + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + return detail::compare_ckey_cval< + key_extractor_tuple,value_type, + cons_key_tuple,detail::generic_operator_less_tuple + >::compare( + detail::make_cons_stdtuple(x),y.composite_key.key_extractors(), + y.value,detail::generic_operator_less_tuple()); +} +#endif + +/* rest of comparison operators */ + +#define BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(t1,t2,a1,a2) \ +template inline bool operator!=(const a1& x,const a2& y) \ +{ \ + return !(x==y); \ +} \ + \ +template inline bool operator>(const a1& x,const a2& y) \ +{ \ + return y inline bool operator>=(const a1& x,const a2& y) \ +{ \ + return !(x inline bool operator<=(const a1& x,const a2& y) \ +{ \ + return !(y, + composite_key_result +) + +BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( + typename CompositeKey, + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), + composite_key_result, + tuple +) + +BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), + typename CompositeKey, + tuple, + composite_key_result +) + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( + typename CompositeKey, + typename... Values, + composite_key_result, + std::tuple +) + +BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( + typename CompositeKey, + typename... Values, + std::tuple, + composite_key_result +) +#endif + +/* composite_key_equal_to */ + +template +< + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Pred) +> +struct composite_key_equal_to: + private tuple +{ +private: + typedef tuple super; + +public: + typedef super key_eq_tuple; + + composite_key_equal_to( + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Pred)): + super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) + {} + + composite_key_equal_to(const key_eq_tuple& x):super(x){} + + const key_eq_tuple& key_eqs()const{return *this;} + key_eq_tuple& key_eqs(){return *this;} + + template + bool operator()( + const composite_key_result & x, + const composite_key_result & y)const + { + typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; + typedef typename CompositeKey1::value_type value_type1; + typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; + typedef typename CompositeKey2::value_type value_type2; + + BOOST_STATIC_ASSERT( + tuples::length::value<= + tuples::length::value&& + tuples::length::value== + tuples::length::value); + + return detail::equal_ckey_ckey< + key_extractor_tuple1,value_type1, + key_extractor_tuple2,value_type2, + key_eq_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + y.composite_key.key_extractors(),y.value, + key_eqs()); + } + + template + < + typename CompositeKey, + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) + > + bool operator()( + const composite_key_result& x, + const tuple& y)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef tuple key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value<= + tuples::length::value&& + tuples::length::value== + tuples::length::value); + + return detail::equal_ckey_cval< + key_extractor_tuple,value_type, + key_tuple,key_eq_tuple + >::compare(x.composite_key.key_extractors(),x.value,y,key_eqs()); + } + + template + < + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), + typename CompositeKey + > + bool operator()( + const tuple& x, + const composite_key_result& y)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef tuple key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value<= + tuples::length::value&& + tuples::length::value== + tuples::length::value); + + return detail::equal_ckey_cval< + key_extractor_tuple,value_type, + key_tuple,key_eq_tuple + >::compare(x,y.composite_key.key_extractors(),y.value,key_eqs()); + } + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + bool operator()( + const composite_key_result& x, + const std::tuple& y)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value<= + tuples::length::value&& + static_cast(tuples::length::value)== + std::tuple_size::value); + + return detail::equal_ckey_cval< + key_extractor_tuple,value_type, + cons_key_tuple,key_eq_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + detail::make_cons_stdtuple(y),key_eqs()); + } + + template + bool operator()( + const std::tuple& x, + const composite_key_result& y)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + BOOST_STATIC_ASSERT( + std::tuple_size::value<= + static_cast(tuples::length::value)&& + std::tuple_size::value== + static_cast(tuples::length::value)); + + return detail::equal_ckey_cval< + key_extractor_tuple,value_type, + cons_key_tuple,key_eq_tuple + >::compare( + detail::make_cons_stdtuple(x),y.composite_key.key_extractors(), + y.value,key_eqs()); + } +#endif +}; + +/* composite_key_compare */ + +template +< + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Compare) +> +struct composite_key_compare: + private tuple +{ +private: + typedef tuple super; + +public: + typedef super key_comp_tuple; + + composite_key_compare( + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Compare)): + super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) + {} + + composite_key_compare(const key_comp_tuple& x):super(x){} + + const key_comp_tuple& key_comps()const{return *this;} + key_comp_tuple& key_comps(){return *this;} + + template + bool operator()( + const composite_key_result & x, + const composite_key_result & y)const + { + typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; + typedef typename CompositeKey1::value_type value_type1; + typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; + typedef typename CompositeKey2::value_type value_type2; + + BOOST_STATIC_ASSERT( + tuples::length::value<= + tuples::length::value|| + tuples::length::value<= + tuples::length::value); + + return detail::compare_ckey_ckey< + key_extractor_tuple1,value_type1, + key_extractor_tuple2,value_type2, + key_comp_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + y.composite_key.key_extractors(),y.value, + key_comps()); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + template + bool operator()( + const composite_key_result& x, + const Value& y)const + { + return operator()(x,boost::make_tuple(boost::cref(y))); + } +#endif + + template + < + typename CompositeKey, + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) + > + bool operator()( + const composite_key_result& x, + const tuple& y)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef tuple key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value<= + tuples::length::value|| + tuples::length::value<= + tuples::length::value); + + return detail::compare_ckey_cval< + key_extractor_tuple,value_type, + key_tuple,key_comp_tuple + >::compare(x.composite_key.key_extractors(),x.value,y,key_comps()); + } + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + template + bool operator()( + const Value& x, + const composite_key_result& y)const + { + return operator()(boost::make_tuple(boost::cref(x)),y); + } +#endif + + template + < + BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), + typename CompositeKey + > + bool operator()( + const tuple& x, + const composite_key_result& y)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef tuple key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value<= + tuples::length::value|| + tuples::length::value<= + tuples::length::value); + + return detail::compare_ckey_cval< + key_extractor_tuple,value_type, + key_tuple,key_comp_tuple + >::compare(x,y.composite_key.key_extractors(),y.value,key_comps()); + } + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + bool operator()( + const composite_key_result& x, + const std::tuple& y)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value<= + tuples::length::value|| + std::tuple_size::value<= + static_cast(tuples::length::value)); + + return detail::compare_ckey_cval< + key_extractor_tuple,value_type, + cons_key_tuple,key_comp_tuple + >::compare( + x.composite_key.key_extractors(),x.value, + detail::make_cons_stdtuple(y),key_comps()); + } + + template + bool operator()( + const std::tuple& x, + const composite_key_result& y)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + BOOST_STATIC_ASSERT( + std::tuple_size::value<= + static_cast(tuples::length::value)|| + tuples::length::value<= + tuples::length::value); + + return detail::compare_ckey_cval< + key_extractor_tuple,value_type, + cons_key_tuple,key_comp_tuple + >::compare( + detail::make_cons_stdtuple(x),y.composite_key.key_extractors(), + y.value,key_comps()); + } +#endif +}; + +/* composite_key_hash */ + +template +< + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Hash) +> +struct composite_key_hash: + private tuple +{ +private: + typedef tuple super; + +public: + typedef super key_hasher_tuple; + + composite_key_hash( + BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Hash)): + super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) + {} + + composite_key_hash(const key_hasher_tuple& x):super(x){} + + const key_hasher_tuple& key_hash_functions()const{return *this;} + key_hasher_tuple& key_hash_functions(){return *this;} + + template + std::size_t operator()(const composite_key_result & x)const + { + typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; + typedef typename CompositeKey::value_type value_type; + + BOOST_STATIC_ASSERT( + tuples::length::value== + tuples::length::value); + + return detail::hash_ckey< + key_extractor_tuple,value_type, + key_hasher_tuple + >::hash(x.composite_key.key_extractors(),x.value,key_hash_functions()); + } + + template + std::size_t operator()( + const tuple& x)const + { + typedef tuple key_tuple; + + BOOST_STATIC_ASSERT( + tuples::length::value== + tuples::length::value); + + return detail::hash_cval< + key_tuple,key_hasher_tuple + >::hash(x,key_hash_functions()); + } + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ + !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + std::size_t operator()(const std::tuple& x)const + { + typedef std::tuple key_tuple; + typedef typename detail::cons_stdtuple_ctor< + key_tuple>::result_type cons_key_tuple; + + BOOST_STATIC_ASSERT( + std::tuple_size::value== + static_cast(tuples::length::value)); + + return detail::hash_cval< + cons_key_tuple,key_hasher_tuple + >::hash(detail::make_cons_stdtuple(x),key_hash_functions()); + } +#endif +}; + +/* Instantiations of the former functors with "natural" basic components: + * composite_key_result_equal_to uses std::equal_to of the values. + * composite_key_result_less uses std::less. + * composite_key_result_greater uses std::greater. + * composite_key_result_hash uses boost::hash. + */ + +#define BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER \ +composite_key_equal_to< \ + BOOST_MULTI_INDEX_CK_ENUM( \ + BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ + /* the argument is a PP list */ \ + (detail::nth_composite_key_equal_to, \ + (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ + BOOST_PP_NIL))) \ + > + +template +struct composite_key_result_equal_to: +BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS +BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER +{ +private: + typedef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER super; + +public: + typedef CompositeKeyResult first_argument_type; + typedef first_argument_type second_argument_type; + typedef bool result_type; + + using super::operator(); +}; + +#define BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER \ +composite_key_compare< \ + BOOST_MULTI_INDEX_CK_ENUM( \ + BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ + /* the argument is a PP list */ \ + (detail::nth_composite_key_less, \ + (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ + BOOST_PP_NIL))) \ + > + +template +struct composite_key_result_less: +BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS +BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER +{ +private: + typedef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER super; + +public: + typedef CompositeKeyResult first_argument_type; + typedef first_argument_type second_argument_type; + typedef bool result_type; + + using super::operator(); +}; + +#define BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER \ +composite_key_compare< \ + BOOST_MULTI_INDEX_CK_ENUM( \ + BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ + /* the argument is a PP list */ \ + (detail::nth_composite_key_greater, \ + (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ + BOOST_PP_NIL))) \ + > + +template +struct composite_key_result_greater: +BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS +BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER +{ +private: + typedef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER super; + +public: + typedef CompositeKeyResult first_argument_type; + typedef first_argument_type second_argument_type; + typedef bool result_type; + + using super::operator(); +}; + +#define BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER \ +composite_key_hash< \ + BOOST_MULTI_INDEX_CK_ENUM( \ + BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ + /* the argument is a PP list */ \ + (detail::nth_composite_key_hash, \ + (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ + BOOST_PP_NIL))) \ + > + +template +struct composite_key_result_hash: +BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS +BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER +{ +private: + typedef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER super; + +public: + typedef CompositeKeyResult argument_type; + typedef std::size_t result_type; + + using super::operator(); +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +/* Specializations of std::equal_to, std::less, std::greater and boost::hash + * for composite_key_results enabling interoperation with tuples of values. + */ + +namespace std{ + +template +struct equal_to >: + boost::multi_index::composite_key_result_equal_to< + boost::multi_index::composite_key_result + > +{ +}; + +template +struct less >: + boost::multi_index::composite_key_result_less< + boost::multi_index::composite_key_result + > +{ +}; + +template +struct greater >: + boost::multi_index::composite_key_result_greater< + boost::multi_index::composite_key_result + > +{ +}; + +} /* namespace std */ + +namespace boost{ + +template +struct hash >: + boost::multi_index::composite_key_result_hash< + boost::multi_index::composite_key_result + > +{ +}; + +} /* namespace boost */ + +#undef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER +#undef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER +#undef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER +#undef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER +#undef BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS +#undef BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO +#undef BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR +#undef BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N +#undef BOOST_MULTI_INDEX_CK_CTOR_ARG +#undef BOOST_MULTI_INDEX_CK_TEMPLATE_PARM +#undef BOOST_MULTI_INDEX_CK_ENUM_PARAMS +#undef BOOST_MULTI_INDEX_CK_ENUM +#undef BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/access_specifier.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/access_specifier.hpp new file mode 100644 index 00000000000..f3346e836d4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/access_specifier.hpp @@ -0,0 +1,54 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_ACCESS_SPECIFIER_HPP +#define BOOST_MULTI_INDEX_DETAIL_ACCESS_SPECIFIER_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include +#include + +/* In those compilers that do not accept the member template friend syntax, + * some protected and private sections might need to be specified as + * public. + */ + +#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) +#define BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS public +#define BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS public +#else +#define BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS protected +#define BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS private +#endif + +/* GCC does not correctly support in-class using declarations for template + * functions. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9810 + * MSVC 7.1/8.0 seem to have a similar problem, though the conditions in + * which the error happens are not that simple. I have yet to isolate this + * into a snippet suitable for bug reporting. + * Sun Studio also has this problem, which might be related, from the + * information gathered at Sun forums, with a known issue notified at the + * internal bug report 6421933. The bug is present up to Studio Express 2, + * the latest preview version of the future Sun Studio 12. As of this writing + * (October 2006) it is not known whether a fix will finally make it into the + * official Sun Studio 12. + */ + +#if BOOST_WORKAROUND(__GNUC__,==3)&&(__GNUC_MINOR__<4)||\ + BOOST_WORKAROUND(BOOST_MSVC,==1310)||\ + BOOST_WORKAROUND(BOOST_MSVC,==1400)||\ + BOOST_WORKAROUND(__SUNPRO_CC,BOOST_TESTED_AT(0x590)) +#define BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS public +#else +#define BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS private +#endif + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/adl_swap.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/adl_swap.hpp new file mode 100644 index 00000000000..02b06442290 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/adl_swap.hpp @@ -0,0 +1,44 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_ADL_SWAP_HPP +#define BOOST_MULTI_INDEX_DETAIL_ADL_SWAP_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +void adl_swap(T& x,T& y) +{ + +#if !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) + using std::swap; + swap(x,y); +#else + std::swap(x,y); +#endif + +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/archive_constructed.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/archive_constructed.hpp new file mode 100644 index 00000000000..0a7a26e0d4e --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/archive_constructed.hpp @@ -0,0 +1,83 @@ +/* Copyright 2003-2016 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_ARCHIVE_CONSTRUCTED_HPP +#define BOOST_MULTI_INDEX_DETAIL_ARCHIVE_CONSTRUCTED_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* constructs a stack-based object from a serialization archive */ + +template +struct archive_constructed:private noncopyable +{ + template + archive_constructed(Archive& ar,const unsigned int version) + { + serialization::load_construct_data_adl(ar,&get(),version); + BOOST_TRY{ + ar>>get(); + } + BOOST_CATCH(...){ + (&get())->~T(); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + template + archive_constructed(const char* name,Archive& ar,const unsigned int version) + { + serialization::load_construct_data_adl(ar,&get(),version); + BOOST_TRY{ + ar>>serialization::make_nvp(name,get()); + } + BOOST_CATCH(...){ + (&get())->~T(); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + ~archive_constructed() + { + (&get())->~T(); + } + +#include + + T& get(){return *reinterpret_cast(&space);} + +#include + +private: + typename aligned_storage::value>::type space; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/auto_space.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/auto_space.hpp new file mode 100644 index 00000000000..9d78c3a363f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/auto_space.hpp @@ -0,0 +1,91 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP +#define BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* auto_space provides uninitialized space suitably to store + * a given number of elements of a given type. + */ + +/* NB: it is not clear whether using an allocator to handle + * zero-sized arrays of elements is conformant or not. GCC 3.3.1 + * and prior fail here, other stdlibs handle the issue gracefully. + * To be on the safe side, the case n==0 is given special treatment. + * References: + * GCC Bugzilla, "standard allocator crashes when deallocating segment + * "of zero length", http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14176 + * C++ Standard Library Defect Report List (Revision 28), issue 199 + * "What does allocate(0) return?", + * http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#199 + */ + +template > +struct auto_space:private noncopyable +{ + typedef typename boost::detail::allocator::rebind_to< + Allocator,T + >::type::pointer pointer; + + explicit auto_space(const Allocator& al=Allocator(),std::size_t n=1): + al_(al),n_(n),data_(n_?al_.allocate(n_):pointer(0)) + {} + + ~auto_space() + { + if(n_)al_.deallocate(data_,n_); + } + + Allocator get_allocator()const{return al_;} + + pointer data()const{return data_;} + + void swap(auto_space& x) + { + if(al_!=x.al_)adl_swap(al_,x.al_); + std::swap(n_,x.n_); + std::swap(data_,x.data_); + } + +private: + typename boost::detail::allocator::rebind_to< + Allocator,T>::type al_; + std::size_t n_; + pointer data_; +}; + +template +void swap(auto_space& x,auto_space& y) +{ + x.swap(y); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/base_type.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/base_type.hpp new file mode 100644 index 00000000000..8c9b62b716a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/base_type.hpp @@ -0,0 +1,74 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_BASE_TYPE_HPP +#define BOOST_MULTI_INDEX_DETAIL_BASE_TYPE_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* MPL machinery to construct a linear hierarchy of indices out of + * a index list. + */ + +struct index_applier +{ + template + struct apply + { + typedef typename IndexSpecifierMeta::type index_specifier; + typedef typename index_specifier:: + BOOST_NESTED_TEMPLATE index_class::type type; + }; +}; + +template +struct nth_layer +{ + BOOST_STATIC_CONSTANT(int,length=mpl::size::value); + + typedef typename mpl::eval_if_c< + N==length, + mpl::identity >, + mpl::apply2< + index_applier, + mpl::at_c, + nth_layer + > + >::type type; +}; + +template +struct multi_index_base_type:nth_layer<0,Value,IndexSpecifierList,Allocator> +{ + BOOST_STATIC_ASSERT(detail::is_index_list::value); +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bidir_node_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bidir_node_iterator.hpp new file mode 100644 index 00000000000..9be5ec84b43 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bidir_node_iterator.hpp @@ -0,0 +1,114 @@ +/* Copyright 2003-2014 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_BIDIR_NODE_ITERATOR_HPP +#define BOOST_MULTI_INDEX_DETAIL_BIDIR_NODE_ITERATOR_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Iterator class for node-based indices with bidirectional + * iterators (ordered and sequenced indices.) + */ + +template +class bidir_node_iterator: + public bidirectional_iterator_helper< + bidir_node_iterator, + typename Node::value_type, + std::ptrdiff_t, + const typename Node::value_type*, + const typename Node::value_type&> +{ +public: + /* coverity[uninit_ctor]: suppress warning */ + bidir_node_iterator(){} + explicit bidir_node_iterator(Node* node_):node(node_){} + + const typename Node::value_type& operator*()const + { + return node->value(); + } + + bidir_node_iterator& operator++() + { + Node::increment(node); + return *this; + } + + bidir_node_iterator& operator--() + { + Node::decrement(node); + return *this; + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + /* Serialization. As for why the following is public, + * see explanation in safe_mode_iterator notes in safe_mode.hpp. + */ + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + typedef typename Node::base_type node_base_type; + + template + void save(Archive& ar,const unsigned int)const + { + node_base_type* bnode=node; + ar< + void load(Archive& ar,const unsigned int) + { + node_base_type* bnode; + ar>>serialization::make_nvp("pointer",bnode); + node=static_cast(bnode); + } +#endif + + /* get_node is not to be used by the user */ + + typedef Node node_type; + + Node* get_node()const{return node;} + +private: + Node* node; +}; + +template +bool operator==( + const bidir_node_iterator& x, + const bidir_node_iterator& y) +{ + return x.get_node()==y.get_node(); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bucket_array.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bucket_array.hpp new file mode 100644 index 00000000000..d9fa434d9a9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bucket_array.hpp @@ -0,0 +1,243 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_BUCKET_ARRAY_HPP +#define BOOST_MULTI_INDEX_DETAIL_BUCKET_ARRAY_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#include +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* bucket structure for use by hashed indices */ + +#define BOOST_MULTI_INDEX_BA_SIZES_32BIT \ +(53ul)(97ul)(193ul)(389ul)(769ul) \ +(1543ul)(3079ul)(6151ul)(12289ul)(24593ul) \ +(49157ul)(98317ul)(196613ul)(393241ul)(786433ul) \ +(1572869ul)(3145739ul)(6291469ul)(12582917ul)(25165843ul) \ +(50331653ul)(100663319ul)(201326611ul)(402653189ul)(805306457ul) \ +(1610612741ul)(3221225473ul) + +#if ((((ULONG_MAX>>16)>>16)>>16)>>15)==0 /* unsigned long less than 64 bits */ +#define BOOST_MULTI_INDEX_BA_SIZES \ +BOOST_MULTI_INDEX_BA_SIZES_32BIT \ +(4294967291ul) +#else + /* obtained with aid from + * http://javaboutique.internet.com/prime_numb/ + * http://www.rsok.com/~jrm/next_ten_primes.html + * and verified with + * http://www.alpertron.com.ar/ECM.HTM + */ + +#define BOOST_MULTI_INDEX_BA_SIZES \ +BOOST_MULTI_INDEX_BA_SIZES_32BIT \ +(6442450939ul)(12884901893ul)(25769803751ul)(51539607551ul) \ +(103079215111ul)(206158430209ul)(412316860441ul)(824633720831ul) \ +(1649267441651ul)(3298534883309ul)(6597069766657ul)(13194139533299ul) \ +(26388279066623ul)(52776558133303ul)(105553116266489ul)(211106232532969ul) \ +(422212465066001ul)(844424930131963ul)(1688849860263953ul) \ +(3377699720527861ul)(6755399441055731ul)(13510798882111483ul) \ +(27021597764222939ul)(54043195528445957ul)(108086391056891903ul) \ +(216172782113783843ul)(432345564227567621ul)(864691128455135207ul) \ +(1729382256910270481ul)(3458764513820540933ul)(6917529027641081903ul) \ +(13835058055282163729ul)(18446744073709551557ul) +#endif + +template /* templatized to have in-header static var defs */ +class bucket_array_base:private noncopyable +{ +protected: + static const std::size_t sizes[ + BOOST_PP_SEQ_SIZE(BOOST_MULTI_INDEX_BA_SIZES)]; + + static std::size_t size_index(std::size_t n) + { + const std::size_t *bound=std::lower_bound(sizes,sizes+sizes_length,n); + if(bound==sizes+sizes_length)--bound; + return bound-sizes; + } + +#define BOOST_MULTI_INDEX_BA_POSITION_CASE(z,n,_) \ + case n:return hash%BOOST_PP_SEQ_ELEM(n,BOOST_MULTI_INDEX_BA_SIZES); + + static std::size_t position(std::size_t hash,std::size_t size_index_) + { + /* Accelerate hash%sizes[size_index_] by replacing with a switch on + * hash%Ci expressions, each Ci a compile-time constant, which the + * compiler can implement without using integer division. + */ + + switch(size_index_){ + default: /* never used */ + BOOST_PP_REPEAT( + BOOST_PP_SEQ_SIZE(BOOST_MULTI_INDEX_BA_SIZES), + BOOST_MULTI_INDEX_BA_POSITION_CASE,~) + } + } + +private: + static const std::size_t sizes_length; +}; + +template +const std::size_t bucket_array_base<_>::sizes[]={ + BOOST_PP_SEQ_ENUM(BOOST_MULTI_INDEX_BA_SIZES) +}; + +template +const std::size_t bucket_array_base<_>::sizes_length= + sizeof(bucket_array_base<_>::sizes)/ + sizeof(bucket_array_base<_>::sizes[0]); + +#undef BOOST_MULTI_INDEX_BA_POSITION_CASE +#undef BOOST_MULTI_INDEX_BA_SIZES +#undef BOOST_MULTI_INDEX_BA_SIZES_32BIT + +template +class bucket_array:bucket_array_base<> +{ + typedef bucket_array_base<> super; + typedef hashed_index_base_node_impl< + typename boost::detail::allocator::rebind_to< + Allocator, + char + >::type + > base_node_impl_type; + +public: + typedef typename base_node_impl_type::base_pointer base_pointer; + typedef typename base_node_impl_type::pointer pointer; + + bucket_array(const Allocator& al,pointer end_,std::size_t size_): + size_index_(super::size_index(size_)), + spc(al,super::sizes[size_index_]+1) + { + clear(end_); + } + + std::size_t size()const + { + return super::sizes[size_index_]; + } + + std::size_t position(std::size_t hash)const + { + return super::position(hash,size_index_); + } + + base_pointer begin()const{return buckets();} + base_pointer end()const{return buckets()+size();} + base_pointer at(std::size_t n)const{return buckets()+n;} + + void clear(pointer end_) + { + for(base_pointer x=begin(),y=end();x!=y;++x)x->prior()=pointer(0); + end()->prior()=end_->prior()=end_; + end_->next()=end(); + } + + void swap(bucket_array& x) + { + std::swap(size_index_,x.size_index_); + spc.swap(x.spc); + } + +private: + std::size_t size_index_; + auto_space spc; + + base_pointer buckets()const + { + return spc.data(); + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + friend class boost::serialization::access; + + /* bucket_arrays do not emit any kind of serialization info. They are + * fed to Boost.Serialization as hashed index iterators need to track + * them during serialization. + */ + + template + void serialize(Archive&,const unsigned int) + { + } +#endif +}; + +template +void swap(bucket_array& x,bucket_array& y) +{ + x.swap(y); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +/* bucket_arrays never get constructed directly by Boost.Serialization, + * as archives are always fed pointers to previously existent + * arrays. So, if this is called it means we are dealing with a + * somehow invalid archive. + */ + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +namespace serialization{ +#else +namespace multi_index{ +namespace detail{ +#endif + +template +inline void load_construct_data( + Archive&,boost::multi_index::detail::bucket_array*, + const unsigned int) +{ + throw_exception( + archive::archive_exception(archive::archive_exception::other_exception)); +} + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +} /* namespace serialization */ +#else +} /* namespace multi_index::detail */ +} /* namespace multi_index */ +#endif + +#endif + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/cons_stdtuple.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/cons_stdtuple.hpp new file mode 100644 index 00000000000..855c5e06aa9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/cons_stdtuple.hpp @@ -0,0 +1,93 @@ +/* Copyright 2003-2014 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_CONS_STDTUPLE_HPP +#define BOOST_MULTI_INDEX_DETAIL_CONS_STDTUPLE_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* std::tuple wrapper providing the cons-based interface of boost::tuple for + * composite_key interoperability. + */ + +template +struct cons_stdtuple; + +struct cons_stdtuple_ctor_terminal +{ + typedef boost::tuples::null_type result_type; + + template + static result_type create(const StdTuple&) + { + return boost::tuples::null_type(); + } +}; + +template +struct cons_stdtuple_ctor_normal +{ + typedef cons_stdtuple result_type; + + static result_type create(const StdTuple& t) + { + return result_type(t); + } +}; + +template +struct cons_stdtuple_ctor: + boost::mpl::if_c< + N::value, + cons_stdtuple_ctor_normal, + cons_stdtuple_ctor_terminal + >::type +{}; + +template +struct cons_stdtuple +{ + typedef typename std::tuple_element::type head_type; + typedef cons_stdtuple_ctor tail_ctor; + typedef typename tail_ctor::result_type tail_type; + + cons_stdtuple(const StdTuple& t_):t(t_){} + + const head_type& get_head()const{return std::get(t);} + tail_type get_tail()const{return tail_ctor::create(t);} + + const StdTuple& t; +}; + +template +typename cons_stdtuple_ctor::result_type +make_cons_stdtuple(const StdTuple& t) +{ + return cons_stdtuple_ctor::create(t); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/converter.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/converter.hpp new file mode 100644 index 00000000000..3e04a3e8295 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/converter.hpp @@ -0,0 +1,52 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_CONVERTER_HPP +#define BOOST_MULTI_INDEX_DETAIL_CONVERTER_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* converter offers means to access indices of a given multi_index_container + * and for convertibilty between index iterators, so providing a + * localized access point for get() and project() functions. + */ + +template +struct converter +{ + static const Index& index(const MultiIndexContainer& x){return x;} + static Index& index(MultiIndexContainer& x){return x;} + + static typename Index::const_iterator const_iterator( + const MultiIndexContainer& x,typename MultiIndexContainer::node_type* node) + { + return x.Index::make_iterator(node); + } + + static typename Index::iterator iterator( + MultiIndexContainer& x,typename MultiIndexContainer::node_type* node) + { + return x.Index::make_iterator(node); + } +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/copy_map.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/copy_map.hpp new file mode 100644 index 00000000000..9a34b259cf3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/copy_map.hpp @@ -0,0 +1,142 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_COPY_MAP_HPP +#define BOOST_MULTI_INDEX_DETAIL_COPY_MAP_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* copy_map is used as an auxiliary structure during copy_() operations. + * When a container with n nodes is replicated, node_map holds the pairings + * between original and copied nodes, and provides a fast way to find a + * copied node from an original one. + * The semantics of the class are not simple, and no attempt has been made + * to enforce it: multi_index_container handles it right. On the other hand, + * the const interface, which is the one provided to index implementations, + * only allows for: + * - Enumeration of pairs of (original,copied) nodes (excluding the headers), + * - fast retrieval of copied nodes (including the headers.) + */ + +template +struct copy_map_entry +{ + copy_map_entry(Node* f,Node* s):first(f),second(s){} + + Node* first; + Node* second; + + bool operator<(const copy_map_entry& x)const + { + return std::less()(first,x.first); + } +}; + +template +class copy_map:private noncopyable +{ +public: + typedef const copy_map_entry* const_iterator; + + copy_map( + const Allocator& al,std::size_t size,Node* header_org,Node* header_cpy): + al_(al),size_(size),spc(al_,size_),n(0), + header_org_(header_org),header_cpy_(header_cpy),released(false) + {} + + ~copy_map() + { + if(!released){ + for(std::size_t i=0;isecond->value()); + deallocate((spc.data()+i)->second); + } + } + } + + const_iterator begin()const{return raw_ptr(spc.data());} + const_iterator end()const{return raw_ptr(spc.data()+n);} + + void clone(Node* node) + { + (spc.data()+n)->first=node; + (spc.data()+n)->second=raw_ptr(al_.allocate(1)); + BOOST_TRY{ + boost::detail::allocator::construct( + &(spc.data()+n)->second->value(),node->value()); + } + BOOST_CATCH(...){ + deallocate((spc.data()+n)->second); + BOOST_RETHROW; + } + BOOST_CATCH_END + ++n; + + if(n==size_){ + std::sort( + raw_ptr*>(spc.data()), + raw_ptr*>(spc.data())+size_); + } + } + + Node* find(Node* node)const + { + if(node==header_org_)return header_cpy_; + return std::lower_bound( + begin(),end(),copy_map_entry(node,0))->second; + } + + void release() + { + released=true; + } + +private: + typedef typename boost::detail::allocator::rebind_to< + Allocator,Node + >::type allocator_type; + typedef typename allocator_type::pointer allocator_pointer; + + allocator_type al_; + std::size_t size_; + auto_space,Allocator> spc; + std::size_t n; + Node* header_org_; + Node* header_cpy_; + bool released; + + void deallocate(Node* node) + { + al_.deallocate(static_cast(node),1); + } +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/do_not_copy_elements_tag.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/do_not_copy_elements_tag.hpp new file mode 100644 index 00000000000..f0fa7304253 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/do_not_copy_elements_tag.hpp @@ -0,0 +1,34 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_DO_NOT_COPY_ELEMENTS_TAG_HPP +#define BOOST_MULTI_INDEX_DETAIL_DO_NOT_COPY_ELEMENTS_TAG_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Used to mark a special ctor variant that copies the internal objects of + * a container but not its elements. + */ + +struct do_not_copy_elements_tag{}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/duplicates_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/duplicates_iterator.hpp new file mode 100644 index 00000000000..cbebf264045 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/duplicates_iterator.hpp @@ -0,0 +1,120 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP +#define BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* duplicates_operator is given a range of ordered elements and + * passes only over those which are duplicated. + */ + +template +class duplicates_iterator +{ +public: + typedef typename Node::value_type value_type; + typedef std::ptrdiff_t difference_type; + typedef const typename Node::value_type* pointer; + typedef const typename Node::value_type& reference; + typedef std::forward_iterator_tag iterator_category; + + duplicates_iterator(Node* node_,Node* end_,Predicate pred_): + node(node_),begin_chunk(0),end(end_),pred(pred_) + { + advance(); + } + + duplicates_iterator(Node* end_,Predicate pred_): + node(end_),begin_chunk(end_),end(end_),pred(pred_) + { + } + + reference operator*()const + { + return node->value(); + } + + pointer operator->()const + { + return &node->value(); + } + + duplicates_iterator& operator++() + { + Node::increment(node); + sync(); + return *this; + } + + duplicates_iterator operator++(int) + { + duplicates_iterator tmp(*this); + ++(*this); + return tmp; + } + + Node* get_node()const{return node;} + +private: + void sync() + { + if(node!=end&&pred(begin_chunk->value(),node->value()))advance(); + } + + void advance() + { + for(Node* node2=node;node!=end;node=node2){ + Node::increment(node2); + if(node2!=end&&!pred(node->value(),node2->value()))break; + } + begin_chunk=node; + } + + Node* node; + Node* begin_chunk; + Node* end; + Predicate pred; +}; + +template +bool operator==( + const duplicates_iterator& x, + const duplicates_iterator& y) +{ + return x.get_node()==y.get_node(); +} + +template +bool operator!=( + const duplicates_iterator& x, + const duplicates_iterator& y) +{ + return !(x==y); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/has_tag.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/has_tag.hpp new file mode 100644 index 00000000000..217b61143af --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/has_tag.hpp @@ -0,0 +1,42 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_HAS_TAG_HPP +#define BOOST_MULTI_INDEX_DETAIL_HAS_TAG_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* determines whether an index type has a given tag in its tag list */ + +template +struct has_tag +{ + template + struct apply:mpl::contains + { + }; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_args.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_args.hpp new file mode 100644 index 00000000000..81902f5a4a5 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_args.hpp @@ -0,0 +1,105 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ARGS_HPP +#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ARGS_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Hashed index specifiers can be instantiated in two forms: + * + * (hashed_unique|hashed_non_unique)< + * KeyFromValue, + * Hash=boost::hash, + * Pred=std::equal_to > + * (hashed_unique|hashed_non_unique)< + * TagList, + * KeyFromValue, + * Hash=boost::hash, + * Pred=std::equal_to > + * + * hashed_index_args implements the machinery to accept this + * argument-dependent polymorphism. + */ + +template +struct index_args_default_hash +{ + typedef ::boost::hash type; +}; + +template +struct index_args_default_pred +{ + typedef std::equal_to type; +}; + +template +struct hashed_index_args +{ + typedef is_tag full_form; + + typedef typename mpl::if_< + full_form, + Arg1, + tag< > >::type tag_list_type; + typedef typename mpl::if_< + full_form, + Arg2, + Arg1>::type key_from_value_type; + typedef typename mpl::if_< + full_form, + Arg3, + Arg2>::type supplied_hash_type; + typedef typename mpl::eval_if< + mpl::is_na, + index_args_default_hash, + mpl::identity + >::type hash_type; + typedef typename mpl::if_< + full_form, + Arg4, + Arg3>::type supplied_pred_type; + typedef typename mpl::eval_if< + mpl::is_na, + index_args_default_pred, + mpl::identity + >::type pred_type; + + BOOST_STATIC_ASSERT(is_tag::value); + BOOST_STATIC_ASSERT(!mpl::is_na::value); + BOOST_STATIC_ASSERT(!mpl::is_na::value); + BOOST_STATIC_ASSERT(!mpl::is_na::value); +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_iterator.hpp new file mode 100644 index 00000000000..8d063002a1d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_iterator.hpp @@ -0,0 +1,166 @@ +/* Copyright 2003-2014 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_HPP +#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#include +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Iterator class for hashed indices. + */ + +struct hashed_index_global_iterator_tag{}; +struct hashed_index_local_iterator_tag{}; + +template +class hashed_index_iterator: + public forward_iterator_helper< + hashed_index_iterator, + typename Node::value_type, + std::ptrdiff_t, + const typename Node::value_type*, + const typename Node::value_type&> +{ +public: + /* coverity[uninit_ctor]: suppress warning */ + hashed_index_iterator(){} + hashed_index_iterator(Node* node_):node(node_){} + + const typename Node::value_type& operator*()const + { + return node->value(); + } + + hashed_index_iterator& operator++() + { + this->increment(Category()); + return *this; + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + /* Serialization. As for why the following is public, + * see explanation in safe_mode_iterator notes in safe_mode.hpp. + */ + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + typedef typename Node::base_type node_base_type; + + template + void save(Archive& ar,const unsigned int)const + { + node_base_type* bnode=node; + ar< + void load(Archive& ar,const unsigned int version) + { + load(ar,version,Category()); + } + + template + void load( + Archive& ar,const unsigned int version,hashed_index_global_iterator_tag) + { + node_base_type* bnode; + ar>>serialization::make_nvp("pointer",bnode); + node=static_cast(bnode); + if(version<1){ + BucketArray* throw_away; /* consume unused ptr */ + ar>>serialization::make_nvp("pointer",throw_away); + } + } + + template + void load( + Archive& ar,const unsigned int version,hashed_index_local_iterator_tag) + { + node_base_type* bnode; + ar>>serialization::make_nvp("pointer",bnode); + node=static_cast(bnode); + if(version<1){ + BucketArray* buckets; + ar>>serialization::make_nvp("pointer",buckets); + if(buckets&&node&&node->impl()==buckets->end()->prior()){ + /* end local_iterators used to point to end node, now they are null */ + node=0; + } + } + } +#endif + + /* get_node is not to be used by the user */ + + typedef Node node_type; + + Node* get_node()const{return node;} + +private: + + void increment(hashed_index_global_iterator_tag) + { + Node::increment(node); + } + + void increment(hashed_index_local_iterator_tag) + { + Node::increment_local(node); + } + + Node* node; +}; + +template +bool operator==( + const hashed_index_iterator& x, + const hashed_index_iterator& y) +{ + return x.get_node()==y.get_node(); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +/* class version = 1 : hashed_index_iterator does no longer serialize a bucket + * array pointer. + */ + +namespace serialization { +template +struct version< + boost::multi_index::detail::hashed_index_iterator +> +{ + BOOST_STATIC_CONSTANT(int,value=1); +}; +} /* namespace serialization */ +#endif + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_node.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_node.hpp new file mode 100644 index 00000000000..7788e810ac9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_node.hpp @@ -0,0 +1,778 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_NODE_HPP +#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_NODE_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Certain C++ requirements on unordered associative containers (see LWG issue + * #579) imply a data structure where nodes are linked in a single list, which + * in its turn forces implementors to add additional overhed per node to + * associate each with its corresponding bucket. Others resort to storing hash + * values, we use an alternative structure providing unconditional O(1) + * manipulation, even in situations of unfair hash distribution, plus some + * lookup speedups. For unique indices we maintain a doubly linked list of + * nodes except that if N is the first node of a bucket its associated + * bucket node is embedded between N and the preceding node in the following + * manner: + * + * +---+ +---+ +---+ +---+ + * <--+ |<--+ | <--+ |<--+ | + * ... | B0| | B1| ... | B1| | B2| ... + * | |-+ | +--> | |-+ | +--> + * +-+-+ | +---+ +-+-+ | +---+ + * | ^ | ^ + * | | | | + * | +-+ | +-+ + * | | | | + * v | v | + * --+---+---+---+-- --+---+---+---+-- + * ... | | B1| | ... | | B2| | ... + * --+---+---+---+-- --+---+---+---+-- + * + * + * The fist and last nodes of buckets can be checked with + * + * first node of a bucket: Npn != N + * last node of a bucket: Nnp != N + * + * (n and p short for ->next(), ->prior(), bucket nodes have prior pointers + * only). Pure insert and erase (without lookup) can be unconditionally done + * in O(1). + * For non-unique indices we add the following additional complexity: when + * there is a group of 3 or more equivalent elements, they are linked as + * follows: + * + * +-----------------------+ + * | v + * +---+ | +---+ +---+ +---+ + * | | +-+ | | |<--+ | + * | F | | S | ... | P | | L | + * | +-->| | | +-+ | | + * +---+ +---+ +---+ | +---+ + * ^ | + * +-----------------------+ + * + * F, S, P and L are the first, second, penultimate and last node in the + * group, respectively (S and P can coincide if the group has size 3.) This + * arrangement is used to skip equivalent elements in O(1) when doing lookup, + * while preserving O(1) insert/erase. The following invariants identify + * special positions (some of the operations have to be carefully implemented + * as Xnn is not valid if Xn points to a bucket): + * + * first node of a bucket: Npnp == N + * last node of a bucket: Nnpp == N + * first node of a group: Nnp != N && Nnppn == N + * second node of a group: Npn != N && Nppnn == N + * n-1 node of a group: Nnp != N && Nnnpp == N + * last node of a group: Npn != N && Npnnp == N + * + * The memory overhead is one pointer per bucket plus two pointers per node, + * probably unbeatable. The resulting structure is bidirectonally traversable, + * though currently we are just providing forward iteration. + */ + +template +struct hashed_index_node_impl; + +/* half-header (only prior() pointer) to use for the bucket array */ + +template +struct hashed_index_base_node_impl +{ + typedef typename + boost::detail::allocator::rebind_to< + Allocator,hashed_index_base_node_impl + >::type::pointer base_pointer; + typedef typename + boost::detail::allocator::rebind_to< + Allocator,hashed_index_base_node_impl + >::type::const_pointer const_base_pointer; + typedef typename + boost::detail::allocator::rebind_to< + Allocator, + hashed_index_node_impl + >::type::pointer pointer; + typedef typename + boost::detail::allocator::rebind_to< + Allocator, + hashed_index_node_impl + >::type::const_pointer const_pointer; + + pointer& prior(){return prior_;} + pointer prior()const{return prior_;} + +private: + pointer prior_; +}; + +/* full header (prior() and next()) for the nodes */ + +template +struct hashed_index_node_impl:hashed_index_base_node_impl +{ +private: + typedef hashed_index_base_node_impl super; + +public: + typedef typename super::base_pointer base_pointer; + typedef typename super::const_base_pointer const_base_pointer; + typedef typename super::pointer pointer; + typedef typename super::const_pointer const_pointer; + + base_pointer& next(){return next_;} + base_pointer next()const{return next_;} + + static pointer pointer_from(base_pointer x) + { + return static_cast( + static_cast( + raw_ptr(x))); + } + + static base_pointer base_pointer_from(pointer x) + { + return static_cast( + raw_ptr(x)); + } + +private: + base_pointer next_; +}; + +/* Boost.MultiIndex requires machinery to reverse unlink operations. A simple + * way to make a pointer-manipulation function undoable is to templatize + * its internal pointer assignments with a functor that, besides doing the + * assignment, keeps track of the original pointer values and can later undo + * the operations in reverse order. + */ + +struct default_assigner +{ + template void operator()(T& x,const T& val){x=val;} +}; + +template +struct unlink_undo_assigner +{ + typedef typename Node::base_pointer base_pointer; + typedef typename Node::pointer pointer; + + unlink_undo_assigner():pointer_track_count(0),base_pointer_track_count(0){} + + void operator()(pointer& x,pointer val) + { + pointer_tracks[pointer_track_count].x=&x; + pointer_tracks[pointer_track_count++].val=x; + x=val; + } + + void operator()(base_pointer& x,base_pointer val) + { + base_pointer_tracks[base_pointer_track_count].x=&x; + base_pointer_tracks[base_pointer_track_count++].val=x; + x=val; + } + + void operator()() /* undo op */ + { + /* in the absence of aliasing, restitution order is immaterial */ + + while(pointer_track_count--){ + *(pointer_tracks[pointer_track_count].x)= + pointer_tracks[pointer_track_count].val; + } + while(base_pointer_track_count--){ + *(base_pointer_tracks[base_pointer_track_count].x)= + base_pointer_tracks[base_pointer_track_count].val; + } + } + + struct pointer_track {pointer* x; pointer val;}; + struct base_pointer_track{base_pointer* x; base_pointer val;}; + + /* We know the maximum number of pointer and base pointer assignments that + * the two unlink versions do, so we can statically reserve the needed + * storage. + */ + + pointer_track pointer_tracks[3]; + int pointer_track_count; + base_pointer_track base_pointer_tracks[2]; + int base_pointer_track_count; +}; + +/* algorithmic stuff for unique and non-unique variants */ + +struct hashed_unique_tag{}; +struct hashed_non_unique_tag{}; + +template +struct hashed_index_node_alg; + +template +struct hashed_index_node_alg +{ + typedef typename Node::base_pointer base_pointer; + typedef typename Node::const_base_pointer const_base_pointer; + typedef typename Node::pointer pointer; + typedef typename Node::const_pointer const_pointer; + + static bool is_first_of_bucket(pointer x) + { + return x->prior()->next()!=base_pointer_from(x); + } + + static pointer after(pointer x) + { + return is_last_of_bucket(x)?x->next()->prior():pointer_from(x->next()); + } + + static pointer after_local(pointer x) + { + return is_last_of_bucket(x)?pointer(0):pointer_from(x->next()); + } + + static pointer next_to_inspect(pointer x) + { + return is_last_of_bucket(x)?pointer(0):pointer_from(x->next()); + } + + static void link(pointer x,base_pointer buc,pointer end) + { + if(buc->prior()==pointer(0)){ /* empty bucket */ + x->prior()=end->prior(); + x->next()=end->prior()->next(); + x->prior()->next()=buc; + buc->prior()=x; + end->prior()=x; + } + else{ + x->prior()=buc->prior()->prior(); + x->next()=base_pointer_from(buc->prior()); + buc->prior()=x; + x->next()->prior()=x; + } + } + + static void unlink(pointer x) + { + default_assigner assign; + unlink(x,assign); + } + + typedef unlink_undo_assigner unlink_undo; + + template + static void unlink(pointer x,Assigner& assign) + { + if(is_first_of_bucket(x)){ + if(is_last_of_bucket(x)){ + assign(x->prior()->next()->prior(),pointer(0)); + assign(x->prior()->next(),x->next()); + assign(x->next()->prior()->prior(),x->prior()); + } + else{ + assign(x->prior()->next()->prior(),pointer_from(x->next())); + assign(x->next()->prior(),x->prior()); + } + } + else if(is_last_of_bucket(x)){ + assign(x->prior()->next(),x->next()); + assign(x->next()->prior()->prior(),x->prior()); + } + else{ + assign(x->prior()->next(),x->next()); + assign(x->next()->prior(),x->prior()); + } + } + + /* used only at rehashing */ + + static void append(pointer x,pointer end) + { + x->prior()=end->prior(); + x->next()=end->prior()->next(); + x->prior()->next()=base_pointer_from(x); + end->prior()=x; + } + + static bool unlink_last(pointer end) + { + /* returns true iff bucket is emptied */ + + pointer x=end->prior(); + if(x->prior()->next()==base_pointer_from(x)){ + x->prior()->next()=x->next(); + end->prior()=x->prior(); + return false; + } + else{ + x->prior()->next()->prior()=pointer(0); + x->prior()->next()=x->next(); + end->prior()=x->prior(); + return true; + } + } + +private: + static pointer pointer_from(base_pointer x) + { + return Node::pointer_from(x); + } + + static base_pointer base_pointer_from(pointer x) + { + return Node::base_pointer_from(x); + } + + static bool is_last_of_bucket(pointer x) + { + return x->next()->prior()!=x; + } +}; + +template +struct hashed_index_node_alg +{ + typedef typename Node::base_pointer base_pointer; + typedef typename Node::const_base_pointer const_base_pointer; + typedef typename Node::pointer pointer; + typedef typename Node::const_pointer const_pointer; + + static bool is_first_of_bucket(pointer x) + { + return x->prior()->next()->prior()==x; + } + + static bool is_first_of_group(pointer x) + { + return + x->next()->prior()!=x&& + x->next()->prior()->prior()->next()==base_pointer_from(x); + } + + static pointer after(pointer x) + { + if(x->next()->prior()==x)return pointer_from(x->next()); + if(x->next()->prior()->prior()==x)return x->next()->prior(); + if(x->next()->prior()->prior()->next()==base_pointer_from(x)) + return pointer_from(x->next()); + return pointer_from(x->next())->next()->prior(); + } + + static pointer after_local(pointer x) + { + if(x->next()->prior()==x)return pointer_from(x->next()); + if(x->next()->prior()->prior()==x)return pointer(0); + if(x->next()->prior()->prior()->next()==base_pointer_from(x)) + return pointer_from(x->next()); + return pointer_from(x->next())->next()->prior(); + } + + static pointer next_to_inspect(pointer x) + { + if(x->next()->prior()==x)return pointer_from(x->next()); + if(x->next()->prior()->prior()==x)return pointer(0); + if(x->next()->prior()->next()->prior()!=x->next()->prior()) + return pointer(0); + return pointer_from(x->next()->prior()->next()); + } + + static void link(pointer x,base_pointer buc,pointer end) + { + if(buc->prior()==pointer(0)){ /* empty bucket */ + x->prior()=end->prior(); + x->next()=end->prior()->next(); + x->prior()->next()=buc; + buc->prior()=x; + end->prior()=x; + } + else{ + x->prior()=buc->prior()->prior(); + x->next()=base_pointer_from(buc->prior()); + buc->prior()=x; + x->next()->prior()=x; + } + }; + + static void link(pointer x,pointer first,pointer last) + { + x->prior()=first->prior(); + x->next()=base_pointer_from(first); + if(is_first_of_bucket(first)){ + x->prior()->next()->prior()=x; + } + else{ + x->prior()->next()=base_pointer_from(x); + } + + if(first==last){ + last->prior()=x; + } + else if(first->next()==base_pointer_from(last)){ + first->prior()=last; + first->next()=base_pointer_from(x); + } + else{ + pointer second=pointer_from(first->next()), + lastbutone=last->prior(); + second->prior()=first; + first->prior()=last; + lastbutone->next()=base_pointer_from(x); + } + } + + static void unlink(pointer x) + { + default_assigner assign; + unlink(x,assign); + } + + typedef unlink_undo_assigner unlink_undo; + + template + static void unlink(pointer x,Assigner& assign) + { + if(x->prior()->next()==base_pointer_from(x)){ + if(x->next()->prior()==x){ + left_unlink(x,assign); + right_unlink(x,assign); + } + else if(x->next()->prior()->prior()==x){ /* last of bucket */ + left_unlink(x,assign); + right_unlink_last_of_bucket(x,assign); + } + else if(x->next()->prior()->prior()->next()== + base_pointer_from(x)){ /* first of group size */ + left_unlink(x,assign); + right_unlink_first_of_group(x,assign); + } + else{ /* n-1 of group */ + unlink_last_but_one_of_group(x,assign); + } + } + else if(x->prior()->next()->prior()==x){ /* first of bucket */ + if(x->next()->prior()==x){ + left_unlink_first_of_bucket(x,assign); + right_unlink(x,assign); + } + else if(x->next()->prior()->prior()==x){ /* last of bucket */ + assign(x->prior()->next()->prior(),pointer(0)); + assign(x->prior()->next(),x->next()); + assign(x->next()->prior()->prior(),x->prior()); + } + else{ /* first of group */ + left_unlink_first_of_bucket(x,assign); + right_unlink_first_of_group(x,assign); + } + } + else if(x->next()->prior()->prior()==x){ /* last of group and bucket */ + left_unlink_last_of_group(x,assign); + right_unlink_last_of_bucket(x,assign); + } + else if(pointer_from(x->prior()->prior()->next()) + ->next()==base_pointer_from(x)){ /* second of group */ + unlink_second_of_group(x,assign); + } + else{ /* last of group, ~(last of bucket) */ + left_unlink_last_of_group(x,assign); + right_unlink(x,assign); + } + } + + /* used only at rehashing */ + + static void link_range( + pointer first,pointer last,base_pointer buc,pointer cend) + { + if(buc->prior()==pointer(0)){ /* empty bucket */ + first->prior()=cend->prior(); + last->next()=cend->prior()->next(); + first->prior()->next()=buc; + buc->prior()=first; + cend->prior()=last; + } + else{ + first->prior()=buc->prior()->prior(); + last->next()=base_pointer_from(buc->prior()); + buc->prior()=first; + last->next()->prior()=last; + } + } + + static void append_range(pointer first,pointer last,pointer cend) + { + first->prior()=cend->prior(); + last->next()=cend->prior()->next(); + first->prior()->next()=base_pointer_from(first); + cend->prior()=last; + } + + static std::pair unlink_last_group(pointer end) + { + /* returns first of group true iff bucket is emptied */ + + pointer x=end->prior(); + if(x->prior()->next()==base_pointer_from(x)){ + x->prior()->next()=x->next(); + end->prior()=x->prior(); + return std::make_pair(x,false); + } + else if(x->prior()->next()->prior()==x){ + x->prior()->next()->prior()=pointer(0); + x->prior()->next()=x->next(); + end->prior()=x->prior(); + return std::make_pair(x,true); + } + else{ + pointer y=pointer_from(x->prior()->next()); + + if(y->prior()->next()==base_pointer_from(y)){ + y->prior()->next()=x->next(); + end->prior()=y->prior(); + return std::make_pair(y,false); + } + else{ + y->prior()->next()->prior()=pointer(0); + y->prior()->next()=x->next(); + end->prior()=y->prior(); + return std::make_pair(y,true); + } + } + } + + static void unlink_range(pointer first,pointer last) + { + if(is_first_of_bucket(first)){ + if(is_last_of_bucket(last)){ + first->prior()->next()->prior()=pointer(0); + first->prior()->next()=last->next(); + last->next()->prior()->prior()=first->prior(); + } + else{ + first->prior()->next()->prior()=pointer_from(last->next()); + last->next()->prior()=first->prior(); + } + } + else if(is_last_of_bucket(last)){ + first->prior()->next()=last->next(); + last->next()->prior()->prior()=first->prior(); + } + else{ + first->prior()->next()=last->next(); + last->next()->prior()=first->prior(); + } + } + +private: + static pointer pointer_from(base_pointer x) + { + return Node::pointer_from(x); + } + + static base_pointer base_pointer_from(pointer x) + { + return Node::base_pointer_from(x); + } + + static bool is_last_of_bucket(pointer x) + { + return x->next()->prior()->prior()==x; + } + + template + static void left_unlink(pointer x,Assigner& assign) + { + assign(x->prior()->next(),x->next()); + } + + template + static void right_unlink(pointer x,Assigner& assign) + { + assign(x->next()->prior(),x->prior()); + } + + template + static void left_unlink_first_of_bucket(pointer x,Assigner& assign) + { + assign(x->prior()->next()->prior(),pointer_from(x->next())); + } + + template + static void right_unlink_last_of_bucket(pointer x,Assigner& assign) + { + assign(x->next()->prior()->prior(),x->prior()); + } + + template + static void right_unlink_first_of_group(pointer x,Assigner& assign) + { + pointer second=pointer_from(x->next()), + last=second->prior(), + lastbutone=last->prior(); + if(second==lastbutone){ + assign(second->next(),base_pointer_from(last)); + assign(second->prior(),x->prior()); + } + else{ + assign(lastbutone->next(),base_pointer_from(second)); + assign(second->next()->prior(),last); + assign(second->prior(),x->prior()); + } + } + + template + static void left_unlink_last_of_group(pointer x,Assigner& assign) + { + pointer lastbutone=x->prior(), + first=pointer_from(lastbutone->next()), + second=pointer_from(first->next()); + if(lastbutone==second){ + assign(lastbutone->prior(),first); + assign(lastbutone->next(),x->next()); + } + else{ + assign(second->prior(),lastbutone); + assign(lastbutone->prior()->next(),base_pointer_from(first)); + assign(lastbutone->next(),x->next()); + } + } + + template + static void unlink_last_but_one_of_group(pointer x,Assigner& assign) + { + pointer first=pointer_from(x->next()), + second=pointer_from(first->next()), + last=second->prior(); + if(second==x){ + assign(last->prior(),first); + assign(first->next(),base_pointer_from(last)); + } + else{ + assign(last->prior(),x->prior()); + assign(x->prior()->next(),base_pointer_from(first)); + } + } + + template + static void unlink_second_of_group(pointer x,Assigner& assign) + { + pointer last=x->prior(), + lastbutone=last->prior(), + first=pointer_from(lastbutone->next()); + if(lastbutone==x){ + assign(first->next(),base_pointer_from(last)); + assign(last->prior(),first); + } + else{ + assign(first->next(),x->next()); + assign(x->next()->prior(),last); + } + } +}; + +template +struct hashed_index_node_trampoline: + hashed_index_node_impl< + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > +{ + typedef typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type impl_allocator_type; + typedef hashed_index_node_impl impl_type; +}; + +template +struct hashed_index_node: + Super,hashed_index_node_trampoline +{ +private: + typedef hashed_index_node_trampoline trampoline; + +public: + typedef typename trampoline::impl_type impl_type; + typedef hashed_index_node_alg< + impl_type,Category> node_alg; + typedef typename trampoline::base_pointer impl_base_pointer; + typedef typename trampoline::const_base_pointer const_impl_base_pointer; + typedef typename trampoline::pointer impl_pointer; + typedef typename trampoline::const_pointer const_impl_pointer; + + impl_pointer& prior(){return trampoline::prior();} + impl_pointer prior()const{return trampoline::prior();} + impl_base_pointer& next(){return trampoline::next();} + impl_base_pointer next()const{return trampoline::next();} + + impl_pointer impl() + { + return static_cast( + static_cast(static_cast(this))); + } + + const_impl_pointer impl()const + { + return static_cast( + static_cast(static_cast(this))); + } + + static hashed_index_node* from_impl(impl_pointer x) + { + return + static_cast( + static_cast( + raw_ptr(x))); + } + + static const hashed_index_node* from_impl(const_impl_pointer x) + { + return + static_cast( + static_cast( + raw_ptr(x))); + } + + /* interoperability with hashed_index_iterator */ + + static void increment(hashed_index_node*& x) + { + x=from_impl(node_alg::after(x->impl())); + } + + static void increment_local(hashed_index_node*& x) + { + x=from_impl(node_alg::after_local(x->impl())); + } +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/header_holder.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/header_holder.hpp new file mode 100644 index 00000000000..ca8a9b2edb1 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/header_holder.hpp @@ -0,0 +1,50 @@ +/* Copyright 2003-2008 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_HEADER_HOLDER_HPP +#define BOOST_MULTI_INDEX_DETAIL_HEADER_HOLDER_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* A utility class used to hold a pointer to the header node. + * The base from member idiom is used because index classes, which are + * superclasses of multi_index_container, need this header in construction + * time. The allocation is made by the allocator of the multi_index_container + * class --hence, this allocator needs also be stored resorting + * to the base from member trick. + */ + +template +struct header_holder:private noncopyable +{ + header_holder():member(final().allocate_node()){} + ~header_holder(){final().deallocate_node(&*member);} + + NodeTypePtr member; + +private: + Final& final(){return *static_cast(this);} +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ignore_wstrict_aliasing.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ignore_wstrict_aliasing.hpp new file mode 100644 index 00000000000..ae398456d1f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ignore_wstrict_aliasing.hpp @@ -0,0 +1,18 @@ +/* Copyright 2003-2016 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#include + +#if defined(BOOST_GCC)&&(BOOST_GCC>=4*10000+6*100) +#if !defined(BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +#else +#pragma GCC diagnostic pop +#endif +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_base.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_base.hpp new file mode 100644 index 00000000000..99000ed4813 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_base.hpp @@ -0,0 +1,293 @@ +/* Copyright 2003-2014 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP +#define BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* The role of this class is threefold: + * - tops the linear hierarchy of indices. + * - terminates some cascading backbone function calls (insert_, etc.), + * - grants access to the backbone functions of the final + * multi_index_container class (for access restriction reasons, these + * cannot be called directly from the index classes.) + */ + +struct lvalue_tag{}; +struct rvalue_tag{}; +struct emplaced_tag{}; + +template +class index_base +{ +protected: + typedef index_node_base node_type; + typedef typename multi_index_node_type< + Value,IndexSpecifierList,Allocator>::type final_node_type; + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> final_type; + typedef tuples::null_type ctor_args_list; + typedef typename + boost::detail::allocator::rebind_to< + Allocator, + typename Allocator::value_type + >::type final_allocator_type; + typedef mpl::vector0<> index_type_list; + typedef mpl::vector0<> iterator_type_list; + typedef mpl::vector0<> const_iterator_type_list; + typedef copy_map< + final_node_type, + final_allocator_type> copy_map_type; + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + typedef index_saver< + node_type, + final_allocator_type> index_saver_type; + typedef index_loader< + node_type, + final_node_type, + final_allocator_type> index_loader_type; +#endif + +private: + typedef Value value_type; + +protected: + explicit index_base(const ctor_args_list&,const Allocator&){} + + index_base( + const index_base&, + do_not_copy_elements_tag) + {} + + void copy_( + const index_base&,const copy_map_type&) + {} + + final_node_type* insert_(const value_type& v,final_node_type*& x,lvalue_tag) + { + x=final().allocate_node(); + BOOST_TRY{ + boost::detail::allocator::construct(&x->value(),v); + } + BOOST_CATCH(...){ + final().deallocate_node(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + return x; + } + + final_node_type* insert_(const value_type& v,final_node_type*& x,rvalue_tag) + { + x=final().allocate_node(); + BOOST_TRY{ + /* This shoud have used a modified, T&&-compatible version of + * boost::detail::allocator::construct, but + * is too old and venerable to + * mess with; besides, it is a general internal utility and the imperfect + * perfect forwarding emulation of Boost.Move might break other libs. + */ + + new (&x->value()) value_type(boost::move(const_cast(v))); + } + BOOST_CATCH(...){ + final().deallocate_node(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + return x; + } + + final_node_type* insert_(const value_type&,final_node_type*& x,emplaced_tag) + { + return x; + } + + final_node_type* insert_( + const value_type& v,node_type*,final_node_type*& x,lvalue_tag) + { + return insert_(v,x,lvalue_tag()); + } + + final_node_type* insert_( + const value_type& v,node_type*,final_node_type*& x,rvalue_tag) + { + return insert_(v,x,rvalue_tag()); + } + + final_node_type* insert_( + const value_type&,node_type*,final_node_type*& x,emplaced_tag) + { + return x; + } + + void erase_(node_type* x) + { + boost::detail::allocator::destroy(&x->value()); + } + + void delete_node_(node_type* x) + { + boost::detail::allocator::destroy(&x->value()); + } + + void clear_(){} + + void swap_(index_base&){} + + void swap_elements_(index_base&){} + + bool replace_(const value_type& v,node_type* x,lvalue_tag) + { + x->value()=v; + return true; + } + + bool replace_(const value_type& v,node_type* x,rvalue_tag) + { + x->value()=boost::move(const_cast(v)); + return true; + } + + bool modify_(node_type*){return true;} + + bool modify_rollback_(node_type*){return true;} + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + /* serialization */ + + template + void save_(Archive&,const unsigned int,const index_saver_type&)const{} + + template + void load_(Archive&,const unsigned int,const index_loader_type&){} +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + /* invariant stuff */ + + bool invariant_()const{return true;} +#endif + + /* access to backbone memfuns of Final class */ + + final_type& final(){return *static_cast(this);} + const final_type& final()const{return *static_cast(this);} + + final_node_type* final_header()const{return final().header();} + + bool final_empty_()const{return final().empty_();} + std::size_t final_size_()const{return final().size_();} + std::size_t final_max_size_()const{return final().max_size_();} + + std::pair final_insert_(const value_type& x) + {return final().insert_(x);} + std::pair final_insert_rv_(const value_type& x) + {return final().insert_rv_(x);} + template + std::pair final_insert_ref_(const T& t) + {return final().insert_ref_(t);} + template + std::pair final_insert_ref_(T& t) + {return final().insert_ref_(t);} + + template + std::pair final_emplace_( + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return final().emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } + + std::pair final_insert_( + const value_type& x,final_node_type* position) + {return final().insert_(x,position);} + std::pair final_insert_rv_( + const value_type& x,final_node_type* position) + {return final().insert_rv_(x,position);} + template + std::pair final_insert_ref_( + const T& t,final_node_type* position) + {return final().insert_ref_(t,position);} + template + std::pair final_insert_ref_( + T& t,final_node_type* position) + {return final().insert_ref_(t,position);} + + template + std::pair final_emplace_hint_( + final_node_type* position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return final().emplace_hint_( + position,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } + + void final_erase_(final_node_type* x){final().erase_(x);} + + void final_delete_node_(final_node_type* x){final().delete_node_(x);} + void final_delete_all_nodes_(){final().delete_all_nodes_();} + void final_clear_(){final().clear_();} + + void final_swap_(final_type& x){final().swap_(x);} + + bool final_replace_( + const value_type& k,final_node_type* x) + {return final().replace_(k,x);} + bool final_replace_rv_( + const value_type& k,final_node_type* x) + {return final().replace_rv_(k,x);} + + template + bool final_modify_(Modifier& mod,final_node_type* x) + {return final().modify_(mod,x);} + + template + bool final_modify_(Modifier& mod,Rollback& back,final_node_type* x) + {return final().modify_(mod,back,x);} + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + void final_check_invariant_()const{final().check_invariant_();} +#endif +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_loader.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_loader.hpp new file mode 100644 index 00000000000..71418a10e19 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_loader.hpp @@ -0,0 +1,139 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP +#define BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Counterpart of index_saver (check index_saver.hpp for serialization + * details.)* multi_index_container is in charge of supplying the info about + * the base sequence, and each index can subsequently load itself using the + * const interface of index_loader. + */ + +template +class index_loader:private noncopyable +{ +public: + index_loader(const Allocator& al,std::size_t size): + spc(al,size),size_(size),n(0),sorted(false) + { + } + + template + void add(Node* node,Archive& ar,const unsigned int) + { + ar>>serialization::make_nvp("position",*node); + entries()[n++]=node; + } + + template + void add_track(Node* node,Archive& ar,const unsigned int) + { + ar>>serialization::make_nvp("position",*node); + } + + /* A rearranger is passed two nodes, and is expected to + * reposition the second after the first. + * If the first node is 0, then the second should be moved + * to the beginning of the sequence. + */ + + template + void load(Rearranger r,Archive& ar,const unsigned int)const + { + FinalNode* prev=unchecked_load_node(ar); + if(!prev)return; + + if(!sorted){ + std::sort(entries(),entries()+size_); + sorted=true; + } + + check_node(prev); + + for(;;){ + for(;;){ + FinalNode* node=load_node(ar); + if(!node)break; + + if(node==prev)prev=0; + r(prev,node); + + prev=node; + } + prev=load_node(ar); + if(!prev)break; + } + } + +private: + Node** entries()const{return raw_ptr(spc.data());} + + /* We try to delay sorting as much as possible just in case it + * is not necessary, hence this version of load_node. + */ + + template + FinalNode* unchecked_load_node(Archive& ar)const + { + Node* node=0; + ar>>serialization::make_nvp("pointer",node); + return static_cast(node); + } + + template + FinalNode* load_node(Archive& ar)const + { + Node* node=0; + ar>>serialization::make_nvp("pointer",node); + check_node(node); + return static_cast(node); + } + + void check_node(Node* node)const + { + if(node!=0&&!std::binary_search(entries(),entries()+size_,node)){ + throw_exception( + archive::archive_exception( + archive::archive_exception::other_exception)); + } + } + + auto_space spc; + std::size_t size_; + std::size_t n; + mutable bool sorted; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_matcher.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_matcher.hpp new file mode 100644 index 00000000000..34d1f9d5a8d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_matcher.hpp @@ -0,0 +1,249 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_MATCHER_HPP +#define BOOST_MULTI_INDEX_DETAIL_INDEX_MATCHER_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* index_matcher compares a sequence of elements against a + * base sequence, identifying those elements that belong to the + * longest subsequence which is ordered with respect to the base. + * For instance, if the base sequence is: + * + * 0 1 2 3 4 5 6 7 8 9 + * + * and the compared sequence (not necesarilly the same length): + * + * 1 4 2 3 0 7 8 9 + * + * the elements of the longest ordered subsequence are: + * + * 1 2 3 7 8 9 + * + * The algorithm for obtaining such a subsequence is called + * Patience Sorting, described in ch. 1 of: + * Aldous, D., Diaconis, P.: "Longest increasing subsequences: from + * patience sorting to the Baik-Deift-Johansson Theorem", Bulletin + * of the American Mathematical Society, vol. 36, no 4, pp. 413-432, + * July 1999. + * http://www.ams.org/bull/1999-36-04/S0273-0979-99-00796-X/ + * S0273-0979-99-00796-X.pdf + * + * This implementation is not fully generic since it assumes that + * the sequences given are pointed to by index iterators (having a + * get_node() memfun.) + */ + +namespace index_matcher{ + +/* The algorithm stores the nodes of the base sequence and a number + * of "piles" that are dynamically updated during the calculation + * stage. From a logical point of view, nodes form an independent + * sequence from piles. They are stored together so as to minimize + * allocated memory. + */ + +struct entry +{ + entry(void* node_,std::size_t pos_=0):node(node_),pos(pos_){} + + /* node stuff */ + + void* node; + std::size_t pos; + entry* previous; + bool ordered; + + struct less_by_node + { + bool operator()( + const entry& x,const entry& y)const + { + return std::less()(x.node,y.node); + } + }; + + /* pile stuff */ + + std::size_t pile_top; + entry* pile_top_entry; + + struct less_by_pile_top + { + bool operator()( + const entry& x,const entry& y)const + { + return x.pile_top +class algorithm_base:private noncopyable +{ +protected: + algorithm_base(const Allocator& al,std::size_t size): + spc(al,size),size_(size),n_(0),sorted(false) + { + } + + void add(void* node) + { + entries()[n_]=entry(node,n_); + ++n_; + } + + void begin_algorithm()const + { + if(!sorted){ + std::sort(entries(),entries()+size_,entry::less_by_node()); + sorted=true; + } + num_piles=0; + } + + void add_node_to_algorithm(void* node)const + { + entry* ent= + std::lower_bound( + entries(),entries()+size_, + entry(node),entry::less_by_node()); /* localize entry */ + ent->ordered=false; + std::size_t n=ent->pos; /* get its position */ + + entry dummy(0); + dummy.pile_top=n; + + entry* pile_ent= /* find the first available pile */ + std::lower_bound( /* to stack the entry */ + entries(),entries()+num_piles, + dummy,entry::less_by_pile_top()); + + pile_ent->pile_top=n; /* stack the entry */ + pile_ent->pile_top_entry=ent; + + /* if not the first pile, link entry to top of the preceding pile */ + if(pile_ent>&entries()[0]){ + ent->previous=(pile_ent-1)->pile_top_entry; + } + + if(pile_ent==&entries()[num_piles]){ /* new pile? */ + ++num_piles; + } + } + + void finish_algorithm()const + { + if(num_piles>0){ + /* Mark those elements which are in their correct position, i.e. those + * belonging to the longest increasing subsequence. These are those + * elements linked from the top of the last pile. + */ + + entry* ent=entries()[num_piles-1].pile_top_entry; + for(std::size_t n=num_piles;n--;){ + ent->ordered=true; + ent=ent->previous; + } + } + } + + bool is_ordered(void * node)const + { + return std::lower_bound( + entries(),entries()+size_, + entry(node),entry::less_by_node())->ordered; + } + +private: + entry* entries()const{return raw_ptr(spc.data());} + + auto_space spc; + std::size_t size_; + std::size_t n_; + mutable bool sorted; + mutable std::size_t num_piles; +}; + +/* The algorithm has three phases: + * - Initialization, during which the nodes of the base sequence are added. + * - Execution. + * - Results querying, through the is_ordered memfun. + */ + +template +class algorithm:private algorithm_base +{ + typedef algorithm_base super; + +public: + algorithm(const Allocator& al,std::size_t size):super(al,size){} + + void add(Node* node) + { + super::add(node); + } + + template + void execute(IndexIterator first,IndexIterator last)const + { + super::begin_algorithm(); + + for(IndexIterator it=first;it!=last;++it){ + add_node_to_algorithm(get_node(it)); + } + + super::finish_algorithm(); + } + + bool is_ordered(Node* node)const + { + return super::is_ordered(node); + } + +private: + void add_node_to_algorithm(Node* node)const + { + super::add_node_to_algorithm(node); + } + + template + static Node* get_node(IndexIterator it) + { + return static_cast(it.get_node()); + } +}; + +} /* namespace multi_index::detail::index_matcher */ + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_node_base.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_node_base.hpp new file mode 100644 index 00000000000..1a1f0cae4be --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_node_base.hpp @@ -0,0 +1,135 @@ +/* Copyright 2003-2016 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_NODE_BASE_HPP +#define BOOST_MULTI_INDEX_DETAIL_INDEX_NODE_BASE_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#include +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* index_node_base tops the node hierarchy of multi_index_container. It holds + * the value of the element contained. + */ + +template +struct pod_value_holder +{ + typename aligned_storage< + sizeof(Value), + alignment_of::value + >::type space; +}; + +template +struct index_node_base:private pod_value_holder +{ + typedef index_node_base base_type; /* used for serialization purposes */ + typedef Value value_type; + typedef Allocator allocator_type; + +#include + + value_type& value() + { + return *reinterpret_cast(&this->space); + } + + const value_type& value()const + { + return *reinterpret_cast(&this->space); + } + +#include + + static index_node_base* from_value(const value_type* p) + { + return static_cast( + reinterpret_cast*>( /* std 9.2.17 */ + const_cast(p))); + } + +private: +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + friend class boost::serialization::access; + + /* nodes do not emit any kind of serialization info. They are + * fed to Boost.Serialization so that pointers to nodes are + * tracked correctly. + */ + + template + void serialize(Archive&,const unsigned int) + { + } +#endif +}; + +template +Node* node_from_value(const Value* p) +{ + typedef typename Node::allocator_type allocator_type; + return static_cast( + index_node_base::from_value(p)); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +/* Index nodes never get constructed directly by Boost.Serialization, + * as archives are always fed pointers to previously existent + * nodes. So, if this is called it means we are dealing with a + * somehow invalid archive. + */ + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +namespace serialization{ +#else +namespace multi_index{ +namespace detail{ +#endif + +template +inline void load_construct_data( + Archive&,boost::multi_index::detail::index_node_base*, + const unsigned int) +{ + throw_exception( + archive::archive_exception(archive::archive_exception::other_exception)); +} + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) +} /* namespace serialization */ +#else +} /* namespace multi_index::detail */ +} /* namespace multi_index */ +#endif + +#endif + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_saver.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_saver.hpp new file mode 100644 index 00000000000..ae09d4eba4f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_saver.hpp @@ -0,0 +1,135 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP +#define BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* index_saver accepts a base sequence of previously saved elements + * and saves a possibly reordered subsequence in an efficient manner, + * serializing only the information needed to rearrange the subsequence + * based on the original order of the base. + * multi_index_container is in charge of supplying the info about the + * base sequence, and each index can subsequently save itself using the + * const interface of index_saver. + */ + +template +class index_saver:private noncopyable +{ +public: + index_saver(const Allocator& al,std::size_t size):alg(al,size){} + + template + void add(Node* node,Archive& ar,const unsigned int) + { + ar< + void add_track(Node* node,Archive& ar,const unsigned int) + { + ar< + void save( + IndexIterator first,IndexIterator last,Archive& ar, + const unsigned int)const + { + /* calculate ordered positions */ + + alg.execute(first,last); + + /* Given a consecutive subsequence of displaced elements + * x1,...,xn, the following information is serialized: + * + * p0,p1,...,pn,0 + * + * where pi is a pointer to xi and p0 is a pointer to the element + * preceding x1. Crealy, from this information is possible to + * restore the original order on loading time. If x1 is the first + * element in the sequence, the following is serialized instead: + * + * p1,p1,...,pn,0 + * + * For each subsequence of n elements, n+2 pointers are serialized. + * An optimization policy is applied: consider for instance the + * sequence + * + * a,B,c,D + * + * where B and D are displaced, but c is in its correct position. + * Applying the schema described above we would serialize 6 pointers: + * + * p(a),p(B),0 + * p(c),p(D),0 + * + * but this can be reduced to 5 pointers by treating c as a displaced + * element: + * + * p(a),p(B),p(c),p(D),0 + */ + + std::size_t last_saved=3; /* distance to last pointer saved */ + for(IndexIterator it=first,prev=first;it!=last;prev=it++,++last_saved){ + if(!alg.is_ordered(get_node(it))){ + if(last_saved>1)save_node(get_node(prev),ar); + save_node(get_node(it),ar); + last_saved=0; + } + else if(last_saved==2)save_node(null_node(),ar); + } + if(last_saved<=2)save_node(null_node(),ar); + + /* marks the end of the serialization info for [first,last) */ + + save_node(null_node(),ar); + } + +private: + template + static Node* get_node(IndexIterator it) + { + return it.get_node(); + } + + static Node* null_node(){return 0;} + + template + static void save_node(Node* node,Archive& ar) + { + ar< alg; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/invariant_assert.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/invariant_assert.hpp new file mode 100644 index 00000000000..c6c547c7c33 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/invariant_assert.hpp @@ -0,0 +1,21 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_INVARIANT_ASSERT_HPP +#define BOOST_MULTI_INDEX_DETAIL_INVARIANT_ASSERT_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#if !defined(BOOST_MULTI_INDEX_INVARIANT_ASSERT) +#include +#define BOOST_MULTI_INDEX_INVARIANT_ASSERT BOOST_ASSERT +#endif + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_index_list.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_index_list.hpp new file mode 100644 index 00000000000..f6a24218b81 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_index_list.hpp @@ -0,0 +1,40 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_IS_INDEX_LIST_HPP +#define BOOST_MULTI_INDEX_DETAIL_IS_INDEX_LIST_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +struct is_index_list +{ + BOOST_STATIC_CONSTANT(bool,mpl_sequence=mpl::is_sequence::value); + BOOST_STATIC_CONSTANT(bool,non_empty=!mpl::empty::value); + BOOST_STATIC_CONSTANT(bool,value=mpl_sequence&&non_empty); +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_transparent.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_transparent.hpp new file mode 100644 index 00000000000..72036d257e2 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_transparent.hpp @@ -0,0 +1,135 @@ +/* Copyright 2003-2014 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_IS_TRANSPARENT_HPP +#define BOOST_MULTI_INDEX_DETAIL_IS_TRANSPARENT_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Metafunction that checks if f(arg,arg2) executes without argument type + * conversion. By default (i.e. when it cannot be determined) it evaluates to + * true. + */ + +template +struct is_transparent:mpl::true_{}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#if !defined(BOOST_NO_SFINAE)&&!defined(BOOST_NO_SFINAE_EXPR)&& \ + !defined(BOOST_NO_CXX11_DECLTYPE)&& \ + (defined(BOOST_NO_CXX11_FINAL)||defined(BOOST_IS_FINAL)) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +struct not_is_transparent_result_type{}; + +template +struct is_transparent_class_helper:F +{ + using F::operator(); + template + not_is_transparent_result_type operator()(const T&,const Q&)const; +}; + +template +struct is_transparent_class:mpl::true_{}; + +template +struct is_transparent_class< + F,Arg1,Arg2, + typename enable_if< + is_same< + decltype( + declval >()( + declval(),declval()) + ), + not_is_transparent_result_type + > + >::type +>:mpl::false_{}; + +template +struct is_transparent< + F,Arg1,Arg2, + typename enable_if< + mpl::and_< + is_class, + mpl::not_ > /* is_transparent_class_helper derives from F */ + > + >::type +>:is_transparent_class{}; + +template +struct is_transparent_function:mpl::true_{}; + +template +struct is_transparent_function< + F,Arg1,Arg2, + typename enable_if< + mpl::or_< + mpl::not_::arg1_type,const Arg1&>, + is_same::arg1_type,Arg1> + > >, + mpl::not_::arg2_type,const Arg2&>, + is_same::arg2_type,Arg2> + > > + > + >::type +>:mpl::false_{}; + +template +struct is_transparent< + F,Arg1,Arg2, + typename enable_if< + is_function::type> + >::type +>:is_transparent_function::type,Arg1,Arg2>{}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/iter_adaptor.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/iter_adaptor.hpp new file mode 100644 index 00000000000..7a032350b36 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/iter_adaptor.hpp @@ -0,0 +1,321 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP +#define BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Poor man's version of boost::iterator_adaptor. Used instead of the + * original as compile times for the latter are significantly higher. + * The interface is not replicated exactly, only to the extent necessary + * for internal consumption. + */ + +/* NB. The purpose of the (non-inclass) global operators ==, < and - defined + * above is to partially alleviate a problem of MSVC++ 6.0 by * which + * friend-injected operators on T are not visible if T is instantiated only + * in template code where T is a dependent type. + */ + +class iter_adaptor_access +{ +public: + template + static typename Class::reference dereference(const Class& x) + { + return x.dereference(); + } + + template + static bool equal(const Class& x,const Class& y) + { + return x.equal(y); + } + + template + static void increment(Class& x) + { + x.increment(); + } + + template + static void decrement(Class& x) + { + x.decrement(); + } + + template + static void advance(Class& x,typename Class::difference_type n) + { + x.advance(n); + } + + template + static typename Class::difference_type distance_to( + const Class& x,const Class& y) + { + return x.distance_to(y); + } +}; + +template +struct iter_adaptor_selector; + +template +class forward_iter_adaptor_base: + public forward_iterator_helper< + Derived, + typename Base::value_type, + typename Base::difference_type, + typename Base::pointer, + typename Base::reference> +{ +public: + typedef typename Base::reference reference; + + reference operator*()const + { + return iter_adaptor_access::dereference(final()); + } + + friend bool operator==(const Derived& x,const Derived& y) + { + return iter_adaptor_access::equal(x,y); + } + + Derived& operator++() + { + iter_adaptor_access::increment(final()); + return final(); + } + +private: + Derived& final(){return *static_cast(this);} + const Derived& final()const{return *static_cast(this);} +}; + +template +bool operator==( + const forward_iter_adaptor_base& x, + const forward_iter_adaptor_base& y) +{ + return iter_adaptor_access::equal( + static_cast(x),static_cast(y)); +} + +template<> +struct iter_adaptor_selector +{ + template + struct apply + { + typedef forward_iter_adaptor_base type; + }; +}; + +template +class bidirectional_iter_adaptor_base: + public bidirectional_iterator_helper< + Derived, + typename Base::value_type, + typename Base::difference_type, + typename Base::pointer, + typename Base::reference> +{ +public: + typedef typename Base::reference reference; + + reference operator*()const + { + return iter_adaptor_access::dereference(final()); + } + + friend bool operator==(const Derived& x,const Derived& y) + { + return iter_adaptor_access::equal(x,y); + } + + Derived& operator++() + { + iter_adaptor_access::increment(final()); + return final(); + } + + Derived& operator--() + { + iter_adaptor_access::decrement(final()); + return final(); + } + +private: + Derived& final(){return *static_cast(this);} + const Derived& final()const{return *static_cast(this);} +}; + +template +bool operator==( + const bidirectional_iter_adaptor_base& x, + const bidirectional_iter_adaptor_base& y) +{ + return iter_adaptor_access::equal( + static_cast(x),static_cast(y)); +} + +template<> +struct iter_adaptor_selector +{ + template + struct apply + { + typedef bidirectional_iter_adaptor_base type; + }; +}; + +template +class random_access_iter_adaptor_base: + public random_access_iterator_helper< + Derived, + typename Base::value_type, + typename Base::difference_type, + typename Base::pointer, + typename Base::reference> +{ +public: + typedef typename Base::reference reference; + typedef typename Base::difference_type difference_type; + + reference operator*()const + { + return iter_adaptor_access::dereference(final()); + } + + friend bool operator==(const Derived& x,const Derived& y) + { + return iter_adaptor_access::equal(x,y); + } + + friend bool operator<(const Derived& x,const Derived& y) + { + return iter_adaptor_access::distance_to(x,y)>0; + } + + Derived& operator++() + { + iter_adaptor_access::increment(final()); + return final(); + } + + Derived& operator--() + { + iter_adaptor_access::decrement(final()); + return final(); + } + + Derived& operator+=(difference_type n) + { + iter_adaptor_access::advance(final(),n); + return final(); + } + + Derived& operator-=(difference_type n) + { + iter_adaptor_access::advance(final(),-n); + return final(); + } + + friend difference_type operator-(const Derived& x,const Derived& y) + { + return iter_adaptor_access::distance_to(y,x); + } + +private: + Derived& final(){return *static_cast(this);} + const Derived& final()const{return *static_cast(this);} +}; + +template +bool operator==( + const random_access_iter_adaptor_base& x, + const random_access_iter_adaptor_base& y) +{ + return iter_adaptor_access::equal( + static_cast(x),static_cast(y)); +} + +template +bool operator<( + const random_access_iter_adaptor_base& x, + const random_access_iter_adaptor_base& y) +{ + return iter_adaptor_access::distance_to( + static_cast(x),static_cast(y))>0; +} + +template +typename random_access_iter_adaptor_base::difference_type +operator-( + const random_access_iter_adaptor_base& x, + const random_access_iter_adaptor_base& y) +{ + return iter_adaptor_access::distance_to( + static_cast(y),static_cast(x)); +} + +template<> +struct iter_adaptor_selector +{ + template + struct apply + { + typedef random_access_iter_adaptor_base type; + }; +}; + +template +struct iter_adaptor_base +{ + typedef iter_adaptor_selector< + typename Base::iterator_category> selector; + typedef typename mpl::apply2< + selector,Derived,Base>::type type; +}; + +template +class iter_adaptor:public iter_adaptor_base::type +{ +protected: + iter_adaptor(){} + explicit iter_adaptor(const Base& b_):b(b_){} + + const Base& base_reference()const{return b;} + Base& base_reference(){return b;} + +private: + Base b; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/modify_key_adaptor.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/modify_key_adaptor.hpp new file mode 100644 index 00000000000..6df89b18386 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/modify_key_adaptor.hpp @@ -0,0 +1,49 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_MODIFY_KEY_ADAPTOR_HPP +#define BOOST_MULTI_INDEX_DETAIL_MODIFY_KEY_ADAPTOR_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Functional adaptor to resolve modify_key as a call to modify. + * Preferred over compose_f_gx and stuff cause it eliminates problems + * with references to references, dealing with function pointers, etc. + */ + +template +struct modify_key_adaptor +{ + + modify_key_adaptor(Fun f_,KeyFromValue kfv_):f(f_),kfv(kfv_){} + + void operator()(Value& x) + { + f(kfv(x)); + } + +private: + Fun f; + KeyFromValue kfv; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/no_duplicate_tags.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/no_duplicate_tags.hpp new file mode 100644 index 00000000000..ba216ed82cf --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/no_duplicate_tags.hpp @@ -0,0 +1,97 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_NO_DUPLICATE_TAGS_HPP +#define BOOST_MULTI_INDEX_DETAIL_NO_DUPLICATE_TAGS_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* no_duplicate_tags check at compile-time that a tag list + * has no duplicate tags. + * The algorithm deserves some explanation: tags + * are sequentially inserted into a mpl::set if they were + * not already present. Due to the magic of mpl::set + * (mpl::has_key is contant time), this operation takes linear + * time, and even MSVC++ 6.5 handles it gracefully (other obvious + * solutions are quadratic.) + */ + +struct duplicate_tag_mark{}; + +struct duplicate_tag_marker +{ + template + struct apply + { + typedef mpl::s_item< + typename mpl::if_,duplicate_tag_mark,Tag>::type, + MplSet + > type; + }; +}; + +template +struct no_duplicate_tags +{ + typedef typename mpl::fold< + TagList, + mpl::set0<>, + duplicate_tag_marker + >::type aux; + + BOOST_STATIC_CONSTANT( + bool,value=!(mpl::has_key::value)); +}; + +/* Variant for an index list: duplication is checked + * across all the indices. + */ + +struct duplicate_tag_list_marker +{ + template + struct apply:mpl::fold< + BOOST_DEDUCED_TYPENAME Index::tag_list, + MplSet, + duplicate_tag_marker> + { + }; +}; + +template +struct no_duplicate_tags_in_index_list +{ + typedef typename mpl::fold< + IndexList, + mpl::set0<>, + duplicate_tag_list_marker + >::type aux; + + BOOST_STATIC_CONSTANT( + bool,value=!(mpl::has_key::value)); +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/node_type.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/node_type.hpp new file mode 100644 index 00000000000..7fe85cf968b --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/node_type.hpp @@ -0,0 +1,66 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_NODE_TYPE_HPP +#define BOOST_MULTI_INDEX_DETAIL_NODE_TYPE_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* MPL machinery to construct the internal node type associated to an + * index list. + */ + +struct index_node_applier +{ + template + struct apply + { + typedef typename mpl::deref::type index_specifier; + typedef typename index_specifier:: + BOOST_NESTED_TEMPLATE node_class::type type; + }; +}; + +template +struct multi_index_node_type +{ + BOOST_STATIC_ASSERT(detail::is_index_list::value); + + typedef typename mpl::reverse_iter_fold< + IndexSpecifierList, + index_node_base, + mpl::bind2 + >::type type; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_args.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_args.hpp new file mode 100644 index 00000000000..3e2641f2f4d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_args.hpp @@ -0,0 +1,83 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_ARGS_HPP +#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_ARGS_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Oredered index specifiers can be instantiated in two forms: + * + * (ordered_unique|ordered_non_unique)< + * KeyFromValue,Compare=std::less > + * (ordered_unique|ordered_non_unique)< + * TagList,KeyFromValue,Compare=std::less > + * + * index_args implements the machinery to accept this argument-dependent + * polymorphism. + */ + +template +struct index_args_default_compare +{ + typedef std::less type; +}; + +template +struct ordered_index_args +{ + typedef is_tag full_form; + + typedef typename mpl::if_< + full_form, + Arg1, + tag< > >::type tag_list_type; + typedef typename mpl::if_< + full_form, + Arg2, + Arg1>::type key_from_value_type; + typedef typename mpl::if_< + full_form, + Arg3, + Arg2>::type supplied_compare_type; + typedef typename mpl::eval_if< + mpl::is_na, + index_args_default_compare, + mpl::identity + >::type compare_type; + + BOOST_STATIC_ASSERT(is_tag::value); + BOOST_STATIC_ASSERT(!mpl::is_na::value); + BOOST_STATIC_ASSERT(!mpl::is_na::value); +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl.hpp new file mode 100644 index 00000000000..040cb989630 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl.hpp @@ -0,0 +1,1567 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + * + * The internal implementation of red-black trees is based on that of SGI STL + * stl_tree.h file: + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_HPP +#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#include +#include +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) +#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) \ + detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ + detail::make_obj_guard(x,&ordered_index_impl::check_invariant_); \ + BOOST_JOIN(check_invariant_,__LINE__).touch(); +#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \ + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(*this) +#else +#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) +#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* ordered_index adds a layer of ordered indexing to a given Super and accepts + * an augmenting policy for optional addition of order statistics. + */ + +/* Most of the implementation of unique and non-unique indices is + * shared. We tell from one another on instantiation time by using + * these tags. + */ + +struct ordered_unique_tag{}; +struct ordered_non_unique_tag{}; + +template< + typename KeyFromValue,typename Compare, + typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy +> +class ordered_index; + +template< + typename KeyFromValue,typename Compare, + typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy +> +class ordered_index_impl: + BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + ,public safe_mode::safe_container< + ordered_index_impl< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy> > +#endif + +{ +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ + BOOST_WORKAROUND(__MWERKS__,<=0x3003) +/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the + * lifetime of const references bound to temporaries --precisely what + * scopeguards are. + */ + +#pragma parse_mfunc_templ off +#endif + + typedef typename SuperMeta::type super; + +protected: + typedef ordered_index_node< + AugmentPolicy,typename super::node_type> node_type; + +protected: /* for the benefit of AugmentPolicy::augmented_interface */ + typedef typename node_type::impl_type node_impl_type; + typedef typename node_impl_type::pointer node_impl_pointer; + +public: + /* types */ + + typedef typename KeyFromValue::result_type key_type; + typedef typename node_type::value_type value_type; + typedef KeyFromValue key_from_value; + typedef Compare key_compare; + typedef value_comparison< + value_type,KeyFromValue,Compare> value_compare; + typedef tuple ctor_args; + typedef typename super::final_allocator_type allocator_type; + typedef typename allocator_type::reference reference; + typedef typename allocator_type::const_reference const_reference; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef safe_mode::safe_iterator< + bidir_node_iterator, + ordered_index_impl> iterator; +#else + typedef bidir_node_iterator iterator; +#endif + + typedef iterator const_iterator; + + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef typename allocator_type::pointer pointer; + typedef typename allocator_type::const_pointer const_pointer; + typedef typename + boost::reverse_iterator reverse_iterator; + typedef typename + boost::reverse_iterator const_reverse_iterator; + typedef TagList tag_list; + +protected: + typedef typename super::final_node_type final_node_type; + typedef tuples::cons< + ctor_args, + typename super::ctor_args_list> ctor_args_list; + typedef typename mpl::push_front< + typename super::index_type_list, + ordered_index< + KeyFromValue,Compare, + SuperMeta,TagList,Category,AugmentPolicy + > >::type index_type_list; + typedef typename mpl::push_front< + typename super::iterator_type_list, + iterator>::type iterator_type_list; + typedef typename mpl::push_front< + typename super::const_iterator_type_list, + const_iterator>::type const_iterator_type_list; + typedef typename super::copy_map_type copy_map_type; + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + typedef typename super::index_saver_type index_saver_type; + typedef typename super::index_loader_type index_loader_type; +#endif + +protected: +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef safe_mode::safe_container< + ordered_index_impl> safe_super; +#endif + + typedef typename call_traits< + value_type>::param_type value_param_type; + typedef typename call_traits< + key_type>::param_type key_param_type; + + /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * expansion. + */ + + typedef std::pair emplace_return_type; + +public: + + /* construct/copy/destroy + * Default and copy ctors are in the protected section as indices are + * not supposed to be created on their own. No range ctor either. + * Assignment operators defined at ordered_index rather than here. + */ + + allocator_type get_allocator()const BOOST_NOEXCEPT + { + return this->final().get_allocator(); + } + + /* iterators */ + + iterator + begin()BOOST_NOEXCEPT{return make_iterator(leftmost());} + const_iterator + begin()const BOOST_NOEXCEPT{return make_iterator(leftmost());} + iterator + end()BOOST_NOEXCEPT{return make_iterator(header());} + const_iterator + end()const BOOST_NOEXCEPT{return make_iterator(header());} + reverse_iterator + rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} + const_reverse_iterator + rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} + reverse_iterator + rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} + const_reverse_iterator + rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} + const_iterator + cbegin()const BOOST_NOEXCEPT{return begin();} + const_iterator + cend()const BOOST_NOEXCEPT{return end();} + const_reverse_iterator + crbegin()const BOOST_NOEXCEPT{return rbegin();} + const_reverse_iterator + crend()const BOOST_NOEXCEPT{return rend();} + + iterator iterator_to(const value_type& x) + { + return make_iterator(node_from_value(&x)); + } + + const_iterator iterator_to(const value_type& x)const + { + return make_iterator(node_from_value(&x)); + } + + /* capacity */ + + bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} + size_type size()const BOOST_NOEXCEPT{return this->final_size_();} + size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} + + /* modifiers */ + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace,emplace_impl) + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( + iterator,emplace_hint,emplace_hint_impl,iterator,position) + + std::pair insert(const value_type& x) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_(x); + return std::pair(make_iterator(p.first),p.second); + } + + std::pair insert(BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_(x); + return std::pair(make_iterator(p.first),p.second); + } + + iterator insert(iterator position,const value_type& x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_( + x,static_cast(position.get_node())); + return make_iterator(p.first); + } + + iterator insert(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_( + x,static_cast(position.get_node())); + return make_iterator(p.first); + } + + template + void insert(InputIterator first,InputIterator last) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + node_type* hint=header(); /* end() */ + for(;first!=last;++first){ + hint=this->final_insert_ref_( + *first,static_cast(hint)).first; + node_type::increment(hint); + } + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void insert(std::initializer_list list) + { + insert(list.begin(),list.end()); + } +#endif + + iterator erase(iterator position) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + this->final_erase_(static_cast(position++.get_node())); + return position; + } + + size_type erase(key_param_type x) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pair p=equal_range(x); + size_type s=0; + while(p.first!=p.second){ + p.first=erase(p.first); + ++s; + } + return s; + } + + iterator erase(iterator first,iterator last) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); + BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + while(first!=last){ + first=erase(first); + } + return first; + } + + bool replace(iterator position,const value_type& x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + return this->final_replace_( + x,static_cast(position.get_node())); + } + + bool replace(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + return this->final_replace_rv_( + x,static_cast(position.get_node())); + } + + template + bool modify(iterator position,Modifier mod) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + /* MSVC++ 6.0 optimizer on safe mode code chokes if this + * this is not added. Left it for all compilers as it does no + * harm. + */ + + position.detach(); +#endif + + return this->final_modify_( + mod,static_cast(position.get_node())); + } + + template + bool modify(iterator position,Modifier mod,Rollback back_) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + /* MSVC++ 6.0 optimizer on safe mode code chokes if this + * this is not added. Left it for all compilers as it does no + * harm. + */ + + position.detach(); +#endif + + return this->final_modify_( + mod,back_,static_cast(position.get_node())); + } + + template + bool modify_key(iterator position,Modifier mod) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + return modify( + position,modify_key_adaptor(mod,key)); + } + + template + bool modify_key(iterator position,Modifier mod,Rollback back_) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + return modify( + position, + modify_key_adaptor(mod,key), + modify_key_adaptor(back_,key)); + } + + void swap( + ordered_index< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x); + this->final_swap_(x.final()); + } + + void clear()BOOST_NOEXCEPT + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + this->final_clear_(); + } + + /* observers */ + + key_from_value key_extractor()const{return key;} + key_compare key_comp()const{return comp_;} + value_compare value_comp()const{return value_compare(key,comp_);} + + /* set operations */ + + /* Internally, these ops rely on const_iterator being the same + * type as iterator. + */ + + template + iterator find(const CompatibleKey& x)const + { + return make_iterator(ordered_index_find(root(),header(),key,x,comp_)); + } + + template + iterator find( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + return make_iterator(ordered_index_find(root(),header(),key,x,comp)); + } + + template + size_type count(const CompatibleKey& x)const + { + return count(x,comp_); + } + + template + size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const + { + std::pair p=equal_range(x,comp); + size_type n=std::distance(p.first,p.second); + return n; + } + + template + iterator lower_bound(const CompatibleKey& x)const + { + return make_iterator( + ordered_index_lower_bound(root(),header(),key,x,comp_)); + } + + template + iterator lower_bound( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + return make_iterator( + ordered_index_lower_bound(root(),header(),key,x,comp)); + } + + template + iterator upper_bound(const CompatibleKey& x)const + { + return make_iterator( + ordered_index_upper_bound(root(),header(),key,x,comp_)); + } + + template + iterator upper_bound( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + return make_iterator( + ordered_index_upper_bound(root(),header(),key,x,comp)); + } + + template + std::pair equal_range( + const CompatibleKey& x)const + { + std::pair p= + ordered_index_equal_range(root(),header(),key,x,comp_); + return std::pair( + make_iterator(p.first),make_iterator(p.second)); + } + + template + std::pair equal_range( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + std::pair p= + ordered_index_equal_range(root(),header(),key,x,comp); + return std::pair( + make_iterator(p.first),make_iterator(p.second)); + } + + /* range */ + + template + std::pair + range(LowerBounder lower,UpperBounder upper)const + { + typedef typename mpl::if_< + is_same, + BOOST_DEDUCED_TYPENAME mpl::if_< + is_same, + both_unbounded_tag, + lower_unbounded_tag + >::type, + BOOST_DEDUCED_TYPENAME mpl::if_< + is_same, + upper_unbounded_tag, + none_unbounded_tag + >::type + >::type dispatch; + + return range(lower,upper,dispatch()); + } + +BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: + ordered_index_impl(const ctor_args_list& args_list,const allocator_type& al): + super(args_list.get_tail(),al), + key(tuples::get<0>(args_list.get_head())), + comp_(tuples::get<1>(args_list.get_head())) + { + empty_initialize(); + } + + ordered_index_impl( + const ordered_index_impl< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x): + super(x), + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super(), +#endif + + key(x.key), + comp_(x.comp_) + { + /* Copy ctor just takes the key and compare objects from x. The rest is + * done in a subsequent call to copy_(). + */ + } + + ordered_index_impl( + const ordered_index_impl< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x, + do_not_copy_elements_tag): + super(x,do_not_copy_elements_tag()), + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super(), +#endif + + key(x.key), + comp_(x.comp_) + { + empty_initialize(); + } + + ~ordered_index_impl() + { + /* the container is guaranteed to be empty by now */ + } + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + iterator make_iterator(node_type* node){return iterator(node,this);} + const_iterator make_iterator(node_type* node)const + {return const_iterator(node,const_cast(this));} +#else + iterator make_iterator(node_type* node){return iterator(node);} + const_iterator make_iterator(node_type* node)const + {return const_iterator(node);} +#endif + + void copy_( + const ordered_index_impl< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x, + const copy_map_type& map) + { + if(!x.root()){ + empty_initialize(); + } + else{ + header()->color()=x.header()->color(); + AugmentPolicy::copy(x.header()->impl(),header()->impl()); + + node_type* root_cpy=map.find(static_cast(x.root())); + header()->parent()=root_cpy->impl(); + + node_type* leftmost_cpy=map.find( + static_cast(x.leftmost())); + header()->left()=leftmost_cpy->impl(); + + node_type* rightmost_cpy=map.find( + static_cast(x.rightmost())); + header()->right()=rightmost_cpy->impl(); + + typedef typename copy_map_type::const_iterator copy_map_iterator; + for(copy_map_iterator it=map.begin(),it_end=map.end();it!=it_end;++it){ + node_type* org=it->first; + node_type* cpy=it->second; + + cpy->color()=org->color(); + AugmentPolicy::copy(org->impl(),cpy->impl()); + + node_impl_pointer parent_org=org->parent(); + if(parent_org==node_impl_pointer(0))cpy->parent()=node_impl_pointer(0); + else{ + node_type* parent_cpy=map.find( + static_cast(node_type::from_impl(parent_org))); + cpy->parent()=parent_cpy->impl(); + if(parent_org->left()==org->impl()){ + parent_cpy->left()=cpy->impl(); + } + else if(parent_org->right()==org->impl()){ + /* header() does not satisfy this nor the previous check */ + parent_cpy->right()=cpy->impl(); + } + } + + if(org->left()==node_impl_pointer(0)) + cpy->left()=node_impl_pointer(0); + if(org->right()==node_impl_pointer(0)) + cpy->right()=node_impl_pointer(0); + } + } + + super::copy_(x,map); + } + + template + final_node_type* insert_( + value_param_type v,final_node_type*& x,Variant variant) + { + link_info inf; + if(!link_point(key(v),inf,Category())){ + return static_cast(node_type::from_impl(inf.pos)); + } + + final_node_type* res=super::insert_(v,x,variant); + if(res==x){ + node_impl_type::link( + static_cast(x)->impl(),inf.side,inf.pos,header()->impl()); + } + return res; + } + + template + final_node_type* insert_( + value_param_type v,node_type* position,final_node_type*& x,Variant variant) + { + link_info inf; + if(!hinted_link_point(key(v),position,inf,Category())){ + return static_cast(node_type::from_impl(inf.pos)); + } + + final_node_type* res=super::insert_(v,position,x,variant); + if(res==x){ + node_impl_type::link( + static_cast(x)->impl(),inf.side,inf.pos,header()->impl()); + } + return res; + } + + void erase_(node_type* x) + { + node_impl_type::rebalance_for_erase( + x->impl(),header()->parent(),header()->left(),header()->right()); + super::erase_(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + } + + void delete_all_nodes_() + { + delete_all_nodes(root()); + } + + void clear_() + { + super::clear_(); + empty_initialize(); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::detach_dereferenceable_iterators(); +#endif + } + + void swap_( + ordered_index_impl< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x) + { + std::swap(key,x.key); + std::swap(comp_,x.comp_); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_(x); + } + + void swap_elements_( + ordered_index_impl< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x) + { +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_elements_(x); + } + + template + bool replace_(value_param_type v,node_type* x,Variant variant) + { + if(in_place(v,x,Category())){ + return super::replace_(v,x,variant); + } + + node_type* next=x; + node_type::increment(next); + + node_impl_type::rebalance_for_erase( + x->impl(),header()->parent(),header()->left(),header()->right()); + + BOOST_TRY{ + link_info inf; + if(link_point(key(v),inf,Category())&&super::replace_(v,x,variant)){ + node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); + return true; + } + node_impl_type::restore(x->impl(),next->impl(),header()->impl()); + return false; + } + BOOST_CATCH(...){ + node_impl_type::restore(x->impl(),next->impl(),header()->impl()); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + bool modify_(node_type* x) + { + bool b; + BOOST_TRY{ + b=in_place(x->value(),x,Category()); + } + BOOST_CATCH(...){ + erase_(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + if(!b){ + node_impl_type::rebalance_for_erase( + x->impl(),header()->parent(),header()->left(),header()->right()); + BOOST_TRY{ + link_info inf; + if(!link_point(key(x->value()),inf,Category())){ + super::erase_(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + return false; + } + node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); + } + BOOST_CATCH(...){ + super::erase_(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + BOOST_TRY{ + if(!super::modify_(x)){ + node_impl_type::rebalance_for_erase( + x->impl(),header()->parent(),header()->left(),header()->right()); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + + return false; + } + else return true; + } + BOOST_CATCH(...){ + node_impl_type::rebalance_for_erase( + x->impl(),header()->parent(),header()->left(),header()->right()); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + bool modify_rollback_(node_type* x) + { + if(in_place(x->value(),x,Category())){ + return super::modify_rollback_(x); + } + + node_type* next=x; + node_type::increment(next); + + node_impl_type::rebalance_for_erase( + x->impl(),header()->parent(),header()->left(),header()->right()); + + BOOST_TRY{ + link_info inf; + if(link_point(key(x->value()),inf,Category())&& + super::modify_rollback_(x)){ + node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); + return true; + } + node_impl_type::restore(x->impl(),next->impl(),header()->impl()); + return false; + } + BOOST_CATCH(...){ + node_impl_type::restore(x->impl(),next->impl(),header()->impl()); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + /* serialization */ + + template + void save_( + Archive& ar,const unsigned int version,const index_saver_type& sm)const + { + save_(ar,version,sm,Category()); + } + + template + void load_(Archive& ar,const unsigned int version,const index_loader_type& lm) + { + load_(ar,version,lm,Category()); + } +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + /* invariant stuff */ + + bool invariant_()const + { + if(size()==0||begin()==end()){ + if(size()!=0||begin()!=end()|| + header()->left()!=header()->impl()|| + header()->right()!=header()->impl())return false; + } + else{ + if((size_type)std::distance(begin(),end())!=size())return false; + + std::size_t len=node_impl_type::black_count( + leftmost()->impl(),root()->impl()); + for(const_iterator it=begin(),it_end=end();it!=it_end;++it){ + node_type* x=it.get_node(); + node_type* left_x=node_type::from_impl(x->left()); + node_type* right_x=node_type::from_impl(x->right()); + + if(x->color()==red){ + if((left_x&&left_x->color()==red)|| + (right_x&&right_x->color()==red))return false; + } + if(left_x&&comp_(key(x->value()),key(left_x->value())))return false; + if(right_x&&comp_(key(right_x->value()),key(x->value())))return false; + if(!left_x&&!right_x&& + node_impl_type::black_count(x->impl(),root()->impl())!=len) + return false; + if(!AugmentPolicy::invariant(x->impl()))return false; + } + + if(leftmost()->impl()!=node_impl_type::minimum(root()->impl())) + return false; + if(rightmost()->impl()!=node_impl_type::maximum(root()->impl())) + return false; + } + + return super::invariant_(); + } + + + /* This forwarding function eases things for the boost::mem_fn construct + * in BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT. Actually, + * final_check_invariant is already an inherited member function of + * ordered_index_impl. + */ + void check_invariant_()const{this->final_check_invariant_();} +#endif + +protected: /* for the benefit of AugmentPolicy::augmented_interface */ + node_type* header()const{return this->final_header();} + node_type* root()const{return node_type::from_impl(header()->parent());} + node_type* leftmost()const{return node_type::from_impl(header()->left());} + node_type* rightmost()const{return node_type::from_impl(header()->right());} + +private: + void empty_initialize() + { + header()->color()=red; + /* used to distinguish header() from root, in iterator.operator++ */ + + header()->parent()=node_impl_pointer(0); + header()->left()=header()->impl(); + header()->right()=header()->impl(); + } + + struct link_info + { + /* coverity[uninit_ctor]: suppress warning */ + link_info():side(to_left){} + + ordered_index_side side; + node_impl_pointer pos; + }; + + bool link_point(key_param_type k,link_info& inf,ordered_unique_tag) + { + node_type* y=header(); + node_type* x=root(); + bool c=true; + while(x){ + y=x; + c=comp_(k,key(x->value())); + x=node_type::from_impl(c?x->left():x->right()); + } + node_type* yy=y; + if(c){ + if(yy==leftmost()){ + inf.side=to_left; + inf.pos=y->impl(); + return true; + } + else node_type::decrement(yy); + } + + if(comp_(key(yy->value()),k)){ + inf.side=c?to_left:to_right; + inf.pos=y->impl(); + return true; + } + else{ + inf.pos=yy->impl(); + return false; + } + } + + bool link_point(key_param_type k,link_info& inf,ordered_non_unique_tag) + { + node_type* y=header(); + node_type* x=root(); + bool c=true; + while (x){ + y=x; + c=comp_(k,key(x->value())); + x=node_type::from_impl(c?x->left():x->right()); + } + inf.side=c?to_left:to_right; + inf.pos=y->impl(); + return true; + } + + bool lower_link_point(key_param_type k,link_info& inf,ordered_non_unique_tag) + { + node_type* y=header(); + node_type* x=root(); + bool c=false; + while (x){ + y=x; + c=comp_(key(x->value()),k); + x=node_type::from_impl(c?x->right():x->left()); + } + inf.side=c?to_right:to_left; + inf.pos=y->impl(); + return true; + } + + bool hinted_link_point( + key_param_type k,node_type* position,link_info& inf,ordered_unique_tag) + { + if(position->impl()==header()->left()){ + if(size()>0&&comp_(k,key(position->value()))){ + inf.side=to_left; + inf.pos=position->impl(); + return true; + } + else return link_point(k,inf,ordered_unique_tag()); + } + else if(position==header()){ + if(comp_(key(rightmost()->value()),k)){ + inf.side=to_right; + inf.pos=rightmost()->impl(); + return true; + } + else return link_point(k,inf,ordered_unique_tag()); + } + else{ + node_type* before=position; + node_type::decrement(before); + if(comp_(key(before->value()),k)&&comp_(k,key(position->value()))){ + if(before->right()==node_impl_pointer(0)){ + inf.side=to_right; + inf.pos=before->impl(); + return true; + } + else{ + inf.side=to_left; + inf.pos=position->impl(); + return true; + } + } + else return link_point(k,inf,ordered_unique_tag()); + } + } + + bool hinted_link_point( + key_param_type k,node_type* position,link_info& inf,ordered_non_unique_tag) + { + if(position->impl()==header()->left()){ + if(size()>0&&!comp_(key(position->value()),k)){ + inf.side=to_left; + inf.pos=position->impl(); + return true; + } + else return lower_link_point(k,inf,ordered_non_unique_tag()); + } + else if(position==header()){ + if(!comp_(k,key(rightmost()->value()))){ + inf.side=to_right; + inf.pos=rightmost()->impl(); + return true; + } + else return link_point(k,inf,ordered_non_unique_tag()); + } + else{ + node_type* before=position; + node_type::decrement(before); + if(!comp_(k,key(before->value()))){ + if(!comp_(key(position->value()),k)){ + if(before->right()==node_impl_pointer(0)){ + inf.side=to_right; + inf.pos=before->impl(); + return true; + } + else{ + inf.side=to_left; + inf.pos=position->impl(); + return true; + } + } + else return lower_link_point(k,inf,ordered_non_unique_tag()); + } + else return link_point(k,inf,ordered_non_unique_tag()); + } + } + + void delete_all_nodes(node_type* x) + { + if(!x)return; + + delete_all_nodes(node_type::from_impl(x->left())); + delete_all_nodes(node_type::from_impl(x->right())); + this->final_delete_node_(static_cast(x)); + } + + bool in_place(value_param_type v,node_type* x,ordered_unique_tag) + { + node_type* y; + if(x!=leftmost()){ + y=x; + node_type::decrement(y); + if(!comp_(key(y->value()),key(v)))return false; + } + + y=x; + node_type::increment(y); + return y==header()||comp_(key(v),key(y->value())); + } + + bool in_place(value_param_type v,node_type* x,ordered_non_unique_tag) + { + node_type* y; + if(x!=leftmost()){ + y=x; + node_type::decrement(y); + if(comp_(key(v),key(y->value())))return false; + } + + y=x; + node_type::increment(y); + return y==header()||!comp_(key(y->value()),key(v)); + } + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + void detach_iterators(node_type* x) + { + iterator it=make_iterator(x); + safe_mode::detach_equivalent_iterators(it); + } +#endif + + template + std::pair emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pairp= + this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + return std::pair(make_iterator(p.first),p.second); + } + + template + iterator emplace_hint_impl( + iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; + std::pairp= + this->final_emplace_hint_( + static_cast(position.get_node()), + BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + return make_iterator(p.first); + } + + template + std::pair + range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const + { + node_type* y=header(); + node_type* z=root(); + + while(z){ + if(!lower(key(z->value()))){ + z=node_type::from_impl(z->right()); + } + else if(!upper(key(z->value()))){ + y=z; + z=node_type::from_impl(z->left()); + } + else{ + return std::pair( + make_iterator( + lower_range(node_type::from_impl(z->left()),z,lower)), + make_iterator( + upper_range(node_type::from_impl(z->right()),y,upper))); + } + } + + return std::pair(make_iterator(y),make_iterator(y)); + } + + template + std::pair + range(LowerBounder,UpperBounder upper,lower_unbounded_tag)const + { + return std::pair( + begin(), + make_iterator(upper_range(root(),header(),upper))); + } + + template + std::pair + range(LowerBounder lower,UpperBounder,upper_unbounded_tag)const + { + return std::pair( + make_iterator(lower_range(root(),header(),lower)), + end()); + } + + template + std::pair + range(LowerBounder,UpperBounder,both_unbounded_tag)const + { + return std::pair(begin(),end()); + } + + template + node_type * lower_range(node_type* top,node_type* y,LowerBounder lower)const + { + while(top){ + if(lower(key(top->value()))){ + y=top; + top=node_type::from_impl(top->left()); + } + else top=node_type::from_impl(top->right()); + } + + return y; + } + + template + node_type * upper_range(node_type* top,node_type* y,UpperBounder upper)const + { + while(top){ + if(!upper(key(top->value()))){ + y=top; + top=node_type::from_impl(top->left()); + } + else top=node_type::from_impl(top->right()); + } + + return y; + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + template + void save_( + Archive& ar,const unsigned int version,const index_saver_type& sm, + ordered_unique_tag)const + { + super::save_(ar,version,sm); + } + + template + void load_( + Archive& ar,const unsigned int version,const index_loader_type& lm, + ordered_unique_tag) + { + super::load_(ar,version,lm); + } + + template + void save_( + Archive& ar,const unsigned int version,const index_saver_type& sm, + ordered_non_unique_tag)const + { + typedef duplicates_iterator dup_iterator; + + sm.save( + dup_iterator(begin().get_node(),end().get_node(),value_comp()), + dup_iterator(end().get_node(),value_comp()), + ar,version); + super::save_(ar,version,sm); + } + + template + void load_( + Archive& ar,const unsigned int version,const index_loader_type& lm, + ordered_non_unique_tag) + { + lm.load( + ::boost::bind( + &ordered_index_impl::rearranger,this, + ::boost::arg<1>(),::boost::arg<2>()), + ar,version); + super::load_(ar,version,lm); + } + + void rearranger(node_type* position,node_type *x) + { + if(!position||comp_(key(position->value()),key(x->value()))){ + position=lower_bound(key(x->value())).get_node(); + } + else if(comp_(key(x->value()),key(position->value()))){ + /* inconsistent rearrangement */ + throw_exception( + archive::archive_exception( + archive::archive_exception::other_exception)); + } + else node_type::increment(position); + + if(position!=x){ + node_impl_type::rebalance_for_erase( + x->impl(),header()->parent(),header()->left(),header()->right()); + node_impl_type::restore( + x->impl(),position->impl(),header()->impl()); + } + } +#endif /* serialization */ + +protected: /* for the benefit of AugmentPolicy::augmented_interface */ + key_from_value key; + key_compare comp_; + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ + BOOST_WORKAROUND(__MWERKS__,<=0x3003) +#pragma parse_mfunc_templ reset +#endif +}; + +template< + typename KeyFromValue,typename Compare, + typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy +> +class ordered_index: + public AugmentPolicy::template augmented_interface< + ordered_index_impl< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy + > + >::type +{ + typedef typename AugmentPolicy::template + augmented_interface< + ordered_index_impl< + KeyFromValue,Compare, + SuperMeta,TagList,Category,AugmentPolicy + > + >::type super; +public: + typedef typename super::ctor_args_list ctor_args_list; + typedef typename super::allocator_type allocator_type; + typedef typename super::iterator iterator; + + /* construct/copy/destroy + * Default and copy ctors are in the protected section as indices are + * not supposed to be created on their own. No range ctor either. + */ + + ordered_index& operator=(const ordered_index& x) + { + this->final()=x.final(); + return *this; + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + ordered_index& operator=( + std::initializer_list list) + { + this->final()=list; + return *this; + } +#endif + +protected: + ordered_index( + const ctor_args_list& args_list,const allocator_type& al): + super(args_list,al){} + + ordered_index(const ordered_index& x):super(x){}; + + ordered_index(const ordered_index& x,do_not_copy_elements_tag): + super(x,do_not_copy_elements_tag()){}; +}; + +/* comparison */ + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator==( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) +{ + return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); +} + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator<( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) +{ + return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); +} + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator!=( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) +{ + return !(x==y); +} + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator>( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) +{ + return y +bool operator>=( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) +{ + return !(x +bool operator<=( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) +{ + return !(x>y); +} + +/* specialized algorithms */ + +template< + typename KeyFromValue,typename Compare, + typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy +> +void swap( + ordered_index< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x, + ordered_index< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& y) +{ + x.swap(y); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +/* Boost.Foreach compatibility */ + +template< + typename KeyFromValue,typename Compare, + typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy +> +inline boost::mpl::true_* boost_foreach_is_noncopyable( + boost::multi_index::detail::ordered_index< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>*&, + boost_foreach_argument_dependent_lookup_hack) +{ + return 0; +} + +#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT +#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl_fwd.hpp new file mode 100644 index 00000000000..6590ef05fdd --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl_fwd.hpp @@ -0,0 +1,128 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_FWD_HPP +#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_FWD_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template< + typename KeyFromValue,typename Compare, + typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy +> +class ordered_index; + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator==( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator<( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator!=( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator>( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator>=( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); + +template< + typename KeyFromValue1,typename Compare1, + typename SuperMeta1,typename TagList1,typename Category1, + typename AugmentPolicy1, + typename KeyFromValue2,typename Compare2, + typename SuperMeta2,typename TagList2,typename Category2, + typename AugmentPolicy2 +> +bool operator<=( + const ordered_index< + KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, + const ordered_index< + KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); + +template< + typename KeyFromValue,typename Compare, + typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy +> +void swap( + ordered_index< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x, + ordered_index< + KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& y); + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_node.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_node.hpp new file mode 100644 index 00000000000..e7af0377fb9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_node.hpp @@ -0,0 +1,658 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + * + * The internal implementation of red-black trees is based on that of SGI STL + * stl_tree.h file: + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_NODE_HPP +#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_NODE_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include + +#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES) +#include +#include +#include +#include +#include +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* definition of red-black nodes for ordered_index */ + +enum ordered_index_color{red=false,black=true}; +enum ordered_index_side{to_left=false,to_right=true}; + +template +struct ordered_index_node_impl; /* fwd decl. */ + +template +struct ordered_index_node_std_base +{ + typedef typename + boost::detail::allocator::rebind_to< + Allocator, + ordered_index_node_impl + >::type::pointer pointer; + typedef typename + boost::detail::allocator::rebind_to< + Allocator, + ordered_index_node_impl + >::type::const_pointer const_pointer; + typedef ordered_index_color& color_ref; + typedef pointer& parent_ref; + + ordered_index_color& color(){return color_;} + ordered_index_color color()const{return color_;} + pointer& parent(){return parent_;} + pointer parent()const{return parent_;} + pointer& left(){return left_;} + pointer left()const{return left_;} + pointer& right(){return right_;} + pointer right()const{return right_;} + +private: + ordered_index_color color_; + pointer parent_; + pointer left_; + pointer right_; +}; + +#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES) +/* If ordered_index_node_impl has even alignment, we can use the least + * significant bit of one of the ordered_index_node_impl pointers to + * store color information. This typically reduces the size of + * ordered_index_node_impl by 25%. + */ + +#if defined(BOOST_MSVC) +/* This code casts pointers to an integer type that has been computed + * to be large enough to hold the pointer, however the metaprogramming + * logic is not always spotted by the VC++ code analyser that issues a + * long list of warnings. + */ + +#pragma warning(push) +#pragma warning(disable:4312 4311) +#endif + +template +struct ordered_index_node_compressed_base +{ + typedef ordered_index_node_impl< + AugmentPolicy,Allocator>* pointer; + typedef const ordered_index_node_impl< + AugmentPolicy,Allocator>* const_pointer; + + struct color_ref + { + color_ref(uintptr_type* r_):r(r_){} + + operator ordered_index_color()const + { + return ordered_index_color(*r&uintptr_type(1)); + } + + color_ref& operator=(ordered_index_color c) + { + *r&=~uintptr_type(1); + *r|=uintptr_type(c); + return *this; + } + + color_ref& operator=(const color_ref& x) + { + return operator=(x.operator ordered_index_color()); + } + + private: + uintptr_type* r; + }; + + struct parent_ref + { + parent_ref(uintptr_type* r_):r(r_){} + + operator pointer()const + { + return (pointer)(void*)(*r&~uintptr_type(1)); + } + + parent_ref& operator=(pointer p) + { + *r=((uintptr_type)(void*)p)|(*r&uintptr_type(1)); + return *this; + } + + parent_ref& operator=(const parent_ref& x) + { + return operator=(x.operator pointer()); + } + + pointer operator->()const + { + return operator pointer(); + } + + private: + uintptr_type* r; + }; + + color_ref color(){return color_ref(&parentcolor_);} + ordered_index_color color()const + { + return ordered_index_color(parentcolor_&uintptr_type(1)); + } + + parent_ref parent(){return parent_ref(&parentcolor_);} + pointer parent()const + { + return (pointer)(void*)(parentcolor_&~uintptr_type(1)); + } + + pointer& left(){return left_;} + pointer left()const{return left_;} + pointer& right(){return right_;} + pointer right()const{return right_;} + +private: + uintptr_type parentcolor_; + pointer left_; + pointer right_; +}; +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif +#endif + +template +struct ordered_index_node_impl_base: + +#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES) + AugmentPolicy::template augmented_node< + typename mpl::if_c< + !(has_uintptr_type::value)|| + (alignment_of< + ordered_index_node_compressed_base + >::value%2)|| + !(is_same< + typename boost::detail::allocator::rebind_to< + Allocator, + ordered_index_node_impl + >::type::pointer, + ordered_index_node_impl*>::value), + ordered_index_node_std_base, + ordered_index_node_compressed_base + >::type + >::type +#else + AugmentPolicy::template augmented_node< + ordered_index_node_std_base + >::type +#endif + +{}; + +template +struct ordered_index_node_impl: + ordered_index_node_impl_base +{ +private: + typedef ordered_index_node_impl_base super; + +public: + typedef typename super::color_ref color_ref; + typedef typename super::parent_ref parent_ref; + typedef typename super::pointer pointer; + typedef typename super::const_pointer const_pointer; + + /* interoperability with bidir_node_iterator */ + + static void increment(pointer& x) + { + if(x->right()!=pointer(0)){ + x=x->right(); + while(x->left()!=pointer(0))x=x->left(); + } + else{ + pointer y=x->parent(); + while(x==y->right()){ + x=y; + y=y->parent(); + } + if(x->right()!=y)x=y; + } + } + + static void decrement(pointer& x) + { + if(x->color()==red&&x->parent()->parent()==x){ + x=x->right(); + } + else if(x->left()!=pointer(0)){ + pointer y=x->left(); + while(y->right()!=pointer(0))y=y->right(); + x=y; + }else{ + pointer y=x->parent(); + while(x==y->left()){ + x=y; + y=y->parent(); + } + x=y; + } + } + + /* algorithmic stuff */ + + static void rotate_left(pointer x,parent_ref root) + { + pointer y=x->right(); + x->right()=y->left(); + if(y->left()!=pointer(0))y->left()->parent()=x; + y->parent()=x->parent(); + + if(x==root) root=y; + else if(x==x->parent()->left())x->parent()->left()=y; + else x->parent()->right()=y; + y->left()=x; + x->parent()=y; + AugmentPolicy::rotate_left(x,y); + } + + static pointer minimum(pointer x) + { + while(x->left()!=pointer(0))x=x->left(); + return x; + } + + static pointer maximum(pointer x) + { + while(x->right()!=pointer(0))x=x->right(); + return x; + } + + static void rotate_right(pointer x,parent_ref root) + { + pointer y=x->left(); + x->left()=y->right(); + if(y->right()!=pointer(0))y->right()->parent()=x; + y->parent()=x->parent(); + + if(x==root) root=y; + else if(x==x->parent()->right())x->parent()->right()=y; + else x->parent()->left()=y; + y->right()=x; + x->parent()=y; + AugmentPolicy::rotate_right(x,y); + } + + static void rebalance(pointer x,parent_ref root) + { + x->color()=red; + while(x!=root&&x->parent()->color()==red){ + if(x->parent()==x->parent()->parent()->left()){ + pointer y=x->parent()->parent()->right(); + if(y!=pointer(0)&&y->color()==red){ + x->parent()->color()=black; + y->color()=black; + x->parent()->parent()->color()=red; + x=x->parent()->parent(); + } + else{ + if(x==x->parent()->right()){ + x=x->parent(); + rotate_left(x,root); + } + x->parent()->color()=black; + x->parent()->parent()->color()=red; + rotate_right(x->parent()->parent(),root); + } + } + else{ + pointer y=x->parent()->parent()->left(); + if(y!=pointer(0)&&y->color()==red){ + x->parent()->color()=black; + y->color()=black; + x->parent()->parent()->color()=red; + x=x->parent()->parent(); + } + else{ + if(x==x->parent()->left()){ + x=x->parent(); + rotate_right(x,root); + } + x->parent()->color()=black; + x->parent()->parent()->color()=red; + rotate_left(x->parent()->parent(),root); + } + } + } + root->color()=black; + } + + static void link( + pointer x,ordered_index_side side,pointer position,pointer header) + { + if(side==to_left){ + position->left()=x; /* also makes leftmost=x when parent==header */ + if(position==header){ + header->parent()=x; + header->right()=x; + } + else if(position==header->left()){ + header->left()=x; /* maintain leftmost pointing to min node */ + } + } + else{ + position->right()=x; + if(position==header->right()){ + header->right()=x; /* maintain rightmost pointing to max node */ + } + } + x->parent()=position; + x->left()=pointer(0); + x->right()=pointer(0); + AugmentPolicy::add(x,pointer(header->parent())); + ordered_index_node_impl::rebalance(x,header->parent()); + } + + static pointer rebalance_for_erase( + pointer z,parent_ref root,pointer& leftmost,pointer& rightmost) + { + pointer y=z; + pointer x=pointer(0); + pointer x_parent=pointer(0); + if(y->left()==pointer(0)){ /* z has at most one non-null child. y==z. */ + x=y->right(); /* x might be null */ + } + else{ + if(y->right()==pointer(0)){ /* z has exactly one non-null child. y==z. */ + x=y->left(); /* x is not null */ + } + else{ /* z has two non-null children. Set y to */ + y=y->right(); /* z's successor. x might be null. */ + while(y->left()!=pointer(0))y=y->left(); + x=y->right(); + } + } + AugmentPolicy::remove(y,pointer(root)); + if(y!=z){ + AugmentPolicy::copy(z,y); + z->left()->parent()=y; /* relink y in place of z. y is z's successor */ + y->left()=z->left(); + if(y!=z->right()){ + x_parent=y->parent(); + if(x!=pointer(0))x->parent()=y->parent(); + y->parent()->left()=x; /* y must be a child of left */ + y->right()=z->right(); + z->right()->parent()=y; + } + else{ + x_parent=y; + } + + if(root==z) root=y; + else if(z->parent()->left()==z)z->parent()->left()=y; + else z->parent()->right()=y; + y->parent()=z->parent(); + ordered_index_color c=y->color(); + y->color()=z->color(); + z->color()=c; + y=z; /* y now points to node to be actually deleted */ + } + else{ /* y==z */ + x_parent=y->parent(); + if(x!=pointer(0))x->parent()=y->parent(); + if(root==z){ + root=x; + } + else{ + if(z->parent()->left()==z)z->parent()->left()=x; + else z->parent()->right()=x; + } + if(leftmost==z){ + if(z->right()==pointer(0)){ /* z->left() must be null also */ + leftmost=z->parent(); + } + else{ + leftmost=minimum(x); /* makes leftmost==header if z==root */ + } + } + if(rightmost==z){ + if(z->left()==pointer(0)){ /* z->right() must be null also */ + rightmost=z->parent(); + } + else{ /* x==z->left() */ + rightmost=maximum(x); /* makes rightmost==header if z==root */ + } + } + } + if(y->color()!=red){ + while(x!=root&&(x==pointer(0)|| x->color()==black)){ + if(x==x_parent->left()){ + pointer w=x_parent->right(); + if(w->color()==red){ + w->color()=black; + x_parent->color()=red; + rotate_left(x_parent,root); + w=x_parent->right(); + } + if((w->left()==pointer(0)||w->left()->color()==black) && + (w->right()==pointer(0)||w->right()->color()==black)){ + w->color()=red; + x=x_parent; + x_parent=x_parent->parent(); + } + else{ + if(w->right()==pointer(0 ) + || w->right()->color()==black){ + if(w->left()!=pointer(0)) w->left()->color()=black; + w->color()=red; + rotate_right(w,root); + w=x_parent->right(); + } + w->color()=x_parent->color(); + x_parent->color()=black; + if(w->right()!=pointer(0))w->right()->color()=black; + rotate_left(x_parent,root); + break; + } + } + else{ /* same as above,with right <-> left */ + pointer w=x_parent->left(); + if(w->color()==red){ + w->color()=black; + x_parent->color()=red; + rotate_right(x_parent,root); + w=x_parent->left(); + } + if((w->right()==pointer(0)||w->right()->color()==black) && + (w->left()==pointer(0)||w->left()->color()==black)){ + w->color()=red; + x=x_parent; + x_parent=x_parent->parent(); + } + else{ + if(w->left()==pointer(0)||w->left()->color()==black){ + if(w->right()!=pointer(0))w->right()->color()=black; + w->color()=red; + rotate_left(w,root); + w=x_parent->left(); + } + w->color()=x_parent->color(); + x_parent->color()=black; + if(w->left()!=pointer(0))w->left()->color()=black; + rotate_right(x_parent,root); + break; + } + } + } + if(x!=pointer(0))x->color()=black; + } + return y; + } + + static void restore(pointer x,pointer position,pointer header) + { + if(position->left()==pointer(0)||position->left()==header){ + link(x,to_left,position,header); + } + else{ + decrement(position); + link(x,to_right,position,header); + } + } + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + /* invariant stuff */ + + static std::size_t black_count(pointer node,pointer root) + { + if(node==pointer(0))return 0; + std::size_t sum=0; + for(;;){ + if(node->color()==black)++sum; + if(node==root)break; + node=node->parent(); + } + return sum; + } +#endif +}; + +template +struct ordered_index_node_trampoline: + ordered_index_node_impl< + AugmentPolicy, + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > +{ + typedef ordered_index_node_impl< + AugmentPolicy, + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > impl_type; +}; + +template +struct ordered_index_node: + Super,ordered_index_node_trampoline +{ +private: + typedef ordered_index_node_trampoline trampoline; + +public: + typedef typename trampoline::impl_type impl_type; + typedef typename trampoline::color_ref impl_color_ref; + typedef typename trampoline::parent_ref impl_parent_ref; + typedef typename trampoline::pointer impl_pointer; + typedef typename trampoline::const_pointer const_impl_pointer; + + impl_color_ref color(){return trampoline::color();} + ordered_index_color color()const{return trampoline::color();} + impl_parent_ref parent(){return trampoline::parent();} + impl_pointer parent()const{return trampoline::parent();} + impl_pointer& left(){return trampoline::left();} + impl_pointer left()const{return trampoline::left();} + impl_pointer& right(){return trampoline::right();} + impl_pointer right()const{return trampoline::right();} + + impl_pointer impl() + { + return static_cast( + static_cast(static_cast(this))); + } + + const_impl_pointer impl()const + { + return static_cast( + static_cast(static_cast(this))); + } + + static ordered_index_node* from_impl(impl_pointer x) + { + return + static_cast( + static_cast( + raw_ptr(x))); + } + + static const ordered_index_node* from_impl(const_impl_pointer x) + { + return + static_cast( + static_cast( + raw_ptr(x))); + } + + /* interoperability with bidir_node_iterator */ + + static void increment(ordered_index_node*& x) + { + impl_pointer xi=x->impl(); + trampoline::increment(xi); + x=from_impl(xi); + } + + static void decrement(ordered_index_node*& x) + { + impl_pointer xi=x->impl(); + trampoline::decrement(xi); + x=from_impl(xi); + } +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_ops.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_ops.hpp new file mode 100644 index 00000000000..84d5cacae19 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_ops.hpp @@ -0,0 +1,266 @@ +/* Copyright 2003-2014 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + * + * The internal implementation of red-black trees is based on that of SGI STL + * stl_tree.h file: + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_OPS_HPP +#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_OPS_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Common code for index memfuns having templatized and + * non-templatized versions. + * Implementation note: When CompatibleKey is consistently promoted to + * KeyFromValue::result_type for comparison, the promotion is made once in + * advance to increase efficiency. + */ + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline Node* ordered_index_find( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp) +{ + typedef typename KeyFromValue::result_type key_type; + + return ordered_index_find( + top,y,key,x,comp, + mpl::and_< + promotes_1st_arg, + promotes_2nd_arg >()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleCompare +> +inline Node* ordered_index_find( + Node* top,Node* y,const KeyFromValue& key, + const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, + const CompatibleCompare& comp,mpl::true_) +{ + return ordered_index_find(top,y,key,x,comp,mpl::false_()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline Node* ordered_index_find( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp,mpl::false_) +{ + Node* y0=y; + + while (top){ + if(!comp(key(top->value()),x)){ + y=top; + top=Node::from_impl(top->left()); + } + else top=Node::from_impl(top->right()); + } + + return (y==y0||comp(x,key(y->value())))?y0:y; +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline Node* ordered_index_lower_bound( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp) +{ + typedef typename KeyFromValue::result_type key_type; + + return ordered_index_lower_bound( + top,y,key,x,comp, + promotes_2nd_arg()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleCompare +> +inline Node* ordered_index_lower_bound( + Node* top,Node* y,const KeyFromValue& key, + const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, + const CompatibleCompare& comp,mpl::true_) +{ + return ordered_index_lower_bound(top,y,key,x,comp,mpl::false_()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline Node* ordered_index_lower_bound( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp,mpl::false_) +{ + while(top){ + if(!comp(key(top->value()),x)){ + y=top; + top=Node::from_impl(top->left()); + } + else top=Node::from_impl(top->right()); + } + + return y; +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline Node* ordered_index_upper_bound( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp) +{ + typedef typename KeyFromValue::result_type key_type; + + return ordered_index_upper_bound( + top,y,key,x,comp, + promotes_1st_arg()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleCompare +> +inline Node* ordered_index_upper_bound( + Node* top,Node* y,const KeyFromValue& key, + const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, + const CompatibleCompare& comp,mpl::true_) +{ + return ordered_index_upper_bound(top,y,key,x,comp,mpl::false_()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline Node* ordered_index_upper_bound( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp,mpl::false_) +{ + while(top){ + if(comp(x,key(top->value()))){ + y=top; + top=Node::from_impl(top->left()); + } + else top=Node::from_impl(top->right()); + } + + return y; +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::pair ordered_index_equal_range( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp) +{ + typedef typename KeyFromValue::result_type key_type; + + return ordered_index_equal_range( + top,y,key,x,comp, + mpl::and_< + promotes_1st_arg, + promotes_2nd_arg >()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleCompare +> +inline std::pair ordered_index_equal_range( + Node* top,Node* y,const KeyFromValue& key, + const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, + const CompatibleCompare& comp,mpl::true_) +{ + return ordered_index_equal_range(top,y,key,x,comp,mpl::false_()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::pair ordered_index_equal_range( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp,mpl::false_) +{ + while(top){ + if(comp(key(top->value()),x)){ + top=Node::from_impl(top->right()); + } + else if(comp(x,key(top->value()))){ + y=top; + top=Node::from_impl(top->left()); + } + else{ + return std::pair( + ordered_index_lower_bound( + Node::from_impl(top->left()),top,key,x,comp,mpl::false_()), + ordered_index_upper_bound( + Node::from_impl(top->right()),y,key,x,comp,mpl::false_())); + } + } + + return std::pair(y,y); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/promotes_arg.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/promotes_arg.hpp new file mode 100644 index 00000000000..7a11b6e9fbe --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/promotes_arg.hpp @@ -0,0 +1,83 @@ +/* Copyright 2003-2017 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_PROMOTES_ARG_HPP +#define BOOST_MULTI_INDEX_DETAIL_PROMOTES_ARG_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +/* Metafunctions to check if f(arg1,arg2) promotes either arg1 to the type of + * arg2 or viceversa. By default, (i.e. if it cannot be determined), no + * promotion is assumed. + */ + +#if BOOST_WORKAROUND(BOOST_MSVC,<1400) + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +struct promotes_1st_arg:mpl::false_{}; + +template +struct promotes_2nd_arg:mpl::false_{}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#else + +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +struct promotes_1st_arg: + mpl::and_< + mpl::not_ >, + is_convertible, + is_transparent + > +{}; + +template +struct promotes_2nd_arg: + mpl::and_< + mpl::not_ >, + is_convertible, + is_transparent + > +{}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/raw_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/raw_ptr.hpp new file mode 100644 index 00000000000..c32007435c0 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/raw_ptr.hpp @@ -0,0 +1,52 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_RAW_PTR_HPP +#define BOOST_MULTI_INDEX_DETAIL_RAW_PTR_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* gets the underlying pointer of a pointer-like value */ + +template +inline RawPointer raw_ptr(RawPointer const& p,mpl::true_) +{ + return p; +} + +template +inline RawPointer raw_ptr(Pointer const& p,mpl::false_) +{ + return p==Pointer(0)?0:&*p; +} + +template +inline RawPointer raw_ptr(Pointer const& p) +{ + return raw_ptr(p,is_same()); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/restore_wstrict_aliasing.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/restore_wstrict_aliasing.hpp new file mode 100644 index 00000000000..ee2c799d5a8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/restore_wstrict_aliasing.hpp @@ -0,0 +1,11 @@ +/* Copyright 2003-2016 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#define BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING +#include +#undef BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_loader.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_loader.hpp new file mode 100644 index 00000000000..4b00345a6d9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_loader.hpp @@ -0,0 +1,173 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_LOADER_HPP +#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_LOADER_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* This class implements a serialization rearranger for random access + * indices. In order to achieve O(n) performance, the following strategy + * is followed: the nodes of the index are handled as if in a bidirectional + * list, where the next pointers are stored in the original + * random_access_index_ptr_array and the prev pointers are stored in + * an auxiliary array. Rearranging of nodes in such a bidirectional list + * is constant time. Once all the arrangements are performed (on destruction + * time) the list is traversed in reverse order and + * pointers are swapped and set accordingly so that they recover its + * original semantics ( *(node->up())==node ) while retaining the + * new order. + */ + +template +class random_access_index_loader_base:private noncopyable +{ +protected: + typedef random_access_index_node_impl< + typename boost::detail::allocator::rebind_to< + Allocator, + char + >::type + > node_impl_type; + typedef typename node_impl_type::pointer node_impl_pointer; + typedef random_access_index_ptr_array ptr_array; + + random_access_index_loader_base(const Allocator& al_,ptr_array& ptrs_): + al(al_), + ptrs(ptrs_), + header(*ptrs.end()), + prev_spc(al,0), + preprocessed(false) + {} + + ~random_access_index_loader_base() + { + if(preprocessed) + { + node_impl_pointer n=header; + next(n)=n; + + for(std::size_t i=ptrs.size();i--;){ + n=prev(n); + std::size_t d=position(n); + if(d!=i){ + node_impl_pointer m=prev(next_at(i)); + std::swap(m->up(),n->up()); + next_at(d)=next_at(i); + std::swap(prev_at(d),prev_at(i)); + } + next(n)=n; + } + } + } + + void rearrange(node_impl_pointer position_,node_impl_pointer x) + { + preprocess(); /* only incur this penalty if rearrange() is ever called */ + if(position_==node_impl_pointer(0))position_=header; + next(prev(x))=next(x); + prev(next(x))=prev(x); + prev(x)=position_; + next(x)=next(position_); + next(prev(x))=prev(next(x))=x; + } + +private: + void preprocess() + { + if(!preprocessed){ + /* get space for the auxiliary prev array */ + auto_space tmp(al,ptrs.size()+1); + prev_spc.swap(tmp); + + /* prev_spc elements point to the prev nodes */ + std::rotate_copy( + &*ptrs.begin(),&*ptrs.end(),&*ptrs.end()+1,&*prev_spc.data()); + + /* ptrs elements point to the next nodes */ + std::rotate(&*ptrs.begin(),&*ptrs.begin()+1,&*ptrs.end()+1); + + preprocessed=true; + } + } + + std::size_t position(node_impl_pointer x)const + { + return (std::size_t)(x->up()-ptrs.begin()); + } + + node_impl_pointer& next_at(std::size_t n)const + { + return *ptrs.at(n); + } + + node_impl_pointer& prev_at(std::size_t n)const + { + return *(prev_spc.data()+n); + } + + node_impl_pointer& next(node_impl_pointer x)const + { + return *(x->up()); + } + + node_impl_pointer& prev(node_impl_pointer x)const + { + return prev_at(position(x)); + } + + Allocator al; + ptr_array& ptrs; + node_impl_pointer header; + auto_space prev_spc; + bool preprocessed; +}; + +template +class random_access_index_loader: + private random_access_index_loader_base +{ + typedef random_access_index_loader_base super; + typedef typename super::node_impl_pointer node_impl_pointer; + typedef typename super::ptr_array ptr_array; + +public: + random_access_index_loader(const Allocator& al_,ptr_array& ptrs_): + super(al_,ptrs_) + {} + + void rearrange(Node* position_,Node *x) + { + super::rearrange( + position_?position_->impl():node_impl_pointer(0),x->impl()); + } +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_node.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_node.hpp new file mode 100644 index 00000000000..ad61ea25dda --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_node.hpp @@ -0,0 +1,273 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_NODE_HPP +#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_NODE_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +struct random_access_index_node_impl +{ + typedef typename + boost::detail::allocator::rebind_to< + Allocator,random_access_index_node_impl + >::type::pointer pointer; + typedef typename + boost::detail::allocator::rebind_to< + Allocator,random_access_index_node_impl + >::type::const_pointer const_pointer; + typedef typename + boost::detail::allocator::rebind_to< + Allocator,pointer + >::type::pointer ptr_pointer; + + ptr_pointer& up(){return up_;} + ptr_pointer up()const{return up_;} + + /* interoperability with rnd_node_iterator */ + + static void increment(pointer& x) + { + x=*(x->up()+1); + } + + static void decrement(pointer& x) + { + x=*(x->up()-1); + } + + static void advance(pointer& x,std::ptrdiff_t n) + { + x=*(x->up()+n); + } + + static std::ptrdiff_t distance(pointer x,pointer y) + { + return y->up()-x->up(); + } + + /* algorithmic stuff */ + + static void relocate(ptr_pointer pos,ptr_pointer x) + { + pointer n=*x; + if(xup()=pos-1; + } + else{ + while(x!=pos){ + *x=*(x-1); + (*x)->up()=x; + --x; + } + *pos=n; + n->up()=pos; + } + }; + + static void relocate(ptr_pointer pos,ptr_pointer first,ptr_pointer last) + { + ptr_pointer begin,middle,end; + if(posup()=begin+j; + break; + } + else{ + *(begin+j)=*(begin+k); + (*(begin+j))->up()=begin+j; + } + + if(kup()=begin+k; + break; + } + else{ + *(begin+k)=*(begin+j); + (*(begin+k))->up()=begin+k; + } + } + } + }; + + static void extract(ptr_pointer x,ptr_pointer pend) + { + --pend; + while(x!=pend){ + *x=*(x+1); + (*x)->up()=x; + ++x; + } + } + + static void transfer( + ptr_pointer pbegin0,ptr_pointer pend0,ptr_pointer pbegin1) + { + while(pbegin0!=pend0){ + *pbegin1=*pbegin0++; + (*pbegin1)->up()=pbegin1; + ++pbegin1; + } + } + + static void reverse(ptr_pointer pbegin,ptr_pointer pend) + { + std::ptrdiff_t d=(pend-pbegin)/2; + for(std::ptrdiff_t i=0;iup()=pbegin; + (*pend)->up()=pend; + ++pbegin; + } + } + +private: + ptr_pointer up_; +}; + +template +struct random_access_index_node_trampoline: + random_access_index_node_impl< + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > +{ + typedef random_access_index_node_impl< + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > impl_type; +}; + +template +struct random_access_index_node: + Super,random_access_index_node_trampoline +{ +private: + typedef random_access_index_node_trampoline trampoline; + +public: + typedef typename trampoline::impl_type impl_type; + typedef typename trampoline::pointer impl_pointer; + typedef typename trampoline::const_pointer const_impl_pointer; + typedef typename trampoline::ptr_pointer impl_ptr_pointer; + + impl_ptr_pointer& up(){return trampoline::up();} + impl_ptr_pointer up()const{return trampoline::up();} + + impl_pointer impl() + { + return static_cast( + static_cast(static_cast(this))); + } + + const_impl_pointer impl()const + { + return static_cast( + static_cast(static_cast(this))); + } + + static random_access_index_node* from_impl(impl_pointer x) + { + return + static_cast( + static_cast( + raw_ptr(x))); + } + + static const random_access_index_node* from_impl(const_impl_pointer x) + { + return + static_cast( + static_cast( + raw_ptr(x))); + } + + /* interoperability with rnd_node_iterator */ + + static void increment(random_access_index_node*& x) + { + impl_pointer xi=x->impl(); + trampoline::increment(xi); + x=from_impl(xi); + } + + static void decrement(random_access_index_node*& x) + { + impl_pointer xi=x->impl(); + trampoline::decrement(xi); + x=from_impl(xi); + } + + static void advance(random_access_index_node*& x,std::ptrdiff_t n) + { + impl_pointer xi=x->impl(); + trampoline::advance(xi,n); + x=from_impl(xi); + } + + static std::ptrdiff_t distance( + random_access_index_node* x,random_access_index_node* y) + { + return trampoline::distance(x->impl(),y->impl()); + } +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ops.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ops.hpp new file mode 100644 index 00000000000..f5e76e4441f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ops.hpp @@ -0,0 +1,203 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_OPS_HPP +#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_OPS_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Common code for random_access_index memfuns having templatized and + * non-templatized versions. + */ + +template +Node* random_access_index_remove( + random_access_index_ptr_array& ptrs,Predicate pred) +{ + typedef typename Node::value_type value_type; + typedef typename Node::impl_ptr_pointer impl_ptr_pointer; + + impl_ptr_pointer first=ptrs.begin(), + res=first, + last=ptrs.end(); + for(;first!=last;++first){ + if(!pred( + const_cast(Node::from_impl(*first)->value()))){ + if(first!=res){ + std::swap(*first,*res); + (*first)->up()=first; + (*res)->up()=res; + } + ++res; + } + } + return Node::from_impl(*res); +} + +template +Node* random_access_index_unique( + random_access_index_ptr_array& ptrs,BinaryPredicate binary_pred) +{ + typedef typename Node::value_type value_type; + typedef typename Node::impl_ptr_pointer impl_ptr_pointer; + + impl_ptr_pointer first=ptrs.begin(), + res=first, + last=ptrs.end(); + if(first!=last){ + for(;++first!=last;){ + if(!binary_pred( + const_cast(Node::from_impl(*res)->value()), + const_cast(Node::from_impl(*first)->value()))){ + ++res; + if(first!=res){ + std::swap(*first,*res); + (*first)->up()=first; + (*res)->up()=res; + } + } + } + ++res; + } + return Node::from_impl(*res); +} + +template +void random_access_index_inplace_merge( + const Allocator& al, + random_access_index_ptr_array& ptrs, + BOOST_DEDUCED_TYPENAME Node::impl_ptr_pointer first1,Compare comp) +{ + typedef typename Node::value_type value_type; + typedef typename Node::impl_pointer impl_pointer; + typedef typename Node::impl_ptr_pointer impl_ptr_pointer; + + auto_space spc(al,ptrs.size()); + + impl_ptr_pointer first0=ptrs.begin(), + last0=first1, + last1=ptrs.end(), + out=spc.data(); + while(first0!=last0&&first1!=last1){ + if(comp( + const_cast(Node::from_impl(*first1)->value()), + const_cast(Node::from_impl(*first0)->value()))){ + *out++=*first1++; + } + else{ + *out++=*first0++; + } + } + std::copy(&*first0,&*last0,&*out); + std::copy(&*first1,&*last1,&*out); + + first1=ptrs.begin(); + out=spc.data(); + while(first1!=last1){ + *first1=*out++; + (*first1)->up()=first1; + ++first1; + } +} + +/* sorting */ + +/* auxiliary stuff */ + +template +struct random_access_index_sort_compare +{ + typedef typename Node::impl_pointer first_argument_type; + typedef typename Node::impl_pointer second_argument_type; + typedef bool result_type; + + random_access_index_sort_compare(Compare comp_=Compare()):comp(comp_){} + + bool operator()( + typename Node::impl_pointer x,typename Node::impl_pointer y)const + { + typedef typename Node::value_type value_type; + + return comp( + const_cast(Node::from_impl(x)->value()), + const_cast(Node::from_impl(y)->value())); + } + +private: + Compare comp; +}; + +template +void random_access_index_sort( + const Allocator& al, + random_access_index_ptr_array& ptrs, + Compare comp) +{ + /* The implementation is extremely simple: an auxiliary + * array of pointers is sorted using stdlib facilities and + * then used to rearrange the index. This is suboptimal + * in space and time, but has some advantages over other + * possible approaches: + * - Use std::stable_sort() directly on ptrs using some + * special iterator in charge of maintaining pointers + * and up() pointers in sync: we cannot guarantee + * preservation of the container invariants in the face of + * exceptions, if, for instance, std::stable_sort throws + * when ptrs transitorily contains duplicate elements. + * - Rewrite the internal algorithms of std::stable_sort + * adapted for this case: besides being a fair amount of + * work, making a stable sort compatible with Boost.MultiIndex + * invariants (basically, no duplicates or missing elements + * even if an exception is thrown) is complicated, error-prone + * and possibly won't perform much better than the + * solution adopted. + */ + + if(ptrs.size()<=1)return; + + typedef typename Node::impl_pointer impl_pointer; + typedef typename Node::impl_ptr_pointer impl_ptr_pointer; + typedef random_access_index_sort_compare< + Node,Compare> ptr_compare; + + impl_ptr_pointer first=ptrs.begin(); + impl_ptr_pointer last=ptrs.end(); + auto_space< + impl_pointer, + Allocator> spc(al,ptrs.size()); + impl_ptr_pointer buf=spc.data(); + + std::copy(&*first,&*last,&*buf); + std::stable_sort(&*buf,&*buf+ptrs.size(),ptr_compare(comp)); + + while(first!=last){ + *first=*buf++; + (*first)->up()=first; + ++first; + } +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ptr_array.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ptr_array.hpp new file mode 100644 index 00000000000..bae1c851b8e --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ptr_array.hpp @@ -0,0 +1,144 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_PTR_ARRAY_HPP +#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_PTR_ARRAY_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* pointer structure for use by random access indices */ + +template +class random_access_index_ptr_array:private noncopyable +{ + typedef random_access_index_node_impl< + typename boost::detail::allocator::rebind_to< + Allocator, + char + >::type + > node_impl_type; + +public: + typedef typename node_impl_type::pointer value_type; + typedef typename boost::detail::allocator::rebind_to< + Allocator,value_type + >::type::pointer pointer; + + random_access_index_ptr_array( + const Allocator& al,value_type end_,std::size_t sz): + size_(sz), + capacity_(sz), + spc(al,capacity_+1) + { + *end()=end_; + end_->up()=end(); + } + + std::size_t size()const{return size_;} + std::size_t capacity()const{return capacity_;} + + void room_for_one() + { + if(size_==capacity_){ + reserve(capacity_<=10?15:capacity_+capacity_/2); + } + } + + void reserve(std::size_t c) + { + if(c>capacity_)set_capacity(c); + } + + void shrink_to_fit() + { + if(capacity_>size_)set_capacity(size_); + } + + pointer begin()const{return ptrs();} + pointer end()const{return ptrs()+size_;} + pointer at(std::size_t n)const{return ptrs()+n;} + + void push_back(value_type x) + { + *(end()+1)=*end(); + (*(end()+1))->up()=end()+1; + *end()=x; + (*end())->up()=end(); + ++size_; + } + + void erase(value_type x) + { + node_impl_type::extract(x->up(),end()+1); + --size_; + } + + void clear() + { + *begin()=*end(); + (*begin())->up()=begin(); + size_=0; + } + + void swap(random_access_index_ptr_array& x) + { + std::swap(size_,x.size_); + std::swap(capacity_,x.capacity_); + spc.swap(x.spc); + } + +private: + std::size_t size_; + std::size_t capacity_; + auto_space spc; + + pointer ptrs()const + { + return spc.data(); + } + + void set_capacity(std::size_t c) + { + auto_space spc1(spc.get_allocator(),c+1); + node_impl_type::transfer(begin(),end()+1,spc1.data()); + spc.swap(spc1); + capacity_=c; + } +}; + +template +void swap( + random_access_index_ptr_array& x, + random_access_index_ptr_array& y) +{ + x.swap(y); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_node_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_node_iterator.hpp new file mode 100644 index 00000000000..48026132fb7 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_node_iterator.hpp @@ -0,0 +1,140 @@ +/* Copyright 2003-2014 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_RND_NODE_ITERATOR_HPP +#define BOOST_MULTI_INDEX_DETAIL_RND_NODE_ITERATOR_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Iterator class for node-based indices with random access iterators. */ + +template +class rnd_node_iterator: + public random_access_iterator_helper< + rnd_node_iterator, + typename Node::value_type, + std::ptrdiff_t, + const typename Node::value_type*, + const typename Node::value_type&> +{ +public: + /* coverity[uninit_ctor]: suppress warning */ + rnd_node_iterator(){} + explicit rnd_node_iterator(Node* node_):node(node_){} + + const typename Node::value_type& operator*()const + { + return node->value(); + } + + rnd_node_iterator& operator++() + { + Node::increment(node); + return *this; + } + + rnd_node_iterator& operator--() + { + Node::decrement(node); + return *this; + } + + rnd_node_iterator& operator+=(std::ptrdiff_t n) + { + Node::advance(node,n); + return *this; + } + + rnd_node_iterator& operator-=(std::ptrdiff_t n) + { + Node::advance(node,-n); + return *this; + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + /* Serialization. As for why the following is public, + * see explanation in safe_mode_iterator notes in safe_mode.hpp. + */ + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + typedef typename Node::base_type node_base_type; + + template + void save(Archive& ar,const unsigned int)const + { + node_base_type* bnode=node; + ar< + void load(Archive& ar,const unsigned int) + { + node_base_type* bnode; + ar>>serialization::make_nvp("pointer",bnode); + node=static_cast(bnode); + } +#endif + + /* get_node is not to be used by the user */ + + typedef Node node_type; + + Node* get_node()const{return node;} + +private: + Node* node; +}; + +template +bool operator==( + const rnd_node_iterator& x, + const rnd_node_iterator& y) +{ + return x.get_node()==y.get_node(); +} + +template +bool operator<( + const rnd_node_iterator& x, + const rnd_node_iterator& y) +{ + return Node::distance(x.get_node(),y.get_node())>0; +} + +template +std::ptrdiff_t operator-( + const rnd_node_iterator& x, + const rnd_node_iterator& y) +{ + return Node::distance(y.get_node(),x.get_node()); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnk_index_ops.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnk_index_ops.hpp new file mode 100644 index 00000000000..fb233cf4973 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnk_index_ops.hpp @@ -0,0 +1,300 @@ +/* Copyright 2003-2017 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_RNK_INDEX_OPS_HPP +#define BOOST_MULTI_INDEX_DETAIL_RNK_INDEX_OPS_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Common code for ranked_index memfuns having templatized and + * non-templatized versions. + */ + +template +inline std::size_t ranked_node_size(Pointer x) +{ + return x!=Pointer(0)?x->size:0; +} + +template +inline Pointer ranked_index_nth(std::size_t n,Pointer end_) +{ + Pointer top=end_->parent(); + if(top==Pointer(0)||n>=top->size)return end_; + + for(;;){ + std::size_t s=ranked_node_size(top->left()); + if(n==s)return top; + if(nleft(); + else{ + top=top->right(); + n-=s+1; + } + } +} + +template +inline std::size_t ranked_index_rank(Pointer x,Pointer end_) +{ + Pointer top=end_->parent(); + if(top==Pointer(0))return 0; + if(x==end_)return top->size; + + std::size_t s=ranked_node_size(x->left()); + while(x!=top){ + Pointer z=x->parent(); + if(x==z->right()){ + s+=ranked_node_size(z->left())+1; + } + x=z; + } + return s; +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::size_t ranked_index_find_rank( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp) +{ + typedef typename KeyFromValue::result_type key_type; + + return ranked_index_find_rank( + top,y,key,x,comp, + mpl::and_< + promotes_1st_arg, + promotes_2nd_arg >()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleCompare +> +inline std::size_t ranked_index_find_rank( + Node* top,Node* y,const KeyFromValue& key, + const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, + const CompatibleCompare& comp,mpl::true_) +{ + return ranked_index_find_rank(top,y,key,x,comp,mpl::false_()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::size_t ranked_index_find_rank( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp,mpl::false_) +{ + if(!top)return 0; + + std::size_t s=top->impl()->size, + s0=s; + Node* y0=y; + + do{ + if(!comp(key(top->value()),x)){ + y=top; + s-=ranked_node_size(y->right())+1; + top=Node::from_impl(top->left()); + } + else top=Node::from_impl(top->right()); + }while(top); + + return (y==y0||comp(x,key(y->value())))?s0:s; +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::size_t ranked_index_lower_bound_rank( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp) +{ + typedef typename KeyFromValue::result_type key_type; + + return ranked_index_lower_bound_rank( + top,y,key,x,comp, + promotes_2nd_arg()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleCompare +> +inline std::size_t ranked_index_lower_bound_rank( + Node* top,Node* y,const KeyFromValue& key, + const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, + const CompatibleCompare& comp,mpl::true_) +{ + return ranked_index_lower_bound_rank(top,y,key,x,comp,mpl::false_()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::size_t ranked_index_lower_bound_rank( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp,mpl::false_) +{ + if(!top)return 0; + + std::size_t s=top->impl()->size; + + do{ + if(!comp(key(top->value()),x)){ + y=top; + s-=ranked_node_size(y->right())+1; + top=Node::from_impl(top->left()); + } + else top=Node::from_impl(top->right()); + }while(top); + + return s; +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::size_t ranked_index_upper_bound_rank( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp) +{ + typedef typename KeyFromValue::result_type key_type; + + return ranked_index_upper_bound_rank( + top,y,key,x,comp, + promotes_1st_arg()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleCompare +> +inline std::size_t ranked_index_upper_bound_rank( + Node* top,Node* y,const KeyFromValue& key, + const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, + const CompatibleCompare& comp,mpl::true_) +{ + return ranked_index_upper_bound_rank(top,y,key,x,comp,mpl::false_()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::size_t ranked_index_upper_bound_rank( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp,mpl::false_) +{ + if(!top)return 0; + + std::size_t s=top->impl()->size; + + do{ + if(comp(x,key(top->value()))){ + y=top; + s-=ranked_node_size(y->right())+1; + top=Node::from_impl(top->left()); + } + else top=Node::from_impl(top->right()); + }while(top); + + return s; +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::pair ranked_index_equal_range_rank( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp) +{ + typedef typename KeyFromValue::result_type key_type; + + return ranked_index_equal_range_rank( + top,y,key,x,comp, + mpl::and_< + promotes_1st_arg, + promotes_2nd_arg >()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleCompare +> +inline std::pair ranked_index_equal_range_rank( + Node* top,Node* y,const KeyFromValue& key, + const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, + const CompatibleCompare& comp,mpl::true_) +{ + return ranked_index_equal_range_rank(top,y,key,x,comp,mpl::false_()); +} + +template< + typename Node,typename KeyFromValue, + typename CompatibleKey,typename CompatibleCompare +> +inline std::pair ranked_index_equal_range_rank( + Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, + const CompatibleCompare& comp,mpl::false_) +{ + if(!top)return std::pair(0,0); + + std::size_t s=top->impl()->size; + + do{ + if(comp(key(top->value()),x)){ + top=Node::from_impl(top->right()); + } + else if(comp(x,key(top->value()))){ + y=top; + s-=ranked_node_size(y->right())+1; + top=Node::from_impl(top->left()); + } + else{ + return std::pair( + s-top->impl()->size+ + ranked_index_lower_bound_rank( + Node::from_impl(top->left()),top,key,x,comp,mpl::false_()), + s-ranked_node_size(top->right())+ + ranked_index_upper_bound_rank( + Node::from_impl(top->right()),y,key,x,comp,mpl::false_())); + } + }while(top); + + return std::pair(s,s); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/safe_mode.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/safe_mode.hpp new file mode 100644 index 00000000000..905270e9fb3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/safe_mode.hpp @@ -0,0 +1,588 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_SAFE_MODE_HPP +#define BOOST_MULTI_INDEX_DETAIL_SAFE_MODE_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +/* Safe mode machinery, in the spirit of Cay Hortmann's "Safe STL" + * (http://www.horstmann.com/safestl.html). + * In this mode, containers of type Container are derived from + * safe_container, and their corresponding iterators + * are wrapped with safe_iterator. These classes provide + * an internal record of which iterators are at a given moment associated + * to a given container, and properly mark the iterators as invalid + * when the container gets destroyed. + * Iterators are chained in a single attached list, whose header is + * kept by the container. More elaborate data structures would yield better + * performance, but I decided to keep complexity to a minimum since + * speed is not an issue here. + * Safe mode iterators automatically check that only proper operations + * are performed on them: for instance, an invalid iterator cannot be + * dereferenced. Additionally, a set of utilty macros and functions are + * provided that serve to implement preconditions and cooperate with + * the framework within the container. + * Iterators can also be unchecked, i.e. they do not have info about + * which container they belong in. This situation arises when the iterator + * is restored from a serialization archive: only information on the node + * is available, and it is not possible to determine to which container + * the iterator is associated to. The only sensible policy is to assume + * unchecked iterators are valid, though this can certainly generate false + * positive safe mode checks. + * This is not a full-fledged safe mode framework, and is only intended + * for use within the limits of Boost.MultiIndex. + */ + +/* Assertion macros. These resolve to no-ops if + * !defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE). + */ + +#if !defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) +#undef BOOST_MULTI_INDEX_SAFE_MODE_ASSERT +#define BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(expr,error_code) ((void)0) +#else +#if !defined(BOOST_MULTI_INDEX_SAFE_MODE_ASSERT) +#include +#define BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(expr,error_code) BOOST_ASSERT(expr) +#endif +#endif + +#define BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_valid_iterator(it), \ + safe_mode::invalid_iterator); + +#define BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(it) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_dereferenceable_iterator(it), \ + safe_mode::not_dereferenceable_iterator); + +#define BOOST_MULTI_INDEX_CHECK_INCREMENTABLE_ITERATOR(it) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_incrementable_iterator(it), \ + safe_mode::not_incrementable_iterator); + +#define BOOST_MULTI_INDEX_CHECK_DECREMENTABLE_ITERATOR(it) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_decrementable_iterator(it), \ + safe_mode::not_decrementable_iterator); + +#define BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,cont) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_is_owner(it,cont), \ + safe_mode::not_owner); + +#define BOOST_MULTI_INDEX_CHECK_SAME_OWNER(it0,it1) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_same_owner(it0,it1), \ + safe_mode::not_same_owner); + +#define BOOST_MULTI_INDEX_CHECK_VALID_RANGE(it0,it1) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_valid_range(it0,it1), \ + safe_mode::invalid_range); + +#define BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(it,it0,it1) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_outside_range(it,it0,it1), \ + safe_mode::inside_range); + +#define BOOST_MULTI_INDEX_CHECK_IN_BOUNDS(it,n) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_in_bounds(it,n), \ + safe_mode::out_of_bounds); + +#define BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(cont0,cont1) \ + BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ + safe_mode::check_different_container(cont0,cont1), \ + safe_mode::same_container); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#endif + +#if defined(BOOST_HAS_THREADS) +#include +#endif + +namespace boost{ + +namespace multi_index{ + +namespace safe_mode{ + +/* Checking routines. Assume the best for unchecked iterators + * (i.e. they pass the checking when there is not enough info + * to know.) + */ + +template +inline bool check_valid_iterator(const Iterator& it) +{ + return it.valid()||it.unchecked(); +} + +template +inline bool check_dereferenceable_iterator(const Iterator& it) +{ + return (it.valid()&&it!=it.owner()->end())||it.unchecked(); +} + +template +inline bool check_incrementable_iterator(const Iterator& it) +{ + return (it.valid()&&it!=it.owner()->end())||it.unchecked(); +} + +template +inline bool check_decrementable_iterator(const Iterator& it) +{ + return (it.valid()&&it!=it.owner()->begin())||it.unchecked(); +} + +template +inline bool check_is_owner( + const Iterator& it,const typename Iterator::container_type& cont) +{ + return (it.valid()&&it.owner()==&cont)||it.unchecked(); +} + +template +inline bool check_same_owner(const Iterator& it0,const Iterator& it1) +{ + return (it0.valid()&&it1.valid()&&it0.owner()==it1.owner())|| + it0.unchecked()||it1.unchecked(); +} + +template +inline bool check_valid_range(const Iterator& it0,const Iterator& it1) +{ + if(!check_same_owner(it0,it1))return false; + + if(it0.valid()){ + Iterator last=it0.owner()->end(); + if(it1==last)return true; + + for(Iterator first=it0;first!=last;++first){ + if(first==it1)return true; + } + return false; + } + return true; +} + +template +inline bool check_outside_range( + const Iterator& it,const Iterator& it0,const Iterator& it1) +{ + if(!check_same_owner(it0,it1))return false; + + if(it0.valid()){ + Iterator last=it0.owner()->end(); + bool found=false; + + Iterator first=it0; + for(;first!=last;++first){ + if(first==it1)break; + + /* crucial that this check goes after previous break */ + + if(first==it)found=true; + } + if(first!=it1)return false; + return !found; + } + return true; +} + +template +inline bool check_in_bounds(const Iterator& it,Difference n) +{ + if(it.unchecked())return true; + if(!it.valid()) return false; + if(n>0) return it.owner()->end()-it>=n; + else return it.owner()->begin()-it<=n; +} + +template +inline bool check_different_container( + const Container& cont0,const Container& cont1) +{ + return &cont0!=&cont1; +} + +/* Invalidates all iterators equivalent to that given. Safe containers + * must call this when deleting elements: the safe mode framework cannot + * perform this operation automatically without outside help. + */ + +template +inline void detach_equivalent_iterators(Iterator& it) +{ + if(it.valid()){ + { +#if defined(BOOST_HAS_THREADS) + boost::detail::lightweight_mutex::scoped_lock lock(it.cont->mutex); +#endif + + Iterator *prev_,*next_; + for( + prev_=static_cast(&it.cont->header); + (next_=static_cast(prev_->next))!=0;){ + if(next_!=&it&&*next_==it){ + prev_->next=next_->next; + next_->cont=0; + } + else prev_=next_; + } + } + it.detach(); + } +} + +template class safe_container; /* fwd decl. */ + +} /* namespace multi_index::safe_mode */ + +namespace detail{ + +class safe_container_base; /* fwd decl. */ + +class safe_iterator_base +{ +public: + bool valid()const{return cont!=0;} + bool unchecked()const{return unchecked_;} + + inline void detach(); + + void uncheck() + { + detach(); + unchecked_=true; + } + +protected: + safe_iterator_base():cont(0),next(0),unchecked_(false){} + + explicit safe_iterator_base(safe_container_base* cont_): + unchecked_(false) + { + attach(cont_); + } + + safe_iterator_base(const safe_iterator_base& it): + unchecked_(it.unchecked_) + { + attach(it.cont); + } + + safe_iterator_base& operator=(const safe_iterator_base& it) + { + unchecked_=it.unchecked_; + safe_container_base* new_cont=it.cont; + if(cont!=new_cont){ + detach(); + attach(new_cont); + } + return *this; + } + + ~safe_iterator_base() + { + detach(); + } + + const safe_container_base* owner()const{return cont;} + +BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS: + friend class safe_container_base; + +#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + template friend class safe_mode::safe_container; + template friend + void safe_mode::detach_equivalent_iterators(Iterator&); +#endif + + inline void attach(safe_container_base* cont_); + + safe_container_base* cont; + safe_iterator_base* next; + bool unchecked_; +}; + +class safe_container_base:private noncopyable +{ +public: + safe_container_base(){} + +BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: + friend class safe_iterator_base; + +#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + template friend + void safe_mode::detach_equivalent_iterators(Iterator&); +#endif + + ~safe_container_base() + { + /* Detaches all remaining iterators, which by now will + * be those pointing to the end of the container. + */ + + for(safe_iterator_base* it=header.next;it;it=it->next)it->cont=0; + header.next=0; + } + + void swap(safe_container_base& x) + { + for(safe_iterator_base* it0=header.next;it0;it0=it0->next)it0->cont=&x; + for(safe_iterator_base* it1=x.header.next;it1;it1=it1->next)it1->cont=this; + std::swap(header.cont,x.header.cont); + std::swap(header.next,x.header.next); + } + + safe_iterator_base header; + +#if defined(BOOST_HAS_THREADS) + boost::detail::lightweight_mutex mutex; +#endif +}; + +void safe_iterator_base::attach(safe_container_base* cont_) +{ + cont=cont_; + if(cont){ +#if defined(BOOST_HAS_THREADS) + boost::detail::lightweight_mutex::scoped_lock lock(cont->mutex); +#endif + + next=cont->header.next; + cont->header.next=this; + } +} + +void safe_iterator_base::detach() +{ + if(cont){ +#if defined(BOOST_HAS_THREADS) + boost::detail::lightweight_mutex::scoped_lock lock(cont->mutex); +#endif + + safe_iterator_base *prev_,*next_; + for(prev_=&cont->header;(next_=prev_->next)!=this;prev_=next_){} + prev_->next=next; + cont=0; + } +} + +} /* namespace multi_index::detail */ + +namespace safe_mode{ + +/* In order to enable safe mode on a container: + * - The container must derive from safe_container, + * - iterators must be generated via safe_iterator, which adapts a + * preexistent unsafe iterator class. + */ + +template +class safe_container; + +template +class safe_iterator: + public detail::iter_adaptor,Iterator>, + public detail::safe_iterator_base +{ + typedef detail::iter_adaptor super; + typedef detail::safe_iterator_base safe_super; + +public: + typedef Container container_type; + typedef typename Iterator::reference reference; + typedef typename Iterator::difference_type difference_type; + + safe_iterator(){} + explicit safe_iterator(safe_container* cont_): + safe_super(cont_){} + template + safe_iterator(const T0& t0,safe_container* cont_): + super(Iterator(t0)),safe_super(cont_){} + template + safe_iterator( + const T0& t0,const T1& t1,safe_container* cont_): + super(Iterator(t0,t1)),safe_super(cont_){} + + safe_iterator& operator=(const safe_iterator& x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x); + this->base_reference()=x.base_reference(); + safe_super::operator=(x); + return *this; + } + + const container_type* owner()const + { + return + static_cast( + static_cast*>( + this->safe_super::owner())); + } + + /* get_node is not to be used by the user */ + + typedef typename Iterator::node_type node_type; + + node_type* get_node()const{return this->base_reference().get_node();} + +private: + friend class boost::multi_index::detail::iter_adaptor_access; + + reference dereference()const + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(*this); + return *(this->base_reference()); + } + + bool equal(const safe_iterator& x)const + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x); + BOOST_MULTI_INDEX_CHECK_SAME_OWNER(*this,x); + return this->base_reference()==x.base_reference(); + } + + void increment() + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); + BOOST_MULTI_INDEX_CHECK_INCREMENTABLE_ITERATOR(*this); + ++(this->base_reference()); + } + + void decrement() + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); + BOOST_MULTI_INDEX_CHECK_DECREMENTABLE_ITERATOR(*this); + --(this->base_reference()); + } + + void advance(difference_type n) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); + BOOST_MULTI_INDEX_CHECK_IN_BOUNDS(*this,n); + this->base_reference()+=n; + } + + difference_type distance_to(const safe_iterator& x)const + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x); + BOOST_MULTI_INDEX_CHECK_SAME_OWNER(*this,x); + return x.base_reference()-this->base_reference(); + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + /* Serialization. Note that Iterator::save and Iterator:load + * are assumed to be defined and public: at first sight it seems + * like we could have resorted to the public serialization interface + * for doing the forwarding to the adapted iterator class: + * ar<>base_reference(); + * but this would cause incompatibilities if a saving + * program is in safe mode and the loading program is not, or + * viceversa --in safe mode, the archived iterator data is one layer + * deeper, this is especially relevant with XML archives. + * It'd be nice if Boost.Serialization provided some forwarding + * facility for use by adaptor classes. + */ + + friend class boost::serialization::access; + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + template + void save(Archive& ar,const unsigned int version)const + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); + this->base_reference().save(ar,version); + } + + template + void load(Archive& ar,const unsigned int version) + { + this->base_reference().load(ar,version); + safe_super::uncheck(); + } +#endif +}; + +template +class safe_container:public detail::safe_container_base +{ + typedef detail::safe_container_base super; + +public: + void detach_dereferenceable_iterators() + { + typedef typename Container::iterator iterator; + + iterator end_=static_cast(this)->end(); + iterator *prev_,*next_; + for( + prev_=static_cast(&this->header); + (next_=static_cast(prev_->next))!=0;){ + if(*next_!=end_){ + prev_->next=next_->next; + next_->cont=0; + } + else prev_=next_; + } + } + + void swap(safe_container& x) + { + super::swap(x); + } +}; + +} /* namespace multi_index::safe_mode */ + +} /* namespace multi_index */ + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +namespace serialization{ +template +struct version< + boost::multi_index::safe_mode::safe_iterator +> +{ + BOOST_STATIC_CONSTANT( + int,value=boost::serialization::version::value); +}; +} /* namespace serialization */ +#endif + +} /* namespace boost */ + +#endif /* BOOST_MULTI_INDEX_ENABLE_SAFE_MODE */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/scope_guard.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/scope_guard.hpp new file mode 100644 index 00000000000..116f8f50415 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/scope_guard.hpp @@ -0,0 +1,453 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_SCOPE_GUARD_HPP +#define BOOST_MULTI_INDEX_DETAIL_SCOPE_GUARD_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Until some official version of the ScopeGuard idiom makes it into Boost, + * we locally define our own. This is a merely reformated version of + * ScopeGuard.h as defined in: + * Alexandrescu, A., Marginean, P.:"Generic: Change the Way You + * Write Exception-Safe Code - Forever", C/C++ Users Jornal, Dec 2000, + * http://www.drdobbs.com/184403758 + * with the following modifications: + * - General pretty formatting (pretty to my taste at least.) + * - Naming style changed to standard C++ library requirements. + * - Added scope_guard_impl4 and obj_scope_guard_impl3, (Boost.MultiIndex + * needs them). A better design would provide guards for many more + * arguments through the Boost Preprocessor Library. + * - Added scope_guard_impl_base::touch (see below.) + * - Removed RefHolder and ByRef, whose functionality is provided + * already by Boost.Ref. + * - Removed static make_guard's and make_obj_guard's, so that the code + * will work even if BOOST_NO_MEMBER_TEMPLATES is defined. This forces + * us to move some private ctors to public, though. + * + * NB: CodeWarrior Pro 8 seems to have problems looking up safe_execute + * without an explicit qualification. + * + * We also define the following variants of the idiom: + * + * - make_guard_if_c( ... ) + * - make_guard_if( ... ) + * - make_obj_guard_if_c( ... ) + * - make_obj_guard_if( ... ) + * which may be used with a compile-time constant to yield + * a "null_guard" if the boolean compile-time parameter is false, + * or conversely, the guard is only constructed if the constant is true. + * This is useful to avoid extra tagging, because the returned + * null_guard can be optimzed comlpetely away by the compiler. + */ + +class scope_guard_impl_base +{ +public: + scope_guard_impl_base():dismissed_(false){} + void dismiss()const{dismissed_=true;} + + /* This helps prevent some "unused variable" warnings under, for instance, + * GCC 3.2. + */ + void touch()const{} + +protected: + ~scope_guard_impl_base(){} + + scope_guard_impl_base(const scope_guard_impl_base& other): + dismissed_(other.dismissed_) + { + other.dismiss(); + } + + template + static void safe_execute(J& j){ + BOOST_TRY{ + if(!j.dismissed_)j.execute(); + } + BOOST_CATCH(...){} + BOOST_CATCH_END + } + + mutable bool dismissed_; + +private: + scope_guard_impl_base& operator=(const scope_guard_impl_base&); +}; + +typedef const scope_guard_impl_base& scope_guard; + +struct null_guard : public scope_guard_impl_base +{ + template< class T1 > + null_guard( const T1& ) + { } + + template< class T1, class T2 > + null_guard( const T1&, const T2& ) + { } + + template< class T1, class T2, class T3 > + null_guard( const T1&, const T2&, const T3& ) + { } + + template< class T1, class T2, class T3, class T4 > + null_guard( const T1&, const T2&, const T3&, const T4& ) + { } + + template< class T1, class T2, class T3, class T4, class T5 > + null_guard( const T1&, const T2&, const T3&, const T4&, const T5& ) + { } +}; + +template< bool cond, class T > +struct null_guard_return +{ + typedef typename boost::mpl::if_c::type type; +}; + +template +class scope_guard_impl0:public scope_guard_impl_base +{ +public: + scope_guard_impl0(F fun):fun_(fun){} + ~scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);} + void execute(){fun_();} + +protected: + + F fun_; +}; + +template +inline scope_guard_impl0 make_guard(F fun) +{ + return scope_guard_impl0(fun); +} + +template +inline typename null_guard_return >::type +make_guard_if_c(F fun) +{ + return typename null_guard_return >::type(fun); +} + +template +inline typename null_guard_return >::type +make_guard_if(F fun) +{ + return make_guard_if(fun); +} + +template +class scope_guard_impl1:public scope_guard_impl_base +{ +public: + scope_guard_impl1(F fun,P1 p1):fun_(fun),p1_(p1){} + ~scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);} + void execute(){fun_(p1_);} + +protected: + F fun_; + const P1 p1_; +}; + +template +inline scope_guard_impl1 make_guard(F fun,P1 p1) +{ + return scope_guard_impl1(fun,p1); +} + +template +inline typename null_guard_return >::type +make_guard_if_c(F fun,P1 p1) +{ + return typename null_guard_return >::type(fun,p1); +} + +template +inline typename null_guard_return >::type +make_guard_if(F fun,P1 p1) +{ + return make_guard_if_c(fun,p1); +} + +template +class scope_guard_impl2:public scope_guard_impl_base +{ +public: + scope_guard_impl2(F fun,P1 p1,P2 p2):fun_(fun),p1_(p1),p2_(p2){} + ~scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);} + void execute(){fun_(p1_,p2_);} + +protected: + F fun_; + const P1 p1_; + const P2 p2_; +}; + +template +inline scope_guard_impl2 make_guard(F fun,P1 p1,P2 p2) +{ + return scope_guard_impl2(fun,p1,p2); +} + +template +inline typename null_guard_return >::type +make_guard_if_c(F fun,P1 p1,P2 p2) +{ + return typename null_guard_return >::type(fun,p1,p2); +} + +template +inline typename null_guard_return >::type +make_guard_if(F fun,P1 p1,P2 p2) +{ + return make_guard_if_c(fun,p1,p2); +} + +template +class scope_guard_impl3:public scope_guard_impl_base +{ +public: + scope_guard_impl3(F fun,P1 p1,P2 p2,P3 p3):fun_(fun),p1_(p1),p2_(p2),p3_(p3){} + ~scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);} + void execute(){fun_(p1_,p2_,p3_);} + +protected: + F fun_; + const P1 p1_; + const P2 p2_; + const P3 p3_; +}; + +template +inline scope_guard_impl3 make_guard(F fun,P1 p1,P2 p2,P3 p3) +{ + return scope_guard_impl3(fun,p1,p2,p3); +} + +template +inline typename null_guard_return >::type +make_guard_if_c(F fun,P1 p1,P2 p2,P3 p3) +{ + return typename null_guard_return >::type(fun,p1,p2,p3); +} + +template +inline typename null_guard_return< C::value,scope_guard_impl3 >::type +make_guard_if(F fun,P1 p1,P2 p2,P3 p3) +{ + return make_guard_if_c(fun,p1,p2,p3); +} + +template +class scope_guard_impl4:public scope_guard_impl_base +{ +public: + scope_guard_impl4(F fun,P1 p1,P2 p2,P3 p3,P4 p4): + fun_(fun),p1_(p1),p2_(p2),p3_(p3),p4_(p4){} + ~scope_guard_impl4(){scope_guard_impl_base::safe_execute(*this);} + void execute(){fun_(p1_,p2_,p3_,p4_);} + +protected: + F fun_; + const P1 p1_; + const P2 p2_; + const P3 p3_; + const P4 p4_; +}; + +template +inline scope_guard_impl4 make_guard( + F fun,P1 p1,P2 p2,P3 p3,P4 p4) +{ + return scope_guard_impl4(fun,p1,p2,p3,p4); +} + +template +inline typename null_guard_return >::type +make_guard_if_c( + F fun,P1 p1,P2 p2,P3 p3,P4 p4) +{ + return typename null_guard_return >::type(fun,p1,p2,p3,p4); +} + +template +inline typename null_guard_return >::type +make_guard_if( + F fun,P1 p1,P2 p2,P3 p3,P4 p4) +{ + return make_guard_if_c(fun,p1,p2,p3,p4); +} + +template +class obj_scope_guard_impl0:public scope_guard_impl_base +{ +public: + obj_scope_guard_impl0(Obj& obj,MemFun mem_fun):obj_(obj),mem_fun_(mem_fun){} + ~obj_scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);} + void execute(){(obj_.*mem_fun_)();} + +protected: + Obj& obj_; + MemFun mem_fun_; +}; + +template +inline obj_scope_guard_impl0 make_obj_guard(Obj& obj,MemFun mem_fun) +{ + return obj_scope_guard_impl0(obj,mem_fun); +} + +template +inline typename null_guard_return >::type +make_obj_guard_if_c(Obj& obj,MemFun mem_fun) +{ + return typename null_guard_return >::type(obj,mem_fun); +} + +template +inline typename null_guard_return >::type +make_obj_guard_if(Obj& obj,MemFun mem_fun) +{ + return make_obj_guard_if_c(obj,mem_fun); +} + +template +class obj_scope_guard_impl1:public scope_guard_impl_base +{ +public: + obj_scope_guard_impl1(Obj& obj,MemFun mem_fun,P1 p1): + obj_(obj),mem_fun_(mem_fun),p1_(p1){} + ~obj_scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);} + void execute(){(obj_.*mem_fun_)(p1_);} + +protected: + Obj& obj_; + MemFun mem_fun_; + const P1 p1_; +}; + +template +inline obj_scope_guard_impl1 make_obj_guard( + Obj& obj,MemFun mem_fun,P1 p1) +{ + return obj_scope_guard_impl1(obj,mem_fun,p1); +} + +template +inline typename null_guard_return >::type +make_obj_guard_if_c( Obj& obj,MemFun mem_fun,P1 p1) +{ + return typename null_guard_return >::type(obj,mem_fun,p1); +} + +template +inline typename null_guard_return >::type +make_obj_guard_if( Obj& obj,MemFun mem_fun,P1 p1) +{ + return make_obj_guard_if_c(obj,mem_fun,p1); +} + +template +class obj_scope_guard_impl2:public scope_guard_impl_base +{ +public: + obj_scope_guard_impl2(Obj& obj,MemFun mem_fun,P1 p1,P2 p2): + obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2) + {} + ~obj_scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);} + void execute(){(obj_.*mem_fun_)(p1_,p2_);} + +protected: + Obj& obj_; + MemFun mem_fun_; + const P1 p1_; + const P2 p2_; +}; + +template +inline obj_scope_guard_impl2 +make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2) +{ + return obj_scope_guard_impl2(obj,mem_fun,p1,p2); +} + +template +inline typename null_guard_return >::type +make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2) +{ + return typename null_guard_return >::type(obj,mem_fun,p1,p2); +} + +template +inline typename null_guard_return >::type +make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2) +{ + return make_obj_guard_if_c(obj,mem_fun,p1,p2); +} + +template +class obj_scope_guard_impl3:public scope_guard_impl_base +{ +public: + obj_scope_guard_impl3(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3): + obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2),p3_(p3) + {} + ~obj_scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);} + void execute(){(obj_.*mem_fun_)(p1_,p2_,p3_);} + +protected: + Obj& obj_; + MemFun mem_fun_; + const P1 p1_; + const P2 p2_; + const P3 p3_; +}; + +template +inline obj_scope_guard_impl3 +make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3) +{ + return obj_scope_guard_impl3(obj,mem_fun,p1,p2,p3); +} + +template +inline typename null_guard_return >::type +make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3) +{ + return typename null_guard_return >::type(obj,mem_fun,p1,p2,p3); +} + +template +inline typename null_guard_return >::type +make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3) +{ + return make_obj_guard_if_c(obj,mem_fun,p1,p2,p3); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_node.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_node.hpp new file mode 100644 index 00000000000..85b345af938 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_node.hpp @@ -0,0 +1,217 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_NODE_HPP +#define BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_NODE_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* doubly-linked node for use by sequenced_index */ + +template +struct sequenced_index_node_impl +{ + typedef typename + boost::detail::allocator::rebind_to< + Allocator,sequenced_index_node_impl + >::type::pointer pointer; + typedef typename + boost::detail::allocator::rebind_to< + Allocator,sequenced_index_node_impl + >::type::const_pointer const_pointer; + + pointer& prior(){return prior_;} + pointer prior()const{return prior_;} + pointer& next(){return next_;} + pointer next()const{return next_;} + + /* interoperability with bidir_node_iterator */ + + static void increment(pointer& x){x=x->next();} + static void decrement(pointer& x){x=x->prior();} + + /* algorithmic stuff */ + + static void link(pointer x,pointer header) + { + x->prior()=header->prior(); + x->next()=header; + x->prior()->next()=x->next()->prior()=x; + }; + + static void unlink(pointer x) + { + x->prior()->next()=x->next(); + x->next()->prior()=x->prior(); + } + + static void relink(pointer position,pointer x) + { + unlink(x); + x->prior()=position->prior(); + x->next()=position; + x->prior()->next()=x->next()->prior()=x; + } + + static void relink(pointer position,pointer x,pointer y) + { + /* position is assumed not to be in [x,y) */ + + if(x!=y){ + pointer z=y->prior(); + x->prior()->next()=y; + y->prior()=x->prior(); + x->prior()=position->prior(); + z->next()=position; + x->prior()->next()=x; + z->next()->prior()=z; + } + } + + static void reverse(pointer header) + { + pointer x=header; + do{ + pointer y=x->next(); + std::swap(x->prior(),x->next()); + x=y; + }while(x!=header); + } + + static void swap(pointer x,pointer y) + { + /* This swap function does not exchange the header nodes, + * but rather their pointers. This is *not* used for implementing + * sequenced_index::swap. + */ + + if(x->next()!=x){ + if(y->next()!=y){ + std::swap(x->next(),y->next()); + std::swap(x->prior(),y->prior()); + x->next()->prior()=x->prior()->next()=x; + y->next()->prior()=y->prior()->next()=y; + } + else{ + y->next()=x->next(); + y->prior()=x->prior(); + x->next()=x->prior()=x; + y->next()->prior()=y->prior()->next()=y; + } + } + else if(y->next()!=y){ + x->next()=y->next(); + x->prior()=y->prior(); + y->next()=y->prior()=y; + x->next()->prior()=x->prior()->next()=x; + } + } + +private: + pointer prior_; + pointer next_; +}; + +template +struct sequenced_index_node_trampoline: + sequenced_index_node_impl< + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > +{ + typedef sequenced_index_node_impl< + typename boost::detail::allocator::rebind_to< + typename Super::allocator_type, + char + >::type + > impl_type; +}; + +template +struct sequenced_index_node:Super,sequenced_index_node_trampoline +{ +private: + typedef sequenced_index_node_trampoline trampoline; + +public: + typedef typename trampoline::impl_type impl_type; + typedef typename trampoline::pointer impl_pointer; + typedef typename trampoline::const_pointer const_impl_pointer; + + impl_pointer& prior(){return trampoline::prior();} + impl_pointer prior()const{return trampoline::prior();} + impl_pointer& next(){return trampoline::next();} + impl_pointer next()const{return trampoline::next();} + + impl_pointer impl() + { + return static_cast( + static_cast(static_cast(this))); + } + + const_impl_pointer impl()const + { + return static_cast( + static_cast(static_cast(this))); + } + + static sequenced_index_node* from_impl(impl_pointer x) + { + return + static_cast( + static_cast( + raw_ptr(x))); + } + + static const sequenced_index_node* from_impl(const_impl_pointer x) + { + return + static_cast( + static_cast( + raw_ptr(x))); + } + + /* interoperability with bidir_node_iterator */ + + static void increment(sequenced_index_node*& x) + { + impl_pointer xi=x->impl(); + trampoline::increment(xi); + x=from_impl(xi); + } + + static void decrement(sequenced_index_node*& x) + { + impl_pointer xi=x->impl(); + trampoline::decrement(xi); + x=from_impl(xi); + } +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_ops.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_ops.hpp new file mode 100644 index 00000000000..142bdd9dd9a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_ops.hpp @@ -0,0 +1,203 @@ +/* Copyright 2003-2016 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_OPS_HPP +#define BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_OPS_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Common code for sequenced_index memfuns having templatized and + * non-templatized versions. + */ + +template +void sequenced_index_remove(SequencedIndex& x,Predicate pred) +{ + typedef typename SequencedIndex::iterator iterator; + iterator first=x.begin(),last=x.end(); + while(first!=last){ + if(pred(*first))x.erase(first++); + else ++first; + } +} + +template +void sequenced_index_unique(SequencedIndex& x,BinaryPredicate binary_pred) +{ + typedef typename SequencedIndex::iterator iterator; + iterator first=x.begin(); + iterator last=x.end(); + if(first!=last){ + for(iterator middle=first;++middle!=last;middle=first){ + if(binary_pred(*middle,*first))x.erase(middle); + else first=middle; + } + } +} + +template +void sequenced_index_merge(SequencedIndex& x,SequencedIndex& y,Compare comp) +{ + typedef typename SequencedIndex::iterator iterator; + if(&x!=&y){ + iterator first0=x.begin(),last0=x.end(); + iterator first1=y.begin(),last1=y.end(); + while(first0!=last0&&first1!=last1){ + if(comp(*first1,*first0))x.splice(first0,y,first1++); + else ++first0; + } + x.splice(last0,y,first1,last1); + } +} + +/* sorting */ + +/* auxiliary stuff */ + +template +void sequenced_index_collate( + BOOST_DEDUCED_TYPENAME Node::impl_type* x, + BOOST_DEDUCED_TYPENAME Node::impl_type* y, + Compare comp) +{ + typedef typename Node::impl_type impl_type; + typedef typename Node::impl_pointer impl_pointer; + + impl_pointer first0=x->next(); + impl_pointer last0=x; + impl_pointer first1=y->next(); + impl_pointer last1=y; + while(first0!=last0&&first1!=last1){ + if(comp( + Node::from_impl(first1)->value(),Node::from_impl(first0)->value())){ + impl_pointer tmp=first1->next(); + impl_type::relink(first0,first1); + first1=tmp; + } + else first0=first0->next(); + } + impl_type::relink(last0,first1,last1); +} + +/* Some versions of CGG require a bogus typename in counter_spc + * inside sequenced_index_sort if the following is defined + * also inside sequenced_index_sort. + */ + +BOOST_STATIC_CONSTANT( + std::size_t, + sequenced_index_sort_max_fill= + (std::size_t)std::numeric_limits::digits+1); + +#include + +template +void sequenced_index_sort(Node* header,Compare comp) +{ + /* Musser's mergesort, see http://www.cs.rpi.edu/~musser/gp/List/lists1.html. + * The implementation is a little convoluted: in the original code + * counter elements and carry are std::lists: here we do not want + * to use multi_index instead, so we do things at a lower level, managing + * directly the internal node representation. + * Incidentally, the implementations I've seen of this algorithm (SGI, + * Dinkumware, STLPort) are not exception-safe: this is. Moreover, we do not + * use any dynamic storage. + */ + + if(header->next()==header->impl()|| + header->next()->next()==header->impl())return; + + typedef typename Node::impl_type impl_type; + typedef typename Node::impl_pointer impl_pointer; + + typedef typename aligned_storage< + sizeof(impl_type), + alignment_of::value + >::type carry_spc_type; + carry_spc_type carry_spc; + impl_type& carry= + *reinterpret_cast(&carry_spc); + typedef typename aligned_storage< + sizeof( + impl_type + [sequenced_index_sort_max_fill]), + alignment_of< + impl_type + [sequenced_index_sort_max_fill] + >::value + >::type counter_spc_type; + counter_spc_type counter_spc; + impl_type* counter= + reinterpret_cast(&counter_spc); + std::size_t fill=0; + + carry.prior()=carry.next()=static_cast(&carry); + counter[0].prior()=counter[0].next()=static_cast(&counter[0]); + + BOOST_TRY{ + while(header->next()!=header->impl()){ + impl_type::relink(carry.next(),header->next()); + std::size_t i=0; + while(i(&counter[i])){ + sequenced_index_collate(&carry,&counter[i++],comp); + } + impl_type::swap( + static_cast(&carry), + static_cast(&counter[i])); + if(i==fill){ + ++fill; + counter[fill].prior()=counter[fill].next()= + static_cast(&counter[fill]); + } + } + + for(std::size_t i=1;i(&counter[i],&counter[i-1],comp); + } + impl_type::swap( + header->impl(),static_cast(&counter[fill-1])); + } + BOOST_CATCH(...) + { + impl_type::relink( + header->impl(),carry.next(),static_cast(&carry)); + for(std::size_t i=0;i<=fill;++i){ + impl_type::relink( + header->impl(),counter[i].next(), + static_cast(&counter[i])); + } + BOOST_RETHROW; + } + BOOST_CATCH_END +} + +#include + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/serialization_version.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/serialization_version.hpp new file mode 100644 index 00000000000..ccd8bb4f791 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/serialization_version.hpp @@ -0,0 +1,73 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_SERIALIZATION_VERSION_HPP +#define BOOST_MULTI_INDEX_DETAIL_SERIALIZATION_VERSION_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* Helper class for storing and retrieving a given type serialization class + * version while avoiding saving the number multiple times in the same + * archive. + * Behavior undefined if template partial specialization is not supported. + */ + +template +struct serialization_version +{ + serialization_version(): + value(boost::serialization::version::value){} + + serialization_version& operator=(unsigned int x){value=x;return *this;}; + + operator unsigned int()const{return value;} + +private: + friend class boost::serialization::access; + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + template + void save(Archive&,const unsigned int)const{} + + template + void load(Archive&,const unsigned int version) + { + this->value=version; + } + + unsigned int value; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +namespace serialization { +template +struct version > +{ + BOOST_STATIC_CONSTANT(int,value=version::value); +}; +} /* namespace serialization */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/uintptr_type.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/uintptr_type.hpp new file mode 100644 index 00000000000..9c92d01d4de --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/uintptr_type.hpp @@ -0,0 +1,76 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_UINTPTR_TYPE_HPP +#define BOOST_MULTI_INDEX_DETAIL_UINTPTR_TYPE_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* has_uintptr_type is an MPL integral constant determining whether + * there exists an unsigned integral type with the same size as + * void *. + * uintptr_type is such a type if has_uintptr is true, or unsigned int + * otherwise. + * Note that uintptr_type is more restrictive than C99 uintptr_t, + * where an integral type with size greater than that of void * + * would be conformant. + */ + +templatestruct uintptr_candidates; +template<>struct uintptr_candidates<-1>{typedef unsigned int type;}; +template<>struct uintptr_candidates<0> {typedef unsigned int type;}; +template<>struct uintptr_candidates<1> {typedef unsigned short type;}; +template<>struct uintptr_candidates<2> {typedef unsigned long type;}; + +#if defined(BOOST_HAS_LONG_LONG) +template<>struct uintptr_candidates<3> {typedef boost::ulong_long_type type;}; +#else +template<>struct uintptr_candidates<3> {typedef unsigned int type;}; +#endif + +#if defined(BOOST_HAS_MS_INT64) +template<>struct uintptr_candidates<4> {typedef unsigned __int64 type;}; +#else +template<>struct uintptr_candidates<4> {typedef unsigned int type;}; +#endif + +struct uintptr_aux +{ + BOOST_STATIC_CONSTANT(int,index= + sizeof(void*)==sizeof(uintptr_candidates<0>::type)?0: + sizeof(void*)==sizeof(uintptr_candidates<1>::type)?1: + sizeof(void*)==sizeof(uintptr_candidates<2>::type)?2: + sizeof(void*)==sizeof(uintptr_candidates<3>::type)?3: + sizeof(void*)==sizeof(uintptr_candidates<4>::type)?4:-1); + + BOOST_STATIC_CONSTANT(bool,has_uintptr_type=(index>=0)); + + typedef uintptr_candidates::type type; +}; + +typedef mpl::bool_ has_uintptr_type; +typedef uintptr_aux::type uintptr_type; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/unbounded.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/unbounded.hpp new file mode 100644 index 00000000000..dc09be1770d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/unbounded.hpp @@ -0,0 +1,66 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_UNBOUNDED_HPP +#define BOOST_MULTI_INDEX_DETAIL_UNBOUNDED_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +namespace boost{ + +namespace multi_index{ + +/* dummy type and variable for use in ordered_index::range() */ + +/* ODR-abiding technique shown at the example attached to + * http://lists.boost.org/Archives/boost/2006/07/108355.php + */ + +namespace detail{class unbounded_helper;} + +detail::unbounded_helper unbounded(detail::unbounded_helper); + +namespace detail{ + +class unbounded_helper +{ + unbounded_helper(){} + unbounded_helper(const unbounded_helper&){} + friend unbounded_helper multi_index::unbounded(unbounded_helper); +}; + +typedef unbounded_helper (*unbounded_type)(unbounded_helper); + +} /* namespace multi_index::detail */ + +inline detail::unbounded_helper unbounded(detail::unbounded_helper) +{ + return detail::unbounded_helper(); +} + +/* tags used in the implementation of range */ + +namespace detail{ + +struct none_unbounded_tag{}; +struct lower_unbounded_tag{}; +struct upper_unbounded_tag{}; +struct both_unbounded_tag{}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/value_compare.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/value_compare.hpp new file mode 100644 index 00000000000..ac42e8779aa --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/value_compare.hpp @@ -0,0 +1,56 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_VALUE_COMPARE_HPP +#define BOOST_MULTI_INDEX_DETAIL_VALUE_COMPARE_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +struct value_comparison +{ + typedef Value first_argument_type; + typedef Value second_argument_type; + typedef bool result_type; + + value_comparison( + const KeyFromValue& key_=KeyFromValue(),const Compare& comp_=Compare()): + key(key_),comp(comp_) + { + } + + bool operator()( + typename call_traits::param_type x, + typename call_traits::param_type y)const + { + return comp(key(x),key(y)); + } + +private: + KeyFromValue key; + Compare comp; +}; + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/vartempl_support.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/vartempl_support.hpp new file mode 100644 index 00000000000..06ff430f4be --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/vartempl_support.hpp @@ -0,0 +1,247 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP +#define BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +/* Utilities for emulation of variadic template functions. Variadic packs are + * replaced by lists of BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS parameters: + * + * - typename... Args --> BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK + * - Args&&... args --> BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK + * - std::forward(args)... --> BOOST_MULTI_INDEX_FORWARD_PARAM_PACK + * + * Forwarding emulated with Boost.Move. A template functions foo_imp + * defined in such way accepts *exactly* BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS + * arguments: variable number of arguments is emulated by providing a set of + * overloads foo forwarding to foo_impl with + * + * BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG (initial extra arg) + * + * which fill the extra args with boost::multi_index::detail::noarg's. + * boost::multi_index::detail::vartempl_placement_new works the opposite + * way: it acceps a full a pointer x to Value and a + * BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK and forwards to + * new(x) Value(args) where args is the argument pack after discarding + * noarg's. + * + * Emulation decays to the real thing when the compiler supports variadic + * templates and move semantics natively. + */ + +#include + +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)||\ + defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS) +#define BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS 5 +#endif + +#define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK \ +BOOST_PP_ENUM_PARAMS( \ + BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,typename T) + +#define BOOST_MULTI_INDEX_VARTEMPL_ARG(z,n,_) \ +BOOST_FWD_REF(BOOST_PP_CAT(T,n)) BOOST_PP_CAT(t,n) + +#define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK \ +BOOST_PP_ENUM( \ + BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ + BOOST_MULTI_INDEX_VARTEMPL_ARG,~) + +#define BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG(z,n,_) \ +boost::forward(BOOST_PP_CAT(t,n)) + +#define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK \ +BOOST_PP_ENUM( \ + BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ + BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) + +namespace boost{namespace multi_index{namespace detail{ +struct noarg{}; +}}} + +/* call vartempl function without args */ + +#define BOOST_MULTI_INDEX_NULL_PARAM_PACK \ +BOOST_PP_ENUM_PARAMS( \ + BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ + boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) + +#define BOOST_MULTI_INDEX_TEMPLATE_N(n) \ +template + +#define BOOST_MULTI_INDEX_TEMPLATE_0(n) + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX(z,n,data) \ +BOOST_PP_IF(n, \ + BOOST_MULTI_INDEX_TEMPLATE_N, \ + BOOST_MULTI_INDEX_TEMPLATE_0)(n) \ +BOOST_PP_SEQ_ELEM(0,data) /* ret */ \ +BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \ +{ \ + return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_AND( \ + n,BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n))) \ + BOOST_PP_ENUM_PARAMS( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ + boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \ + ); \ +} + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \ + ret,name_from,name_to) \ +BOOST_PP_REPEAT_FROM_TO( \ + 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX, \ + (ret)(name_from)(name_to)) + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX( \ + z,n,data) \ +BOOST_PP_IF(n, \ + BOOST_MULTI_INDEX_TEMPLATE_N, \ + BOOST_MULTI_INDEX_TEMPLATE_0)(n) \ +BOOST_PP_SEQ_ELEM(0,data) /* ret */ \ +BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \ + BOOST_PP_SEQ_ELEM(3,data) BOOST_PP_SEQ_ELEM(4,data) /* extra arg */\ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \ +{ \ + return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \ + BOOST_PP_SEQ_ELEM(4,data) /* extra_arg_name */ \ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \ + BOOST_PP_ENUM_PARAMS( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ + boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \ + ); \ +} + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \ + ret,name_from,name_to,extra_arg_type,extra_arg_name) \ +BOOST_PP_REPEAT_FROM_TO( \ + 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX, \ + (ret)(name_from)(name_to)(extra_arg_type)(extra_arg_name)) + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +#define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX(z,n,name) \ +template< \ + typename Value \ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM_PARAMS(n,typename T) \ +> \ +Value* name( \ + Value* x \ + BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~) \ + BOOST_PP_COMMA_IF( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \ + BOOST_PP_ENUM_PARAMS( \ + BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ + BOOST_FWD_REF(noarg) BOOST_PP_INTERCEPT)) \ +{ \ + return new(x) Value( \ + BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~)); \ +} + +#define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(name) \ +BOOST_PP_REPEAT_FROM_TO( \ + 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ + BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX, \ + name) + +BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(vartempl_placement_new) + +#undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX +#undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#else + +/* native variadic templates support */ + +#include + +#define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK typename... Args +#define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK Args&&... args +#define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK std::forward(args)... +#define BOOST_MULTI_INDEX_NULL_PARAM_PACK + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \ + ret,name_from,name_to) \ +template ret name_from(Args&&... args) \ +{ \ + return name_to(std::forward(args)...); \ +} + +#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \ + ret,name_from,name_to,extra_arg_type,extra_arg_name) \ +template ret name_from( \ + extra_arg_type extra_arg_name,Args&&... args) \ +{ \ + return name_to(extra_arg_name,std::forward(args)...); \ +} + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +Value* vartempl_placement_new(Value*x,Args&&... args) +{ + return new(x) Value(std::forward(args)...); +} + +} /* namespace multi_index::detail */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/global_fun.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/global_fun.hpp new file mode 100644 index 00000000000..2c13769100c --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/global_fun.hpp @@ -0,0 +1,185 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_GLOBAL_FUN_HPP +#define BOOST_MULTI_INDEX_GLOBAL_FUN_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_SFINAE) +#include +#endif + +namespace boost{ + +template class reference_wrapper; /* fwd decl. */ + +namespace multi_index{ + +namespace detail{ + +/* global_fun is a read-only key extractor from Value based on a given global + * (or static member) function with signature: + * + * Type f([const] Value [&]); + * + * Additionally, global_fun and const_global_fun are overloaded to support + * referece_wrappers of Value and "chained pointers" to Value's. By chained + * pointer to T we mean a type P such that, given a p of Type P + * *...n...*x is convertible to T&, for some n>=1. + * Examples of chained pointers are raw and smart pointers, iterators and + * arbitrary combinations of these (vg. T** or unique_ptr.) + */ + +template +struct const_ref_global_fun_base +{ + typedef typename remove_reference::type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type>::type +#else + Type +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type operator()(Value x)const + { + return PtrToFunction(x); + } + + Type operator()( + const reference_wrapper< + typename remove_reference::type>& x)const + { + return operator()(x.get()); + } + + Type operator()( + const reference_wrapper< + typename remove_const< + typename remove_reference::type>::type>& x + +#if BOOST_WORKAROUND(BOOST_MSVC,==1310) +/* http://lists.boost.org/Archives/boost/2015/10/226135.php */ + ,int=0 +#endif + + )const + { + return operator()(x.get()); + } +}; + +template +struct non_const_ref_global_fun_base +{ + typedef typename remove_reference::type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type>::type +#else + Type +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type operator()(Value x)const + { + return PtrToFunction(x); + } + + Type operator()( + const reference_wrapper< + typename remove_reference::type>& x)const + { + return operator()(x.get()); + } +}; + +template +struct non_ref_global_fun_base +{ + typedef typename remove_reference::type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type>::type +#else + Type +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type operator()(const Value& x)const + { + return PtrToFunction(x); + } + + Type operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } + + Type operator()( + const reference_wrapper::type>& x)const + { + return operator()(x.get()); + } +}; + +} /* namespace multi_index::detail */ + +template +struct global_fun: + mpl::if_c< + is_reference::value, + typename mpl::if_c< + is_const::type>::value, + detail::const_ref_global_fun_base, + detail::non_const_ref_global_fun_base + >::type, + detail::non_ref_global_fun_base + >::type +{ +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index.hpp new file mode 100644 index 00000000000..352d0c13f17 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index.hpp @@ -0,0 +1,1725 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_HASHED_INDEX_HPP +#define BOOST_MULTI_INDEX_HASHED_INDEX_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) +#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x) \ + detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ + detail::make_obj_guard(x,&hashed_index::check_invariant_); \ + BOOST_JOIN(check_invariant_,__LINE__).touch(); +#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT \ + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(*this) +#else +#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x) +#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* hashed_index adds a layer of hashed indexing to a given Super */ + +/* Most of the implementation of unique and non-unique indices is + * shared. We tell from one another on instantiation time by using + * Category tags defined in hash_index_node.hpp. + */ + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +class hashed_index: + BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + ,public safe_mode::safe_container< + hashed_index > +#endif + +{ +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ + BOOST_WORKAROUND(__MWERKS__,<=0x3003) +/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the + * lifetime of const references bound to temporaries --precisely what + * scopeguards are. + */ + +#pragma parse_mfunc_templ off +#endif + + typedef typename SuperMeta::type super; + +protected: + typedef hashed_index_node< + typename super::node_type,Category> node_type; + +private: + typedef typename node_type::node_alg node_alg; + typedef typename node_type::impl_type node_impl_type; + typedef typename node_impl_type::pointer node_impl_pointer; + typedef typename node_impl_type::base_pointer node_impl_base_pointer; + typedef bucket_array< + typename super::final_allocator_type> bucket_array_type; + +public: + /* types */ + + typedef typename KeyFromValue::result_type key_type; + typedef typename node_type::value_type value_type; + typedef KeyFromValue key_from_value; + typedef Hash hasher; + typedef Pred key_equal; + typedef tuple ctor_args; + typedef typename super::final_allocator_type allocator_type; + typedef typename allocator_type::pointer pointer; + typedef typename allocator_type::const_pointer const_pointer; + typedef typename allocator_type::reference reference; + typedef typename allocator_type::const_reference const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef safe_mode::safe_iterator< + hashed_index_iterator< + node_type,bucket_array_type, + hashed_index_global_iterator_tag>, + hashed_index> iterator; +#else + typedef hashed_index_iterator< + node_type,bucket_array_type, + hashed_index_global_iterator_tag> iterator; +#endif + + typedef iterator const_iterator; + + typedef hashed_index_iterator< + node_type,bucket_array_type, + hashed_index_local_iterator_tag> local_iterator; + typedef local_iterator const_local_iterator; + + typedef TagList tag_list; + +protected: + typedef typename super::final_node_type final_node_type; + typedef tuples::cons< + ctor_args, + typename super::ctor_args_list> ctor_args_list; + typedef typename mpl::push_front< + typename super::index_type_list, + hashed_index>::type index_type_list; + typedef typename mpl::push_front< + typename super::iterator_type_list, + iterator>::type iterator_type_list; + typedef typename mpl::push_front< + typename super::const_iterator_type_list, + const_iterator>::type const_iterator_type_list; + typedef typename super::copy_map_type copy_map_type; + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + typedef typename super::index_saver_type index_saver_type; + typedef typename super::index_loader_type index_loader_type; +#endif + +private: +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef safe_mode::safe_container< + hashed_index> safe_super; +#endif + + typedef typename call_traits::param_type value_param_type; + typedef typename call_traits< + key_type>::param_type key_param_type; + + /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * expansion. + */ + + typedef std::pair emplace_return_type; + +public: + + /* construct/destroy/copy + * Default and copy ctors are in the protected section as indices are + * not supposed to be created on their own. No range ctor either. + */ + + hashed_index& operator=( + const hashed_index& x) + { + this->final()=x.final(); + return *this; + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + hashed_index& operator=( + std::initializer_list list) + { + this->final()=list; + return *this; + } +#endif + + allocator_type get_allocator()const BOOST_NOEXCEPT + { + return this->final().get_allocator(); + } + + /* size and capacity */ + + bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} + size_type size()const BOOST_NOEXCEPT{return this->final_size_();} + size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} + + /* iterators */ + + iterator begin()BOOST_NOEXCEPT + {return make_iterator(node_type::from_impl(header()->next()->prior()));} + const_iterator begin()const BOOST_NOEXCEPT + {return make_iterator(node_type::from_impl(header()->next()->prior()));} + iterator end()BOOST_NOEXCEPT{return make_iterator(header());} + const_iterator end()const BOOST_NOEXCEPT{return make_iterator(header());} + const_iterator cbegin()const BOOST_NOEXCEPT{return begin();} + const_iterator cend()const BOOST_NOEXCEPT{return end();} + + iterator iterator_to(const value_type& x) + { + return make_iterator(node_from_value(&x)); + } + + const_iterator iterator_to(const value_type& x)const + { + return make_iterator(node_from_value(&x)); + } + + /* modifiers */ + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace,emplace_impl) + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( + iterator,emplace_hint,emplace_hint_impl,iterator,position) + + std::pair insert(const value_type& x) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_(x); + return std::pair(make_iterator(p.first),p.second); + } + + std::pair insert(BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_(x); + return std::pair(make_iterator(p.first),p.second); + } + + iterator insert(iterator position,const value_type& x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_( + x,static_cast(position.get_node())); + return make_iterator(p.first); + } + + iterator insert(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_( + x,static_cast(position.get_node())); + return make_iterator(p.first); + } + + template + void insert(InputIterator first,InputIterator last) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + for(;first!=last;++first)this->final_insert_ref_(*first); + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void insert(std::initializer_list list) + { + insert(list.begin(),list.end()); + } +#endif + + iterator erase(iterator position) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + this->final_erase_(static_cast(position++.get_node())); + return position; + } + + size_type erase(key_param_type k) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + + std::size_t buc=buckets.position(hash_(k)); + for(node_impl_pointer x=buckets.at(buc)->prior(); + x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ + if(eq_(k,key(node_type::from_impl(x)->value()))){ + node_impl_pointer y=end_of_range(x); + size_type s=0; + do{ + node_impl_pointer z=node_alg::after(x); + this->final_erase_( + static_cast(node_type::from_impl(x))); + x=z; + ++s; + }while(x!=y); + return s; + } + } + return 0; + } + + iterator erase(iterator first,iterator last) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); + BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + while(first!=last){ + first=erase(first); + } + return first; + } + + bool replace(iterator position,const value_type& x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + return this->final_replace_( + x,static_cast(position.get_node())); + } + + bool replace(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + return this->final_replace_rv_( + x,static_cast(position.get_node())); + } + + template + bool modify(iterator position,Modifier mod) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + /* MSVC++ 6.0 optimizer on safe mode code chokes if this + * this is not added. Left it for all compilers as it does no + * harm. + */ + + position.detach(); +#endif + + return this->final_modify_( + mod,static_cast(position.get_node())); + } + + template + bool modify(iterator position,Modifier mod,Rollback back_) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + /* MSVC++ 6.0 optimizer on safe mode code chokes if this + * this is not added. Left it for all compilers as it does no + * harm. + */ + + position.detach(); +#endif + + return this->final_modify_( + mod,back_,static_cast(position.get_node())); + } + + template + bool modify_key(iterator position,Modifier mod) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + return modify( + position,modify_key_adaptor(mod,key)); + } + + template + bool modify_key(iterator position,Modifier mod,Rollback back_) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + return modify( + position, + modify_key_adaptor(mod,key), + modify_key_adaptor(back_,key)); + } + + void clear()BOOST_NOEXCEPT + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + this->final_clear_(); + } + + void swap(hashed_index& x) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x); + this->final_swap_(x.final()); + } + + /* observers */ + + key_from_value key_extractor()const{return key;} + hasher hash_function()const{return hash_;} + key_equal key_eq()const{return eq_;} + + /* lookup */ + + /* Internally, these ops rely on const_iterator being the same + * type as iterator. + */ + + /* Implementation note: When CompatibleKey is consistently promoted to + * KeyFromValue::result_type for equality comparison, the promotion is made + * once in advance to increase efficiency. + */ + + template + iterator find(const CompatibleKey& k)const + { + return find(k,hash_,eq_); + } + + template< + typename CompatibleKey,typename CompatibleHash,typename CompatiblePred + > + iterator find( + const CompatibleKey& k, + const CompatibleHash& hash,const CompatiblePred& eq)const + { + return find( + k,hash,eq,promotes_1st_arg()); + } + + template + size_type count(const CompatibleKey& k)const + { + return count(k,hash_,eq_); + } + + template< + typename CompatibleKey,typename CompatibleHash,typename CompatiblePred + > + size_type count( + const CompatibleKey& k, + const CompatibleHash& hash,const CompatiblePred& eq)const + { + return count( + k,hash,eq,promotes_1st_arg()); + } + + template + std::pair equal_range(const CompatibleKey& k)const + { + return equal_range(k,hash_,eq_); + } + + template< + typename CompatibleKey,typename CompatibleHash,typename CompatiblePred + > + std::pair equal_range( + const CompatibleKey& k, + const CompatibleHash& hash,const CompatiblePred& eq)const + { + return equal_range( + k,hash,eq,promotes_1st_arg()); + } + + /* bucket interface */ + + size_type bucket_count()const BOOST_NOEXCEPT{return buckets.size();} + size_type max_bucket_count()const BOOST_NOEXCEPT{return static_cast(-1);} + + size_type bucket_size(size_type n)const + { + size_type res=0; + for(node_impl_pointer x=buckets.at(n)->prior(); + x!=node_impl_pointer(0);x=node_alg::after_local(x)){ + ++res; + } + return res; + } + + size_type bucket(key_param_type k)const + { + return buckets.position(hash_(k)); + } + + local_iterator begin(size_type n) + { + return const_cast(this)->begin(n); + } + + const_local_iterator begin(size_type n)const + { + node_impl_pointer x=buckets.at(n)->prior(); + if(x==node_impl_pointer(0))return end(n); + return make_local_iterator(node_type::from_impl(x)); + } + + local_iterator end(size_type n) + { + return const_cast(this)->end(n); + } + + const_local_iterator end(size_type)const + { + return make_local_iterator(0); + } + + const_local_iterator cbegin(size_type n)const{return begin(n);} + const_local_iterator cend(size_type n)const{return end(n);} + + local_iterator local_iterator_to(const value_type& x) + { + return make_local_iterator(node_from_value(&x)); + } + + const_local_iterator local_iterator_to(const value_type& x)const + { + return make_local_iterator(node_from_value(&x)); + } + + /* hash policy */ + + float load_factor()const BOOST_NOEXCEPT + {return static_cast(size())/bucket_count();} + float max_load_factor()const BOOST_NOEXCEPT{return mlf;} + void max_load_factor(float z){mlf=z;calculate_max_load();} + + void rehash(size_type n) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + if(size()<=max_load&&n<=bucket_count())return; + + size_type bc =(std::numeric_limits::max)(); + float fbc=static_cast(1+size()/mlf); + if(bc>fbc){ + bc=static_cast(fbc); + if(bc(std::ceil(static_cast(n)/mlf))); + } + +BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: + hashed_index(const ctor_args_list& args_list,const allocator_type& al): + super(args_list.get_tail(),al), + key(tuples::get<1>(args_list.get_head())), + hash_(tuples::get<2>(args_list.get_head())), + eq_(tuples::get<3>(args_list.get_head())), + buckets(al,header()->impl(),tuples::get<0>(args_list.get_head())), + mlf(1.0f) + { + calculate_max_load(); + } + + hashed_index( + const hashed_index& x): + super(x), + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super(), +#endif + + key(x.key), + hash_(x.hash_), + eq_(x.eq_), + buckets(x.get_allocator(),header()->impl(),x.buckets.size()), + mlf(x.mlf), + max_load(x.max_load) + { + /* Copy ctor just takes the internal configuration objects from x. The rest + * is done in subsequent call to copy_(). + */ + } + + hashed_index( + const hashed_index& x, + do_not_copy_elements_tag): + super(x,do_not_copy_elements_tag()), + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super(), +#endif + + key(x.key), + hash_(x.hash_), + eq_(x.eq_), + buckets(x.get_allocator(),header()->impl(),0), + mlf(1.0f) + { + calculate_max_load(); + } + + ~hashed_index() + { + /* the container is guaranteed to be empty by now */ + } + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + iterator make_iterator(node_type* node) + { + return iterator(node,this); + } + + const_iterator make_iterator(node_type* node)const + { + return const_iterator(node,const_cast(this)); + } +#else + iterator make_iterator(node_type* node) + { + return iterator(node); + } + + const_iterator make_iterator(node_type* node)const + { + return const_iterator(node); + } +#endif + + local_iterator make_local_iterator(node_type* node) + { + return local_iterator(node); + } + + const_local_iterator make_local_iterator(node_type* node)const + { + return const_local_iterator(node); + } + + void copy_( + const hashed_index& x, + const copy_map_type& map) + { + copy_(x,map,Category()); + } + + void copy_( + const hashed_index& x, + const copy_map_type& map,hashed_unique_tag) + { + if(x.size()!=0){ + node_impl_pointer end_org=x.header()->impl(), + org=end_org, + cpy=header()->impl(); + do{ + node_impl_pointer prev_org=org->prior(), + prev_cpy= + static_cast(map.find(static_cast( + node_type::from_impl(prev_org))))->impl(); + cpy->prior()=prev_cpy; + if(node_alg::is_first_of_bucket(org)){ + node_impl_base_pointer buc_org=prev_org->next(), + buc_cpy= + buckets.begin()+(buc_org-x.buckets.begin()); + prev_cpy->next()=buc_cpy; + buc_cpy->prior()=cpy; + } + else{ + prev_cpy->next()=node_impl_type::base_pointer_from(cpy); + } + org=prev_org; + cpy=prev_cpy; + }while(org!=end_org); + } + + super::copy_(x,map); + } + + void copy_( + const hashed_index& x, + const copy_map_type& map,hashed_non_unique_tag) + { + if(x.size()!=0){ + node_impl_pointer end_org=x.header()->impl(), + org=end_org, + cpy=header()->impl(); + do{ + node_impl_pointer next_org=node_alg::after(org), + next_cpy= + static_cast(map.find(static_cast( + node_type::from_impl(next_org))))->impl(); + if(node_alg::is_first_of_bucket(next_org)){ + node_impl_base_pointer buc_org=org->next(), + buc_cpy= + buckets.begin()+(buc_org-x.buckets.begin()); + cpy->next()=buc_cpy; + buc_cpy->prior()=next_cpy; + next_cpy->prior()=cpy; + } + else{ + if(org->next()==node_impl_type::base_pointer_from(next_org)){ + cpy->next()=node_impl_type::base_pointer_from(next_cpy); + } + else{ + cpy->next()= + node_impl_type::base_pointer_from( + static_cast(map.find(static_cast( + node_type::from_impl( + node_impl_type::pointer_from(org->next())))))->impl()); + } + + if(next_org->prior()!=org){ + next_cpy->prior()= + static_cast(map.find(static_cast( + node_type::from_impl(next_org->prior()))))->impl(); + } + else{ + next_cpy->prior()=cpy; + } + } + org=next_org; + cpy=next_cpy; + }while(org!=end_org); + } + + super::copy_(x,map); + } + + template + final_node_type* insert_( + value_param_type v,final_node_type*& x,Variant variant) + { + reserve_for_insert(size()+1); + + std::size_t buc=find_bucket(v); + link_info pos(buckets.at(buc)); + if(!link_point(v,pos)){ + return static_cast( + node_type::from_impl(node_impl_type::pointer_from(pos))); + } + + final_node_type* res=super::insert_(v,x,variant); + if(res==x)link(static_cast(x),pos); + return res; + } + + template + final_node_type* insert_( + value_param_type v,node_type* position,final_node_type*& x,Variant variant) + { + reserve_for_insert(size()+1); + + std::size_t buc=find_bucket(v); + link_info pos(buckets.at(buc)); + if(!link_point(v,pos)){ + return static_cast( + node_type::from_impl(node_impl_type::pointer_from(pos))); + } + + final_node_type* res=super::insert_(v,position,x,variant); + if(res==x)link(static_cast(x),pos); + return res; + } + + void erase_(node_type* x) + { + unlink(x); + super::erase_(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + } + + void delete_all_nodes_() + { + delete_all_nodes_(Category()); + } + + void delete_all_nodes_(hashed_unique_tag) + { + for(node_impl_pointer x_end=header()->impl(),x=x_end->prior();x!=x_end;){ + node_impl_pointer y=x->prior(); + this->final_delete_node_( + static_cast(node_type::from_impl(x))); + x=y; + } + } + + void delete_all_nodes_(hashed_non_unique_tag) + { + for(node_impl_pointer x_end=header()->impl(),x=x_end->prior();x!=x_end;){ + node_impl_pointer y=x->prior(); + if(y->next()!=node_impl_type::base_pointer_from(x)&& + y->next()->prior()!=x){ /* n-1 of group */ + /* Make the second node prior() pointer back-linked so that it won't + * refer to a deleted node when the time for its own destruction comes. + */ + + node_impl_pointer first=node_impl_type::pointer_from(y->next()); + first->next()->prior()=first; + } + this->final_delete_node_( + static_cast(node_type::from_impl(x))); + x=y; + } + } + + void clear_() + { + super::clear_(); + buckets.clear(header()->impl()); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::detach_dereferenceable_iterators(); +#endif + } + + void swap_( + hashed_index& x) + { + std::swap(key,x.key); + std::swap(hash_,x.hash_); + std::swap(eq_,x.eq_); + buckets.swap(x.buckets); + std::swap(mlf,x.mlf); + std::swap(max_load,x.max_load); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_(x); + } + + void swap_elements_( + hashed_index& x) + { + buckets.swap(x.buckets); + std::swap(mlf,x.mlf); + std::swap(max_load,x.max_load); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_elements_(x); + } + + template + bool replace_(value_param_type v,node_type* x,Variant variant) + { + if(eq_(key(v),key(x->value()))){ + return super::replace_(v,x,variant); + } + + unlink_undo undo; + unlink(x,undo); + + BOOST_TRY{ + std::size_t buc=find_bucket(v); + link_info pos(buckets.at(buc)); + if(link_point(v,pos)&&super::replace_(v,x,variant)){ + link(x,pos); + return true; + } + undo(); + return false; + } + BOOST_CATCH(...){ + undo(); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + bool modify_(node_type* x) + { + std::size_t buc; + bool b; + BOOST_TRY{ + buc=find_bucket(x->value()); + b=in_place(x->impl(),key(x->value()),buc); + } + BOOST_CATCH(...){ + erase_(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + if(!b){ + unlink(x); + BOOST_TRY{ + link_info pos(buckets.at(buc)); + if(!link_point(x->value(),pos)){ + super::erase_(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + return false; + } + link(x,pos); + } + BOOST_CATCH(...){ + super::erase_(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + BOOST_TRY{ + if(!super::modify_(x)){ + unlink(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + return false; + } + else return true; + } + BOOST_CATCH(...){ + unlink(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + bool modify_rollback_(node_type* x) + { + std::size_t buc=find_bucket(x->value()); + if(in_place(x->impl(),key(x->value()),buc)){ + return super::modify_rollback_(x); + } + + unlink_undo undo; + unlink(x,undo); + + BOOST_TRY{ + link_info pos(buckets.at(buc)); + if(link_point(x->value(),pos)&&super::modify_rollback_(x)){ + link(x,pos); + return true; + } + undo(); + return false; + } + BOOST_CATCH(...){ + undo(); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + /* comparison */ + +#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + /* defect macro refers to class, not function, templates, but anyway */ + + template + friend bool operator==( + const hashed_index&,const hashed_index& y); +#endif + + bool equals(const hashed_index& x)const{return equals(x,Category());} + + bool equals(const hashed_index& x,hashed_unique_tag)const + { + if(size()!=x.size())return false; + for(const_iterator it=begin(),it_end=end(),it2_end=x.end(); + it!=it_end;++it){ + const_iterator it2=x.find(key(*it)); + if(it2==it2_end||!(*it==*it2))return false; + } + return true; + } + + bool equals(const hashed_index& x,hashed_non_unique_tag)const + { + if(size()!=x.size())return false; + for(const_iterator it=begin(),it_end=end();it!=it_end;){ + const_iterator it2,it2_last; + boost::tie(it2,it2_last)=x.equal_range(key(*it)); + if(it2==it2_last)return false; + + const_iterator it_last=make_iterator( + node_type::from_impl(end_of_range(it.get_node()->impl()))); + if(std::distance(it,it_last)!=std::distance(it2,it2_last))return false; + + /* From is_permutation code in + * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3068.pdf + */ + + for(;it!=it_last;++it,++it2){ + if(!(*it==*it2))break; + } + if(it!=it_last){ + for(const_iterator scan=it;scan!=it_last;++scan){ + if(std::find(it,scan,*scan)!=scan)continue; + std::ptrdiff_t matches=std::count(it2,it2_last,*scan); + if(matches==0||matches!=std::count(scan,it_last,*scan))return false; + } + it=it_last; + } + } + return true; + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + /* serialization */ + + template + void save_( + Archive& ar,const unsigned int version,const index_saver_type& sm)const + { + ar< + void load_(Archive& ar,const unsigned int version,const index_loader_type& lm) + { + ar>>serialization::make_nvp("position",buckets); + super::load_(ar,version,lm); + } +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + /* invariant stuff */ + + bool invariant_()const + { + if(size()==0||begin()==end()){ + if(size()!=0||begin()!=end())return false; + } + else{ + size_type s0=0; + for(const_iterator it=begin(),it_end=end();it!=it_end;++it,++s0){} + if(s0!=size())return false; + + size_type s1=0; + for(size_type buc=0;bucfinal_check_invariant_();} +#endif + +private: + node_type* header()const{return this->final_header();} + + std::size_t find_bucket(value_param_type v)const + { + return bucket(key(v)); + } + + struct link_info_non_unique + { + link_info_non_unique(node_impl_base_pointer pos): + first(pos),last(node_impl_base_pointer(0)){} + + operator const node_impl_base_pointer&()const{return this->first;} + + node_impl_base_pointer first,last; + }; + + typedef typename mpl::if_< + is_same, + node_impl_base_pointer, + link_info_non_unique + >::type link_info; + + bool link_point(value_param_type v,link_info& pos) + { + return link_point(v,pos,Category()); + } + + bool link_point( + value_param_type v,node_impl_base_pointer& pos,hashed_unique_tag) + { + for(node_impl_pointer x=pos->prior();x!=node_impl_pointer(0); + x=node_alg::after_local(x)){ + if(eq_(key(v),key(node_type::from_impl(x)->value()))){ + pos=node_impl_type::base_pointer_from(x); + return false; + } + } + return true; + } + + bool link_point( + value_param_type v,link_info_non_unique& pos,hashed_non_unique_tag) + { + for(node_impl_pointer x=pos.first->prior();x!=node_impl_pointer(0); + x=node_alg::next_to_inspect(x)){ + if(eq_(key(v),key(node_type::from_impl(x)->value()))){ + pos.first=node_impl_type::base_pointer_from(x); + pos.last=node_impl_type::base_pointer_from(last_of_range(x)); + return true; + } + } + return true; + } + + node_impl_pointer last_of_range(node_impl_pointer x)const + { + return last_of_range(x,Category()); + } + + node_impl_pointer last_of_range(node_impl_pointer x,hashed_unique_tag)const + { + return x; + } + + node_impl_pointer last_of_range( + node_impl_pointer x,hashed_non_unique_tag)const + { + node_impl_base_pointer y=x->next(); + node_impl_pointer z=y->prior(); + if(z==x){ /* range of size 1 or 2 */ + node_impl_pointer yy=node_impl_type::pointer_from(y); + return + eq_( + key(node_type::from_impl(x)->value()), + key(node_type::from_impl(yy)->value()))?yy:x; + } + else if(z->prior()==x) /* last of bucket */ + return x; + else /* group of size>2 */ + return z; + } + + node_impl_pointer end_of_range(node_impl_pointer x)const + { + return end_of_range(x,Category()); + } + + node_impl_pointer end_of_range(node_impl_pointer x,hashed_unique_tag)const + { + return node_alg::after(last_of_range(x)); + } + + node_impl_pointer end_of_range( + node_impl_pointer x,hashed_non_unique_tag)const + { + node_impl_base_pointer y=x->next(); + node_impl_pointer z=y->prior(); + if(z==x){ /* range of size 1 or 2 */ + node_impl_pointer yy=node_impl_type::pointer_from(y); + if(!eq_( + key(node_type::from_impl(x)->value()), + key(node_type::from_impl(yy)->value())))yy=x; + return yy->next()->prior()==yy? + node_impl_type::pointer_from(yy->next()): + yy->next()->prior(); + } + else if(z->prior()==x) /* last of bucket */ + return z; + else /* group of size>2 */ + return z->next()->prior()==z? + node_impl_type::pointer_from(z->next()): + z->next()->prior(); + } + + void link(node_type* x,const link_info& pos) + { + link(x,pos,Category()); + } + + void link(node_type* x,node_impl_base_pointer pos,hashed_unique_tag) + { + node_alg::link(x->impl(),pos,header()->impl()); + } + + void link(node_type* x,const link_info_non_unique& pos,hashed_non_unique_tag) + { + if(pos.last==node_impl_base_pointer(0)){ + node_alg::link(x->impl(),pos.first,header()->impl()); + } + else{ + node_alg::link( + x->impl(), + node_impl_type::pointer_from(pos.first), + node_impl_type::pointer_from(pos.last)); + } + } + + void unlink(node_type* x) + { + node_alg::unlink(x->impl()); + } + + typedef typename node_alg::unlink_undo unlink_undo; + + void unlink(node_type* x,unlink_undo& undo) + { + node_alg::unlink(x->impl(),undo); + } + + void calculate_max_load() + { + float fml=static_cast(mlf*static_cast(bucket_count())); + max_load=(std::numeric_limits::max)(); + if(max_load>fml)max_load=static_cast(fml); + } + + void reserve_for_insert(size_type n) + { + if(n>max_load){ + size_type bc =(std::numeric_limits::max)(); + float fbc=static_cast(1+static_cast(n)/mlf); + if(bc>fbc)bc =static_cast(fbc); + unchecked_rehash(bc); + } + } + + void unchecked_rehash(size_type n){unchecked_rehash(n,Category());} + + void unchecked_rehash(size_type n,hashed_unique_tag) + { + node_impl_type cpy_end_node; + node_impl_pointer cpy_end=node_impl_pointer(&cpy_end_node), + end_=header()->impl(); + bucket_array_type buckets_cpy(get_allocator(),cpy_end,n); + + if(size()!=0){ + auto_space< + std::size_t,allocator_type> hashes(get_allocator(),size()); + auto_space< + node_impl_pointer,allocator_type> node_ptrs(get_allocator(),size()); + std::size_t i=0,size_=size(); + bool within_bucket=false; + BOOST_TRY{ + for(;i!=size_;++i){ + node_impl_pointer x=end_->prior(); + + /* only this can possibly throw */ + std::size_t h=hash_(key(node_type::from_impl(x)->value())); + + hashes.data()[i]=h; + node_ptrs.data()[i]=x; + within_bucket=!node_alg::unlink_last(end_); + node_alg::link(x,buckets_cpy.at(buckets_cpy.position(h)),cpy_end); + } + } + BOOST_CATCH(...){ + if(i!=0){ + std::size_t prev_buc=buckets.position(hashes.data()[i-1]); + if(!within_bucket)prev_buc=~prev_buc; + + for(std::size_t j=i;j--;){ + std::size_t buc=buckets.position(hashes.data()[j]); + node_impl_pointer x=node_ptrs.data()[j]; + if(buc==prev_buc)node_alg::append(x,end_); + else node_alg::link(x,buckets.at(buc),end_); + prev_buc=buc; + } + } + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + end_->prior()=cpy_end->prior()!=cpy_end?cpy_end->prior():end_; + end_->next()=cpy_end->next(); + end_->prior()->next()->prior()=end_->next()->prior()->prior()=end_; + buckets.swap(buckets_cpy); + calculate_max_load(); + } + + void unchecked_rehash(size_type n,hashed_non_unique_tag) + { + node_impl_type cpy_end_node; + node_impl_pointer cpy_end=node_impl_pointer(&cpy_end_node), + end_=header()->impl(); + bucket_array_type buckets_cpy(get_allocator(),cpy_end,n); + + if(size()!=0){ + auto_space< + std::size_t,allocator_type> hashes(get_allocator(),size()); + auto_space< + node_impl_pointer,allocator_type> node_ptrs(get_allocator(),size()); + std::size_t i=0; + bool within_bucket=false; + BOOST_TRY{ + for(;;++i){ + node_impl_pointer x=end_->prior(); + if(x==end_)break; + + /* only this can possibly throw */ + std::size_t h=hash_(key(node_type::from_impl(x)->value())); + + hashes.data()[i]=h; + node_ptrs.data()[i]=x; + std::pair p= + node_alg::unlink_last_group(end_); + node_alg::link_range( + p.first,x,buckets_cpy.at(buckets_cpy.position(h)),cpy_end); + within_bucket=!(p.second); + } + } + BOOST_CATCH(...){ + if(i!=0){ + std::size_t prev_buc=buckets.position(hashes.data()[i-1]); + if(!within_bucket)prev_buc=~prev_buc; + + for(std::size_t j=i;j--;){ + std::size_t buc=buckets.position(hashes.data()[j]); + node_impl_pointer x=node_ptrs.data()[j], + y= + x->prior()->next()!=node_impl_type::base_pointer_from(x)&& + x->prior()->next()->prior()!=x? + node_impl_type::pointer_from(x->prior()->next()):x; + node_alg::unlink_range(y,x); + if(buc==prev_buc)node_alg::append_range(y,x,end_); + else node_alg::link_range(y,x,buckets.at(buc),end_); + prev_buc=buc; + } + } + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + end_->prior()=cpy_end->prior()!=cpy_end?cpy_end->prior():end_; + end_->next()=cpy_end->next(); + end_->prior()->next()->prior()=end_->next()->prior()->prior()=end_; + buckets.swap(buckets_cpy); + calculate_max_load(); + } + + bool in_place(node_impl_pointer x,key_param_type k,std::size_t buc)const + { + return in_place(x,k,buc,Category()); + } + + bool in_place( + node_impl_pointer x,key_param_type k,std::size_t buc, + hashed_unique_tag)const + { + bool found=false; + for(node_impl_pointer y=buckets.at(buc)->prior(); + y!=node_impl_pointer(0);y=node_alg::after_local(y)){ + if(y==x)found=true; + else if(eq_(k,key(node_type::from_impl(y)->value())))return false; + } + return found; + } + + bool in_place( + node_impl_pointer x,key_param_type k,std::size_t buc, + hashed_non_unique_tag)const + { + bool found=false; + int range_size=0; + for(node_impl_pointer y=buckets.at(buc)->prior();y!=node_impl_pointer(0);){ + if(node_alg::is_first_of_group(y)){ /* group of 3 or more */ + if(y==x){ + /* in place <-> equal to some other member of the group */ + return eq_( + k, + key(node_type::from_impl( + node_impl_type::pointer_from(y->next()))->value())); + } + else{ + node_impl_pointer z= + node_alg::after_local(y->next()->prior()); /* end of range */ + if(eq_(k,key(node_type::from_impl(y)->value()))){ + if(found)return false; /* x lies outside */ + do{ + if(y==x)return true; + y=node_alg::after_local(y); + }while(y!=z); + return false; /* x not found */ + } + else{ + if(range_size==1&&!found)return false; + if(range_size==2)return found; + range_size=0; + y=z; /* skip range (and potentially x, too, which is fine) */ + } + } + } + else{ /* group of 1 or 2 */ + if(y==x){ + if(range_size==1)return true; + range_size=1; + found=true; + } + else if(eq_(k,key(node_type::from_impl(y)->value()))){ + if(range_size==0&&found)return false; + if(range_size==1&&!found)return false; + if(range_size==2)return false; + ++range_size; + } + else{ + if(range_size==1&&!found)return false; + if(range_size==2)return found; + range_size=0; + } + y=node_alg::after_local(y); + } + } + return found; + } + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + void detach_iterators(node_type* x) + { + iterator it=make_iterator(x); + safe_mode::detach_equivalent_iterators(it); + } +#endif + + template + std::pair emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pairp= + this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + return std::pair(make_iterator(p.first),p.second); + } + + template + iterator emplace_hint_impl( + iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; + std::pairp= + this->final_emplace_hint_( + static_cast(position.get_node()), + BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + return make_iterator(p.first); + } + + template< + typename CompatibleHash,typename CompatiblePred + > + iterator find( + const key_type& k, + const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const + { + return find(k,hash,eq,mpl::false_()); + } + + template< + typename CompatibleKey,typename CompatibleHash,typename CompatiblePred + > + iterator find( + const CompatibleKey& k, + const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const + { + std::size_t buc=buckets.position(hash(k)); + for(node_impl_pointer x=buckets.at(buc)->prior(); + x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ + if(eq(k,key(node_type::from_impl(x)->value()))){ + return make_iterator(node_type::from_impl(x)); + } + } + return end(); + } + + template< + typename CompatibleHash,typename CompatiblePred + > + size_type count( + const key_type& k, + const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const + { + return count(k,hash,eq,mpl::false_()); + } + + template< + typename CompatibleKey,typename CompatibleHash,typename CompatiblePred + > + size_type count( + const CompatibleKey& k, + const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const + { + std::size_t buc=buckets.position(hash(k)); + for(node_impl_pointer x=buckets.at(buc)->prior(); + x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ + if(eq(k,key(node_type::from_impl(x)->value()))){ + size_type res=0; + node_impl_pointer y=end_of_range(x); + do{ + ++res; + x=node_alg::after(x); + }while(x!=y); + return res; + } + } + return 0; + } + + template< + typename CompatibleHash,typename CompatiblePred + > + std::pair equal_range( + const key_type& k, + const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const + { + return equal_range(k,hash,eq,mpl::false_()); + } + + template< + typename CompatibleKey,typename CompatibleHash,typename CompatiblePred + > + std::pair equal_range( + const CompatibleKey& k, + const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const + { + std::size_t buc=buckets.position(hash(k)); + for(node_impl_pointer x=buckets.at(buc)->prior(); + x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ + if(eq(k,key(node_type::from_impl(x)->value()))){ + return std::pair( + make_iterator(node_type::from_impl(x)), + make_iterator(node_type::from_impl(end_of_range(x)))); + } + } + return std::pair(end(),end()); + } + + key_from_value key; + hasher hash_; + key_equal eq_; + bucket_array_type buckets; + float mlf; + size_type max_load; + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ + BOOST_WORKAROUND(__MWERKS__,<=0x3003) +#pragma parse_mfunc_templ reset +#endif +}; + +/* comparison */ + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +bool operator==( + const hashed_index& x, + const hashed_index& y) +{ + return x.equals(y); +} + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +bool operator!=( + const hashed_index& x, + const hashed_index& y) +{ + return !(x==y); +} + +/* specialized algorithms */ + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +void swap( + hashed_index& x, + hashed_index& y) +{ + x.swap(y); +} + +} /* namespace multi_index::detail */ + +/* hashed index specifiers */ + +template +struct hashed_unique +{ + typedef typename detail::hashed_index_args< + Arg1,Arg2,Arg3,Arg4> index_args; + typedef typename index_args::tag_list_type::type tag_list_type; + typedef typename index_args::key_from_value_type key_from_value_type; + typedef typename index_args::hash_type hash_type; + typedef typename index_args::pred_type pred_type; + + template + struct node_class + { + typedef detail::hashed_index_node type; + }; + + template + struct index_class + { + typedef detail::hashed_index< + key_from_value_type,hash_type,pred_type, + SuperMeta,tag_list_type,detail::hashed_unique_tag> type; + }; +}; + +template +struct hashed_non_unique +{ + typedef typename detail::hashed_index_args< + Arg1,Arg2,Arg3,Arg4> index_args; + typedef typename index_args::tag_list_type::type tag_list_type; + typedef typename index_args::key_from_value_type key_from_value_type; + typedef typename index_args::hash_type hash_type; + typedef typename index_args::pred_type pred_type; + + template + struct node_class + { + typedef detail::hashed_index_node< + Super,detail::hashed_non_unique_tag> type; + }; + + template + struct index_class + { + typedef detail::hashed_index< + key_from_value_type,hash_type,pred_type, + SuperMeta,tag_list_type,detail::hashed_non_unique_tag> type; + }; +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +/* Boost.Foreach compatibility */ + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +inline boost::mpl::true_* boost_foreach_is_noncopyable( + boost::multi_index::detail::hashed_index< + KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>*&, + boost_foreach_argument_dependent_lookup_hack) +{ + return 0; +} + +#undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT +#undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index_fwd.hpp new file mode 100644 index 00000000000..d77e36c321b --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index_fwd.hpp @@ -0,0 +1,74 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_HASHED_INDEX_FWD_HPP +#define BOOST_MULTI_INDEX_HASHED_INDEX_FWD_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +class hashed_index; + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +bool operator==( + const hashed_index& x, + const hashed_index& y); + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +bool operator!=( + const hashed_index& x, + const hashed_index& y); + +template< + typename KeyFromValue,typename Hash,typename Pred, + typename SuperMeta,typename TagList,typename Category +> +void swap( + hashed_index& x, + hashed_index& y); + +} /* namespace multi_index::detail */ + +/* hashed_index specifiers */ + +template< + typename Arg1,typename Arg2=mpl::na, + typename Arg3=mpl::na,typename Arg4=mpl::na +> +struct hashed_unique; + +template< + typename Arg1,typename Arg2=mpl::na, + typename Arg3=mpl::na,typename Arg4=mpl::na +> +struct hashed_non_unique; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/identity.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/identity.hpp new file mode 100644 index 00000000000..6c832ce1562 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/identity.hpp @@ -0,0 +1,145 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_IDENTITY_HPP +#define BOOST_MULTI_INDEX_IDENTITY_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_SFINAE) +#include +#endif + +namespace boost{ + +template class reference_wrapper; /* fwd decl. */ + +namespace multi_index{ + +namespace detail{ + +/* identity is a do-nothing key extractor that returns the [const] Type& + * object passed. + * Additionally, identity is overloaded to support referece_wrappers + * of Type and "chained pointers" to Type's. By chained pointer to Type we + * mean a type P such that, given a p of type P + * *...n...*x is convertible to Type&, for some n>=1. + * Examples of chained pointers are raw and smart pointers, iterators and + * arbitrary combinations of these (vg. Type** or unique_ptr.) + */ + +template +struct const_identity_base +{ + typedef Type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if,Type&>::type +#else + Type& +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type& operator()(Type& x)const + { + return x; + } + + Type& operator()(const reference_wrapper& x)const + { + return x.get(); + } + + Type& operator()( + const reference_wrapper::type>& x + +#if BOOST_WORKAROUND(BOOST_MSVC,==1310) +/* http://lists.boost.org/Archives/boost/2015/10/226135.php */ + ,int=0 +#endif + + )const + { + return x.get(); + } +}; + +template +struct non_const_identity_base +{ + typedef Type result_type; + + /* templatized for pointer-like types */ + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type&>::type +#else + Type& +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + const Type& operator()(const Type& x)const + { + return x; + } + + Type& operator()(Type& x)const + { + return x; + } + + const Type& operator()(const reference_wrapper& x)const + { + return x.get(); + } + + Type& operator()(const reference_wrapper& x)const + { + return x.get(); + } +}; + +} /* namespace multi_index::detail */ + +template +struct identity: + mpl::if_c< + is_const::value, + detail::const_identity_base,detail::non_const_identity_base + >::type +{ +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/identity_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/identity_fwd.hpp new file mode 100644 index 00000000000..af6bd55ef5f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/identity_fwd.hpp @@ -0,0 +1,26 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_IDENTITY_FWD_HPP +#define BOOST_MULTI_INDEX_IDENTITY_FWD_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +namespace boost{ + +namespace multi_index{ + +template struct identity; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/indexed_by.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/indexed_by.hpp new file mode 100644 index 00000000000..d2217e39166 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/indexed_by.hpp @@ -0,0 +1,68 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_INDEXED_BY_HPP +#define BOOST_MULTI_INDEX_INDEXED_BY_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include + +/* An alias to mpl::vector used to hide MPL from the user. + * indexed_by contains the index specifiers for instantiation + * of a multi_index_container. + */ + +/* This user_definable macro limits the number of elements of an index list; + * useful for shortening resulting symbol names (MSVC++ 6.0, for instance, + * has problems coping with very long symbol names.) + */ + +#if !defined(BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE) +#define BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE BOOST_MPL_LIMIT_VECTOR_SIZE +#endif + +#if BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE +struct indexed_by: + mpl::vector +{ +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#undef BOOST_MULTI_INDEX_INDEXED_BY_TEMPLATE_PARM +#undef BOOST_MULTI_INDEX_INDEXED_BY_SIZE + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/key_extractors.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/key_extractors.hpp new file mode 100644 index 00000000000..60179ba2339 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/key_extractors.hpp @@ -0,0 +1,22 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_KEY_EXTRACTORS_HPP +#define BOOST_MULTI_INDEX_KEY_EXTRACTORS_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include +#include +#include +#include +#include + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/mem_fun.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/mem_fun.hpp new file mode 100644 index 00000000000..111c386c5f5 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/mem_fun.hpp @@ -0,0 +1,205 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_MEM_FUN_HPP +#define BOOST_MULTI_INDEX_MEM_FUN_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include + +#if !defined(BOOST_NO_SFINAE) +#include +#endif + +namespace boost{ + +template class reference_wrapper; /* fwd decl. */ + +namespace multi_index{ + +/* mem_fun implements a read-only key extractor based on a given non-const + * member function of a class. + * const_mem_fun does the same for const member functions. + * Additionally, mem_fun and const_mem_fun are overloaded to support + * referece_wrappers of T and "chained pointers" to T's. By chained pointer + * to T we mean a type P such that, given a p of Type P + * *...n...*x is convertible to T&, for some n>=1. + * Examples of chained pointers are raw and smart pointers, iterators and + * arbitrary combinations of these (vg. T** or unique_ptr.) + */ + +template +struct const_mem_fun +{ + typedef typename remove_reference::type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type>::type +#else + Type +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type operator()(const Class& x)const + { + return (x.*PtrToMemberFunction)(); + } + + Type operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } + + Type operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } +}; + +template +struct mem_fun +{ + typedef typename remove_reference::type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type>::type +#else + Type +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type operator()(Class& x)const + { + return (x.*PtrToMemberFunction)(); + } + + Type operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } +}; + +/* MSVC++ 6.0 has problems with const member functions as non-type template + * parameters, somehow it takes them as non-const. const_mem_fun_explicit + * workarounds this deficiency by accepting an extra type parameter that + * specifies the signature of the member function. The workaround was found at: + * Daniel, C.:"Re: weird typedef problem in VC", + * news:microsoft.public.vc.language, 21st nov 2002, + * http://groups.google.com/groups? + * hl=en&lr=&ie=UTF-8&selm=ukwvg3O0BHA.1512%40tkmsftngp05 + * + * MSVC++ 6.0 support has been dropped and [const_]mem_fun_explicit is + * deprecated. + */ + +template< + class Class,typename Type, + typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction> +struct const_mem_fun_explicit +{ + typedef typename remove_reference::type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type>::type +#else + Type +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type operator()(const Class& x)const + { + return (x.*PtrToMemberFunction)(); + } + + Type operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } + + Type operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } +}; + +template< + class Class,typename Type, + typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction> +struct mem_fun_explicit +{ + typedef typename remove_reference::type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type>::type +#else + Type +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type operator()(Class& x)const + { + return (x.*PtrToMemberFunction)(); + } + + Type operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } +}; + +/* BOOST_MULTI_INDEX_CONST_MEM_FUN and BOOST_MULTI_INDEX_MEM_FUN used to + * resolve to [const_]mem_fun_explicit for MSVC++ 6.0 and to + * [const_]mem_fun otherwise. Support for this compiler having been dropped, + * they are now just wrappers over [const_]mem_fun kept for backwards- + * compatibility reasons. + */ + +#define BOOST_MULTI_INDEX_CONST_MEM_FUN(Class,Type,MemberFunName) \ +::boost::multi_index::const_mem_fun< Class,Type,&Class::MemberFunName > +#define BOOST_MULTI_INDEX_MEM_FUN(Class,Type,MemberFunName) \ +::boost::multi_index::mem_fun< Class,Type,&Class::MemberFunName > + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/member.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/member.hpp new file mode 100644 index 00000000000..a8e645074a2 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/member.hpp @@ -0,0 +1,262 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_MEMBER_HPP +#define BOOST_MULTI_INDEX_MEMBER_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include + +#if !defined(BOOST_NO_SFINAE) +#include +#endif + +namespace boost{ + +template class reference_wrapper; /* fwd decl. */ + +namespace multi_index{ + +namespace detail{ + +/* member is a read/write key extractor for accessing a given + * member of a class. + * Additionally, member is overloaded to support referece_wrappers + * of T and "chained pointers" to T's. By chained pointer to T we mean + * a type P such that, given a p of Type P + * *...n...*x is convertible to T&, for some n>=1. + * Examples of chained pointers are raw and smart pointers, iterators and + * arbitrary combinations of these (vg. T** or unique_ptr.) + */ + +template +struct const_member_base +{ + typedef Type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type&>::type +#else + Type& +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type& operator()(const Class& x)const + { + return x.*PtrToMember; + } + + Type& operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } + + Type& operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } +}; + +template +struct non_const_member_base +{ + typedef Type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type&>::type +#else + Type& +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + const Type& operator()(const Class& x)const + { + return x.*PtrToMember; + } + + Type& operator()(Class& x)const + { + return x.*PtrToMember; + } + + const Type& operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } + + Type& operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } +}; + +} /* namespace multi_index::detail */ + +template +struct member: + mpl::if_c< + is_const::value, + detail::const_member_base, + detail::non_const_member_base + >::type +{ +}; + +namespace detail{ + +/* MSVC++ 6.0 does not support properly pointers to members as + * non-type template arguments, as reported in + * http://support.microsoft.com/default.aspx?scid=kb;EN-US;249045 + * A similar problem (though not identical) is shown by MSVC++ 7.0. + * We provide an alternative to member<> accepting offsets instead + * of pointers to members. This happens to work even for non-POD + * types (although the standard forbids use of offsetof on these), + * so it serves as a workaround in this compiler for all practical + * purposes. + * Surprisingly enough, other compilers, like Intel C++ 7.0/7.1 and + * Visual Age 6.0, have similar bugs. This replacement of member<> + * can be used for them too. + * + * Support for such old compilers is dropped and + * [non_]const_member_offset_base is deprecated. + */ + +template +struct const_member_offset_base +{ + typedef Type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type&>::type +#else + Type& +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + Type& operator()(const Class& x)const + { + return *static_cast( + static_cast( + static_cast( + static_cast(&x))+OffsetOfMember)); + } + + Type& operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } + + Type& operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } +}; + +template +struct non_const_member_offset_base +{ + typedef Type result_type; + + template + +#if !defined(BOOST_NO_SFINAE) + typename disable_if< + is_convertible,Type&>::type +#else + Type& +#endif + + operator()(const ChainedPtr& x)const + { + return operator()(*x); + } + + const Type& operator()(const Class& x)const + { + return *static_cast( + static_cast( + static_cast( + static_cast(&x))+OffsetOfMember)); + } + + Type& operator()(Class& x)const + { + return *static_cast( + static_cast( + static_cast(static_cast(&x))+OffsetOfMember)); + } + + const Type& operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } + + Type& operator()(const reference_wrapper& x)const + { + return operator()(x.get()); + } +}; + +} /* namespace multi_index::detail */ + +template +struct member_offset: + mpl::if_c< + is_const::value, + detail::const_member_offset_base, + detail::non_const_member_offset_base + >::type +{ +}; + +/* BOOST_MULTI_INDEX_MEMBER resolves to member in the normal cases, + * and to member_offset as a workaround in those defective compilers for + * which BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS is defined. + */ + +#if defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS) +#define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) \ +::boost::multi_index::member_offset< Class,Type,offsetof(Class,MemberName) > +#else +#define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) \ +::boost::multi_index::member< Class,Type,&Class::MemberName > +#endif + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index.hpp new file mode 100644 index 00000000000..5bcd69de8c9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index.hpp @@ -0,0 +1,114 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_ORDERED_INDEX_HPP +#define BOOST_MULTI_INDEX_ORDERED_INDEX_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* no augment policy for plain ordered indices */ + +struct null_augment_policy +{ + template + struct augmented_interface + { + typedef OrderedIndexImpl type; + }; + + template + struct augmented_node + { + typedef OrderedIndexNodeImpl type; + }; + + template static void add(Pointer,Pointer){} + template static void remove(Pointer,Pointer){} + template static void copy(Pointer,Pointer){} + template static void rotate_left(Pointer,Pointer){} + template static void rotate_right(Pointer,Pointer){} + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + /* invariant stuff */ + + template static bool invariant(Pointer){return true;} + +#endif +}; + +} /* namespace multi_index::detail */ + +/* ordered_index specifiers */ + +template +struct ordered_unique +{ + typedef typename detail::ordered_index_args< + Arg1,Arg2,Arg3> index_args; + typedef typename index_args::tag_list_type::type tag_list_type; + typedef typename index_args::key_from_value_type key_from_value_type; + typedef typename index_args::compare_type compare_type; + + template + struct node_class + { + typedef detail::ordered_index_node type; + }; + + template + struct index_class + { + typedef detail::ordered_index< + key_from_value_type,compare_type, + SuperMeta,tag_list_type,detail::ordered_unique_tag, + detail::null_augment_policy> type; + }; +}; + +template +struct ordered_non_unique +{ + typedef detail::ordered_index_args< + Arg1,Arg2,Arg3> index_args; + typedef typename index_args::tag_list_type::type tag_list_type; + typedef typename index_args::key_from_value_type key_from_value_type; + typedef typename index_args::compare_type compare_type; + + template + struct node_class + { + typedef detail::ordered_index_node type; + }; + + template + struct index_class + { + typedef detail::ordered_index< + key_from_value_type,compare_type, + SuperMeta,tag_list_type,detail::ordered_non_unique_tag, + detail::null_augment_policy> type; + }; +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index_fwd.hpp new file mode 100644 index 00000000000..fe44aaf860d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index_fwd.hpp @@ -0,0 +1,35 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_ORDERED_INDEX_FWD_HPP +#define BOOST_MULTI_INDEX_ORDERED_INDEX_FWD_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include +#include + +namespace boost{ + +namespace multi_index{ + +/* ordered_index specifiers */ + +template +struct ordered_unique; + +template +struct ordered_non_unique; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index.hpp new file mode 100644 index 00000000000..fe1884ddd38 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index.hpp @@ -0,0 +1,1167 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_HPP +#define BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) +#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x) \ + detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ + detail::make_obj_guard(x,&random_access_index::check_invariant_); \ + BOOST_JOIN(check_invariant_,__LINE__).touch(); +#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT \ + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(*this) +#else +#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x) +#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* random_access_index adds a layer of random access indexing + * to a given Super + */ + +template +class random_access_index: + BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + ,public safe_mode::safe_container< + random_access_index > +#endif + +{ +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ + BOOST_WORKAROUND(__MWERKS__,<=0x3003) +/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the + * lifetime of const references bound to temporaries --precisely what + * scopeguards are. + */ + +#pragma parse_mfunc_templ off +#endif + + typedef typename SuperMeta::type super; + +protected: + typedef random_access_index_node< + typename super::node_type> node_type; + +private: + typedef typename node_type::impl_type node_impl_type; + typedef random_access_index_ptr_array< + typename super::final_allocator_type> ptr_array; + typedef typename ptr_array::pointer node_impl_ptr_pointer; + +public: + /* types */ + + typedef typename node_type::value_type value_type; + typedef tuples::null_type ctor_args; + typedef typename super::final_allocator_type allocator_type; + typedef typename allocator_type::reference reference; + typedef typename allocator_type::const_reference const_reference; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef safe_mode::safe_iterator< + rnd_node_iterator, + random_access_index> iterator; +#else + typedef rnd_node_iterator iterator; +#endif + + typedef iterator const_iterator; + + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef typename allocator_type::pointer pointer; + typedef typename allocator_type::const_pointer const_pointer; + typedef typename + boost::reverse_iterator reverse_iterator; + typedef typename + boost::reverse_iterator const_reverse_iterator; + typedef TagList tag_list; + +protected: + typedef typename super::final_node_type final_node_type; + typedef tuples::cons< + ctor_args, + typename super::ctor_args_list> ctor_args_list; + typedef typename mpl::push_front< + typename super::index_type_list, + random_access_index>::type index_type_list; + typedef typename mpl::push_front< + typename super::iterator_type_list, + iterator>::type iterator_type_list; + typedef typename mpl::push_front< + typename super::const_iterator_type_list, + const_iterator>::type const_iterator_type_list; + typedef typename super::copy_map_type copy_map_type; + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + typedef typename super::index_saver_type index_saver_type; + typedef typename super::index_loader_type index_loader_type; +#endif + +private: +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef safe_mode::safe_container< + random_access_index> safe_super; +#endif + + typedef typename call_traits< + value_type>::param_type value_param_type; + + /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * expansion. + */ + + typedef std::pair emplace_return_type; + +public: + + /* construct/copy/destroy + * Default and copy ctors are in the protected section as indices are + * not supposed to be created on their own. No range ctor either. + */ + + random_access_index& operator=( + const random_access_index& x) + { + this->final()=x.final(); + return *this; + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + random_access_index& operator=( + std::initializer_list list) + { + this->final()=list; + return *this; + } +#endif + + template + void assign(InputIterator first,InputIterator last) + { + assign_iter(first,last,mpl::not_ >()); + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void assign(std::initializer_list list) + { + assign(list.begin(),list.end()); + } +#endif + + void assign(size_type n,value_param_type value) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + clear(); + for(size_type i=0;ifinal().get_allocator(); + } + + /* iterators */ + + iterator begin()BOOST_NOEXCEPT + {return make_iterator(node_type::from_impl(*ptrs.begin()));} + const_iterator begin()const BOOST_NOEXCEPT + {return make_iterator(node_type::from_impl(*ptrs.begin()));} + iterator + end()BOOST_NOEXCEPT{return make_iterator(header());} + const_iterator + end()const BOOST_NOEXCEPT{return make_iterator(header());} + reverse_iterator + rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} + const_reverse_iterator + rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} + reverse_iterator + rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} + const_reverse_iterator + rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} + const_iterator + cbegin()const BOOST_NOEXCEPT{return begin();} + const_iterator + cend()const BOOST_NOEXCEPT{return end();} + const_reverse_iterator + crbegin()const BOOST_NOEXCEPT{return rbegin();} + const_reverse_iterator + crend()const BOOST_NOEXCEPT{return rend();} + + iterator iterator_to(const value_type& x) + { + return make_iterator(node_from_value(&x)); + } + + const_iterator iterator_to(const value_type& x)const + { + return make_iterator(node_from_value(&x)); + } + + /* capacity */ + + bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} + size_type size()const BOOST_NOEXCEPT{return this->final_size_();} + size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} + size_type capacity()const BOOST_NOEXCEPT{return ptrs.capacity();} + + void reserve(size_type n) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + ptrs.reserve(n); + } + + void shrink_to_fit() + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + ptrs.shrink_to_fit(); + } + + void resize(size_type n) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + if(n>size()) + for(size_type m=n-size();m--;) + this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK); + else if(nsize())for(size_type m=n-size();m--;)this->final_insert_(x); + else if(nvalue(); + } + + const_reference at(size_type n)const + { + if(n>=size())throw_exception(std::out_of_range("random access index")); + return node_type::from_impl(*ptrs.at(n))->value(); + } + + const_reference front()const{return operator[](0);} + const_reference back()const{return operator[](size()-1);} + + /* modifiers */ + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace_front,emplace_front_impl) + + std::pair push_front(const value_type& x) + {return insert(begin(),x);} + std::pair push_front(BOOST_RV_REF(value_type) x) + {return insert(begin(),boost::move(x));} + void pop_front(){erase(begin());} + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace_back,emplace_back_impl) + + std::pair push_back(const value_type& x) + {return insert(end(),x);} + std::pair push_back(BOOST_RV_REF(value_type) x) + {return insert(end(),boost::move(x));} + void pop_back(){erase(--end());} + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( + emplace_return_type,emplace,emplace_impl,iterator,position) + + std::pair insert(iterator position,const value_type& x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_(x); + if(p.second&&position.get_node()!=header()){ + relocate(position.get_node(),p.first); + } + return std::pair(make_iterator(p.first),p.second); + } + + std::pair insert(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_(x); + if(p.second&&position.get_node()!=header()){ + relocate(position.get_node(),p.first); + } + return std::pair(make_iterator(p.first),p.second); + } + + void insert(iterator position,size_type n,value_param_type x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + size_type s=0; + BOOST_TRY{ + while(n--){ + if(push_back(x).second)++s; + } + } + BOOST_CATCH(...){ + relocate(position,end()-s,end()); + BOOST_RETHROW; + } + BOOST_CATCH_END + relocate(position,end()-s,end()); + } + + template + void insert(iterator position,InputIterator first,InputIterator last) + { + insert_iter(position,first,last,mpl::not_ >()); + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void insert(iterator position,std::initializer_list list) + { + insert(position,list.begin(),list.end()); + } +#endif + + iterator erase(iterator position) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + this->final_erase_(static_cast(position++.get_node())); + return position; + } + + iterator erase(iterator first,iterator last) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); + BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + difference_type n=last-first; + relocate(end(),first,last); + while(n--)pop_back(); + return last; + } + + bool replace(iterator position,const value_type& x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + return this->final_replace_( + x,static_cast(position.get_node())); + } + + bool replace(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + return this->final_replace_rv_( + x,static_cast(position.get_node())); + } + + template + bool modify(iterator position,Modifier mod) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + /* MSVC++ 6.0 optimizer on safe mode code chokes if this + * this is not added. Left it for all compilers as it does no + * harm. + */ + + position.detach(); +#endif + + return this->final_modify_( + mod,static_cast(position.get_node())); + } + + template + bool modify(iterator position,Modifier mod,Rollback back_) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + /* MSVC++ 6.0 optimizer on safe mode code chokes if this + * this is not added. Left it for all compilers as it does no + * harm. + */ + + position.detach(); +#endif + + return this->final_modify_( + mod,back_,static_cast(position.get_node())); + } + + void swap(random_access_index& x) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x); + this->final_swap_(x.final()); + } + + void clear()BOOST_NOEXCEPT + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + this->final_clear_(); + } + + /* list operations */ + + void splice(iterator position,random_access_index& x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(*this,x); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + iterator first=x.begin(),last=x.end(); + size_type n=0; + BOOST_TRY{ + while(first!=last){ + if(push_back(*first).second){ + first=x.erase(first); + ++n; + } + else ++first; + } + } + BOOST_CATCH(...){ + relocate(position,end()-n,end()); + BOOST_RETHROW; + } + BOOST_CATCH_END + relocate(position,end()-n,end()); + } + + void splice( + iterator position,random_access_index& x,iterator i) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + if(&x==this)relocate(position,i); + else{ + if(insert(position,*i).second){ + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + /* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following + * workaround is needed. Left it for all compilers as it does no + * harm. + */ + i.detach(); + x.erase(x.make_iterator(i.get_node())); +#else + x.erase(i); +#endif + + } + } + } + + void splice( + iterator position,random_access_index& x, + iterator first,iterator last) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x); + BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + if(&x==this)relocate(position,first,last); + else{ + size_type n=0; + BOOST_TRY{ + while(first!=last){ + if(push_back(*first).second){ + first=x.erase(first); + ++n; + } + else ++first; + } + } + BOOST_CATCH(...){ + relocate(position,end()-n,end()); + BOOST_RETHROW; + } + BOOST_CATCH_END + relocate(position,end()-n,end()); + } + } + + void remove(value_param_type value) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + difference_type n= + end()-make_iterator( + random_access_index_remove( + ptrs, + ::boost::bind(std::equal_to(),::boost::arg<1>(),value))); + while(n--)pop_back(); + } + + template + void remove_if(Predicate pred) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + difference_type n= + end()-make_iterator(random_access_index_remove(ptrs,pred)); + while(n--)pop_back(); + } + + void unique() + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + difference_type n= + end()-make_iterator( + random_access_index_unique( + ptrs,std::equal_to())); + while(n--)pop_back(); + } + + template + void unique(BinaryPredicate binary_pred) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + difference_type n= + end()-make_iterator( + random_access_index_unique(ptrs,binary_pred)); + while(n--)pop_back(); + } + + void merge(random_access_index& x) + { + if(this!=&x){ + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + size_type s=size(); + splice(end(),x); + random_access_index_inplace_merge( + get_allocator(),ptrs,ptrs.at(s),std::less()); + } + } + + template + void merge(random_access_index& x,Compare comp) + { + if(this!=&x){ + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + size_type s=size(); + splice(end(),x); + random_access_index_inplace_merge( + get_allocator(),ptrs,ptrs.at(s),comp); + } + } + + void sort() + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + random_access_index_sort( + get_allocator(),ptrs,std::less()); + } + + template + void sort(Compare comp) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + random_access_index_sort( + get_allocator(),ptrs,comp); + } + + void reverse()BOOST_NOEXCEPT + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + node_impl_type::reverse(ptrs.begin(),ptrs.end()); + } + + /* rearrange operations */ + + void relocate(iterator position,iterator i) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,*this); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + if(position!=i)relocate(position.get_node(),i.get_node()); + } + + void relocate(iterator position,iterator first,iterator last) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); + BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); + BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + if(position!=last)relocate( + position.get_node(),first.get_node(),last.get_node()); + } + + template + void rearrange(InputIterator first) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + for(node_impl_ptr_pointer p0=ptrs.begin(),p0_end=ptrs.end(); + p0!=p0_end;++first,++p0){ + const value_type& v1=*first; + node_impl_ptr_pointer p1=node_from_value(&v1)->up(); + + std::swap(*p0,*p1); + (*p0)->up()=p0; + (*p1)->up()=p1; + } + } + +BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: + random_access_index( + const ctor_args_list& args_list,const allocator_type& al): + super(args_list.get_tail(),al), + ptrs(al,header()->impl(),0) + { + } + + random_access_index(const random_access_index& x): + super(x), + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super(), +#endif + + ptrs(x.get_allocator(),header()->impl(),x.size()) + { + /* The actual copying takes place in subsequent call to copy_(). + */ + } + + random_access_index( + const random_access_index& x,do_not_copy_elements_tag): + super(x,do_not_copy_elements_tag()), + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super(), +#endif + + ptrs(x.get_allocator(),header()->impl(),0) + { + } + + ~random_access_index() + { + /* the container is guaranteed to be empty by now */ + } + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + iterator make_iterator(node_type* node){return iterator(node,this);} + const_iterator make_iterator(node_type* node)const + {return const_iterator(node,const_cast(this));} +#else + iterator make_iterator(node_type* node){return iterator(node);} + const_iterator make_iterator(node_type* node)const + {return const_iterator(node);} +#endif + + void copy_( + const random_access_index& x,const copy_map_type& map) + { + for(node_impl_ptr_pointer begin_org=x.ptrs.begin(), + begin_cpy=ptrs.begin(), + end_org=x.ptrs.end(); + begin_org!=end_org;++begin_org,++begin_cpy){ + *begin_cpy= + static_cast( + map.find( + static_cast( + node_type::from_impl(*begin_org))))->impl(); + (*begin_cpy)->up()=begin_cpy; + } + + super::copy_(x,map); + } + + template + final_node_type* insert_( + value_param_type v,final_node_type*& x,Variant variant) + { + ptrs.room_for_one(); + final_node_type* res=super::insert_(v,x,variant); + if(res==x)ptrs.push_back(static_cast(x)->impl()); + return res; + } + + template + final_node_type* insert_( + value_param_type v,node_type* position,final_node_type*& x,Variant variant) + { + ptrs.room_for_one(); + final_node_type* res=super::insert_(v,position,x,variant); + if(res==x)ptrs.push_back(static_cast(x)->impl()); + return res; + } + + void erase_(node_type* x) + { + ptrs.erase(x->impl()); + super::erase_(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + } + + void delete_all_nodes_() + { + for(node_impl_ptr_pointer x=ptrs.begin(),x_end=ptrs.end();x!=x_end;++x){ + this->final_delete_node_( + static_cast(node_type::from_impl(*x))); + } + } + + void clear_() + { + super::clear_(); + ptrs.clear(); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::detach_dereferenceable_iterators(); +#endif + } + + void swap_(random_access_index& x) + { + ptrs.swap(x.ptrs); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_(x); + } + + void swap_elements_(random_access_index& x) + { + ptrs.swap(x.ptrs); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_elements_(x); + } + + template + bool replace_(value_param_type v,node_type* x,Variant variant) + { + return super::replace_(v,x,variant); + } + + bool modify_(node_type* x) + { + BOOST_TRY{ + if(!super::modify_(x)){ + ptrs.erase(x->impl()); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + + return false; + } + else return true; + } + BOOST_CATCH(...){ + ptrs.erase(x->impl()); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + bool modify_rollback_(node_type* x) + { + return super::modify_rollback_(x); + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + /* serialization */ + + template + void save_( + Archive& ar,const unsigned int version,const index_saver_type& sm)const + { + sm.save(begin(),end(),ar,version); + super::save_(ar,version,sm); + } + + template + void load_( + Archive& ar,const unsigned int version,const index_loader_type& lm) + { + { + typedef random_access_index_loader loader; + + loader ld(get_allocator(),ptrs); + lm.load( + ::boost::bind( + &loader::rearrange,&ld,::boost::arg<1>(),::boost::arg<2>()), + ar,version); + } /* exit scope so that ld frees its resources */ + super::load_(ar,version,lm); + } +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + /* invariant stuff */ + + bool invariant_()const + { + if(size()>capacity())return false; + if(size()==0||begin()==end()){ + if(size()!=0||begin()!=end())return false; + } + else{ + size_type s=0; + for(const_iterator it=begin(),it_end=end();;++it,++s){ + if(*(it.get_node()->up())!=it.get_node()->impl())return false; + if(it==it_end)break; + } + if(s!=size())return false; + } + + return super::invariant_(); + } + + /* This forwarding function eases things for the boost::mem_fn construct + * in BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT. Actually, + * final_check_invariant is already an inherited member function of index. + */ + void check_invariant_()const{this->final_check_invariant_();} +#endif + +private: + node_type* header()const{return this->final_header();} + + static void relocate(node_type* position,node_type* x) + { + node_impl_type::relocate(position->up(),x->up()); + } + + static void relocate(node_type* position,node_type* first,node_type* last) + { + node_impl_type::relocate( + position->up(),first->up(),last->up()); + } + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + void detach_iterators(node_type* x) + { + iterator it=make_iterator(x); + safe_mode::detach_equivalent_iterators(it); + } +#endif + + template + void assign_iter(InputIterator first,InputIterator last,mpl::true_) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + clear(); + for(;first!=last;++first)this->final_insert_ref_(*first); + } + + void assign_iter(size_type n,value_param_type value,mpl::false_) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + clear(); + for(size_type i=0;i + void insert_iter( + iterator position,InputIterator first,InputIterator last,mpl::true_) + { + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + size_type s=0; + BOOST_TRY{ + for(;first!=last;++first){ + if(this->final_insert_ref_(*first).second)++s; + } + } + BOOST_CATCH(...){ + relocate(position,end()-s,end()); + BOOST_RETHROW; + } + BOOST_CATCH_END + relocate(position,end()-s,end()); + } + + void insert_iter( + iterator position,size_type n,value_param_type x,mpl::false_) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + size_type s=0; + BOOST_TRY{ + while(n--){ + if(push_back(x).second)++s; + } + } + BOOST_CATCH(...){ + relocate(position,end()-s,end()); + BOOST_RETHROW; + } + BOOST_CATCH_END + relocate(position,end()-s,end()); + } + + template + std::pair emplace_front_impl( + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } + + template + std::pair emplace_back_impl( + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } + + template + std::pair emplace_impl( + iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; + std::pair p= + this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + if(p.second&&position.get_node()!=header()){ + relocate(position.get_node(),p.first); + } + return std::pair(make_iterator(p.first),p.second); + } + + ptr_array ptrs; + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ + BOOST_WORKAROUND(__MWERKS__,<=0x3003) +#pragma parse_mfunc_templ reset +#endif +}; + +/* comparison */ + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator==( + const random_access_index& x, + const random_access_index& y) +{ + return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); +} + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator<( + const random_access_index& x, + const random_access_index& y) +{ + return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); +} + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator!=( + const random_access_index& x, + const random_access_index& y) +{ + return !(x==y); +} + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator>( + const random_access_index& x, + const random_access_index& y) +{ + return y +bool operator>=( + const random_access_index& x, + const random_access_index& y) +{ + return !(x +bool operator<=( + const random_access_index& x, + const random_access_index& y) +{ + return !(x>y); +} + +/* specialized algorithms */ + +template +void swap( + random_access_index& x, + random_access_index& y) +{ + x.swap(y); +} + +} /* namespace multi_index::detail */ + +/* random access index specifier */ + +template +struct random_access +{ + BOOST_STATIC_ASSERT(detail::is_tag::value); + + template + struct node_class + { + typedef detail::random_access_index_node type; + }; + + template + struct index_class + { + typedef detail::random_access_index< + SuperMeta,typename TagList::type> type; + }; +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +/* Boost.Foreach compatibility */ + +template +inline boost::mpl::true_* boost_foreach_is_noncopyable( + boost::multi_index::detail::random_access_index*&, + boost_foreach_argument_dependent_lookup_hack) +{ + return 0; +} + +#undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT +#undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index_fwd.hpp new file mode 100644 index 00000000000..2ea19295426 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index_fwd.hpp @@ -0,0 +1,91 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_FWD_HPP +#define BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_FWD_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +class random_access_index; + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator==( + const random_access_index& x, + const random_access_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator<( + const random_access_index& x, + const random_access_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator!=( + const random_access_index& x, + const random_access_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator>( + const random_access_index& x, + const random_access_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator>=( + const random_access_index& x, + const random_access_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator<=( + const random_access_index& x, + const random_access_index& y); + +template +void swap( + random_access_index& x, + random_access_index& y); + +} /* namespace multi_index::detail */ + +/* index specifiers */ + +template > +struct random_access; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index.hpp new file mode 100644 index 00000000000..4b24c4f5937 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index.hpp @@ -0,0 +1,382 @@ +/* Copyright 2003-2017 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_RANKED_INDEX_HPP +#define BOOST_MULTI_INDEX_RANKED_INDEX_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* ranked_index augments a given ordered index to provide rank operations */ + +template +struct ranked_node:OrderedIndexNodeImpl +{ + std::size_t size; +}; + +template +class ranked_index:public OrderedIndexImpl +{ + typedef OrderedIndexImpl super; + +protected: + typedef typename super::node_type node_type; + typedef typename super::node_impl_pointer node_impl_pointer; + +public: + typedef typename super::ctor_args_list ctor_args_list; + typedef typename super::allocator_type allocator_type; + typedef typename super::iterator iterator; + + /* rank operations */ + + iterator nth(std::size_t n)const + { + return this->make_iterator(node_type::from_impl( + ranked_index_nth(n,this->header()->impl()))); + } + + std::size_t rank(iterator position)const + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + + return ranked_index_rank( + position.get_node()->impl(),this->header()->impl()); + } + + template + std::size_t find_rank(const CompatibleKey& x)const + { + return ranked_index_find_rank( + this->root(),this->header(),this->key,x,this->comp_); + } + + template + std::size_t find_rank( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + return ranked_index_find_rank( + this->root(),this->header(),this->key,x,comp); + } + + template + std::size_t lower_bound_rank(const CompatibleKey& x)const + { + return ranked_index_lower_bound_rank( + this->root(),this->header(),this->key,x,this->comp_); + } + + template + std::size_t lower_bound_rank( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + return ranked_index_lower_bound_rank( + this->root(),this->header(),this->key,x,comp); + } + + template + std::size_t upper_bound_rank(const CompatibleKey& x)const + { + return ranked_index_upper_bound_rank( + this->root(),this->header(),this->key,x,this->comp_); + } + + template + std::size_t upper_bound_rank( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + return ranked_index_upper_bound_rank( + this->root(),this->header(),this->key,x,comp); + } + + template + std::pair equal_range_rank( + const CompatibleKey& x)const + { + return ranked_index_equal_range_rank( + this->root(),this->header(),this->key,x,this->comp_); + } + + template + std::pair equal_range_rank( + const CompatibleKey& x,const CompatibleCompare& comp)const + { + return ranked_index_equal_range_rank( + this->root(),this->header(),this->key,x,comp); + } + + template + std::pair + range_rank(LowerBounder lower,UpperBounder upper)const + { + typedef typename mpl::if_< + is_same, + BOOST_DEDUCED_TYPENAME mpl::if_< + is_same, + both_unbounded_tag, + lower_unbounded_tag + >::type, + BOOST_DEDUCED_TYPENAME mpl::if_< + is_same, + upper_unbounded_tag, + none_unbounded_tag + >::type + >::type dispatch; + + return range_rank(lower,upper,dispatch()); + } + +protected: + ranked_index(const ranked_index& x):super(x){}; + + ranked_index(const ranked_index& x,do_not_copy_elements_tag): + super(x,do_not_copy_elements_tag()){}; + + ranked_index( + const ctor_args_list& args_list,const allocator_type& al): + super(args_list,al){} + +private: + template + std::pair + range_rank(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const + { + node_type* y=this->header(); + node_type* z=this->root(); + + if(!z)return std::pair(0,0); + + std::size_t s=z->impl()->size; + + do{ + if(!lower(this->key(z->value()))){ + z=node_type::from_impl(z->right()); + } + else if(!upper(this->key(z->value()))){ + y=z; + s-=ranked_node_size(y->right())+1; + z=node_type::from_impl(z->left()); + } + else{ + return std::pair( + s-z->impl()->size+ + lower_range_rank(node_type::from_impl(z->left()),z,lower), + s-ranked_node_size(z->right())+ + upper_range_rank(node_type::from_impl(z->right()),y,upper)); + } + }while(z); + + return std::pair(s,s); + } + + template + std::pair + range_rank(LowerBounder,UpperBounder upper,lower_unbounded_tag)const + { + return std::pair( + 0, + upper_range_rank(this->root(),this->header(),upper)); + } + + template + std::pair + range_rank(LowerBounder lower,UpperBounder,upper_unbounded_tag)const + { + return std::pair( + lower_range_rank(this->root(),this->header(),lower), + this->size()); + } + + template + std::pair + range_rank(LowerBounder,UpperBounder,both_unbounded_tag)const + { + return std::pair(0,this->size()); + } + + template + std::size_t + lower_range_rank(node_type* top,node_type* y,LowerBounder lower)const + { + if(!top)return 0; + + std::size_t s=top->impl()->size; + + do{ + if(lower(this->key(top->value()))){ + y=top; + s-=ranked_node_size(y->right())+1; + top=node_type::from_impl(top->left()); + } + else top=node_type::from_impl(top->right()); + }while(top); + + return s; + } + + template + std::size_t + upper_range_rank(node_type* top,node_type* y,UpperBounder upper)const + { + if(!top)return 0; + + std::size_t s=top->impl()->size; + + do{ + if(!upper(this->key(top->value()))){ + y=top; + s-=ranked_node_size(y->right())+1; + top=node_type::from_impl(top->left()); + } + else top=node_type::from_impl(top->right()); + }while(top); + + return s; + } +}; + +/* augmenting policy for ordered_index */ + +struct rank_policy +{ + template + struct augmented_node + { + typedef ranked_node type; + }; + + template + struct augmented_interface + { + typedef ranked_index type; + }; + + /* algorithmic stuff */ + + template + static void add(Pointer x,Pointer root) + { + x->size=1; + while(x!=root){ + x=x->parent(); + ++(x->size); + } + } + + template + static void remove(Pointer x,Pointer root) + { + while(x!=root){ + x=x->parent(); + --(x->size); + } + } + + template + static void copy(Pointer x,Pointer y) + { + y->size=x->size; + } + + template + static void rotate_left(Pointer x,Pointer y) /* in: x==y->left() */ + { + y->size=x->size; + x->size=ranked_node_size(x->left())+ranked_node_size(x->right())+1; + } + + template + static void rotate_right(Pointer x,Pointer y) /* in: x==y->right() */ + { + rotate_left(x,y); + } + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + /* invariant stuff */ + + template + static bool invariant(Pointer x) + { + return x->size==ranked_node_size(x->left())+ranked_node_size(x->right())+1; + } +#endif +}; + +} /* namespace multi_index::detail */ + +/* ranked_index specifiers */ + +template +struct ranked_unique +{ + typedef typename detail::ordered_index_args< + Arg1,Arg2,Arg3> index_args; + typedef typename index_args::tag_list_type::type tag_list_type; + typedef typename index_args::key_from_value_type key_from_value_type; + typedef typename index_args::compare_type compare_type; + + template + struct node_class + { + typedef detail::ordered_index_node type; + }; + + template + struct index_class + { + typedef detail::ordered_index< + key_from_value_type,compare_type, + SuperMeta,tag_list_type,detail::ordered_unique_tag, + detail::rank_policy> type; + }; +}; + +template +struct ranked_non_unique +{ + typedef detail::ordered_index_args< + Arg1,Arg2,Arg3> index_args; + typedef typename index_args::tag_list_type::type tag_list_type; + typedef typename index_args::key_from_value_type key_from_value_type; + typedef typename index_args::compare_type compare_type; + + template + struct node_class + { + typedef detail::ordered_index_node type; + }; + + template + struct index_class + { + typedef detail::ordered_index< + key_from_value_type,compare_type, + SuperMeta,tag_list_type,detail::ordered_non_unique_tag, + detail::rank_policy> type; + }; +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index_fwd.hpp new file mode 100644 index 00000000000..380d3480736 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index_fwd.hpp @@ -0,0 +1,35 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_RANKED_INDEX_FWD_HPP +#define BOOST_MULTI_INDEX_RANKED_INDEX_FWD_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include +#include + +namespace boost{ + +namespace multi_index{ + +/* ranked_index specifiers */ + +template +struct ranked_unique; + +template +struct ranked_non_unique; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/safe_mode_errors.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/safe_mode_errors.hpp new file mode 100644 index 00000000000..1904706edec --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/safe_mode_errors.hpp @@ -0,0 +1,48 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_SAFE_MODE_ERRORS_HPP +#define BOOST_MULTI_INDEX_SAFE_MODE_ERRORS_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +namespace boost{ + +namespace multi_index{ + +namespace safe_mode{ + +/* Error codes for Boost.MultiIndex safe mode. These go in a separate + * header so that the user can include it when redefining + * BOOST_MULTI_INDEX_SAFE_MODE_ASSERT prior to the inclusion of + * any other header of Boost.MultiIndex. + */ + +enum error_code +{ + invalid_iterator=0, + not_dereferenceable_iterator, + not_incrementable_iterator, + not_decrementable_iterator, + not_owner, + not_same_owner, + invalid_range, + inside_range, + out_of_bounds, + same_container +}; + +} /* namespace multi_index::safe_mode */ + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index.hpp new file mode 100644 index 00000000000..424eebc376d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index.hpp @@ -0,0 +1,1062 @@ +/* Copyright 2003-2015 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_SEQUENCED_INDEX_HPP +#define BOOST_MULTI_INDEX_SEQUENCED_INDEX_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) +#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) \ + detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ + detail::make_obj_guard(x,&sequenced_index::check_invariant_); \ + BOOST_JOIN(check_invariant_,__LINE__).touch(); +#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT \ + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(*this) +#else +#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) +#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT +#endif + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +/* sequenced_index adds a layer of sequenced indexing to a given Super */ + +template +class sequenced_index: + BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + ,public safe_mode::safe_container< + sequenced_index > +#endif + +{ +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ + BOOST_WORKAROUND(__MWERKS__,<=0x3003) +/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the + * lifetime of const references bound to temporaries --precisely what + * scopeguards are. + */ + +#pragma parse_mfunc_templ off +#endif + + typedef typename SuperMeta::type super; + +protected: + typedef sequenced_index_node< + typename super::node_type> node_type; + +private: + typedef typename node_type::impl_type node_impl_type; + +public: + /* types */ + + typedef typename node_type::value_type value_type; + typedef tuples::null_type ctor_args; + typedef typename super::final_allocator_type allocator_type; + typedef typename allocator_type::reference reference; + typedef typename allocator_type::const_reference const_reference; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef safe_mode::safe_iterator< + bidir_node_iterator, + sequenced_index> iterator; +#else + typedef bidir_node_iterator iterator; +#endif + + typedef iterator const_iterator; + + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef typename allocator_type::pointer pointer; + typedef typename allocator_type::const_pointer const_pointer; + typedef typename + boost::reverse_iterator reverse_iterator; + typedef typename + boost::reverse_iterator const_reverse_iterator; + typedef TagList tag_list; + +protected: + typedef typename super::final_node_type final_node_type; + typedef tuples::cons< + ctor_args, + typename super::ctor_args_list> ctor_args_list; + typedef typename mpl::push_front< + typename super::index_type_list, + sequenced_index>::type index_type_list; + typedef typename mpl::push_front< + typename super::iterator_type_list, + iterator>::type iterator_type_list; + typedef typename mpl::push_front< + typename super::const_iterator_type_list, + const_iterator>::type const_iterator_type_list; + typedef typename super::copy_map_type copy_map_type; + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + typedef typename super::index_saver_type index_saver_type; + typedef typename super::index_loader_type index_loader_type; +#endif + +private: +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef safe_mode::safe_container< + sequenced_index> safe_super; +#endif + + typedef typename call_traits::param_type value_param_type; + + /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL + * expansion. + */ + + typedef std::pair emplace_return_type; + +public: + + /* construct/copy/destroy + * Default and copy ctors are in the protected section as indices are + * not supposed to be created on their own. No range ctor either. + */ + + sequenced_index& operator=( + const sequenced_index& x) + { + this->final()=x.final(); + return *this; + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + sequenced_index& operator=( + std::initializer_list list) + { + this->final()=list; + return *this; + } +#endif + + template + void assign(InputIterator first,InputIterator last) + { + assign_iter(first,last,mpl::not_ >()); + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void assign(std::initializer_list list) + { + assign(list.begin(),list.end()); + } +#endif + + void assign(size_type n,value_param_type value) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + clear(); + for(size_type i=0;ifinal().get_allocator(); + } + + /* iterators */ + + iterator begin()BOOST_NOEXCEPT + {return make_iterator(node_type::from_impl(header()->next()));} + const_iterator begin()const BOOST_NOEXCEPT + {return make_iterator(node_type::from_impl(header()->next()));} + iterator + end()BOOST_NOEXCEPT{return make_iterator(header());} + const_iterator + end()const BOOST_NOEXCEPT{return make_iterator(header());} + reverse_iterator + rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} + const_reverse_iterator + rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} + reverse_iterator + rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} + const_reverse_iterator + rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} + const_iterator + cbegin()const BOOST_NOEXCEPT{return begin();} + const_iterator + cend()const BOOST_NOEXCEPT{return end();} + const_reverse_iterator + crbegin()const BOOST_NOEXCEPT{return rbegin();} + const_reverse_iterator + crend()const BOOST_NOEXCEPT{return rend();} + + iterator iterator_to(const value_type& x) + { + return make_iterator(node_from_value(&x)); + } + + const_iterator iterator_to(const value_type& x)const + { + return make_iterator(node_from_value(&x)); + } + + /* capacity */ + + bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} + size_type size()const BOOST_NOEXCEPT{return this->final_size_();} + size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} + + void resize(size_type n) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + if(n>size()){ + for(size_type m=n-size();m--;) + this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK); + } + else if(nsize())insert(end(),n-size(),x); + else if(n push_front(const value_type& x) + {return insert(begin(),x);} + std::pair push_front(BOOST_RV_REF(value_type) x) + {return insert(begin(),boost::move(x));} + void pop_front(){erase(begin());} + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( + emplace_return_type,emplace_back,emplace_back_impl) + + std::pair push_back(const value_type& x) + {return insert(end(),x);} + std::pair push_back(BOOST_RV_REF(value_type) x) + {return insert(end(),boost::move(x));} + void pop_back(){erase(--end());} + + BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( + emplace_return_type,emplace,emplace_impl,iterator,position) + + std::pair insert(iterator position,const value_type& x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_(x); + if(p.second&&position.get_node()!=header()){ + relink(position.get_node(),p.first); + } + return std::pair(make_iterator(p.first),p.second); + } + + std::pair insert(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + std::pair p=this->final_insert_rv_(x); + if(p.second&&position.get_node()!=header()){ + relink(position.get_node(),p.first); + } + return std::pair(make_iterator(p.first),p.second); + } + + void insert(iterator position,size_type n,value_param_type x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + for(size_type i=0;i + void insert(iterator position,InputIterator first,InputIterator last) + { + insert_iter(position,first,last,mpl::not_ >()); + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + void insert(iterator position,std::initializer_list list) + { + insert(position,list.begin(),list.end()); + } +#endif + + iterator erase(iterator position) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + this->final_erase_(static_cast(position++.get_node())); + return position; + } + + iterator erase(iterator first,iterator last) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); + BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + while(first!=last){ + first=erase(first); + } + return first; + } + + bool replace(iterator position,const value_type& x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + return this->final_replace_( + x,static_cast(position.get_node())); + } + + bool replace(iterator position,BOOST_RV_REF(value_type) x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + return this->final_replace_rv_( + x,static_cast(position.get_node())); + } + + template + bool modify(iterator position,Modifier mod) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + /* MSVC++ 6.0 optimizer on safe mode code chokes if this + * this is not added. Left it for all compilers as it does no + * harm. + */ + + position.detach(); +#endif + + return this->final_modify_( + mod,static_cast(position.get_node())); + } + + template + bool modify(iterator position,Modifier mod,Rollback back_) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + /* MSVC++ 6.0 optimizer on safe mode code chokes if this + * this is not added. Left it for all compilers as it does no + * harm. + */ + + position.detach(); +#endif + + return this->final_modify_( + mod,back_,static_cast(position.get_node())); + } + + void swap(sequenced_index& x) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x); + this->final_swap_(x.final()); + } + + void clear()BOOST_NOEXCEPT + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + this->final_clear_(); + } + + /* list operations */ + + void splice(iterator position,sequenced_index& x) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(*this,x); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + iterator first=x.begin(),last=x.end(); + while(first!=last){ + if(insert(position,*first).second)first=x.erase(first); + else ++first; + } + } + + void splice(iterator position,sequenced_index& x,iterator i) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + if(&x==this){ + if(position!=i)relink(position.get_node(),i.get_node()); + } + else{ + if(insert(position,*i).second){ + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + /* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following + * workaround is needed. Left it for all compilers as it does no + * harm. + */ + i.detach(); + x.erase(x.make_iterator(i.get_node())); +#else + x.erase(i); +#endif + + } + } + } + + void splice( + iterator position,sequenced_index& x, + iterator first,iterator last) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x); + BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + if(&x==this){ + BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last); + if(position!=last)relink( + position.get_node(),first.get_node(),last.get_node()); + } + else{ + while(first!=last){ + if(insert(position,*first).second)first=x.erase(first); + else ++first; + } + } + } + + void remove(value_param_type value) + { + sequenced_index_remove( + *this, + ::boost::bind(std::equal_to(),::boost::arg<1>(),value)); + } + + template + void remove_if(Predicate pred) + { + sequenced_index_remove(*this,pred); + } + + void unique() + { + sequenced_index_unique(*this,std::equal_to()); + } + + template + void unique(BinaryPredicate binary_pred) + { + sequenced_index_unique(*this,binary_pred); + } + + void merge(sequenced_index& x) + { + sequenced_index_merge(*this,x,std::less()); + } + + template + void merge(sequenced_index& x,Compare comp) + { + sequenced_index_merge(*this,x,comp); + } + + void sort() + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + sequenced_index_sort(header(),std::less()); + } + + template + void sort(Compare comp) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + sequenced_index_sort(header(),comp); + } + + void reverse()BOOST_NOEXCEPT + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + node_impl_type::reverse(header()->impl()); + } + + /* rearrange operations */ + + void relocate(iterator position,iterator i) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); + BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + if(position!=i)relink(position.get_node(),i.get_node()); + } + + void relocate(iterator position,iterator first,iterator last) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); + BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); + BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + if(position!=last)relink( + position.get_node(),first.get_node(),last.get_node()); + } + + template + void rearrange(InputIterator first) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + node_type* pos=header(); + for(size_type s=size();s--;){ + const value_type& v=*first++; + relink(pos,node_from_value(&v)); + } + } + +BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: + sequenced_index(const ctor_args_list& args_list,const allocator_type& al): + super(args_list.get_tail(),al) + { + empty_initialize(); + } + + sequenced_index(const sequenced_index& x): + super(x) + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + ,safe_super() +#endif + + { + /* the actual copying takes place in subsequent call to copy_() */ + } + + sequenced_index( + const sequenced_index& x,do_not_copy_elements_tag): + super(x,do_not_copy_elements_tag()) + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + ,safe_super() +#endif + + { + empty_initialize(); + } + + ~sequenced_index() + { + /* the container is guaranteed to be empty by now */ + } + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + iterator make_iterator(node_type* node){return iterator(node,this);} + const_iterator make_iterator(node_type* node)const + {return const_iterator(node,const_cast(this));} +#else + iterator make_iterator(node_type* node){return iterator(node);} + const_iterator make_iterator(node_type* node)const + {return const_iterator(node);} +#endif + + void copy_( + const sequenced_index& x,const copy_map_type& map) + { + node_type* org=x.header(); + node_type* cpy=header(); + do{ + node_type* next_org=node_type::from_impl(org->next()); + node_type* next_cpy=map.find(static_cast(next_org)); + cpy->next()=next_cpy->impl(); + next_cpy->prior()=cpy->impl(); + org=next_org; + cpy=next_cpy; + }while(org!=x.header()); + + super::copy_(x,map); + } + + template + final_node_type* insert_( + value_param_type v,final_node_type*& x,Variant variant) + { + final_node_type* res=super::insert_(v,x,variant); + if(res==x)link(static_cast(x)); + return res; + } + + template + final_node_type* insert_( + value_param_type v,node_type* position,final_node_type*& x,Variant variant) + { + final_node_type* res=super::insert_(v,position,x,variant); + if(res==x)link(static_cast(x)); + return res; + } + + void erase_(node_type* x) + { + unlink(x); + super::erase_(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + } + + void delete_all_nodes_() + { + for(node_type* x=node_type::from_impl(header()->next());x!=header();){ + node_type* y=node_type::from_impl(x->next()); + this->final_delete_node_(static_cast(x)); + x=y; + } + } + + void clear_() + { + super::clear_(); + empty_initialize(); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::detach_dereferenceable_iterators(); +#endif + } + + void swap_(sequenced_index& x) + { +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_(x); + } + + void swap_elements_(sequenced_index& x) + { +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + safe_super::swap(x); +#endif + + super::swap_elements_(x); + } + + template + bool replace_(value_param_type v,node_type* x,Variant variant) + { + return super::replace_(v,x,variant); + } + + bool modify_(node_type* x) + { + BOOST_TRY{ + if(!super::modify_(x)){ + unlink(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + + return false; + } + else return true; + } + BOOST_CATCH(...){ + unlink(x); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + detach_iterators(x); +#endif + + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + bool modify_rollback_(node_type* x) + { + return super::modify_rollback_(x); + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + /* serialization */ + + template + void save_( + Archive& ar,const unsigned int version,const index_saver_type& sm)const + { + sm.save(begin(),end(),ar,version); + super::save_(ar,version,sm); + } + + template + void load_( + Archive& ar,const unsigned int version,const index_loader_type& lm) + { + lm.load( + ::boost::bind( + &sequenced_index::rearranger,this,::boost::arg<1>(),::boost::arg<2>()), + ar,version); + super::load_(ar,version,lm); + } +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + /* invariant stuff */ + + bool invariant_()const + { + if(size()==0||begin()==end()){ + if(size()!=0||begin()!=end()|| + header()->next()!=header()->impl()|| + header()->prior()!=header()->impl())return false; + } + else{ + size_type s=0; + for(const_iterator it=begin(),it_end=end();it!=it_end;++it,++s){ + if(it.get_node()->next()->prior()!=it.get_node()->impl())return false; + if(it.get_node()->prior()->next()!=it.get_node()->impl())return false; + } + if(s!=size())return false; + } + + return super::invariant_(); + } + + /* This forwarding function eases things for the boost::mem_fn construct + * in BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT. Actually, + * final_check_invariant is already an inherited member function of index. + */ + void check_invariant_()const{this->final_check_invariant_();} +#endif + +private: + node_type* header()const{return this->final_header();} + + void empty_initialize() + { + header()->prior()=header()->next()=header()->impl(); + } + + void link(node_type* x) + { + node_impl_type::link(x->impl(),header()->impl()); + }; + + static void unlink(node_type* x) + { + node_impl_type::unlink(x->impl()); + } + + static void relink(node_type* position,node_type* x) + { + node_impl_type::relink(position->impl(),x->impl()); + } + + static void relink(node_type* position,node_type* first,node_type* last) + { + node_impl_type::relink( + position->impl(),first->impl(),last->impl()); + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + void rearranger(node_type* position,node_type *x) + { + if(!position)position=header(); + node_type::increment(position); + if(position!=x)relink(position,x); + } +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + void detach_iterators(node_type* x) + { + iterator it=make_iterator(x); + safe_mode::detach_equivalent_iterators(it); + } +#endif + + template + void assign_iter(InputIterator first,InputIterator last,mpl::true_) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + clear(); + for(;first!=last;++first)this->final_insert_ref_(*first); + } + + void assign_iter(size_type n,value_param_type value,mpl::false_) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + clear(); + for(size_type i=0;i + void insert_iter( + iterator position,InputIterator first,InputIterator last,mpl::true_) + { + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + for(;first!=last;++first){ + std::pair p= + this->final_insert_ref_(*first); + if(p.second&&position.get_node()!=header()){ + relink(position.get_node(),p.first); + } + } + } + + void insert_iter( + iterator position,size_type n,value_param_type x,mpl::false_) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + for(size_type i=0;i + std::pair emplace_front_impl( + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } + + template + std::pair emplace_back_impl( + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + } + + template + std::pair emplace_impl( + iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); + BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); + BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; + std::pair p= + this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + if(p.second&&position.get_node()!=header()){ + relink(position.get_node(),p.first); + } + return std::pair(make_iterator(p.first),p.second); + } + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ + BOOST_WORKAROUND(__MWERKS__,<=0x3003) +#pragma parse_mfunc_templ reset +#endif +}; + +/* comparison */ + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator==( + const sequenced_index& x, + const sequenced_index& y) +{ + return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); +} + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator<( + const sequenced_index& x, + const sequenced_index& y) +{ + return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); +} + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator!=( + const sequenced_index& x, + const sequenced_index& y) +{ + return !(x==y); +} + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator>( + const sequenced_index& x, + const sequenced_index& y) +{ + return y +bool operator>=( + const sequenced_index& x, + const sequenced_index& y) +{ + return !(x +bool operator<=( + const sequenced_index& x, + const sequenced_index& y) +{ + return !(x>y); +} + +/* specialized algorithms */ + +template +void swap( + sequenced_index& x, + sequenced_index& y) +{ + x.swap(y); +} + +} /* namespace multi_index::detail */ + +/* sequenced index specifier */ + +template +struct sequenced +{ + BOOST_STATIC_ASSERT(detail::is_tag::value); + + template + struct node_class + { + typedef detail::sequenced_index_node type; + }; + + template + struct index_class + { + typedef detail::sequenced_index type; + }; +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +/* Boost.Foreach compatibility */ + +template +inline boost::mpl::true_* boost_foreach_is_noncopyable( + boost::multi_index::detail::sequenced_index*&, + boost_foreach_argument_dependent_lookup_hack) +{ + return 0; +} + +#undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT +#undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index_fwd.hpp new file mode 100644 index 00000000000..a019f2a6d2f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index_fwd.hpp @@ -0,0 +1,91 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_SEQUENCED_INDEX_FWD_HPP +#define BOOST_MULTI_INDEX_SEQUENCED_INDEX_FWD_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include + +namespace boost{ + +namespace multi_index{ + +namespace detail{ + +template +class sequenced_index; + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator==( + const sequenced_index& x, + const sequenced_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator<( + const sequenced_index& x, + const sequenced_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator!=( + const sequenced_index& x, + const sequenced_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator>( + const sequenced_index& x, + const sequenced_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator>=( + const sequenced_index& x, + const sequenced_index& y); + +template< + typename SuperMeta1,typename TagList1, + typename SuperMeta2,typename TagList2 +> +bool operator<=( + const sequenced_index& x, + const sequenced_index& y); + +template +void swap( + sequenced_index& x, + sequenced_index& y); + +} /* namespace multi_index::detail */ + +/* index specifiers */ + +template > +struct sequenced; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/tag.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/tag.hpp new file mode 100644 index 00000000000..ce51f8241ee --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index/tag.hpp @@ -0,0 +1,88 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_TAG_HPP +#define BOOST_MULTI_INDEX_TAG_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* A wrapper of mpl::vector used to hide MPL from the user. + * tag contains types used as tag names for indices in get() functions. + */ + +/* This user_definable macro limits the number of elements of a tag; + * useful for shortening resulting symbol names (MSVC++ 6.0, for instance, + * has problems coping with very long symbol names.) + */ + +#if !defined(BOOST_MULTI_INDEX_LIMIT_TAG_SIZE) +#define BOOST_MULTI_INDEX_LIMIT_TAG_SIZE BOOST_MPL_LIMIT_VECTOR_SIZE +#endif + +#if BOOST_MULTI_INDEX_LIMIT_TAG_SIZE +struct is_tag +{ + BOOST_STATIC_CONSTANT(bool,value=(is_base_and_derived::value)); +}; + +} /* namespace multi_index::detail */ + +template< + BOOST_PP_ENUM_BINARY_PARAMS( + BOOST_MULTI_INDEX_TAG_SIZE, + typename T, + =mpl::na BOOST_PP_INTERCEPT) +> +struct tag:private detail::tag_marker +{ + /* The mpl::transform pass produces shorter symbols (without + * trailing mpl::na's.) + */ + + typedef typename mpl::transform< + mpl::vector, + mpl::identity + >::type type; + + BOOST_STATIC_ASSERT(detail::no_duplicate_tags::value); +}; + +} /* namespace multi_index */ + +} /* namespace boost */ + +#undef BOOST_MULTI_INDEX_TAG_SIZE + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index_container.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index_container.hpp new file mode 100644 index 00000000000..9993a8dfa10 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index_container.hpp @@ -0,0 +1,1362 @@ +/* Multiply indexed container. + * + * Copyright 2003-2014 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_HPP +#define BOOST_MULTI_INDEX_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +#include +#include +#include +#include +#include +#include +#include +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) +#include +#define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x) \ + detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ + detail::make_obj_guard(x,&multi_index_container::check_invariant_); \ + BOOST_JOIN(check_invariant_,__LINE__).touch(); +#define BOOST_MULTI_INDEX_CHECK_INVARIANT \ + BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(*this) +#else +#define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x) +#define BOOST_MULTI_INDEX_CHECK_INVARIANT +#endif + +namespace boost{ + +namespace multi_index{ + +#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500)) +#pragma warning(push) +#pragma warning(disable:4522) /* spurious warning on multiple operator=()'s */ +#endif + +template +class multi_index_container: + private ::boost::base_from_member< + typename boost::detail::allocator::rebind_to< + Allocator, + typename detail::multi_index_node_type< + Value,IndexSpecifierList,Allocator>::type + >::type>, + BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS detail::header_holder< + typename boost::detail::allocator::rebind_to< + Allocator, + typename detail::multi_index_node_type< + Value,IndexSpecifierList,Allocator>::type + >::type::pointer, + multi_index_container >, + public detail::multi_index_base_type< + Value,IndexSpecifierList,Allocator>::type +{ +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ + BOOST_WORKAROUND(__MWERKS__,<=0x3003) +/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the + * lifetime of const references bound to temporaries --precisely what + * scopeguards are. + */ + +#pragma parse_mfunc_templ off +#endif + +private: + BOOST_COPYABLE_AND_MOVABLE(multi_index_container) + +#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + template friend class detail::index_base; + template friend struct detail::header_holder; + template friend struct detail::converter; +#endif + + typedef typename detail::multi_index_base_type< + Value,IndexSpecifierList,Allocator>::type super; + typedef typename + boost::detail::allocator::rebind_to< + Allocator, + typename super::node_type + >::type node_allocator; + typedef ::boost::base_from_member< + node_allocator> bfm_allocator; + typedef detail::header_holder< + typename node_allocator::pointer, + multi_index_container> bfm_header; + + +public: + /* All types are inherited from super, a few are explicitly + * brought forward here to save us some typename's. + */ + + typedef typename super::ctor_args_list ctor_args_list; + typedef IndexSpecifierList index_specifier_type_list; + + typedef typename super::index_type_list index_type_list; + + typedef typename super::iterator_type_list iterator_type_list; + typedef typename super::const_iterator_type_list const_iterator_type_list; + typedef typename super::value_type value_type; + typedef typename super::final_allocator_type allocator_type; + typedef typename super::iterator iterator; + typedef typename super::const_iterator const_iterator; + + BOOST_STATIC_ASSERT( + detail::no_duplicate_tags_in_index_list::value); + + /* global project() needs to see this publicly */ + + typedef typename super::node_type node_type; + + /* construct/copy/destroy */ + + explicit multi_index_container( + +#if BOOST_WORKAROUND(__IBMCPP__,<=600) + /* VisualAge seems to have an ETI issue with the default values + * for arguments args_list and al. + */ + + const ctor_args_list& args_list= + typename mpl::identity::type:: + ctor_args_list(), + const allocator_type& al= + typename mpl::identity::type:: + allocator_type()): +#else + const ctor_args_list& args_list=ctor_args_list(), + const allocator_type& al=allocator_type()): +#endif + + bfm_allocator(al), + super(args_list,bfm_allocator::member), + node_count(0) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + } + + explicit multi_index_container(const allocator_type& al): + bfm_allocator(al), + super(ctor_args_list(),bfm_allocator::member), + node_count(0) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + } + + template + multi_index_container( + InputIterator first,InputIterator last, + +#if BOOST_WORKAROUND(__IBMCPP__,<=600) + /* VisualAge seems to have an ETI issue with the default values + * for arguments args_list and al. + */ + + const ctor_args_list& args_list= + typename mpl::identity::type:: + ctor_args_list(), + const allocator_type& al= + typename mpl::identity::type:: + allocator_type()): +#else + const ctor_args_list& args_list=ctor_args_list(), + const allocator_type& al=allocator_type()): +#endif + + bfm_allocator(al), + super(args_list,bfm_allocator::member), + node_count(0) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + BOOST_TRY{ + iterator hint=super::end(); + for(;first!=last;++first){ + hint=super::make_iterator( + insert_ref_(*first,hint.get_node()).first); + ++hint; + } + } + BOOST_CATCH(...){ + clear_(); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + multi_index_container( + std::initializer_list list, + const ctor_args_list& args_list=ctor_args_list(), + const allocator_type& al=allocator_type()): + bfm_allocator(al), + super(args_list,bfm_allocator::member), + node_count(0) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + BOOST_TRY{ + typedef const Value* init_iterator; + + iterator hint=super::end(); + for(init_iterator first=list.begin(),last=list.end(); + first!=last;++first){ + hint=super::make_iterator(insert_(*first,hint.get_node()).first); + ++hint; + } + } + BOOST_CATCH(...){ + clear_(); + BOOST_RETHROW; + } + BOOST_CATCH_END + } +#endif + + multi_index_container( + const multi_index_container& x): + bfm_allocator(x.bfm_allocator::member), + bfm_header(), + super(x), + node_count(0) + { + copy_map_type map(bfm_allocator::member,x.size(),x.header(),header()); + for(const_iterator it=x.begin(),it_end=x.end();it!=it_end;++it){ + map.clone(it.get_node()); + } + super::copy_(x,map); + map.release(); + node_count=x.size(); + + /* Not until this point are the indices required to be consistent, + * hence the position of the invariant checker. + */ + + BOOST_MULTI_INDEX_CHECK_INVARIANT; + } + + multi_index_container(BOOST_RV_REF(multi_index_container) x): + bfm_allocator(x.bfm_allocator::member), + bfm_header(), + super(x,detail::do_not_copy_elements_tag()), + node_count(0) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x); + swap_elements_(x); + } + + ~multi_index_container() + { + delete_all_nodes_(); + } + +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + /* As per http://www.boost.org/doc/html/move/emulation_limitations.html + * #move.emulation_limitations.assignment_operator + */ + + multi_index_container& operator=( + const multi_index_container& x) + { + multi_index_container y(x); + this->swap(y); + return *this; + } +#endif + + multi_index_container& operator=( + BOOST_COPY_ASSIGN_REF(multi_index_container) x) + { + multi_index_container y(x); + this->swap(y); + return *this; + } + + multi_index_container& operator=( + BOOST_RV_REF(multi_index_container) x) + { + this->swap(x); + return *this; + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + multi_index_container& operator=( + std::initializer_list list) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + typedef const Value* init_iterator; + + multi_index_container x(*this,detail::do_not_copy_elements_tag()); + iterator hint=x.end(); + for(init_iterator first=list.begin(),last=list.end(); + first!=last;++first){ + hint=x.make_iterator(x.insert_(*first,hint.get_node()).first); + ++hint; + } + x.swap_elements_(*this); + return*this; + } +#endif + + allocator_type get_allocator()const BOOST_NOEXCEPT + { + return allocator_type(bfm_allocator::member); + } + + /* retrieval of indices by number */ + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) + template + struct nth_index + { + BOOST_STATIC_ASSERT(N>=0&&N::type::value); + typedef typename mpl::at_c::type type; + }; + + template + typename nth_index::type& get()BOOST_NOEXCEPT + { + BOOST_STATIC_ASSERT(N>=0&&N::type::value); + return *this; + } + + template + const typename nth_index::type& get()const BOOST_NOEXCEPT + { + BOOST_STATIC_ASSERT(N>=0&&N::type::value); + return *this; + } +#endif + + /* retrieval of indices by tag */ + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) + template + struct index + { + typedef typename mpl::find_if< + index_type_list, + detail::has_tag + >::type iter; + + BOOST_STATIC_CONSTANT( + bool,index_found=!(is_same::type >::value)); + BOOST_STATIC_ASSERT(index_found); + + typedef typename mpl::deref::type type; + }; + + template + typename index::type& get()BOOST_NOEXCEPT + { + return *this; + } + + template + const typename index::type& get()const BOOST_NOEXCEPT + { + return *this; + } +#endif + + /* projection of iterators by number */ + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) + template + struct nth_index_iterator + { + typedef typename nth_index::type::iterator type; + }; + + template + struct nth_index_const_iterator + { + typedef typename nth_index::type::const_iterator type; + }; + + template + typename nth_index_iterator::type project(IteratorType it) + { + typedef typename nth_index::type index_type; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ + BOOST_STATIC_ASSERT( + (mpl::contains::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + BOOST_MULTI_INDEX_CHECK_IS_OWNER( + it,static_cast(*this)); + + return index_type::make_iterator(static_cast(it.get_node())); + } + + template + typename nth_index_const_iterator::type project(IteratorType it)const + { + typedef typename nth_index::type index_type; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ + BOOST_STATIC_ASSERT(( + mpl::contains::value|| + mpl::contains::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + BOOST_MULTI_INDEX_CHECK_IS_OWNER( + it,static_cast(*this)); + return index_type::make_iterator(static_cast(it.get_node())); + } +#endif + + /* projection of iterators by tag */ + +#if !defined(BOOST_NO_MEMBER_TEMPLATES) + template + struct index_iterator + { + typedef typename index::type::iterator type; + }; + + template + struct index_const_iterator + { + typedef typename index::type::const_iterator type; + }; + + template + typename index_iterator::type project(IteratorType it) + { + typedef typename index::type index_type; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ + BOOST_STATIC_ASSERT( + (mpl::contains::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + BOOST_MULTI_INDEX_CHECK_IS_OWNER( + it,static_cast(*this)); + return index_type::make_iterator(static_cast(it.get_node())); + } + + template + typename index_const_iterator::type project(IteratorType it)const + { + typedef typename index::type index_type; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ + BOOST_STATIC_ASSERT(( + mpl::contains::value|| + mpl::contains::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + BOOST_MULTI_INDEX_CHECK_IS_OWNER( + it,static_cast(*this)); + return index_type::make_iterator(static_cast(it.get_node())); + } +#endif + +BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: + typedef typename super::copy_map_type copy_map_type; + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + multi_index_container( + const multi_index_container& x, + detail::do_not_copy_elements_tag): + bfm_allocator(x.bfm_allocator::member), + bfm_header(), + super(x,detail::do_not_copy_elements_tag()), + node_count(0) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + } +#endif + + node_type* header()const + { + return &*bfm_header::member; + } + + node_type* allocate_node() + { + return &*bfm_allocator::member.allocate(1); + } + + void deallocate_node(node_type* x) + { + typedef typename node_allocator::pointer node_pointer; + bfm_allocator::member.deallocate(static_cast(x),1); + } + + bool empty_()const + { + return node_count==0; + } + + std::size_t size_()const + { + return node_count; + } + + std::size_t max_size_()const + { + return static_cast(-1); + } + + template + std::pair insert_(const Value& v,Variant variant) + { + node_type* x=0; + node_type* res=super::insert_(v,x,variant); + if(res==x){ + ++node_count; + return std::pair(res,true); + } + else{ + return std::pair(res,false); + } + } + + std::pair insert_(const Value& v) + { + return insert_(v,detail::lvalue_tag()); + } + + std::pair insert_rv_(const Value& v) + { + return insert_(v,detail::rvalue_tag()); + } + + template + std::pair insert_ref_(T& t) + { + node_type* x=allocate_node(); + BOOST_TRY{ + new(&x->value()) value_type(t); + BOOST_TRY{ + node_type* res=super::insert_(x->value(),x,detail::emplaced_tag()); + if(res==x){ + ++node_count; + return std::pair(res,true); + } + else{ + boost::detail::allocator::destroy(&x->value()); + deallocate_node(x); + return std::pair(res,false); + } + } + BOOST_CATCH(...){ + boost::detail::allocator::destroy(&x->value()); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + BOOST_CATCH(...){ + deallocate_node(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + std::pair insert_ref_(const value_type& x) + { + return insert_(x); + } + + std::pair insert_ref_(value_type& x) + { + return insert_(x); + } + + template + std::pair emplace_( + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + node_type* x=allocate_node(); + BOOST_TRY{ + detail::vartempl_placement_new( + &x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + BOOST_TRY{ + node_type* res=super::insert_(x->value(),x,detail::emplaced_tag()); + if(res==x){ + ++node_count; + return std::pair(res,true); + } + else{ + boost::detail::allocator::destroy(&x->value()); + deallocate_node(x); + return std::pair(res,false); + } + } + BOOST_CATCH(...){ + boost::detail::allocator::destroy(&x->value()); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + BOOST_CATCH(...){ + deallocate_node(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + template + std::pair insert_( + const Value& v,node_type* position,Variant variant) + { + node_type* x=0; + node_type* res=super::insert_(v,position,x,variant); + if(res==x){ + ++node_count; + return std::pair(res,true); + } + else{ + return std::pair(res,false); + } + } + + std::pair insert_(const Value& v,node_type* position) + { + return insert_(v,position,detail::lvalue_tag()); + } + + std::pair insert_rv_(const Value& v,node_type* position) + { + return insert_(v,position,detail::rvalue_tag()); + } + + template + std::pair insert_ref_( + T& t,node_type* position) + { + node_type* x=allocate_node(); + BOOST_TRY{ + new(&x->value()) value_type(t); + BOOST_TRY{ + node_type* res=super::insert_( + x->value(),position,x,detail::emplaced_tag()); + if(res==x){ + ++node_count; + return std::pair(res,true); + } + else{ + boost::detail::allocator::destroy(&x->value()); + deallocate_node(x); + return std::pair(res,false); + } + } + BOOST_CATCH(...){ + boost::detail::allocator::destroy(&x->value()); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + BOOST_CATCH(...){ + deallocate_node(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + std::pair insert_ref_( + const value_type& x,node_type* position) + { + return insert_(x,position); + } + + std::pair insert_ref_( + value_type& x,node_type* position) + { + return insert_(x,position); + } + + template + std::pair emplace_hint_( + node_type* position, + BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) + { + node_type* x=allocate_node(); + BOOST_TRY{ + detail::vartempl_placement_new( + &x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); + BOOST_TRY{ + node_type* res=super::insert_( + x->value(),position,x,detail::emplaced_tag()); + if(res==x){ + ++node_count; + return std::pair(res,true); + } + else{ + boost::detail::allocator::destroy(&x->value()); + deallocate_node(x); + return std::pair(res,false); + } + } + BOOST_CATCH(...){ + boost::detail::allocator::destroy(&x->value()); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + BOOST_CATCH(...){ + deallocate_node(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + void erase_(node_type* x) + { + --node_count; + super::erase_(x); + deallocate_node(x); + } + + void delete_node_(node_type* x) + { + super::delete_node_(x); + deallocate_node(x); + } + + void delete_all_nodes_() + { + super::delete_all_nodes_(); + } + + void clear_() + { + delete_all_nodes_(); + super::clear_(); + node_count=0; + } + + void swap_(multi_index_container& x) + { + if(bfm_allocator::member!=x.bfm_allocator::member){ + detail::adl_swap(bfm_allocator::member,x.bfm_allocator::member); + } + std::swap(bfm_header::member,x.bfm_header::member); + super::swap_(x); + std::swap(node_count,x.node_count); + } + + void swap_elements_( + multi_index_container& x) + { + std::swap(bfm_header::member,x.bfm_header::member); + super::swap_elements_(x); + std::swap(node_count,x.node_count); + } + + bool replace_(const Value& k,node_type* x) + { + return super::replace_(k,x,detail::lvalue_tag()); + } + + bool replace_rv_(const Value& k,node_type* x) + { + return super::replace_(k,x,detail::rvalue_tag()); + } + + template + bool modify_(Modifier& mod,node_type* x) + { + mod(const_cast(x->value())); + + BOOST_TRY{ + if(!super::modify_(x)){ + deallocate_node(x); + --node_count; + return false; + } + else return true; + } + BOOST_CATCH(...){ + deallocate_node(x); + --node_count; + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + template + bool modify_(Modifier& mod,Rollback& back_,node_type* x) + { + mod(const_cast(x->value())); + + bool b; + BOOST_TRY{ + b=super::modify_rollback_(x); + } + BOOST_CATCH(...){ + BOOST_TRY{ + back_(const_cast(x->value())); + BOOST_RETHROW; + } + BOOST_CATCH(...){ + this->erase_(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + BOOST_CATCH_END + + BOOST_TRY{ + if(!b){ + back_(const_cast(x->value())); + return false; + } + else return true; + } + BOOST_CATCH(...){ + this->erase_(x); + BOOST_RETHROW; + } + BOOST_CATCH_END + } + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + /* serialization */ + + friend class boost::serialization::access; + + BOOST_SERIALIZATION_SPLIT_MEMBER() + + typedef typename super::index_saver_type index_saver_type; + typedef typename super::index_loader_type index_loader_type; + + template + void save(Archive& ar,const unsigned int version)const + { + const serialization::collection_size_type s(size_()); + const detail::serialization_version value_version; + ar< + void load(Archive& ar,const unsigned int version) + { + BOOST_MULTI_INDEX_CHECK_INVARIANT; + + clear_(); + serialization::collection_size_type s; + detail::serialization_version value_version; + if(version<1){ + std::size_t sz; + ar>>serialization::make_nvp("count",sz); + s=static_cast(sz); + } + else{ + ar>>serialization::make_nvp("count",s); + } + if(version<2){ + value_version=0; + } + else{ + ar>>serialization::make_nvp("value_version",value_version); + } + + index_loader_type lm(bfm_allocator::member,s); + + for(std::size_t n=0;n value("item",ar,value_version); + std::pair p=insert_( + value.get(),super::end().get_node()); + if(!p.second)throw_exception( + archive::archive_exception( + archive::archive_exception::other_exception)); + ar.reset_object_address(&p.first->value(),&value.get()); + lm.add(p.first,ar,version); + } + lm.add_track(header(),ar,version); + + super::load_(ar,version,lm); + } +#endif + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) + /* invariant stuff */ + + bool invariant_()const + { + return super::invariant_(); + } + + void check_invariant_()const + { + BOOST_MULTI_INDEX_INVARIANT_ASSERT(invariant_()); + } +#endif + +private: + std::size_t node_count; + +#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ + BOOST_WORKAROUND(__MWERKS__,<=0x3003) +#pragma parse_mfunc_templ reset +#endif +}; + +#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500)) +#pragma warning(pop) /* C4522 */ +#endif + +/* retrieval of indices by number */ + +template +struct nth_index +{ + BOOST_STATIC_CONSTANT( + int, + M=mpl::size::type::value); + BOOST_STATIC_ASSERT(N>=0&&N::type type; +}; + +template +typename nth_index< + multi_index_container,N>::type& +get( + multi_index_container& m)BOOST_NOEXCEPT +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename nth_index< + multi_index_container< + Value,IndexSpecifierList,Allocator>, + N + >::type index_type; + + BOOST_STATIC_ASSERT(N>=0&& + N< + mpl::size< + BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list + >::type::value); + + return detail::converter::index(m); +} + +template +const typename nth_index< + multi_index_container,N>::type& +get( + const multi_index_container& m +)BOOST_NOEXCEPT +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename nth_index< + multi_index_container< + Value,IndexSpecifierList,Allocator>, + N + >::type index_type; + + BOOST_STATIC_ASSERT(N>=0&& + N< + mpl::size< + BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list + >::type::value); + + return detail::converter::index(m); +} + +/* retrieval of indices by tag */ + +template +struct index +{ + typedef typename MultiIndexContainer::index_type_list index_type_list; + + typedef typename mpl::find_if< + index_type_list, + detail::has_tag + >::type iter; + + BOOST_STATIC_CONSTANT( + bool,index_found=!(is_same::type >::value)); + BOOST_STATIC_ASSERT(index_found); + + typedef typename mpl::deref::type type; +}; + +template< + typename Tag,typename Value,typename IndexSpecifierList,typename Allocator +> +typename ::boost::multi_index::index< + multi_index_container,Tag>::type& +get( + multi_index_container& m)BOOST_NOEXCEPT +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename ::boost::multi_index::index< + multi_index_container< + Value,IndexSpecifierList,Allocator>, + Tag + >::type index_type; + + return detail::converter::index(m); +} + +template< + typename Tag,typename Value,typename IndexSpecifierList,typename Allocator +> +const typename ::boost::multi_index::index< + multi_index_container,Tag>::type& +get( + const multi_index_container& m +)BOOST_NOEXCEPT +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename ::boost::multi_index::index< + multi_index_container< + Value,IndexSpecifierList,Allocator>, + Tag + >::type index_type; + + return detail::converter::index(m); +} + +/* projection of iterators by number */ + +template +struct nth_index_iterator +{ + typedef typename nth_index::type::iterator type; +}; + +template +struct nth_index_const_iterator +{ + typedef typename nth_index::type::const_iterator type; +}; + +template< + int N,typename IteratorType, + typename Value,typename IndexSpecifierList,typename Allocator> +typename nth_index_iterator< + multi_index_container,N>::type +project( + multi_index_container& m, + IteratorType it) +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename nth_index::type index_type; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */ + BOOST_STATIC_ASSERT(( + mpl::contains< + BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list, + IteratorType>::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef detail::converter< + multi_index_type, + BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter; + BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m)); +#endif + + return detail::converter::iterator( + m,static_cast(it.get_node())); +} + +template< + int N,typename IteratorType, + typename Value,typename IndexSpecifierList,typename Allocator> +typename nth_index_const_iterator< + multi_index_container,N>::type +project( + const multi_index_container& m, + IteratorType it) +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename nth_index::type index_type; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */ + BOOST_STATIC_ASSERT(( + mpl::contains< + BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list, + IteratorType>::value|| + mpl::contains< + BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list, + IteratorType>::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef detail::converter< + multi_index_type, + BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter; + BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m)); +#endif + + return detail::converter::const_iterator( + m,static_cast(it.get_node())); +} + +/* projection of iterators by tag */ + +template +struct index_iterator +{ + typedef typename ::boost::multi_index::index< + MultiIndexContainer,Tag>::type::iterator type; +}; + +template +struct index_const_iterator +{ + typedef typename ::boost::multi_index::index< + MultiIndexContainer,Tag>::type::const_iterator type; +}; + +template< + typename Tag,typename IteratorType, + typename Value,typename IndexSpecifierList,typename Allocator> +typename index_iterator< + multi_index_container,Tag>::type +project( + multi_index_container& m, + IteratorType it) +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename ::boost::multi_index::index< + multi_index_type,Tag>::type index_type; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */ + BOOST_STATIC_ASSERT(( + mpl::contains< + BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list, + IteratorType>::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef detail::converter< + multi_index_type, + BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter; + BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m)); +#endif + + return detail::converter::iterator( + m,static_cast(it.get_node())); +} + +template< + typename Tag,typename IteratorType, + typename Value,typename IndexSpecifierList,typename Allocator> +typename index_const_iterator< + multi_index_container,Tag>::type +project( + const multi_index_container& m, + IteratorType it) +{ + typedef multi_index_container< + Value,IndexSpecifierList,Allocator> multi_index_type; + typedef typename ::boost::multi_index::index< + multi_index_type,Tag>::type index_type; + +#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */ + BOOST_STATIC_ASSERT(( + mpl::contains< + BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list, + IteratorType>::value|| + mpl::contains< + BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list, + IteratorType>::value)); +#endif + + BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); + +#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) + typedef detail::converter< + multi_index_type, + BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter; + BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m)); +#endif + + return detail::converter::const_iterator( + m,static_cast(it.get_node())); +} + +/* Comparison. Simple forward to first index. */ + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator==( + const multi_index_container& x, + const multi_index_container& y) +{ + return get<0>(x)==get<0>(y); +} + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator<( + const multi_index_container& x, + const multi_index_container& y) +{ + return get<0>(x)(y); +} + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator!=( + const multi_index_container& x, + const multi_index_container& y) +{ + return get<0>(x)!=get<0>(y); +} + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator>( + const multi_index_container& x, + const multi_index_container& y) +{ + return get<0>(x)>get<0>(y); +} + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator>=( + const multi_index_container& x, + const multi_index_container& y) +{ + return get<0>(x)>=get<0>(y); +} + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator<=( + const multi_index_container& x, + const multi_index_container& y) +{ + return get<0>(x)<=get<0>(y); +} + +/* specialized algorithms */ + +template +void swap( + multi_index_container& x, + multi_index_container& y) +{ + x.swap(y); +} + +} /* namespace multi_index */ + +#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) +/* class version = 1 : we now serialize the size through + * boost::serialization::collection_size_type. + * class version = 2 : proper use of {save|load}_construct_data. + */ + +namespace serialization { +template +struct version< + boost::multi_index_container +> +{ + BOOST_STATIC_CONSTANT(int,value=2); +}; +} /* namespace serialization */ +#endif + +/* Associated global functions are promoted to namespace boost, except + * comparison operators and swap, which are meant to be Koenig looked-up. + */ + +using multi_index::get; +using multi_index::project; + +} /* namespace boost */ + +#undef BOOST_MULTI_INDEX_CHECK_INVARIANT +#undef BOOST_MULTI_INDEX_CHECK_INVARIANT_OF + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index_container_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index_container_fwd.hpp new file mode 100644 index 00000000000..b35acad407a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/multi_index_container_fwd.hpp @@ -0,0 +1,121 @@ +/* Copyright 2003-2013 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See http://www.boost.org/libs/multi_index for library home page. + */ + +#ifndef BOOST_MULTI_INDEX_FWD_HPP +#define BOOST_MULTI_INDEX_FWD_HPP + +#if defined(_MSC_VER) +#pragma once +#endif + +#include /* keep it first to prevent nasty warns in MSVC */ +#include +#include +#include +#include + +namespace boost{ + +namespace multi_index{ + +/* Default value for IndexSpecifierList specifies a container + * equivalent to std::set. + */ + +template< + typename Value, + typename IndexSpecifierList=indexed_by > >, + typename Allocator=std::allocator > +class multi_index_container; + +template +struct nth_index; + +template +struct index; + +template +struct nth_index_iterator; + +template +struct nth_index_const_iterator; + +template +struct index_iterator; + +template +struct index_const_iterator; + +/* get and project functions not fwd declared due to problems + * with dependent typenames + */ + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator==( + const multi_index_container& x, + const multi_index_container& y); + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator<( + const multi_index_container& x, + const multi_index_container& y); + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator!=( + const multi_index_container& x, + const multi_index_container& y); + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator>( + const multi_index_container& x, + const multi_index_container& y); + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator>=( + const multi_index_container& x, + const multi_index_container& y); + +template< + typename Value1,typename IndexSpecifierList1,typename Allocator1, + typename Value2,typename IndexSpecifierList2,typename Allocator2 +> +bool operator<=( + const multi_index_container& x, + const multi_index_container& y); + +template +void swap( + multi_index_container& x, + multi_index_container& y); + +} /* namespace multi_index */ + +/* multi_index_container, being the main type of this library, is promoted to + * namespace boost. + */ + +using multi_index::multi_index_container; + +} /* namespace boost */ + +#endif diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/access.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/access.hpp new file mode 100644 index 00000000000..f6581accc91 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/access.hpp @@ -0,0 +1,145 @@ +#ifndef BOOST_SERIALIZATION_ACCESS_HPP +#define BOOST_SERIALIZATION_ACCESS_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// access.hpp: interface for serialization system. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +namespace boost { + +namespace archive { +namespace detail { + template + class iserializer; + template + class oserializer; +} // namespace detail +} // namespace archive + +namespace serialization { + +// forward declarations +template +inline void serialize_adl(Archive &, T &, const unsigned int); +namespace detail { + template + struct member_saver; + template + struct member_loader; +} // namespace detail + +// use an "accessor class so that we can use: +// "friend class boost::serialization::access;" +// in any serialized class to permit clean, safe access to private class members +// by the serialization system + +class access { +public: + // grant access to "real" serialization defaults +#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +public: +#else + template + friend struct detail::member_saver; + template + friend struct detail::member_loader; + template + friend class archive::detail::iserializer; + template + friend class archive::detail::oserializer; + template + friend inline void serialize( + Archive & ar, + T & t, + const unsigned int file_version + ); + template + friend inline void save_construct_data( + Archive & ar, + const T * t, + const unsigned int file_version + ); + template + friend inline void load_construct_data( + Archive & ar, + T * t, + const unsigned int file_version + ); +#endif + + // pass calls to users's class implementation + template + static void member_save( + Archive & ar, + //const T & t, + T & t, + const unsigned int file_version + ){ + t.save(ar, file_version); + } + template + static void member_load( + Archive & ar, + T & t, + const unsigned int file_version + ){ + t.load(ar, file_version); + } + template + static void serialize( + Archive & ar, + T & t, + const unsigned int file_version + ){ + // note: if you get a compile time error here with a + // message something like: + // cannot convert parameter 1 from to + // a likely possible cause is that the class T contains a + // serialize function - but that serialize function isn't + // a template and corresponds to a file type different than + // the class Archive. To resolve this, don't include an + // archive type other than that for which the serialization + // function is defined!!! + t.serialize(ar, file_version); + } + template + static void destroy( const T * t) // const appropriate here? + { + // the const business is an MSVC 6.0 hack that should be + // benign on everything else + delete const_cast(t); + } + template + static void construct(T * t){ + // default is inplace invocation of default constructor + // Note the :: before the placement new. Required if the + // class doesn't have a class-specific placement new defined. + ::new(t)T; + } + template + static T & cast_reference(U & u){ + return static_cast(u); + } + template + static T * cast_pointer(U * u){ + return static_cast(u); + } +}; + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_ACCESS_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_map.hpp new file mode 100644 index 00000000000..ccf806b1813 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_map.hpp @@ -0,0 +1,85 @@ +#ifndef BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_MAP_HPP +#define BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_MAP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization/unordered_map.hpp: +// serialization for stl unordered_map templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2014 Jim Bell +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { +namespace stl { + +// map input +template +struct archive_input_unordered_map +{ + inline void operator()( + Archive &ar, + Container &s, + const unsigned int v + ){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, v); + ar >> boost::serialization::make_nvp("item", t.reference()); + std::pair result = + s.insert(boost::move(t.reference())); + // note: the following presumes that the map::value_type was NOT tracked + // in the archive. This is the usual case, but here there is no way + // to determine that. + if(result.second){ + ar.reset_object_address( + & (result.first->second), + & t.reference().second + ); + } + } +}; + +// multimap input +template +struct archive_input_unordered_multimap +{ + inline void operator()( + Archive &ar, + Container &s, + const unsigned int v + ){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, v); + ar >> boost::serialization::make_nvp("item", t.reference()); + typename Container::const_iterator result = + s.insert(t.reference()); + // note: the following presumes that the map::value_type was NOT tracked + // in the archive. This is the usual case, but here there is no way + // to determine that. + ar.reset_object_address( + & result->second, + & t.reference() + ); + } +}; + +} // stl +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_set.hpp new file mode 100644 index 00000000000..7f0003cc6a4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_set.hpp @@ -0,0 +1,72 @@ +#ifndef BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_SET_HPP +#define BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_SET_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// archive_input_unordered_set.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2014 Jim Bell +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +namespace stl { + +// unordered_set input +template +struct archive_input_unordered_set +{ + inline void operator()( + Archive &ar, + Container &s, + const unsigned int v + ){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, v); + // borland fails silently w/o full namespace + ar >> boost::serialization::make_nvp("item", t.reference()); + std::pair result = + s.insert(boost::move(t.reference())); + if(result.second) + ar.reset_object_address(& (* result.first), & t.reference()); + } +}; + +// unordered_multiset input +template +struct archive_input_unordered_multiset +{ + inline void operator()( + Archive &ar, + Container &s, + const unsigned int v + ){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, v); + ar >> boost::serialization::make_nvp("item", t.reference()); + typename Container::const_iterator result = + s.insert(boost::move(t.reference())); + ar.reset_object_address(& (* result), & t.reference()); + } +}; + +} // stl +} // serialization +} // boost + +#endif // BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/array.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/array.hpp new file mode 100644 index 00000000000..612d1a61985 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/array.hpp @@ -0,0 +1,48 @@ +#ifndef BOOST_SERIALIZATION_ARRAY_HPP +#define BOOST_SERIALIZATION_ARRAY_HPP + +// (C) Copyright 2005 Matthias Troyer and Dave Abrahams +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// for serialization of . If not supported by the standard +// library - this file becomes empty. This is to avoid breaking backward +// compatibiliy for applications which used this header to support +// serialization of native arrays. Code to serialize native arrays is +// now always include by default. RR + +#include // msvc 6.0 needs this for warning suppression + +#if defined(BOOST_NO_STDC_NAMESPACE) + +#include +#include // std::size_t +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include + +#ifndef BOOST_NO_CXX11_HDR_ARRAY + +#include +#include + +namespace boost { namespace serialization { + +template +void serialize(Archive& ar, std::array& a, const unsigned int /* version */) +{ + ar & boost::serialization::make_nvp( + "elems", + *static_cast(static_cast(a.data())) + ); + +} +} } // end namespace boost::serialization + +#endif // BOOST_NO_CXX11_HDR_ARRAY + +#endif //BOOST_SERIALIZATION_ARRAY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/array_optimization.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/array_optimization.hpp new file mode 100644 index 00000000000..40dffba871a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/array_optimization.hpp @@ -0,0 +1,37 @@ +#ifndef BOOST_SERIALIZATION_ARRAY_OPTIMIZATON_HPP +#define BOOST_SERIALIZATION_ARRAY_OPTIMIZATON_HPP + +// (C) Copyright 2005 Matthias Troyer and Dave Abrahams +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include // msvc 6.0 needs this for warning suppression + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include + +namespace boost { namespace serialization { + +template +struct use_array_optimization : boost::mpl::always {}; + +} } // end namespace boost::serialization + +#define BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(Archive) \ +namespace boost { namespace serialization { \ +template <> struct use_array_optimization { \ + template \ + struct apply : boost::mpl::apply1::type \ + >::type {}; \ +}; }} + +#endif //BOOST_SERIALIZATION_ARRAY_OPTIMIZATON_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/array_wrapper.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/array_wrapper.hpp new file mode 100644 index 00000000000..adf436e15b4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/array_wrapper.hpp @@ -0,0 +1,121 @@ +#ifndef BOOST_SERIALIZATION_ARRAY_WRAPPER_HPP +#define BOOST_SERIALIZATION_ARRAY_WRAPPER_HPP + +// (C) Copyright 2005 Matthias Troyer and Dave Abrahams +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +//#include + +#include // msvc 6.0 needs this for warning suppression + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace serialization { + +template +class array_wrapper : + public wrapper_traits > +{ +private: + array_wrapper & operator=(const array_wrapper & rhs); + // note: I would like to make the copy constructor private but this breaks + // make_array. So I make make_array a friend + template + friend const boost::serialization::array_wrapper make_array(Tx * t, S s); +public: + + array_wrapper(const array_wrapper & rhs) : + m_t(rhs.m_t), + m_element_count(rhs.m_element_count) + {} +public: + array_wrapper(T * t, std::size_t s) : + m_t(t), + m_element_count(s) + {} + + // default implementation + template + void serialize_optimized(Archive &ar, const unsigned int, mpl::false_ ) const + { + // default implemention does the loop + std::size_t c = count(); + T * t = address(); + while(0 < c--) + ar & boost::serialization::make_nvp("item", *t++); + } + + // optimized implementation + template + void serialize_optimized(Archive &ar, const unsigned int version, mpl::true_ ) + { + boost::serialization::split_member(ar, *this, version); + } + + // default implementation + template + void save(Archive &ar, const unsigned int version) const + { + ar.save_array(*this,version); + } + + // default implementation + template + void load(Archive &ar, const unsigned int version) + { + ar.load_array(*this,version); + } + + // default implementation + template + void serialize(Archive &ar, const unsigned int version) + { + typedef typename + boost::serialization::use_array_optimization::template apply< + typename remove_const< T >::type + >::type use_optimized; + serialize_optimized(ar,version,use_optimized()); + } + + T * address() const + { + return m_t; + } + + std::size_t count() const + { + return m_element_count; + } + +private: + T * const m_t; + const std::size_t m_element_count; +}; + +template +inline +const array_wrapper< T > make_array(T* t, S s){ + const array_wrapper< T > a(t, s); + return a; +} + +} } // end namespace boost::serialization + + +#endif //BOOST_SERIALIZATION_ARRAY_WRAPPER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/assume_abstract.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/assume_abstract.hpp new file mode 100644 index 00000000000..632f9312f5f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/assume_abstract.hpp @@ -0,0 +1,60 @@ +#ifndef BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP +#define BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// assume_abstract_class.hpp: + +// (C) Copyright 2008 Robert Ramey +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// this is useful for compilers which don't support the boost::is_abstract + +#include +#include + +#ifndef BOOST_NO_IS_ABSTRACT + +// if there is an intrinsic is_abstract defined, we don't have to do anything +#define BOOST_SERIALIZATION_ASSUME_ABSTRACT(T) + +// but forward to the "official" is_abstract +namespace boost { +namespace serialization { + template + struct is_abstract : boost::is_abstract< T > {} ; +} // namespace serialization +} // namespace boost + +#else +// we have to "make" one + +namespace boost { +namespace serialization { + template + struct is_abstract : boost::false_type {}; +} // namespace serialization +} // namespace boost + +// define a macro to make explicit designation of this more transparent +#define BOOST_SERIALIZATION_ASSUME_ABSTRACT(T) \ +namespace boost { \ +namespace serialization { \ +template<> \ +struct is_abstract< T > : boost::true_type {}; \ +template<> \ +struct is_abstract< const T > : boost::true_type {}; \ +}} \ +/**/ + +#endif // BOOST_NO_IS_ABSTRACT + +#endif //BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/base_object.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/base_object.hpp new file mode 100644 index 00000000000..1a82cecd4b5 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/base_object.hpp @@ -0,0 +1,100 @@ +#ifndef BOOST_SERIALIZATION_BASE_OBJECT_HPP +#define BOOST_SERIALIZATION_BASE_OBJECT_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// base_object.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// if no archive headers have been included this is a no op +// this is to permit BOOST_EXPORT etc to be included in a +// file declaration header + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +namespace detail +{ + // get the base type for a given derived type + // preserving the const-ness + template + struct base_cast + { + typedef typename + mpl::if_< + is_const, + const B, + B + >::type type; + BOOST_STATIC_ASSERT(is_const::value == is_const::value); + }; + + // only register void casts if the types are polymorphic + template + struct base_register + { + struct polymorphic { + static void const * invoke(){ + Base const * const b = 0; + Derived const * const d = 0; + return & void_cast_register(d, b); + } + }; + struct non_polymorphic { + static void const * invoke(){ + return 0; + } + }; + static void const * invoke(){ + typedef typename mpl::eval_if< + is_polymorphic, + mpl::identity, + mpl::identity + >::type type; + return type::invoke(); + } + }; + +} // namespace detail +template +typename detail::base_cast::type & +base_object(Derived &d) +{ + BOOST_STATIC_ASSERT(( is_base_and_derived::value)); + BOOST_STATIC_ASSERT(! is_pointer::value); + typedef typename detail::base_cast::type type; + detail::base_register::invoke(); + return access::cast_reference(d); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_BASE_OBJECT_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/binary_object.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/binary_object.hpp new file mode 100644 index 00000000000..5c9038e5a9f --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/binary_object.hpp @@ -0,0 +1,79 @@ +#ifndef BOOST_SERIALIZATION_BINARY_OBJECT_HPP +#define BOOST_SERIALIZATION_BINARY_OBJECT_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// nvp.hpp: interface for serialization system. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include // std::size_t +#include +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +struct binary_object : + public wrapper_traits > +{ + void const * m_t; + std::size_t m_size; + template + void save(Archive & ar, const unsigned int /* file_version */) const { + ar.save_binary(m_t, m_size); + } + template + void load(Archive & ar, const unsigned int /* file_version */) const { + ar.load_binary(const_cast(m_t), m_size); + } + BOOST_SERIALIZATION_SPLIT_MEMBER() + binary_object & operator=(const binary_object & rhs) { + m_t = rhs.m_t; + m_size = rhs.m_size; + return *this; + } + binary_object(const void * const t, std::size_t size) : + m_t(t), + m_size(size) + {} + binary_object(const binary_object & rhs) : + m_t(rhs.m_t), + m_size(rhs.m_size) + {} +}; + +// just a little helper to support the convention that all serialization +// wrappers follow the naming convention make_xxxxx +inline +const binary_object +make_binary_object(const void * t, std::size_t size){ + return binary_object(t, size); +} + +} // namespace serialization +} // boost + +#endif // BOOST_SERIALIZATION_BINARY_OBJECT_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/bitset.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/bitset.hpp new file mode 100644 index 00000000000..78f9bd74336 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/bitset.hpp @@ -0,0 +1,75 @@ +/*! + * \file bitset.hpp + * \brief Provides Boost.Serialization support for std::bitset + * \author Brian Ravnsgaard Riis + * \author Kenneth Riddile + * \date 16.09.2004, updated 04.03.2009 + * \copyright 2004 Brian Ravnsgaard Riis + * \license Boost Software License 1.0 + */ +#ifndef BOOST_SERIALIZATION_BITSET_HPP +#define BOOST_SERIALIZATION_BITSET_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include // size_t + +#include +#include +#include +#include + +namespace boost{ +namespace serialization{ + +template +inline void save( + Archive & ar, + std::bitset const & t, + const unsigned int /* version */ +){ + const std::string bits = t.template to_string< + std::string::value_type, + std::string::traits_type, + std::string::allocator_type + >(); + ar << BOOST_SERIALIZATION_NVP( bits ); +} + +template +inline void load( + Archive & ar, + std::bitset & t, + const unsigned int /* version */ +){ + std::string bits; + ar >> BOOST_SERIALIZATION_NVP( bits ); + t = std::bitset(bits); +} + +template +inline void serialize( + Archive & ar, + std::bitset & t, + const unsigned int version +){ + boost::serialization::split_free( ar, t, version ); +} + +// don't track bitsets since that would trigger tracking +// all over the program - which probably would be a surprise. +// also, tracking would be hard to implement since, we're +// serialization a representation of the data rather than +// the data itself. +template +struct tracking_level > + : mpl::int_ {} ; + +} //serialization +} //boost + +#endif // BOOST_SERIALIZATION_BITSET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/boost_array.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/boost_array.hpp new file mode 100644 index 00000000000..d564ff15de0 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/boost_array.hpp @@ -0,0 +1,33 @@ +#ifndef BOOST_SERIALIZATION_ARRAY_HPP +#define BOOST_SERIALIZATION_ARRAY_HPP + +// (C) Copyright 2005 Matthias Troyer and Dave Abrahams +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +//#include + +#include // msvc 6.0 needs this for warning suppression + +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +#include +#include + +namespace boost { namespace serialization { +// implement serialization for boost::array +template +void serialize(Archive& ar, boost::array& a, const unsigned int /* version */) +{ + ar & boost::serialization::make_nvp("elems", a.elems); +} + +} } // end namespace boost::serialization + + +#endif //BOOST_SERIALIZATION_ARRAY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_map.hpp new file mode 100644 index 00000000000..8913b31f9e6 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_map.hpp @@ -0,0 +1,154 @@ +#ifndef BOOST_SERIALIZATION_UNORDERED_MAP_HPP +#define BOOST_SERIALIZATION_UNORDERED_MAP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization/unordered_map.hpp: +// serialization for stl unordered_map templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2014 Jim Bell +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const boost::unordered_map &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::save_unordered_collection< + Archive, + boost::unordered_map + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + boost::unordered_map &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::load_unordered_collection< + Archive, + boost::unordered_map, + boost::serialization::stl::archive_input_unordered_map< + Archive, + boost::unordered_map + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + boost::unordered_map &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +// unordered_multimap +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const boost::unordered_multimap &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::save_unordered_collection< + Archive, + boost::unordered_multimap + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + boost::unordered_multimap< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::load_unordered_collection< + Archive, + boost::unordered_multimap, + boost::serialization::stl::archive_input_unordered_multimap< + Archive, + boost::unordered_multimap + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + boost::unordered_multimap &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_UNORDERED_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_set.hpp new file mode 100644 index 00000000000..307c7819cbd --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_set.hpp @@ -0,0 +1,150 @@ +#ifndef BOOST_SERIALIZATION_BOOST_UNORDERED_SET_HPP +#define BOOST_SERIALIZATION_BOOST_UNORDERED_SET_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// unordered_set.hpp: serialization for boost unordered_set templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2014 Jim Bell +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include + +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const boost::unordered_set &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::save_unordered_collection< + Archive, + boost::unordered_set + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + boost::unordered_set &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::load_unordered_collection< + Archive, + boost::unordered_set, + boost::serialization::stl::archive_input_unordered_set< + Archive, + boost::unordered_set + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + boost::unordered_set &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +// unordered_multiset +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const boost::unordered_multiset &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::save_unordered_collection< + Archive, + boost::unordered_multiset + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + boost::unordered_multiset &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::load_unordered_collection< + Archive, + boost::unordered_multiset, + boost::serialization::stl::archive_input_unordered_multiset< + Archive, + boost::unordered_multiset + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + boost::unordered_multiset &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_BOOST_UNORDERED_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/collection_size_type.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/collection_size_type.hpp new file mode 100644 index 00000000000..2dd8fa72584 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/collection_size_type.hpp @@ -0,0 +1,62 @@ +#ifndef BOOST_SERIALIZATION_COLLECTION_SIZE_TYPE_HPP +#define BOOST_SERIALIZATION_COLLECTION_SIZE_TYPE_HPP + +// (C) Copyright 2005 Matthias Troyer +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include // size_t +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +//BOOST_STRONG_TYPEDEF(std::size_t, collection_size_type) + +class collection_size_type { +private: + typedef std::size_t base_type; + base_type t; +public: + collection_size_type(): t(0) {}; + explicit collection_size_type(const std::size_t & t_) : + t(t_) + {} + collection_size_type(const collection_size_type & t_) : + t(t_.t) + {} + collection_size_type & operator=(const collection_size_type & rhs){ + t = rhs.t; + return *this; + } + collection_size_type & operator=(const unsigned int & rhs){ + t = rhs; + return *this; + } + // used for text output + operator base_type () const { + return t; + } + // used for text input + operator base_type & () { + return t; + } + bool operator==(const collection_size_type & rhs) const { + return t == rhs.t; + } + bool operator<(const collection_size_type & rhs) const { + return t < rhs.t; + } +}; + + +} } // end namespace boost::serialization + +BOOST_CLASS_IMPLEMENTATION(collection_size_type, primitive_type) +BOOST_IS_BITWISE_SERIALIZABLE(collection_size_type) + +#endif //BOOST_SERIALIZATION_COLLECTION_SIZE_TYPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/collection_traits.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/collection_traits.hpp new file mode 100644 index 00000000000..3ec9401eff0 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/collection_traits.hpp @@ -0,0 +1,79 @@ +#ifndef BOOST_SERIALIZATION_COLLECTION_TRAITS_HPP +#define BOOST_SERIALIZATION_COLLECTION_TRAITS_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// collection_traits.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// This header assigns a level implemenation trait to a collection type +// for all primitives. It is needed so that archives which are meant to be +// portable don't write class information in the archive. Since, not all +// compiles recognize the same set of primitive types, the possibility +// exists for archives to be non-portable if class information for primitive +// types is included. This is addressed by the following macros. +#include +//#include +#include + +#include +#include +#include // ULONG_MAX +#include + +#define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(T, C) \ +template<> \ +struct implementation_level< C < T > > { \ + typedef mpl::integral_c_tag tag; \ + typedef mpl::int_ type; \ + BOOST_STATIC_CONSTANT(int, value = object_serializable); \ +}; \ +/**/ + +#if defined(BOOST_NO_CWCHAR) || defined(BOOST_NO_INTRINSIC_WCHAR_T) + #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C) +#else + #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(wchar_t, C) \ + /**/ +#endif + +#if defined(BOOST_HAS_LONG_LONG) + #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(boost::long_long_type, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(boost::ulong_long_type, C) \ + /**/ +#else + #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C) +#endif + +#define BOOST_SERIALIZATION_COLLECTION_TRAITS(C) \ + namespace boost { namespace serialization { \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(bool, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(char, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed char, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned char, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed int, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned int, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed long, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned long, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(float, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(double, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned short, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed short, C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C) \ + BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C) \ + } } \ + /**/ + +#endif // BOOST_SERIALIZATION_COLLECTION_TRAITS diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/collections_load_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/collections_load_imp.hpp new file mode 100644 index 00000000000..e042c0c130d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/collections_load_imp.hpp @@ -0,0 +1,106 @@ +#ifndef BOOST_SERIALIZATION_COLLECTIONS_LOAD_IMP_HPP +#define BOOST_SERIALIZATION_COLLECTIONS_LOAD_IMP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +#if defined(_MSC_VER) && (_MSC_VER <= 1020) +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// collections_load_imp.hpp: serialization for loading stl collections + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// helper function templates for serialization of collections + +#include +#include // size_t +#include // msvc 6.0 needs this for warning suppression +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ +namespace serialization { +namespace stl { + +////////////////////////////////////////////////////////////////////// +// implementation of serialization for STL containers +// + +template< + class Archive, + class T +> +typename boost::enable_if< + typename detail::is_default_constructible< + typename T::value_type + >, + void +>::type +collection_load_impl( + Archive & ar, + T & t, + collection_size_type count, + item_version_type /*item_version*/ +){ + t.resize(count); + typename T::iterator hint; + hint = t.begin(); + while(count-- > 0){ + ar >> boost::serialization::make_nvp("item", *hint++); + } +} + +template< + class Archive, + class T +> +typename boost::disable_if< + typename detail::is_default_constructible< + typename T::value_type + >, + void +>::type +collection_load_impl( + Archive & ar, + T & t, + collection_size_type count, + item_version_type item_version +){ + t.clear(); + while(count-- > 0){ + detail::stack_construct u(ar, item_version); + ar >> boost::serialization::make_nvp("item", u.reference()); + t.push_back(boost::move(u.reference())); + ar.reset_object_address(& t.back() , & u.reference()); + } +} + +} // namespace stl +} // namespace serialization +} // namespace boost + +#endif //BOOST_SERIALIZATION_COLLECTIONS_LOAD_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/collections_save_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/collections_save_imp.hpp new file mode 100644 index 00000000000..f3cabfcf3f5 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/collections_save_imp.hpp @@ -0,0 +1,82 @@ +#ifndef BOOST_SERIALIZATION_COLLECTIONS_SAVE_IMP_HPP +#define BOOST_SERIALIZATION_COLLECTIONS_SAVE_IMP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// collections_save_imp.hpp: serialization for stl collections + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// helper function templates for serialization of collections + +#include +#include +#include +#include +#include +#include + +namespace boost{ +namespace serialization { +namespace stl { + +////////////////////////////////////////////////////////////////////// +// implementation of serialization for STL containers +// + +template +inline void save_collection( + Archive & ar, + const Container &s, + collection_size_type count) +{ + ar << BOOST_SERIALIZATION_NVP(count); + // record number of elements + const item_version_type item_version( + version::value + ); + #if 0 + boost::archive::library_version_type library_version( + ar.get_library_version() + ); + if(boost::archive::library_version_type(3) < library_version){ + ar << BOOST_SERIALIZATION_NVP(item_version); + } + #else + ar << BOOST_SERIALIZATION_NVP(item_version); + #endif + + typename Container::const_iterator it = s.begin(); + while(count-- > 0){ + // note borland emits a no-op without the explicit namespace + boost::serialization::save_construct_data_adl( + ar, + &(*it), + item_version + ); + ar << boost::serialization::make_nvp("item", *it++); + } +} + +template +inline void save_collection(Archive & ar, const Container &s) +{ + // record number of elements + collection_size_type count(s.size()); + save_collection(ar, s, count); +} + +} // namespace stl +} // namespace serialization +} // namespace boost + +#endif //BOOST_SERIALIZATION_COLLECTIONS_SAVE_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/complex.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/complex.hpp new file mode 100644 index 00000000000..b4ef44cf973 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/complex.hpp @@ -0,0 +1,81 @@ +#ifndef BOOST_SERIALIZATION_COMPLEX_HPP +#define BOOST_SERIALIZATION_COMPLEX_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization/utility.hpp: +// serialization for stl utility templates + +// (C) Copyright 2007 Matthias Troyer . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include +#include +#include + +namespace boost { +namespace serialization { + +template +inline void serialize( + Archive & ar, + std::complex< T > & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +template +inline void save( + Archive & ar, + std::complex< T > const & t, + const unsigned int /* file_version */ +){ + const T re = t.real(); + const T im = t.imag(); + ar << boost::serialization::make_nvp("real", re); + ar << boost::serialization::make_nvp("imag", im); +} + +template +inline void load( + Archive & ar, + std::complex< T >& t, + const unsigned int /* file_version */ +){ + T re; + T im; + ar >> boost::serialization::make_nvp("real", re); + ar >> boost::serialization::make_nvp("imag", im); + t = std::complex< T >(re,im); +} + +// specialization of serialization traits for complex +template +struct is_bitwise_serializable > + : public is_bitwise_serializable< T > {}; + +template +struct implementation_level > + : mpl::int_ {} ; + +// treat complex just like builtin arithmetic types for tracking +template +struct tracking_level > + : mpl::int_ {} ; + +} // serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_COMPLEX_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/config.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/config.hpp new file mode 100644 index 00000000000..ea8cb9239ed --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/config.hpp @@ -0,0 +1,74 @@ +#ifndef BOOST_SERIALIZATION_CONFIG_HPP +#define BOOST_SERIALIZATION_CONFIG_HPP + +// config.hpp ---------------------------------------------// + +// (c) Copyright Robert Ramey 2004 +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See library home page at http://www.boost.org/libs/serialization + +//----------------------------------------------------------------------------// + +// This header implements separate compilation features as described in +// http://www.boost.org/more/separate_compilation.html + +#include +#include + +// note: this version incorporates the related code into the the +// the same library as BOOST_ARCHIVE. This could change some day in the +// future + +// if BOOST_SERIALIZATION_DECL is defined undefine it now: +#ifdef BOOST_SERIALIZATION_DECL + #undef BOOST_SERIALIZATION_DECL +#endif + +// we need to import/export our code only if the user has specifically +// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost +// libraries to be dynamically linked, or BOOST_SERIALIZATION_DYN_LINK +// if they want just this one to be dynamically liked: +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) + #if !defined(BOOST_DYN_LINK) + #define BOOST_DYN_LINK + #endif + // export if this is our own source, otherwise import: + #if defined(BOOST_SERIALIZATION_SOURCE) + #define BOOST_SERIALIZATION_DECL BOOST_SYMBOL_EXPORT + #else + #define BOOST_SERIALIZATION_DECL BOOST_SYMBOL_IMPORT + #endif // defined(BOOST_SERIALIZATION_SOURCE) +#endif // defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) + +// if BOOST_SERIALIZATION_DECL isn't defined yet define it now: +#ifndef BOOST_SERIALIZATION_DECL + #define BOOST_SERIALIZATION_DECL +#endif + +// enable automatic library variant selection ------------------------------// + +#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) \ +&& !defined(BOOST_ARCHIVE_SOURCE) && !defined(BOOST_WARCHIVE_SOURCE) \ +&& !defined(BOOST_SERIALIZATION_SOURCE) + // + // Set the name of our library, this will get undef'ed by auto_link.hpp + // once it's done with it: + // + #define BOOST_LIB_NAME boost_serialization + // + // If we're importing code from a dll, then tell auto_link.hpp about it: + // + #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) + # define BOOST_DYN_LINK + #endif + // + // And include the header that does the work: + // + #include + +#endif + +#endif // BOOST_SERIALIZATION_CONFIG_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/deque.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/deque.hpp new file mode 100644 index 00000000000..bba81364ce2 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/deque.hpp @@ -0,0 +1,80 @@ +#ifndef BOOST_SERIALIZATION_DEQUE_HPP +#define BOOST_SERIALIZATION_DEQUE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// deque.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include + +#include + +#include +#include +#include + +namespace boost { +namespace serialization { + +template +inline void save( + Archive & ar, + const std::deque &t, + const unsigned int /* file_version */ +){ + boost::serialization::stl::save_collection< + Archive, std::deque + >(ar, t); +} + +template +inline void load( + Archive & ar, + std::deque &t, + const unsigned int /* file_version */ +){ + const boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + stl::collection_load_impl(ar, t, count, item_version); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::deque &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(std::deque) + +#endif // BOOST_SERIALIZATION_DEQUE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/is_default_constructible.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/is_default_constructible.hpp new file mode 100644 index 00000000000..4d20b13bf3e --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/detail/is_default_constructible.hpp @@ -0,0 +1,54 @@ +#ifndef BOOST_SERIALIZATION_DETAIL_IS_DEFAULT_CONSTRUCTIBLE_HPP +#define BOOST_SERIALIZATION_DETAIL_IS_DEFAULT_CONSTRUCTIBLE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// is_default_constructible.hpp: serialization for loading stl collections +// +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#if ! defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) + #include + namespace boost{ + namespace serialization { + namespace detail { + + template + struct is_default_constructible : public std::is_default_constructible {}; + + } // detail + } // serializaition + } // boost +#else + // we don't have standard library support for is_default_constructible + // so we fake it by using boost::has_trivial_construtor. But this is not + // actually correct because it's possible that a default constructor + // to be non trivial. So when using this, make sure you're not using your + // own definition of of T() but are using the actual default one! + #include + namespace boost{ + namespace serialization { + namespace detail { + + template + struct is_default_constructible : public boost::has_trivial_constructor {}; + + } // detail + } // serializaition + } // boost + +#endif + + +#endif // BOOST_SERIALIZATION_DETAIL_IS_DEFAULT_CONSTRUCTIBLE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_count_132.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_count_132.hpp new file mode 100644 index 00000000000..a5872557cf2 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_count_132.hpp @@ -0,0 +1,551 @@ +#ifndef BOOST_DETAIL_SHARED_COUNT_132_HPP_INCLUDED +#define BOOST_DETAIL_SHARED_COUNT_132_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) +# pragma once +#endif + +// +// detail/shared_count.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR) +# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible. +#endif + +#include +#include +#include + +#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) +#include +#endif + +#include // std::auto_ptr, std::allocator +#include // std::less +#include // std::exception +#include // std::bad_alloc +#include // std::type_info in get_deleter +#include // std::size_t + +#include // msvc 6.0 needs this for warning suppression +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif + +namespace boost_132 { + +// Debug hooks + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + +void sp_scalar_constructor_hook(void * px, std::size_t size, void * pn); +void sp_array_constructor_hook(void * px); +void sp_scalar_destructor_hook(void * px, std::size_t size, void * pn); +void sp_array_destructor_hook(void * px); + +#endif + + +// The standard library that comes with Borland C++ 5.5.1 +// defines std::exception and its members as having C calling +// convention (-pc). When the definition of bad_weak_ptr +// is compiled with -ps, the compiler issues an error. +// Hence, the temporary #pragma option -pc below. The version +// check is deliberately conservative. + +class bad_weak_ptr: public std::exception +{ +public: + + virtual char const * what() const throw() + { + return "boost::bad_weak_ptr"; + } +}; + +namespace detail{ + +class sp_counted_base +{ +//private: + + typedef boost::detail::lightweight_mutex mutex_type; + +public: + + sp_counted_base(): use_count_(1), weak_count_(1) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destruct() is called when weak_count_ drops to zero. + + virtual void destruct() // nothrow + { + delete this; + } + + virtual void * get_deleter(std::type_info const & ti) = 0; + + void add_ref_copy() + { +#if defined(BOOST_HAS_THREADS) + mutex_type::scoped_lock lock(mtx_); +#endif + ++use_count_; + } + + void add_ref_lock() + { +#if defined(BOOST_HAS_THREADS) + mutex_type::scoped_lock lock(mtx_); +#endif + if(use_count_ == 0) boost::serialization::throw_exception(bad_weak_ptr()); + ++use_count_; + } + + void release() // nothrow + { + { +#if defined(BOOST_HAS_THREADS) + mutex_type::scoped_lock lock(mtx_); +#endif + long new_use_count = --use_count_; + + if(new_use_count != 0) return; + } + + dispose(); + weak_release(); + } + + void weak_add_ref() // nothrow + { +#if defined(BOOST_HAS_THREADS) + mutex_type::scoped_lock lock(mtx_); +#endif + ++weak_count_; + } + + void weak_release() // nothrow + { + long new_weak_count; + + { +#if defined(BOOST_HAS_THREADS) + mutex_type::scoped_lock lock(mtx_); +#endif + new_weak_count = --weak_count_; + } + + if(new_weak_count == 0) + { + destruct(); + } + } + + long use_count() const // nothrow + { +#if defined(BOOST_HAS_THREADS) + mutex_type::scoped_lock lock(mtx_); +#endif + return use_count_; + } + +//private: +public: + sp_counted_base(sp_counted_base const &); + sp_counted_base & operator= (sp_counted_base const &); + + long use_count_; // #shared + long weak_count_; // #weak + (#shared != 0) + +#if defined(BOOST_HAS_THREADS) || defined(BOOST_LWM_WIN32) + mutable mutex_type mtx_; +#endif +}; + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + +template void cbi_call_constructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &) +{ + boost::sp_scalar_constructor_hook(px, sizeof(T), pn); +} + +template void cbi_call_constructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &) +{ + boost::sp_array_constructor_hook(px); +} + +template void cbi_call_constructor_hook(sp_counted_base *, P const &, D const &, long) +{ +} + +template void cbi_call_destructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &) +{ + boost::sp_scalar_destructor_hook(px, sizeof(T), pn); +} + +template void cbi_call_destructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &) +{ + boost::sp_array_destructor_hook(px); +} + +template void cbi_call_destructor_hook(sp_counted_base *, P const &, D const &, long) +{ +} + +#endif + +// +// Borland's Codeguard trips up over the -Vx- option here: +// +#ifdef __CODEGUARD__ +# pragma option push -Vx- +#endif + +template class sp_counted_base_impl: public sp_counted_base +{ +//private: +public: + P ptr; // copy constructor must not throw + D del; // copy constructor must not throw + + sp_counted_base_impl(sp_counted_base_impl const &); + sp_counted_base_impl & operator= (sp_counted_base_impl const &); + + typedef sp_counted_base_impl this_type; + +public: + + // pre: initial_use_count <= initial_weak_count, d(p) must not throw + + sp_counted_base_impl(P p, D d): ptr(p), del(d) + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + detail::cbi_call_constructor_hook(this, p, d, 0); +#endif + } + + virtual void dispose() // nothrow + { +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + detail::cbi_call_destructor_hook(this, ptr, del, 0); +#endif + del(ptr); + } + + virtual void * get_deleter(std::type_info const & ti) + { + return ti == typeid(D)? &del: 0; + } + +#if defined(BOOST_SP_USE_STD_ALLOCATOR) + + void * operator new(std::size_t) + { + return std::allocator().allocate(1, static_cast(0)); + } + + void operator delete(void * p) + { + std::allocator().deallocate(static_cast(p), 1); + } + +#endif + +#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) + + void * operator new(std::size_t) + { + return boost::detail::quick_allocator::alloc(); + } + + void operator delete(void * p) + { + boost::detail::quick_allocator::dealloc(p); + } + +#endif +}; + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + +int const shared_count_id = 0x2C35F101; +int const weak_count_id = 0x298C38A4; + +#endif + +class weak_count; + +class shared_count +{ +//private: +public: + sp_counted_base * pi_; + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + int id_; +#endif + + friend class weak_count; + +public: + + shared_count(): pi_(0) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + } + + template shared_count(P p, D d): pi_(0) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { +#ifndef BOOST_NO_EXCEPTIONS + + try + { + pi_ = new sp_counted_base_impl(p, d); + } + catch(...) + { + d(p); // delete p + throw; + } + +#else + + pi_ = new sp_counted_base_impl(p, d); + + if(pi_ == 0) + { + d(p); // delete p + boost::serialization::throw_exception(std::bad_alloc()); + } + +#endif + } + +#ifndef BOOST_NO_AUTO_PTR + + // auto_ptr is special cased to provide the strong guarantee + + template + explicit shared_count(std::auto_ptr & r): pi_( + new sp_counted_base_impl< + Y *, + boost::checked_deleter + >(r.get(), boost::checked_deleter())) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + r.release(); + } + +#endif + + ~shared_count() // nothrow + { + if(pi_ != 0) pi_->release(); +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + id_ = 0; +#endif + } + + shared_count(shared_count const & r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + if(pi_ != 0) pi_->add_ref_copy(); + } + + explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0 + + shared_count & operator= (shared_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + + if(tmp != pi_) + { + if(tmp != 0) tmp->add_ref_copy(); + if(pi_ != 0) pi_->release(); + pi_ = tmp; + } + + return *this; + } + + void swap(shared_count & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + r.pi_ = pi_; + pi_ = tmp; + } + + long use_count() const // nothrow + { + return pi_ != 0? pi_->use_count(): 0; + } + + bool unique() const // nothrow + { + return use_count() == 1; + } + + friend inline bool operator==(shared_count const & a, shared_count const & b) + { + return a.pi_ == b.pi_; + } + + friend inline bool operator<(shared_count const & a, shared_count const & b) + { + return std::less()(a.pi_, b.pi_); + } + + void * get_deleter(std::type_info const & ti) const + { + return pi_? pi_->get_deleter(ti): 0; + } +}; + +#ifdef __CODEGUARD__ +# pragma option pop +#endif + + +class weak_count +{ +private: + + sp_counted_base * pi_; + +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + int id_; +#endif + + friend class shared_count; + +public: + + weak_count(): pi_(0) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(weak_count_id) +#endif + { + } + + weak_count(shared_count const & r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + if(pi_ != 0) pi_->weak_add_ref(); + } + + weak_count(weak_count const & r): pi_(r.pi_) // nothrow +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif + { + if(pi_ != 0) pi_->weak_add_ref(); + } + + ~weak_count() // nothrow + { + if(pi_ != 0) pi_->weak_release(); +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + id_ = 0; +#endif + } + + weak_count & operator= (shared_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + if(tmp != 0) tmp->weak_add_ref(); + if(pi_ != 0) pi_->weak_release(); + pi_ = tmp; + + return *this; + } + + weak_count & operator= (weak_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + if(tmp != 0) tmp->weak_add_ref(); + if(pi_ != 0) pi_->weak_release(); + pi_ = tmp; + + return *this; + } + + void swap(weak_count & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + r.pi_ = pi_; + pi_ = tmp; + } + + long use_count() const // nothrow + { + return pi_ != 0? pi_->use_count(): 0; + } + + friend inline bool operator==(weak_count const & a, weak_count const & b) + { + return a.pi_ == b.pi_; + } + + friend inline bool operator<(weak_count const & a, weak_count const & b) + { + return std::less()(a.pi_, b.pi_); + } +}; + +inline shared_count::shared_count(weak_count const & r): pi_(r.pi_) +#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) + , id_(shared_count_id) +#endif +{ + if(pi_ != 0) + { + pi_->add_ref_lock(); + } + else + { + boost::serialization::throw_exception(bad_weak_ptr()); + } +} + +} // namespace detail + +} // namespace boost + +BOOST_SERIALIZATION_ASSUME_ABSTRACT(boost_132::detail::sp_counted_base) + +#endif // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_132.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_132.hpp new file mode 100644 index 00000000000..ee98b7b9449 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_132.hpp @@ -0,0 +1,443 @@ +#ifndef BOOST_SHARED_PTR_132_HPP_INCLUDED +#define BOOST_SHARED_PTR_132_HPP_INCLUDED + +// +// shared_ptr.hpp +// +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// Copyright (c) 2001, 2002, 2003 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation. +// + +#include // for broken compiler workarounds + +#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) +#include +#else + +#include +#include +#include +#include + +#include +#include + +#include // for std::auto_ptr +#include // for std::swap +#include // for std::less +#include // for std::bad_cast +#include // for std::basic_ostream + +#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash +# pragma warning(push) +# pragma warning(disable:4284) // odd return type for operator-> +#endif + +namespace boost_132 { + +template class weak_ptr; +template class enable_shared_from_this; + +namespace detail +{ + +struct static_cast_tag {}; +struct const_cast_tag {}; +struct dynamic_cast_tag {}; +struct polymorphic_cast_tag {}; + +template struct shared_ptr_traits +{ + typedef T & reference; +}; + +template<> struct shared_ptr_traits +{ + typedef void reference; +}; + +#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) + +template<> struct shared_ptr_traits +{ + typedef void reference; +}; + +template<> struct shared_ptr_traits +{ + typedef void reference; +}; + +template<> struct shared_ptr_traits +{ + typedef void reference; +}; + +#endif + +// enable_shared_from_this support + +template void sp_enable_shared_from_this( shared_count const & pn, enable_shared_from_this< T > const * pe, Y const * px ) +{ + if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast(px), pn); +} + +inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... ) +{ +} + +} // namespace detail + + +// +// shared_ptr +// +// An enhanced relative of scoped_ptr with reference counted copy semantics. +// The object pointed to is deleted when the last shared_ptr pointing to it +// is destroyed or reset. +// + +template class shared_ptr +{ +private: + // Borland 5.5.1 specific workaround + typedef shared_ptr< T > this_type; + +public: + + typedef T element_type; + typedef T value_type; + typedef T * pointer; + typedef typename detail::shared_ptr_traits< T >::reference reference; + + shared_ptr(): px(0), pn() // never throws in 1.30+ + { + } + + template + explicit shared_ptr(Y * p): px(p), pn(p, boost::checked_deleter()) // Y must be complete + { + detail::sp_enable_shared_from_this( pn, p, p ); + } + + // + // Requirements: D's copy constructor must not throw + // + // shared_ptr will release p by calling d(p) + // + + template shared_ptr(Y * p, D d): px(p), pn(p, d) + { + detail::sp_enable_shared_from_this( pn, p, p ); + } + +// generated copy constructor, assignment, destructor are fine... + +// except that Borland C++ has a bug, and g++ with -Wsynth warns +#if defined(__GNUC__) + shared_ptr & operator=(shared_ptr const & r) // never throws + { + px = r.px; + pn = r.pn; // shared_count::op= doesn't throw + return *this; + } +#endif + + template + explicit shared_ptr(weak_ptr const & r): pn(r.pn) // may throw + { + // it is now safe to copy r.px, as pn(r.pn) did not throw + px = r.px; + } + + template + shared_ptr(shared_ptr const & r): px(r.px), pn(r.pn) // never throws + { + } + + template + shared_ptr(shared_ptr const & r, detail::static_cast_tag): px(static_cast(r.px)), pn(r.pn) + { + } + + template + shared_ptr(shared_ptr const & r, detail::const_cast_tag): px(const_cast(r.px)), pn(r.pn) + { + } + + template + shared_ptr(shared_ptr const & r, detail::dynamic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) + { + if(px == 0) // need to allocate new counter -- the cast failed + { + pn = detail::shared_count(); + } + } + + template + shared_ptr(shared_ptr const & r, detail::polymorphic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) + { + if(px == 0) + { + boost::serialization::throw_exception(std::bad_cast()); + } + } + +#ifndef BOOST_NO_AUTO_PTR + + template + explicit shared_ptr(std::auto_ptr & r): px(r.get()), pn() + { + Y * tmp = r.get(); + pn = detail::shared_count(r); + detail::sp_enable_shared_from_this( pn, tmp, tmp ); + } + +#endif + +#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200) + + template + shared_ptr & operator=(shared_ptr const & r) // never throws + { + px = r.px; + pn = r.pn; // shared_count::op= doesn't throw + return *this; + } + +#endif + +#ifndef BOOST_NO_AUTO_PTR + + template + shared_ptr & operator=(std::auto_ptr & r) + { + this_type(r).swap(*this); + return *this; + } + +#endif + + void reset() // never throws in 1.30+ + { + this_type().swap(*this); + } + + template void reset(Y * p) // Y must be complete + { + BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors + this_type(p).swap(*this); + } + + template void reset(Y * p, D d) + { + this_type(p, d).swap(*this); + } + + reference operator* () const // never throws + { + BOOST_ASSERT(px != 0); + return *px; + } + + T * operator-> () const // never throws + { + BOOST_ASSERT(px != 0); + return px; + } + + T * get() const // never throws + { + return px; + } + + // implicit conversion to "bool" + +#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530) + + operator bool () const + { + return px != 0; + } + +#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) + typedef T * (this_type::*unspecified_bool_type)() const; + + operator unspecified_bool_type() const // never throws + { + return px == 0? 0: &this_type::get; + } + +#else + + typedef T * this_type::*unspecified_bool_type; + + operator unspecified_bool_type() const // never throws + { + return px == 0? 0: &this_type::px; + } + +#endif + + // operator! is redundant, but some compilers need it + + bool operator! () const // never throws + { + return px == 0; + } + + bool unique() const // never throws + { + return pn.unique(); + } + + long use_count() const // never throws + { + return pn.use_count(); + } + + void swap(shared_ptr< T > & other) // never throws + { + std::swap(px, other.px); + pn.swap(other.pn); + } + + template bool _internal_less(shared_ptr const & rhs) const + { + return pn < rhs.pn; + } + + void * _internal_get_deleter(std::type_info const & ti) const + { + return pn.get_deleter(ti); + } + +// Tasteless as this may seem, making all members public allows member templates +// to work in the absence of member template friends. (Matthew Langston) + +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + +private: + + template friend class shared_ptr; + template friend class weak_ptr; + + +#endif +public: // for serialization + T * px; // contained pointer + detail::shared_count pn; // reference counter + +}; // shared_ptr + +template inline bool operator==(shared_ptr< T > const & a, shared_ptr const & b) +{ + return a.get() == b.get(); +} + +template inline bool operator!=(shared_ptr< T > const & a, shared_ptr const & b) +{ + return a.get() != b.get(); +} + +template inline bool operator<(shared_ptr< T > const & a, shared_ptr const & b) +{ + return a._internal_less(b); +} + +template inline void swap(shared_ptr< T > & a, shared_ptr< T > & b) +{ + a.swap(b); +} + +template shared_ptr< T > static_pointer_cast(shared_ptr const & r) +{ + return shared_ptr< T >(r, detail::static_cast_tag()); +} + +template shared_ptr< T > const_pointer_cast(shared_ptr const & r) +{ + return shared_ptr< T >(r, detail::const_cast_tag()); +} + +template shared_ptr< T > dynamic_pointer_cast(shared_ptr const & r) +{ + return shared_ptr< T >(r, detail::dynamic_cast_tag()); +} + +// shared_*_cast names are deprecated. Use *_pointer_cast instead. + +template shared_ptr< T > shared_static_cast(shared_ptr const & r) +{ + return shared_ptr< T >(r, detail::static_cast_tag()); +} + +template shared_ptr< T > shared_dynamic_cast(shared_ptr const & r) +{ + return shared_ptr< T >(r, detail::dynamic_cast_tag()); +} + +template shared_ptr< T > shared_polymorphic_cast(shared_ptr const & r) +{ + return shared_ptr< T >(r, detail::polymorphic_cast_tag()); +} + +template shared_ptr< T > shared_polymorphic_downcast(shared_ptr const & r) +{ + BOOST_ASSERT(dynamic_cast(r.get()) == r.get()); + return shared_static_cast< T >(r); +} + +// get_pointer() enables boost::mem_fn to recognize shared_ptr + +template inline T * get_pointer(shared_ptr< T > const & p) +{ + return p.get(); +} + +// operator<< + + +template std::basic_ostream & operator<< (std::basic_ostream & os, shared_ptr const & p) +{ + os << p.get(); + return os; +} + +// get_deleter (experimental) + +#if defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238) + +// g++ 2.9x doesn't allow static_cast(void *) +// apparently EDG 2.38 also doesn't accept it + +template D * get_deleter(shared_ptr< T > const & p) +{ + void const * q = p._internal_get_deleter(typeid(D)); + return const_cast(static_cast(q)); +} + +#else + +template D * get_deleter(shared_ptr< T > const & p) +{ + return static_cast(p._internal_get_deleter(typeid(D))); +} + +#endif + +} // namespace boost + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) + +#endif // #ifndef BOOST_SHARED_PTR_132_HPP_INCLUDED diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_nmt_132.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_nmt_132.hpp new file mode 100644 index 00000000000..490e7ddd3d0 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_nmt_132.hpp @@ -0,0 +1,182 @@ +#ifndef BOOST_DETAIL_SHARED_PTR_NMT_132_HPP_INCLUDED +#define BOOST_DETAIL_SHARED_PTR_NMT_132_HPP_INCLUDED + +// +// detail/shared_ptr_nmt.hpp - shared_ptr.hpp without member templates +// +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// Copyright (c) 2001, 2002 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation. +// + +#include +#include +#include +#include + +#ifndef BOOST_NO_AUTO_PTR +# include // for std::auto_ptr +#endif + +#include // for std::swap +#include // for std::less +#include // for std::bad_alloc + +namespace boost +{ + +template class shared_ptr +{ +private: + + typedef detail::atomic_count count_type; + +public: + + typedef T element_type; + typedef T value_type; + + explicit shared_ptr(T * p = 0): px(p) + { +#ifndef BOOST_NO_EXCEPTIONS + + try // prevent leak if new throws + { + pn = new count_type(1); + } + catch(...) + { + boost::checked_delete(p); + throw; + } + +#else + + pn = new count_type(1); + + if(pn == 0) + { + boost::checked_delete(p); + boost::serialization::throw_exception(std::bad_alloc()); + } + +#endif + } + + ~shared_ptr() + { + if(--*pn == 0) + { + boost::checked_delete(px); + delete pn; + } + } + + shared_ptr(shared_ptr const & r): px(r.px) // never throws + { + pn = r.pn; + ++*pn; + } + + shared_ptr & operator=(shared_ptr const & r) + { + shared_ptr(r).swap(*this); + return *this; + } + +#ifndef BOOST_NO_AUTO_PTR + + explicit shared_ptr(std::auto_ptr< T > & r) + { + pn = new count_type(1); // may throw + px = r.release(); // fix: moved here to stop leak if new throws + } + + shared_ptr & operator=(std::auto_ptr< T > & r) + { + shared_ptr(r).swap(*this); + return *this; + } + +#endif + + void reset(T * p = 0) + { + BOOST_ASSERT(p == 0 || p != px); + shared_ptr(p).swap(*this); + } + + T & operator*() const // never throws + { + BOOST_ASSERT(px != 0); + return *px; + } + + T * operator->() const // never throws + { + BOOST_ASSERT(px != 0); + return px; + } + + T * get() const // never throws + { + return px; + } + + long use_count() const // never throws + { + return *pn; + } + + bool unique() const // never throws + { + return *pn == 1; + } + + void swap(shared_ptr< T > & other) // never throws + { + std::swap(px, other.px); + std::swap(pn, other.pn); + } + +private: + + T * px; // contained pointer + count_type * pn; // ptr to reference counter +}; + +template inline bool operator==(shared_ptr< T > const & a, shared_ptr const & b) +{ + return a.get() == b.get(); +} + +template inline bool operator!=(shared_ptr< T > const & a, shared_ptr const & b) +{ + return a.get() != b.get(); +} + +template inline bool operator<(shared_ptr< T > const & a, shared_ptr< T > const & b) +{ + return std::less()(a.get(), b.get()); +} + +template void swap(shared_ptr< T > & a, shared_ptr< T > & b) +{ + a.swap(b); +} + +// get_pointer() enables boost::mem_fn to recognize shared_ptr + +template inline T * get_pointer(shared_ptr< T > const & p) +{ + return p.get(); +} + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_SHARED_PTR_NMT_132_HPP_INCLUDED diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/stack_constructor.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/stack_constructor.hpp new file mode 100644 index 00000000000..ae14832c6db --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/detail/stack_constructor.hpp @@ -0,0 +1,66 @@ +#ifndef BOOST_SERIALIZATION_DETAIL_STACK_CONSTRUCTOR_HPP +#define BOOST_SERIALIZATION_DETAIL_STACK_CONSTRUCTOR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// stack_constructor.hpp: serialization for loading stl collections + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +namespace boost{ +namespace serialization { +namespace detail { + +// reserve space on stack for an object of type T without actually +// construction such an object +template +struct stack_allocate +{ + T * address() { + return static_cast(storage_.address()); + } + T & reference() { + return * address(); + } +private: + typedef typename boost::aligned_storage< + sizeof(T), + boost::alignment_of::value + > type; + type storage_; +}; + +// construct element on the stack +template +struct stack_construct : public stack_allocate +{ + stack_construct(Archive & ar, const unsigned int version){ + // note borland emits a no-op without the explicit namespace + boost::serialization::load_construct_data_adl( + ar, + this->address(), + version + ); + } + ~stack_construct(){ + this->address()->~T(); // undo load_construct_data above + } +}; + +} // detail +} // serializaition +} // boost + +#endif // BOOST_SERIALIZATION_DETAIL_STACH_CONSTRUCTOR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/ephemeral.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/ephemeral.hpp new file mode 100644 index 00000000000..3a422c30a35 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/ephemeral.hpp @@ -0,0 +1,72 @@ +#ifndef BOOST_SERIALIZATION_EPHEMERAL_HPP +#define BOOST_SERIALIZATION_EPHEMERAL_HPP + +// MS compatible compilers support +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// ephemeral_object.hpp: interface for serialization system. + +// (C) Copyright 2007 Matthias Troyer. +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template +struct ephemeral_object : + public wrapper_traits > +{ + explicit ephemeral_object(T& t) : + val(t) + {} + + T & value() const { + return val; + } + + const T & const_value() const { + return val; + } + + template + void serialize(Archive &ar, const unsigned int) const + { + ar & val; + } + +private: + T & val; +}; + +template +inline +const ephemeral_object ephemeral(const char * name, T & t){ + return ephemeral_object(name, t); +} + +} // seralization +} // boost + +#endif // BOOST_SERIALIZATION_EPHEMERAL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/export.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/export.hpp new file mode 100644 index 00000000000..9eef440df42 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/export.hpp @@ -0,0 +1,225 @@ +#ifndef BOOST_SERIALIZATION_EXPORT_HPP +#define BOOST_SERIALIZATION_EXPORT_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// export.hpp: set traits of classes to be serialized + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// (C) Copyright 2006 David Abrahams - http://www.boost.org. +// implementation of class export functionality. This is an alternative to +// "forward declaration" method to provoke instantiation of derived classes +// that are to be serialized through pointers. + +#include +#include // NULL + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include // for guid_defined only +#include +#include +#include +#include + +#include + +#include + +namespace boost { +namespace archive { +namespace detail { + +class basic_pointer_iserializer; +class basic_pointer_oserializer; + +template +class pointer_iserializer; +template +class pointer_oserializer; + +template +struct export_impl +{ + static const basic_pointer_iserializer & + enable_load(mpl::true_){ + return boost::serialization::singleton< + pointer_iserializer + >::get_const_instance(); + } + + static const basic_pointer_oserializer & + enable_save(mpl::true_){ + return boost::serialization::singleton< + pointer_oserializer + >::get_const_instance(); + } + inline static void enable_load(mpl::false_) {} + inline static void enable_save(mpl::false_) {} +}; + +// On many platforms, naming a specialization of this template is +// enough to cause its argument to be instantiated. +template +struct instantiate_function {}; + +template +struct ptr_serialization_support +{ +# if defined(BOOST_MSVC) || defined(__SUNPRO_CC) + virtual BOOST_DLLEXPORT void instantiate() BOOST_USED; +# else + static BOOST_DLLEXPORT void instantiate() BOOST_USED; + typedef instantiate_function< + &ptr_serialization_support::instantiate + > x; +# endif +}; + +template +BOOST_DLLEXPORT void +ptr_serialization_support::instantiate() +{ + export_impl::enable_save( + typename Archive::is_saving() + ); + + export_impl::enable_load( + typename Archive::is_loading() + ); +} + +// Note INTENTIONAL usage of anonymous namespace in header. +// This was made this way so that export.hpp could be included +// in other headers. This is still under study. + +namespace extra_detail { + +template +struct guid_initializer +{ + void export_guid(mpl::false_) const { + // generates the statically-initialized objects whose constructors + // register the information allowing serialization of T objects + // through pointers to their base classes. + instantiate_ptr_serialization((T*)0, 0, adl_tag()); + } + void export_guid(mpl::true_) const { + } + guid_initializer const & export_guid() const { + BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); + // note: exporting an abstract base class will have no effect + // and cannot be used to instantitiate serialization code + // (one might be using this in a DLL to instantiate code) + //BOOST_STATIC_WARNING(! boost::serialization::is_abstract< T >::value); + export_guid(boost::serialization::is_abstract< T >()); + return *this; + } +}; + +template +struct init_guid; + +} // anonymous +} // namespace detail +} // namespace archive +} // namespace boost + +#define BOOST_CLASS_EXPORT_IMPLEMENT(T) \ + namespace boost { \ + namespace archive { \ + namespace detail { \ + namespace extra_detail { \ + template<> \ + struct init_guid< T > { \ + static guid_initializer< T > const & g; \ + }; \ + guid_initializer< T > const & init_guid< T >::g = \ + ::boost::serialization::singleton< \ + guid_initializer< T > \ + >::get_mutable_instance().export_guid(); \ + }}}} \ +/**/ + +#define BOOST_CLASS_EXPORT_KEY2(T, K) \ +namespace boost { \ +namespace serialization { \ +template<> \ +struct guid_defined< T > : boost::mpl::true_ {}; \ +template<> \ +inline const char * guid< T >(){ \ + return K; \ +} \ +} /* serialization */ \ +} /* boost */ \ +/**/ + +#define BOOST_CLASS_EXPORT_KEY(T) \ + BOOST_CLASS_EXPORT_KEY2(T, BOOST_PP_STRINGIZE(T)) \ +/**/ + +#define BOOST_CLASS_EXPORT_GUID(T, K) \ +BOOST_CLASS_EXPORT_KEY2(T, K) \ +BOOST_CLASS_EXPORT_IMPLEMENT(T) \ +/**/ + +#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + +// CodeWarrior fails to construct static members of class templates +// when they are instantiated from within templates, so on that +// compiler we ask users to specifically register base/derived class +// relationships for exported classes. On all other compilers, use of +// this macro is entirely optional. +# define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived) \ +namespace { \ + static int BOOST_PP_CAT(boost_serialization_mwerks_init_, __LINE__) = \ + (::boost::archive::detail::instantiate_ptr_serialization((Derived*)0,0), 3); \ + static int BOOST_PP_CAT(boost_serialization_mwerks_init2_, __LINE__) = ( \ + ::boost::serialization::void_cast_register((Derived*)0,(Base*)0) \ + , 3); \ +} + +#else + +# define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived) + +#endif + +// check for unnecessary export. T isn't polymorphic so there is no +// need to export it. +#define BOOST_CLASS_EXPORT_CHECK(T) \ + BOOST_STATIC_WARNING( \ + boost::is_polymorphic::value \ + ); \ + /**/ + +// the default exportable class identifier is the class name +// the default list of archives types for which code id generated +// are the originally included with this serialization system +#define BOOST_CLASS_EXPORT(T) \ + BOOST_CLASS_EXPORT_GUID( \ + T, \ + BOOST_PP_STRINGIZE(T) \ + ) \ + /**/ + +#endif // BOOST_SERIALIZATION_EXPORT_HPP + diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info.hpp new file mode 100644 index 00000000000..bb2a190d465 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info.hpp @@ -0,0 +1,116 @@ +#ifndef BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_HPP +#define BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// extended_type_info.hpp: interface for portable version of type_info + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// for now, extended type info is part of the serialization libraries +// this could change in the future. +#include +#include +#include // NULL +#include +#include +#include + +#include +#include // must be the last header +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4251 4231 4660 4275) +#endif + +#define BOOST_SERIALIZATION_MAX_KEY_SIZE 128 + +namespace boost { +namespace serialization { + +namespace void_cast_detail{ + class void_caster; +} + +class BOOST_SYMBOL_VISIBLE extended_type_info : + private boost::noncopyable +{ +private: + friend class boost::serialization::void_cast_detail::void_caster; + + // used to uniquely identify the type of class derived from this one + // so that different derivations of this class can be simultaneously + // included in implementation of sets and maps. + const unsigned int m_type_info_key; + virtual bool is_less_than(const extended_type_info & /*rhs*/) const = 0; + virtual bool is_equal(const extended_type_info & /*rhs*/) const = 0; + const char * m_key; + +protected: + BOOST_SERIALIZATION_DECL void key_unregister() const; + BOOST_SERIALIZATION_DECL void key_register() const; + // this class can't be used as is. It's just the + // common functionality for all type_info replacement + // systems. Hence, make these protected + BOOST_SERIALIZATION_DECL extended_type_info( + const unsigned int type_info_key, + const char * key + ); + virtual BOOST_SERIALIZATION_DECL ~extended_type_info(); +public: + const char * get_key() const { + return m_key; + } + virtual const char * get_debug_info() const = 0; + BOOST_SERIALIZATION_DECL bool operator<(const extended_type_info &rhs) const; + BOOST_SERIALIZATION_DECL bool operator==(const extended_type_info &rhs) const; + bool operator!=(const extended_type_info &rhs) const { + return !(operator==(rhs)); + } + // note explicit "export" of static function to work around + // gcc 4.5 mingw error + static BOOST_SERIALIZATION_DECL const extended_type_info * + find(const char *key); + // for plugins + virtual void * construct(unsigned int /*count*/ = 0, ...) const = 0; + virtual void destroy(void const * const /*p*/) const = 0; +}; + +template +struct guid_defined : boost::mpl::false_ {}; + +namespace ext { + template + struct guid_impl + { + static inline const char * call() + { + return NULL; + } + }; +} + +template +inline const char * guid(){ + return ext::guid_impl::call(); +} + +} // namespace serialization +} // namespace boost + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_no_rtti.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_no_rtti.hpp new file mode 100644 index 00000000000..aaa8b44459b --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_no_rtti.hpp @@ -0,0 +1,182 @@ +#ifndef BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP +#define BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +// extended_type_info_no_rtti.hpp: implementation for version that depends +// on runtime typing (rtti - typeid) but uses a user specified string +// as the portable class identifier. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +// hijack serialization access +#include + +#include // must be the last header +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4251 4231 4660 4275 4511 4512) +#endif + +namespace boost { +namespace serialization { +/////////////////////////////////////////////////////////////////////// +// define a special type_info that doesn't depend on rtti which is not +// available in all situations. + +namespace no_rtti_system { + +// common base class to share type_info_key. This is used to +// identify the method used to keep track of the extended type +class BOOST_SYMBOL_VISIBLE extended_type_info_no_rtti_0 : + public extended_type_info +{ +protected: + BOOST_SERIALIZATION_DECL extended_type_info_no_rtti_0(const char * key); + BOOST_SERIALIZATION_DECL ~extended_type_info_no_rtti_0(); +public: + virtual BOOST_SERIALIZATION_DECL bool + is_less_than(const boost::serialization::extended_type_info &rhs) const ; + virtual BOOST_SERIALIZATION_DECL bool + is_equal(const boost::serialization::extended_type_info &rhs) const ; +}; + +} // no_rtti_system + +template +class extended_type_info_no_rtti : + public no_rtti_system::extended_type_info_no_rtti_0, + public singleton > +{ + template + struct action { + struct defined { + static const char * invoke(){ + return guid< T >(); + } + }; + struct undefined { + // if your program traps here - you failed to + // export a guid for this type. the no_rtti + // system requires export for types serialized + // as pointers. + BOOST_STATIC_ASSERT(0 == sizeof(T)); + static const char * invoke(); + }; + static const char * invoke(){ + typedef + typename boost::mpl::if_c< + tf, + defined, + undefined + >::type type; + return type::invoke(); + } + }; +public: + extended_type_info_no_rtti() : + no_rtti_system::extended_type_info_no_rtti_0(get_key()) + { + key_register(); + } + ~extended_type_info_no_rtti(){ + key_unregister(); + } + const extended_type_info * + get_derived_extended_type_info(const T & t) const { + // find the type that corresponds to the most derived type. + // this implementation doesn't depend on typeid() but assumes + // that the specified type has a function of the following signature. + // A common implemention of such a function is to define as a virtual + // function. So if the is not a polymporphic type it's likely an error + BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); + const char * derived_key = t.get_key(); + BOOST_ASSERT(NULL != derived_key); + return boost::serialization::extended_type_info::find(derived_key); + } + const char * get_key() const{ + return action::value >::invoke(); + } + virtual const char * get_debug_info() const{ + return action::value >::invoke(); + } + virtual void * construct(unsigned int count, ...) const{ + // count up the arguments + std::va_list ap; + va_start(ap, count); + switch(count){ + case 0: + return factory::type, 0>(ap); + case 1: + return factory::type, 1>(ap); + case 2: + return factory::type, 2>(ap); + case 3: + return factory::type, 3>(ap); + case 4: + return factory::type, 4>(ap); + default: + BOOST_ASSERT(false); // too many arguments + // throw exception here? + return NULL; + } + } + virtual void destroy(void const * const p) const{ + boost::serialization::access::destroy( + static_cast(p) + ); + //delete static_cast(p) ; + } +}; + +} // namespace serialization +} // namespace boost + +/////////////////////////////////////////////////////////////////////////////// +// If no other implementation has been designated as default, +// use this one. To use this implementation as the default, specify it +// before any of the other headers. + +#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO + #define BOOST_SERIALIZATION_DEFAULT_TYPE_INFO + namespace boost { + namespace serialization { + template + struct extended_type_info_impl { + typedef typename + boost::serialization::extended_type_info_no_rtti< T > type; + }; + } // namespace serialization + } // namespace boost +#endif + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_typeid.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_typeid.hpp new file mode 100644 index 00000000000..8ee591b3169 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_typeid.hpp @@ -0,0 +1,167 @@ +#ifndef BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_TYPEID_HPP +#define BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_TYPEID_HPP + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +// extended_type_info_typeid.hpp: implementation for version that depends +// on runtime typing (rtti - typeid) but uses a user specified string +// as the portable class identifier. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +// hijack serialization access +#include + +#include + +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4251 4231 4660 4275 4511 4512) +#endif + +namespace boost { +namespace serialization { +namespace typeid_system { + +class BOOST_SYMBOL_VISIBLE extended_type_info_typeid_0 : + public extended_type_info +{ + virtual const char * get_debug_info() const { + if(static_cast(0) == m_ti) + return static_cast(0); + return m_ti->name(); + } +protected: + const std::type_info * m_ti; + BOOST_SERIALIZATION_DECL extended_type_info_typeid_0(const char * key); + BOOST_SERIALIZATION_DECL ~extended_type_info_typeid_0(); + BOOST_SERIALIZATION_DECL void type_register(const std::type_info & ti); + BOOST_SERIALIZATION_DECL void type_unregister(); + BOOST_SERIALIZATION_DECL const extended_type_info * + get_extended_type_info(const std::type_info & ti) const; +public: + virtual BOOST_SERIALIZATION_DECL bool + is_less_than(const extended_type_info &rhs) const; + virtual BOOST_SERIALIZATION_DECL bool + is_equal(const extended_type_info &rhs) const; + const std::type_info & get_typeid() const { + return *m_ti; + } +}; + +} // typeid_system + +template +class extended_type_info_typeid : + public typeid_system::extended_type_info_typeid_0, + public singleton > +{ +public: + extended_type_info_typeid() : + typeid_system::extended_type_info_typeid_0( + boost::serialization::guid< T >() + ) + { + type_register(typeid(T)); + key_register(); + } + ~extended_type_info_typeid(){ + key_unregister(); + type_unregister(); + } + // get the eti record for the true type of this record + // relying upon standard type info implemenation (rtti) + const extended_type_info * + get_derived_extended_type_info(const T & t) const { + // note: this implementation - based on usage of typeid (rtti) + // only does something if the class has at least one virtual function. + BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); + return + typeid_system::extended_type_info_typeid_0::get_extended_type_info( + typeid(t) + ); + } + const char * get_key() const { + return boost::serialization::guid< T >(); + } + virtual void * construct(unsigned int count, ...) const{ + // count up the arguments + std::va_list ap; + va_start(ap, count); + switch(count){ + case 0: + return factory::type, 0>(ap); + case 1: + return factory::type, 1>(ap); + case 2: + return factory::type, 2>(ap); + case 3: + return factory::type, 3>(ap); + case 4: + return factory::type, 4>(ap); + default: + BOOST_ASSERT(false); // too many arguments + // throw exception here? + return NULL; + } + } + virtual void destroy(void const * const p) const { + boost::serialization::access::destroy( + static_cast(p) + ); + //delete static_cast(p); + } +}; + +} // namespace serialization +} // namespace boost + +/////////////////////////////////////////////////////////////////////////////// +// If no other implementation has been designated as default, +// use this one. To use this implementation as the default, specify it +// before any of the other headers. +#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO + #define BOOST_SERIALIZATION_DEFAULT_TYPE_INFO + namespace boost { + namespace serialization { + template + struct extended_type_info_impl { + typedef typename + boost::serialization::extended_type_info_typeid< T > type; + }; + } // namespace serialization + } // namespace boost +#endif + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_TYPEID_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/factory.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/factory.hpp new file mode 100644 index 00000000000..2db7e7e36c3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/factory.hpp @@ -0,0 +1,102 @@ +#ifndef BOOST_SERIALIZATION_FACTORY_HPP +#define BOOST_SERIALIZATION_FACTORY_HPP + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +// factory.hpp: create an instance from an extended_type_info instance. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // valist +#include // NULL + +#include +#include +#include + +namespace std{ + #if defined(__LIBCOMO__) + using ::va_list; + #endif +} // namespace std + +namespace boost { +namespace serialization { + +// default implementation does nothing. +template +T * factory(std::va_list){ + BOOST_ASSERT(false); + // throw exception here? + return NULL; +} + +} // namespace serialization +} // namespace boost + +#define BOOST_SERIALIZATION_FACTORY(N, T, A0, A1, A2, A3) \ +namespace boost { \ +namespace serialization { \ + template<> \ + T * factory(std::va_list ap){ \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 0) \ + , A0 a0 = va_arg(ap, A0);, BOOST_PP_EMPTY()) \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 1) \ + , A1 a1 = va_arg(ap, A1);, BOOST_PP_EMPTY()) \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 2) \ + , A2 a2 = va_arg(ap, A2);, BOOST_PP_EMPTY()) \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 3) \ + , A3 a3 = va_arg(ap, A3);, BOOST_PP_EMPTY()) \ + return new T( \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 0) \ + , a0, BOOST_PP_EMPTY()) \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 1)) \ + , BOOST_PP_COMMA, BOOST_PP_EMPTY)() \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 1) \ + , a1, BOOST_PP_EMPTY()) \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 2)) \ + , BOOST_PP_COMMA, BOOST_PP_EMPTY)() \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 2) \ + , a2, BOOST_PP_EMPTY()) \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 3)) \ + , BOOST_PP_COMMA, BOOST_PP_EMPTY)() \ + BOOST_PP_IF(BOOST_PP_GREATER(N, 3) \ + , a3, BOOST_PP_EMPTY()) \ + ); \ + } \ +} \ +} /**/ + +#define BOOST_SERIALIZATION_FACTORY_4(T, A0, A1, A2, A3) \ + BOOST_SERIALIZATION_FACTORY(4, T, A0, A1, A2, A3) + +#define BOOST_SERIALIZATION_FACTORY_3(T, A0, A1, A2) \ + BOOST_SERIALIZATION_FACTORY(3, T, A0, A1, A2, 0) + +#define BOOST_SERIALIZATION_FACTORY_2(T, A0, A1) \ + BOOST_SERIALIZATION_FACTORY(2, T, A0, A1, 0, 0) + +#define BOOST_SERIALIZATION_FACTORY_1(T, A0) \ + BOOST_SERIALIZATION_FACTORY(1, T, A0, 0, 0, 0) + +#define BOOST_SERIALIZATION_FACTORY_0(T) \ +namespace boost { \ +namespace serialization { \ + template<> \ + T * factory(std::va_list){ \ + return new T(); \ + } \ +} \ +} \ +/**/ + +#endif // BOOST_SERIALIZATION_FACTORY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/force_include.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/force_include.hpp new file mode 100644 index 00000000000..55ab79d0d58 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/force_include.hpp @@ -0,0 +1,55 @@ +#ifndef BOOST_SERIALIZATION_FORCE_INCLUDE_HPP +#define BOOST_SERIALIZATION_FORCE_INCLUDE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// force_include.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +// the following help macro is to guarentee that certain coded +// is not removed by over-eager linker optimiser. In certain cases +// we create static objects must be created but are actually never +// referenced - creation has a side-effect such as global registration +// which is important to us. We make an effort to refer these objects +// so that a smart linker won't remove them as being unreferenced. +// In microsoft compilers, inlining the code that does the referring +// means the code gets lost and the static object is not included +// in the library and hence never registered. This manifests itself +// in an ungraceful crash at runtime when (and only when) built in +// release mode. + +#if defined(BOOST_HAS_DECLSPEC) && !defined(__COMO__) +# define BOOST_DLLEXPORT __declspec(dllexport) +#elif ! defined(_WIN32) && ! defined(_WIN64) +# if defined(__MWERKS__) +# define BOOST_DLLEXPORT __declspec(dllexport) +# elif defined(__GNUC__) && (__GNUC__ >= 3) +# define BOOST_USED __attribute__ ((__used__)) +# elif defined(__IBMCPP__) && (__IBMCPP__ >= 1110) +# define BOOST_USED __attribute__ ((__used__)) +# elif defined(__INTEL_COMPILER) && (BOOST_INTEL_CXX_VERSION >= 800) +# define BOOST_USED __attribute__ ((__used__)) +# endif +#endif + +#ifndef BOOST_USED +# define BOOST_USED +#endif + +#ifndef BOOST_DLLEXPORT +# define BOOST_DLLEXPORT +#endif + +#endif // BOOST_SERIALIZATION_FORCE_INCLUDE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/forward_list.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/forward_list.hpp new file mode 100644 index 00000000000..b8a3c20a6ea --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/forward_list.hpp @@ -0,0 +1,124 @@ +#ifndef BOOST_SERIALIZATION_FORWARD_LIST_HPP +#define BOOST_SERIALIZATION_FORWARD_LIST_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// forward_list.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include // distance + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template +inline void save( + Archive & ar, + const std::forward_list &t, + const unsigned int /*file_version*/ +){ + const collection_size_type count(std::distance(t.cbegin(), t.cend())); + boost::serialization::stl::save_collection< + Archive, + std::forward_list + >(ar, t, count); +} + +namespace stl { + +template< + class Archive, + class T, + class Allocator +> +typename boost::disable_if< + typename detail::is_default_constructible< + typename std::forward_list::value_type + >, + void +>::type +collection_load_impl( + Archive & ar, + std::forward_list &t, + collection_size_type count, + item_version_type item_version +){ + t.clear(); + boost::serialization::detail::stack_construct u(ar, item_version); + ar >> boost::serialization::make_nvp("item", u.reference()); + t.push_front(boost::move(u.reference())); + typename std::forward_list::iterator last; + last = t.begin(); + ar.reset_object_address(&(*t.begin()) , & u.reference()); + while(--count > 0){ + detail::stack_construct u(ar, item_version); + ar >> boost::serialization::make_nvp("item", u.reference()); + last = t.insert_after(last, boost::move(u.reference())); + ar.reset_object_address(&(*last) , & u.reference()); + } +} + +} // stl + +template +inline void load( + Archive & ar, + std::forward_list &t, + const unsigned int /*file_version*/ +){ + const boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + stl::collection_load_impl(ar, t, count, item_version); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::forward_list &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(std::forward_list) + +#endif // BOOST_SERIALIZATION_FORWARD_LIST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_load_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_load_imp.hpp new file mode 100644 index 00000000000..88def8f1aa4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_load_imp.hpp @@ -0,0 +1,77 @@ +#ifndef BOOST_SERIALIZATION_HASH_COLLECTIONS_LOAD_IMP_HPP +#define BOOST_SERIALIZATION_HASH_COLLECTIONS_LOAD_IMP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// hash_collections_load_imp.hpp: serialization for loading stl collections + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// helper function templates for serialization of hashed collections +#include +#include +#include +#include +#include + +namespace boost{ +namespace serialization { +namespace stl { + +////////////////////////////////////////////////////////////////////// +// implementation of serialization for STL containers +// +template +inline void load_hash_collection(Archive & ar, Container &s) +{ + collection_size_type count; + collection_size_type bucket_count; + boost::serialization::item_version_type item_version(0); + boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + if(boost::archive::library_version_type(6) != library_version){ + ar >> BOOST_SERIALIZATION_NVP(count); + ar >> BOOST_SERIALIZATION_NVP(bucket_count); + } + else{ + // note: fixup for error in version 6. collection size was + // changed to size_t BUT for hashed collections it was implemented + // as an unsigned int. This should be a problem only on win64 machines + // but I'll leave it for everyone just in case. + unsigned int c; + unsigned int bc; + ar >> BOOST_SERIALIZATION_NVP(c); + count = c; + ar >> BOOST_SERIALIZATION_NVP(bc); + bucket_count = bc; + } + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + s.clear(); + #if ! defined(__MWERKS__) + s.resize(bucket_count); + #endif + InputFunction ifunc; + while(count-- > 0){ + ifunc(ar, s, item_version); + } +} + +} // namespace stl +} // namespace serialization +} // namespace boost + +#endif //BOOST_SERIALIZATION_HASH_COLLECTIONS_LOAD_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_save_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_save_imp.hpp new file mode 100644 index 00000000000..65dfe83f16e --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_save_imp.hpp @@ -0,0 +1,97 @@ +#ifndef BOOST_SERIALIZATION_HASH_COLLECTIONS_SAVE_IMP_HPP +#define BOOST_SERIALIZATION_HASH_COLLECTIONS_SAVE_IMP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// hash_collections_save_imp.hpp: serialization for stl collections + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// helper function templates for serialization of collections + +#include +#include +#include +#include +#include +#include + +namespace boost{ +namespace serialization { +namespace stl { + +////////////////////////////////////////////////////////////////////// +// implementation of serialization for STL containers +// + +template +inline void save_hash_collection(Archive & ar, const Container &s) +{ + collection_size_type count(s.size()); + const collection_size_type bucket_count(s.bucket_count()); + const item_version_type item_version( + version::value + ); + + #if 0 + /* should only be necessary to create archives of previous versions + * which is not currently supported. So for now comment this out + */ + boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + if(boost::archive::library_version_type(6) != library_version){ + ar << BOOST_SERIALIZATION_NVP(count); + ar << BOOST_SERIALIZATION_NVP(bucket_count); + } + else{ + // note: fixup for error in version 6. collection size was + // changed to size_t BUT for hashed collections it was implemented + // as an unsigned int. This should be a problem only on win64 machines + // but I'll leave it for everyone just in case. + const unsigned int c = count; + const unsigned int bc = bucket_count; + ar << BOOST_SERIALIZATION_NVP(c); + ar << BOOST_SERIALIZATION_NVP(bc); + } + if(boost::archive::library_version_type(3) < library_version){ + // record number of elements + // make sure the target type is registered so we can retrieve + // the version when we load + ar << BOOST_SERIALIZATION_NVP(item_version); + } + #else + ar << BOOST_SERIALIZATION_NVP(count); + ar << BOOST_SERIALIZATION_NVP(bucket_count); + ar << BOOST_SERIALIZATION_NVP(item_version); + #endif + + typename Container::const_iterator it = s.begin(); + while(count-- > 0){ + // note borland emits a no-op without the explicit namespace + boost::serialization::save_construct_data_adl( + ar, + &(*it), + boost::serialization::version< + typename Container::value_type + >::value + ); + ar << boost::serialization::make_nvp("item", *it++); + } +} + +} // namespace stl +} // namespace serialization +} // namespace boost + +#endif //BOOST_SERIALIZATION_HASH_COLLECTIONS_SAVE_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/hash_map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/hash_map.hpp new file mode 100644 index 00000000000..22626db6838 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/hash_map.hpp @@ -0,0 +1,232 @@ +#ifndef BOOST_SERIALIZATION_HASH_MAP_HPP +#define BOOST_SERIALIZATION_HASH_MAP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization/hash_map.hpp: +// serialization for stl hash_map templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_HAS_HASH +#include BOOST_HASH_MAP_HEADER + +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +namespace stl { + +// map input +template +struct archive_input_hash_map +{ + inline void operator()( + Archive &ar, + Container &s, + const unsigned int v + ){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, v); + // borland fails silently w/o full namespace + ar >> boost::serialization::make_nvp("item", t.reference()); + std::pair result = + s.insert(boost::move(t.reference())); + // note: the following presumes that the map::value_type was NOT tracked + // in the archive. This is the usual case, but here there is no way + // to determine that. + if(result.second){ + ar.reset_object_address( + & (result.first->second), + & t.reference().second + ); + } + } +}; + +// multimap input +template +struct archive_input_hash_multimap +{ + inline void operator()( + Archive &ar, + Container &s, + const unsigned int v + ){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, v); + // borland fails silently w/o full namespace + ar >> boost::serialization::make_nvp("item", t.reference()); + typename Container::const_iterator result + = s.insert(boost::move(t.reference())); + // note: the following presumes that the map::value_type was NOT tracked + // in the archive. This is the usual case, but here there is no way + // to determine that. + ar.reset_object_address( + & result->second, + & t.reference() + ); + } +}; + +} // stl + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const BOOST_STD_EXTENSION_NAMESPACE::hash_map< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::stl::save_hash_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_map< + Key, HashFcn, EqualKey, Allocator + > + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::hash_map< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::stl::load_hash_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_map< + Key, HashFcn, EqualKey, Allocator + >, + boost::serialization::stl::archive_input_hash_map< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_map< + Key, HashFcn, EqualKey, Allocator + > + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::hash_map< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +// hash_multimap +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::stl::save_hash_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< + Key, HashFcn, EqualKey, Allocator + > + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::stl::load_hash_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< + Key, HashFcn, EqualKey, Allocator + >, + boost::serialization::stl::archive_input_hash_multimap< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< + Key, HashFcn, EqualKey, Allocator + > + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_HAS_HASH +#endif // BOOST_SERIALIZATION_HASH_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/hash_set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/hash_set.hpp new file mode 100644 index 00000000000..0c72c18457e --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/hash_set.hpp @@ -0,0 +1,222 @@ +#ifndef BOOST_SERIALIZATION_HASH_SET_HPP +#define BOOST_SERIALIZATION_HASH_SET_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// hash_set.hpp: serialization for stl hash_set templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_HAS_HASH +#include BOOST_HASH_SET_HEADER + +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +namespace stl { + +// hash_set input +template +struct archive_input_hash_set +{ + inline void operator()( + Archive &ar, + Container &s, + const unsigned int v + ){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, v); + // borland fails silently w/o full namespace + ar >> boost::serialization::make_nvp("item", t.reference()); + std::pair result = + s.insert(boost::move(t.reference())); + if(result.second) + ar.reset_object_address(& (* result.first), & t.reference()); + } +}; + +// hash_multiset input +template +struct archive_input_hash_multiset +{ + inline void operator()( + Archive &ar, + Container &s, + const unsigned int v + ){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, v); + // borland fails silently w/o full namespace + ar >> boost::serialization::make_nvp("item", t.reference()); + typename Container::const_iterator result + = s.insert(boost::move(t.reference())); + ar.reset_object_address(& (* result), & t.reference()); + } +}; + +} // stl + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const BOOST_STD_EXTENSION_NAMESPACE::hash_set< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::stl::save_hash_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_set< + Key, HashFcn, EqualKey, Allocator + > + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::hash_set< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::stl::load_hash_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_set< + Key, HashFcn, EqualKey, Allocator + >, + boost::serialization::stl::archive_input_hash_set< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_set< + Key, HashFcn, EqualKey, Allocator + > + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::hash_set< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +// hash_multiset +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::stl::save_hash_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< + Key, HashFcn, EqualKey, Allocator + > + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::stl::load_hash_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< + Key, HashFcn, EqualKey, Allocator + >, + boost::serialization::stl::archive_input_hash_multiset< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< + Key, HashFcn, EqualKey, Allocator + > + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< + Key, HashFcn, EqualKey, Allocator + > & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(BOOST_STD_EXTENSION_NAMESPACE::hash_set) +BOOST_SERIALIZATION_COLLECTION_TRAITS(BOOST_STD_EXTENSION_NAMESPACE::hash_multiset) + +#endif // BOOST_HAS_HASH +#endif // BOOST_SERIALIZATION_HASH_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/is_bitwise_serializable.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/is_bitwise_serializable.hpp new file mode 100644 index 00000000000..7e24a2cb6d8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/is_bitwise_serializable.hpp @@ -0,0 +1,46 @@ +// (C) Copyright 2007 Matthias Troyer + +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Matthias Troyer + +/** @file is_bitwise_serializable.hpp + * + * This header provides a traits class for determining whether a class + * can be serialized (in a non-portable way) just by copying the bits. + */ + + +#ifndef BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP +#define BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include + +namespace boost { +namespace serialization { + template + struct is_bitwise_serializable + : public is_arithmetic< T > + {}; +} // namespace serialization +} // namespace boost + + +// define a macro to make explicit designation of this more transparent +#define BOOST_IS_BITWISE_SERIALIZABLE(T) \ +namespace boost { \ +namespace serialization { \ +template<> \ +struct is_bitwise_serializable< T > : mpl::true_ {}; \ +}} \ +/**/ + +#endif //BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/item_version_type.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/item_version_type.hpp new file mode 100644 index 00000000000..f3e5adac6f8 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/item_version_type.hpp @@ -0,0 +1,68 @@ +#ifndef BOOST_SERIALIZATION_ITEM_VERSION_TYPE_HPP +#define BOOST_SERIALIZATION_ITEM_VERSION_TYPE_HPP + +// (C) Copyright 2010 Robert Ramey +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include // uint_least8_t +#include +#include +#include + +// fixes broken example build on x86_64-linux-gnu-gcc-4.6.0 +#include + +namespace boost { +namespace serialization { + +#if defined(_MSC_VER) +#pragma warning( push ) +#pragma warning( disable : 4244 4267 ) +#endif + +class item_version_type { +private: + typedef unsigned int base_type; + base_type t; +public: + // should be private - but MPI fails if it's not!!! + item_version_type(): t(0) {}; + explicit item_version_type(const unsigned int t_) : t(t_){ + BOOST_ASSERT(t_ <= boost::integer_traits::const_max); + } + item_version_type(const item_version_type & t_) : + t(t_.t) + {} + item_version_type & operator=(item_version_type rhs){ + t = rhs.t; + return *this; + } + // used for text output + operator base_type () const { + return t; + } + // used for text input + operator base_type & () { + return t; + } + bool operator==(const item_version_type & rhs) const { + return t == rhs.t; + } + bool operator<(const item_version_type & rhs) const { + return t < rhs.t; + } +}; + +#if defined(_MSC_VER) +#pragma warning( pop ) +#endif + +} } // end namespace boost::serialization + +BOOST_IS_BITWISE_SERIALIZABLE(item_version_type) + +BOOST_CLASS_IMPLEMENTATION(item_version_type, primitive_type) + +#endif //BOOST_SERIALIZATION_ITEM_VERSION_TYPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/level.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/level.hpp new file mode 100644 index 00000000000..f6a84d10422 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/level.hpp @@ -0,0 +1,116 @@ +#ifndef BOOST_SERIALIZATION_LEVEL_HPP +#define BOOST_SERIALIZATION_LEVEL_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// level.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +namespace boost { +namespace serialization { + +struct basic_traits; + +// default serialization implementation level +template +struct implementation_level_impl { + template + struct traits_class_level { + typedef typename U::level type; + }; + + typedef mpl::integral_c_tag tag; + // note: at least one compiler complained w/o the full qualification + // on basic traits below + typedef + typename mpl::eval_if< + is_base_and_derived, + traits_class_level< T >, + //else + typename mpl::eval_if< + is_fundamental< T >, + mpl::int_, + //else + typename mpl::eval_if< + is_class< T >, + mpl::int_, + //else + typename mpl::eval_if< + is_array< T >, + mpl::int_, + //else + typename mpl::eval_if< + is_enum< T >, + mpl::int_, + //else + mpl::int_ + > + > + > + > + >::type type; + // vc 7.1 doesn't like enums here + BOOST_STATIC_CONSTANT(int, value = type::value); +}; + +template +struct implementation_level : + public implementation_level_impl +{ +}; + +template +inline bool operator>=(implementation_level< T > t, enum level_type l) +{ + return t.value >= (int)l; +} + +} // namespace serialization +} // namespace boost + +// specify the level of serialization implementation for the class +// require that class info saved when versioning is used +#define BOOST_CLASS_IMPLEMENTATION(T, E) \ + namespace boost { \ + namespace serialization { \ + template <> \ + struct implementation_level_impl< const T > \ + { \ + typedef mpl::integral_c_tag tag; \ + typedef mpl::int_< E > type; \ + BOOST_STATIC_CONSTANT( \ + int, \ + value = implementation_level_impl::type::value \ + ); \ + }; \ + } \ + } + /**/ + +#endif // BOOST_SERIALIZATION_LEVEL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/level_enum.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/level_enum.hpp new file mode 100644 index 00000000000..baf64e04f31 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/level_enum.hpp @@ -0,0 +1,55 @@ +#ifndef BOOST_SERIALIZATION_LEVEL_ENUM_HPP +#define BOOST_SERIALIZATION_LEVEL_ENUM_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// level_enum.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +namespace boost { +namespace serialization { + +// for each class used in the program, specify which level +// of serialization should be implemented + +// names for each level +enum level_type +{ + // Don't serialize this type. An attempt to do so should + // invoke a compile time assertion. + not_serializable = 0, + // write/read this type directly to the archive. In this case + // serialization code won't be called. This is the default + // case for fundamental types. It presumes a member function or + // template in the archive class that can handle this type. + // there is no runtime overhead associated reading/writing + // instances of this level + primitive_type = 1, + // Serialize the objects of this type using the objects "serialize" + // function or template. This permits values to be written/read + // to/from archives but includes no class or version information. + object_serializable = 2, + /////////////////////////////////////////////////////////////////// + // once an object is serialized at one of the above levels, the + // corresponding archives cannot be read if the implementation level + // for the archive object is changed. + /////////////////////////////////////////////////////////////////// + // Add class information to the archive. Class information includes + // implementation level, class version and class name if available + object_class_info = 3 +}; + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_LEVEL_ENUM_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/list.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/list.hpp new file mode 100644 index 00000000000..5fdc114d7ed --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/list.hpp @@ -0,0 +1,85 @@ +#ifndef BOOST_SERIALIZATION_LIST_HPP +#define BOOST_SERIALIZATION_LIST_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// list.hpp: serialization for stl list templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template +inline void save( + Archive & ar, + const std::list &t, + const unsigned int /* file_version */ +){ + boost::serialization::stl::save_collection< + Archive, + std::list + >(ar, t); +} + +template +inline void load( + Archive & ar, + std::list &t, + const unsigned int /* file_version */ +){ + const boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + stl::collection_load_impl(ar, t, count, item_version); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::list & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(std::list) + +#endif // BOOST_SERIALIZATION_LIST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/map.hpp new file mode 100644 index 00000000000..9209864c8cf --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/map.hpp @@ -0,0 +1,139 @@ +#ifndef BOOST_SERIALIZATION_MAP_HPP +#define BOOST_SERIALIZATION_MAP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization/map.hpp: +// serialization for stl map templates + +// (C) Copyright 2002-2014 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// implementation of serialization for map and mult-map STL containers + +template +inline void load_map_collection(Archive & ar, Container &s) +{ + s.clear(); + const boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + typename Container::iterator hint; + hint = s.begin(); + while(count-- > 0){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, item_version); + ar >> boost::serialization::make_nvp("item", t.reference()); + typename Container::iterator result = + s.insert(hint, boost::move(t.reference())); + ar.reset_object_address(& (result->second), & t.reference().second); + hint = result; + ++hint; + } +} + +// map +template +inline void save( + Archive & ar, + const std::map &t, + const unsigned int /* file_version */ +){ + boost::serialization::stl::save_collection< + Archive, + std::map + >(ar, t); +} + +template +inline void load( + Archive & ar, + std::map &t, + const unsigned int /* file_version */ +){ + load_map_collection(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::map &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +// multimap +template +inline void save( + Archive & ar, + const std::multimap &t, + const unsigned int /* file_version */ +){ + boost::serialization::stl::save_collection< + Archive, + std::multimap + >(ar, t); +} + +template +inline void load( + Archive & ar, + std::multimap &t, + const unsigned int /* file_version */ +){ + load_map_collection(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::multimap &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/nvp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/nvp.hpp new file mode 100644 index 00000000000..4e2297b3cc9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/nvp.hpp @@ -0,0 +1,123 @@ +#ifndef BOOST_SERIALIZATION_NVP_HPP +#define BOOST_SERIALIZATION_NVP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// nvp.hpp: interface for serialization system. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template +struct nvp : + public std::pair, + public wrapper_traits > +{ +//private: + nvp(const nvp & rhs) : + std::pair(rhs.first, rhs.second) + {} +public: + explicit nvp(const char * name_, T & t) : + // note: added _ to suppress useless gcc warning + std::pair(name_, & t) + {} + + const char * name() const { + return this->first; + } + T & value() const { + return *(this->second); + } + + const T & const_value() const { + return *(this->second); + } + + template + void save( + Archive & ar, + const unsigned int /* file_version */ + ) const { + ar.operator<<(const_value()); + } + template + void load( + Archive & ar, + const unsigned int /* file_version */ + ){ + ar.operator>>(value()); + } + BOOST_SERIALIZATION_SPLIT_MEMBER() +}; + +template +inline +const nvp< T > make_nvp(const char * name, T & t){ + return nvp< T >(name, t); +} + +// to maintain efficiency and portability, we want to assign +// specific serialization traits to all instances of this wrappers. +// we can't strait forward method below as it depends upon +// Partial Template Specialization and doing so would mean that wrappers +// wouldn't be treated the same on different platforms. This would +// break archive portability. Leave this here as reminder not to use it !!! + +template +struct implementation_level > +{ + typedef mpl::integral_c_tag tag; + typedef mpl::int_ type; + BOOST_STATIC_CONSTANT(int, value = implementation_level::type::value); +}; + +// nvp objects are generally created on the stack and are never tracked +template +struct tracking_level > +{ + typedef mpl::integral_c_tag tag; + typedef mpl::int_ type; + BOOST_STATIC_CONSTANT(int, value = tracking_level::type::value); +}; + +} // seralization +} // boost + +#include + +#define BOOST_SERIALIZATION_NVP(name) \ + boost::serialization::make_nvp(BOOST_PP_STRINGIZE(name), name) +/**/ + +#define BOOST_SERIALIZATION_BASE_OBJECT_NVP(name) \ + boost::serialization::make_nvp( \ + BOOST_PP_STRINGIZE(name), \ + boost::serialization::base_object(*this) \ + ) +/**/ + +#endif // BOOST_SERIALIZATION_NVP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/optional.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/optional.hpp new file mode 100644 index 00000000000..d6ff830a8c3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/optional.hpp @@ -0,0 +1,107 @@ +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 + +// (C) Copyright 2002-4 Pavel Vozenilek . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Provides non-intrusive serialization for boost::optional. + +#ifndef BOOST_SERIALIZATION_OPTIONAL_HPP_ +#define BOOST_SERIALIZATION_OPTIONAL_HPP_ + +#if defined(_MSC_VER) +# pragma once +#endif + +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// function specializations must be defined in the appropriate +// namespace - boost::serialization +namespace boost { +namespace serialization { + +template +void save( + Archive & ar, + const boost::optional< T > & t, + const unsigned int /*version*/ +){ + // It is an inherent limitation to the serialization of optional.hpp + // that the underlying type must be either a pointer or must have a + // default constructor. It's possible that this could change sometime + // in the future, but for now, one will have to work around it. This can + // be done by serialization the optional as optional + #if ! defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) + BOOST_STATIC_ASSERT( + boost::serialization::detail::is_default_constructible::value + || boost::is_pointer::value + ); + #endif + const bool tflag = t.is_initialized(); + ar << boost::serialization::make_nvp("initialized", tflag); + if (tflag){ + ar << boost::serialization::make_nvp("value", *t); + } +} + +template +void load( + Archive & ar, + boost::optional< T > & t, + const unsigned int version +){ + bool tflag; + ar >> boost::serialization::make_nvp("initialized", tflag); + if(! tflag){ + t.reset(); + return; + } + + if(0 == version){ + boost::serialization::item_version_type item_version(0); + boost::archive::library_version_type library_version( + ar.get_library_version() + ); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + } + if(! t.is_initialized()) + t = T(); + ar >> boost::serialization::make_nvp("value", *t); +} + +template +void serialize( + Archive & ar, + boost::optional< T > & t, + const unsigned int version +){ + boost::serialization::split_free(ar, t, version); +} + +template +struct version > { + BOOST_STATIC_CONSTANT(int, value = 1); +}; + +} // serialization +} // boost + +#endif // BOOST_SERIALIZATION_OPTIONAL_HPP_ diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/priority_queue.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/priority_queue.hpp new file mode 100644 index 00000000000..5b08ffd1e82 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/priority_queue.hpp @@ -0,0 +1,76 @@ +#ifndef BOOST_SERIALIZATION_PRIORITY_QUEUE_HPP +#define BOOST_SERIALIZATION_PRIORITY_QUEUE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// priority_queue.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include + +// function specializations must be defined in the appropriate +// namespace - boost::serialization +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +#define STD _STLP_STD +#else +#define STD std +#endif + +namespace boost { +namespace serialization { +namespace detail{ + +template +struct priority_queue_save : public STD::priority_queue { + template + void operator()(Archive & ar, const unsigned int file_version) const { + save(ar, STD::priority_queue::c, file_version); + } +}; +template +struct priority_queue_load : public STD::priority_queue { + template + void operator()(Archive & ar, const unsigned int file_version) { + load(ar, STD::priority_queue::c, file_version); + } +}; + +} // detail + +template +inline void serialize( + Archive & ar, + std::priority_queue< T, Container, Compare> & t, + const unsigned int file_version +){ + typedef typename mpl::eval_if< + typename Archive::is_saving, + mpl::identity >, + mpl::identity > + >::type typex; + static_cast(t)(ar, file_version); +} + +} // namespace serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::priority_queue) + +#undef STD + +#endif // BOOST_SERIALIZATION_PRIORITY_QUEUE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/queue.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/queue.hpp new file mode 100644 index 00000000000..b22745215d9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/queue.hpp @@ -0,0 +1,76 @@ +#ifndef BOOST_SERIALIZATION_QUEUE_HPP +#define BOOST_SERIALIZATION_QUEUE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// queue.hpp + +// (C) Copyright 2014 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include + +// function specializations must be defined in the appropriate +// namespace - boost::serialization +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +#define STD _STLP_STD +#else +#define STD std +#endif + +namespace boost { +namespace serialization { +namespace detail { + +template +struct queue_save : public STD::queue { + template + void operator()(Archive & ar, const unsigned int file_version) const { + save(ar, STD::queue::c, file_version); + } +}; +template +struct queue_load : public STD::queue { + template + void operator()(Archive & ar, const unsigned int file_version) { + load(ar, STD::queue::c, file_version); + } +}; + +} // detail + +template +inline void serialize( + Archive & ar, + std::queue< T, C> & t, + const unsigned int file_version +){ + typedef typename mpl::eval_if< + typename Archive::is_saving, + mpl::identity >, + mpl::identity > + >::type typex; + static_cast(t)(ar, file_version); +} + +} // namespace serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::queue) + +#undef STD + +#endif // BOOST_SERIALIZATION_QUEUE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/scoped_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/scoped_ptr.hpp new file mode 100644 index 00000000000..0d11f8436e0 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/scoped_ptr.hpp @@ -0,0 +1,58 @@ +#ifndef BOOST_SERIALIZATION_SCOPED_PTR_HPP_VP_2003_10_30 +#define BOOST_SERIALIZATION_SCOPED_PTR_HPP_VP_2003_10_30 + +#if defined(_MSC_VER) +# pragma once +#endif + +// Copyright (c) 2003 Vladimir Prus. +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Provides non-intrusive serialization for boost::scoped_ptr +// Does not allow to serialize scoped_ptr's to builtin types. + +#include + +#include +#include +#include + +namespace boost { +namespace serialization { + + template + void save( + Archive & ar, + const boost::scoped_ptr< T > & t, + const unsigned int /* version */ + ){ + T* r = t.get(); + ar << boost::serialization::make_nvp("scoped_ptr", r); + } + + template + void load( + Archive & ar, + boost::scoped_ptr< T > & t, + const unsigned int /* version */ + ){ + T* r; + ar >> boost::serialization::make_nvp("scoped_ptr", r); + t.reset(r); + } + + template + void serialize( + Archive& ar, + boost::scoped_ptr< T >& t, + const unsigned int version + ){ + boost::serialization::split_free(ar, t, version); + } + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_SCOPED_PTR_HPP_VP_2003_10_30 diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/serialization.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/serialization.hpp new file mode 100644 index 00000000000..a4d04723c75 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/serialization.hpp @@ -0,0 +1,154 @@ +#ifndef BOOST_SERIALIZATION_SERIALIZATION_HPP +#define BOOST_SERIALIZATION_SERIALIZATION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +#if defined(_MSC_VER) +# pragma warning (disable : 4675) // suppress ADL warning +#endif + +#include +#include + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization.hpp: interface for serialization system. + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +////////////////////////////////////////////////////////////////////// +// public interface to serialization. + +///////////////////////////////////////////////////////////////////////////// +// layer 0 - intrusive verison +// declared and implemented for each user defined class to be serialized +// +// template +// serialize(Archive &ar, const unsigned int file_version){ +// ar & base_object(*this) & member1 & member2 ... ; +// } + +///////////////////////////////////////////////////////////////////////////// +// layer 1 - layer that routes member access through the access class. +// this is what permits us to grant access to private class member functions +// by specifying friend class boost::serialization::access + +#include + +///////////////////////////////////////////////////////////////////////////// +// layer 2 - default implementation of non-intrusive serialization. +// +// note the usage of function overloading to compensate that C++ does not +// currently support Partial Template Specialization for function templates +// We have declared the version number as "const unsigned long". +// Overriding templates for specific data types should declare the version +// number as "const unsigned int". Template matching will first be applied +// to functions with the same version types - that is the overloads. +// If there is no declared function prototype that matches, the second argument +// will be converted to "const unsigned long" and a match will be made with +// one of the default template functions below. + +namespace boost { +namespace serialization { + +BOOST_STRONG_TYPEDEF(unsigned int, version_type) + +// default implementation - call the member function "serialize" +template +inline void serialize( + Archive & ar, T & t, const unsigned int file_version +){ + access::serialize(ar, t, static_cast(file_version)); +} + +// save data required for construction +template +inline void save_construct_data( + Archive & /*ar*/, + const T * /*t*/, + const unsigned int /*file_version */ +){ + // default is to save no data because default constructor + // requires no arguments. +} + +// load data required for construction and invoke constructor in place +template +inline void load_construct_data( + Archive & /*ar*/, + T * t, + const unsigned int /*file_version*/ +){ + // default just uses the default constructor. going + // through access permits usage of otherwise private default + // constructor + access::construct(t); +} + +///////////////////////////////////////////////////////////////////////////// +// layer 3 - move call into serialization namespace so that ADL will function +// in the manner we desire. +// +// on compilers which don't implement ADL. only the current namespace +// i.e. boost::serialization will be searched. +// +// on compilers which DO implement ADL +// serialize overrides can be in any of the following +// +// 1) same namepace as Archive +// 2) same namespace as T +// 3) boost::serialization +// +// Due to Martin Ecker + +template +inline void serialize_adl( + Archive & ar, + T & t, + const unsigned int file_version +){ + // note usage of function overloading to delay final resolution + // until the point of instantiation. This works around the two-phase + // lookup "feature" which inhibits redefintion of a default function + // template implementation. Due to Robert Ramey + // + // Note that this trick generates problems for compiles which don't support + // PFTO, suppress it here. As far as we know, there are no compilers + // which fail to support PFTO while supporting two-phase lookup. + const version_type v(file_version); + serialize(ar, t, v); +} + +template +inline void save_construct_data_adl( + Archive & ar, + const T * t, + const unsigned int file_version +){ + // see above + const version_type v(file_version); + save_construct_data(ar, t, v); +} + +template +inline void load_construct_data_adl( + Archive & ar, + T * t, + const unsigned int file_version +){ + // see above comment + const version_type v(file_version); + load_construct_data(ar, t, v); +} + +} // namespace serialization +} // namespace boost + +#endif //BOOST_SERIALIZATION_SERIALIZATION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/set.hpp new file mode 100644 index 00000000000..643906c5aac --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/set.hpp @@ -0,0 +1,137 @@ +#ifndef BOOST_SERIALIZATION_SET_HPP +#define BOOST_SERIALIZATION_SET_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// set.hpp: serialization for stl set templates + +// (C) Copyright 2002-2014 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace boost { +namespace serialization { + +template +inline void load_set_collection(Archive & ar, Container &s) +{ + s.clear(); + const boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + typename Container::iterator hint; + hint = s.begin(); + while(count-- > 0){ + typedef typename Container::value_type type; + detail::stack_construct t(ar, item_version); + // borland fails silently w/o full namespace + ar >> boost::serialization::make_nvp("item", t.reference()); + typename Container::iterator result = + s.insert(hint, boost::move(t.reference())); + ar.reset_object_address(& (* result), & t.reference()); + hint = result; + } +} + +template +inline void save( + Archive & ar, + const std::set &t, + const unsigned int /* file_version */ +){ + boost::serialization::stl::save_collection< + Archive, std::set + >(ar, t); +} + +template +inline void load( + Archive & ar, + std::set &t, + const unsigned int /* file_version */ +){ + load_set_collection(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::set & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +// multiset +template +inline void save( + Archive & ar, + const std::multiset &t, + const unsigned int /* file_version */ +){ + boost::serialization::stl::save_collection< + Archive, + std::multiset + >(ar, t); +} + +template +inline void load( + Archive & ar, + std::multiset &t, + const unsigned int /* file_version */ +){ + load_set_collection(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::multiset & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(std::set) +BOOST_SERIALIZATION_COLLECTION_TRAITS(std::multiset) + +#endif // BOOST_SERIALIZATION_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr.hpp new file mode 100644 index 00000000000..0d4c5ae6056 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr.hpp @@ -0,0 +1,281 @@ +#ifndef BOOST_SERIALIZATION_SHARED_PTR_HPP +#define BOOST_SERIALIZATION_SHARED_PTR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// shared_ptr.hpp: serialization for boost shared pointer + +// (C) Copyright 2004 Robert Ramey and Martin Ecker +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // NULL +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// boost:: shared_ptr serialization traits +// version 1 to distinguish from boost 1.32 version. Note: we can only do this +// for a template when the compiler supports partial template specialization + +#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + namespace boost { + namespace serialization{ + template + struct version< ::boost::shared_ptr< T > > { + typedef mpl::integral_c_tag tag; + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) + typedef typename mpl::int_<1> type; + #else + typedef mpl::int_<1> type; + #endif + BOOST_STATIC_CONSTANT(int, value = type::value); + }; + // don't track shared pointers + template + struct tracking_level< ::boost::shared_ptr< T > > { + typedef mpl::integral_c_tag tag; + #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) + typedef typename mpl::int_< ::boost::serialization::track_never> type; + #else + typedef mpl::int_< ::boost::serialization::track_never> type; + #endif + BOOST_STATIC_CONSTANT(int, value = type::value); + }; + }} + #define BOOST_SERIALIZATION_SHARED_PTR(T) +#else + // define macro to let users of these compilers do this + #define BOOST_SERIALIZATION_SHARED_PTR(T) \ + BOOST_CLASS_VERSION( \ + ::boost::shared_ptr< T >, \ + 1 \ + ) \ + BOOST_CLASS_TRACKING( \ + ::boost::shared_ptr< T >, \ + ::boost::serialization::track_never \ + ) \ + /**/ +#endif + +namespace boost { +namespace serialization{ + +struct null_deleter { + void operator()(void const *) const {} +}; + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization for boost::shared_ptr + +// Using a constant means that all shared pointers are held in the same set. +// Thus we detect handle multiple pointers to the same value instances +// in the archive. +void * const shared_ptr_helper_id = 0; + +template +inline void save( + Archive & ar, + const boost::shared_ptr< T > &t, + const unsigned int /* file_version */ +){ + // The most common cause of trapping here would be serializing + // something like shared_ptr. This occurs because int + // is never tracked by default. Wrap int in a trackable type + BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); + const T * t_ptr = t.get(); + ar << boost::serialization::make_nvp("px", t_ptr); +} + +#ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP +template +inline void load( + Archive & ar, + boost::shared_ptr< T > &t, + const unsigned int file_version +){ + // something like shared_ptr. This occurs because int + // is never tracked by default. Wrap int in a trackable type + BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); + T* r; + if(file_version < 1){ + ar.register_type(static_cast< + boost_132::detail::sp_counted_base_impl * + >(NULL)); + boost_132::shared_ptr< T > sp; + ar >> boost::serialization::make_nvp("px", sp.px); + ar >> boost::serialization::make_nvp("pn", sp.pn); + // got to keep the sps around so the sp.pns don't disappear + boost::serialization::shared_ptr_helper & h = + ar.template get_helper< shared_ptr_helper >( + shared_ptr_helper_id + ); + h.append(sp); + r = sp.get(); + } + else{ + ar >> boost::serialization::make_nvp("px", r); + } + shared_ptr_helper & h = + ar.template get_helper >( + shared_ptr_helper_id + ); + h.reset(t,r); +} +#else + +template +inline void load( + Archive & ar, + boost::shared_ptr< T > &t, + const unsigned int /*file_version*/ +){ + // The most common cause of trapping here would be serializing + // something like shared_ptr. This occurs because int + // is never tracked by default. Wrap int in a trackable type + BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); + T* r; + ar >> boost::serialization::make_nvp("px", r); + + boost::serialization::shared_ptr_helper & h = + ar.template get_helper >( + shared_ptr_helper_id + ); + h.reset(t,r); +} +#endif + +template +inline void serialize( + Archive & ar, + boost::shared_ptr< T > &t, + const unsigned int file_version +){ + // correct shared_ptr serialization depends upon object tracking + // being used. + BOOST_STATIC_ASSERT( + boost::serialization::tracking_level< T >::value + != boost::serialization::track_never + ); + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// std::shared_ptr serialization traits +// version 1 to distinguish from boost 1.32 version. Note: we can only do this +// for a template when the compiler supports partial template specialization + +#ifndef BOOST_NO_CXX11_SMART_PTR +#include + +// note: we presume that any compiler/library which supports C++11 +// std::pointers also supports template partial specialization +// trap here if such presumption were to turn out to wrong!!! +#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + BOOST_STATIC_ASSERT(false); +#endif + +namespace boost { +namespace serialization{ + template + struct version< ::std::shared_ptr< T > > { + typedef mpl::integral_c_tag tag; + typedef mpl::int_<1> type; + BOOST_STATIC_CONSTANT(int, value = type::value); + }; + // don't track shared pointers + template + struct tracking_level< ::std::shared_ptr< T > > { + typedef mpl::integral_c_tag tag; + typedef mpl::int_< ::boost::serialization::track_never> type; + BOOST_STATIC_CONSTANT(int, value = type::value); + }; +}} +// the following just keeps older programs from breaking +#define BOOST_SERIALIZATION_SHARED_PTR(T) + +namespace boost { +namespace serialization{ + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization for std::shared_ptr + +template +inline void save( + Archive & ar, + const std::shared_ptr< T > &t, + const unsigned int /* file_version */ +){ + // The most common cause of trapping here would be serializing + // something like shared_ptr. This occurs because int + // is never tracked by default. Wrap int in a trackable type + BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); + const T * t_ptr = t.get(); + ar << boost::serialization::make_nvp("px", t_ptr); +} + +template +inline void load( + Archive & ar, + std::shared_ptr< T > &t, + const unsigned int /*file_version*/ +){ + // The most common cause of trapping here would be serializing + // something like shared_ptr. This occurs because int + // is never tracked by default. Wrap int in a trackable type + BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); + T* r; + ar >> boost::serialization::make_nvp("px", r); + //void (* const id)(Archive &, std::shared_ptr< T > &, const unsigned int) = & load; + boost::serialization::shared_ptr_helper & h = + ar.template get_helper< + shared_ptr_helper + >( + shared_ptr_helper_id + ); + h.reset(t,r); +} + +template +inline void serialize( + Archive & ar, + std::shared_ptr< T > &t, + const unsigned int file_version +){ + // correct shared_ptr serialization depends upon object tracking + // being used. + BOOST_STATIC_ASSERT( + boost::serialization::tracking_level< T >::value + != boost::serialization::track_never + ); + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_NO_CXX11_SMART_PTR + +#endif // BOOST_SERIALIZATION_SHARED_PTR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_132.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_132.hpp new file mode 100644 index 00000000000..3dfaba4d69a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_132.hpp @@ -0,0 +1,222 @@ +#ifndef BOOST_SERIALIZATION_SHARED_PTR_132_HPP +#define BOOST_SERIALIZATION_SHARED_PTR_132_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// shared_ptr.hpp: serialization for boost shared pointer + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// note: totally unadvised hack to gain access to private variables +// in shared_ptr and shared_count. Unfortunately its the only way to +// do this without changing shared_ptr and shared_count +// the best we can do is to detect a conflict here +#include + +#include +#include // NULL + +#include +#include +#include +#include +#include + +// mark base class as an (uncreatable) base class +#include + +///////////////////////////////////////////////////////////// +// Maintain a couple of lists of loaded shared pointers of the old previous +// version (1.32) + +namespace boost_132 { +namespace serialization { +namespace detail { + +struct null_deleter { + void operator()(void const *) const {} +}; + +} // namespace detail +} // namespace serialization +} // namespace boost_132 + +///////////////////////////////////////////////////////////// +// sp_counted_base_impl serialization + +namespace boost { +namespace serialization { + +template +inline void serialize( + Archive & /* ar */, + boost_132::detail::sp_counted_base_impl & /* t */, + const unsigned int /*file_version*/ +){ + // register the relationship between each derived class + // its polymorphic base + boost::serialization::void_cast_register< + boost_132::detail::sp_counted_base_impl, + boost_132::detail::sp_counted_base + >( + static_cast *>(NULL), + static_cast(NULL) + ); +} + +template +inline void save_construct_data( + Archive & ar, + const + boost_132::detail::sp_counted_base_impl *t, + const unsigned int /* file_version */ +){ + // variables used for construction + ar << boost::serialization::make_nvp("ptr", t->ptr); +} + +template +inline void load_construct_data( + Archive & ar, + boost_132::detail::sp_counted_base_impl * t, + const unsigned int /* file_version */ +){ + P ptr_; + ar >> boost::serialization::make_nvp("ptr", ptr_); + // ::new(t)boost_132::detail::sp_counted_base_impl(ptr_, D()); + // placement + // note: the original ::new... above is replaced by the one here. This one + // creates all new objects with a null_deleter so that after the archive + // is finished loading and the shared_ptrs are destroyed - the underlying + // raw pointers are NOT deleted. This is necessary as they are used by the + // new system as well. + ::new(t)boost_132::detail::sp_counted_base_impl< + P, + boost_132::serialization::detail::null_deleter + >( + ptr_, boost_132::serialization::detail::null_deleter() + ); // placement new + // compensate for that fact that a new shared count always is + // initialized with one. the add_ref_copy below will increment it + // every time its serialized so without this adjustment + // the use and weak counts will be off by one. + t->use_count_ = 0; +} + +} // serialization +} // namespace boost + +///////////////////////////////////////////////////////////// +// shared_count serialization + +namespace boost { +namespace serialization { + +template +inline void save( + Archive & ar, + const boost_132::detail::shared_count &t, + const unsigned int /* file_version */ +){ + ar << boost::serialization::make_nvp("pi", t.pi_); +} + +template +inline void load( + Archive & ar, + boost_132::detail::shared_count &t, + const unsigned int /* file_version */ +){ + ar >> boost::serialization::make_nvp("pi", t.pi_); + if(NULL != t.pi_) + t.pi_->add_ref_copy(); +} + +} // serialization +} // namespace boost + +BOOST_SERIALIZATION_SPLIT_FREE(boost_132::detail::shared_count) + +///////////////////////////////////////////////////////////// +// implement serialization for shared_ptr< T > + +namespace boost { +namespace serialization { + +template +inline void save( + Archive & ar, + const boost_132::shared_ptr< T > &t, + const unsigned int /* file_version */ +){ + // only the raw pointer has to be saved + // the ref count is maintained automatically as shared pointers are loaded + ar.register_type(static_cast< + boost_132::detail::sp_counted_base_impl > * + >(NULL)); + ar << boost::serialization::make_nvp("px", t.px); + ar << boost::serialization::make_nvp("pn", t.pn); +} + +template +inline void load( + Archive & ar, + boost_132::shared_ptr< T > &t, + const unsigned int /* file_version */ +){ + // only the raw pointer has to be saved + // the ref count is maintained automatically as shared pointers are loaded + ar.register_type(static_cast< + boost_132::detail::sp_counted_base_impl > * + >(NULL)); + ar >> boost::serialization::make_nvp("px", t.px); + ar >> boost::serialization::make_nvp("pn", t.pn); +} + +template +inline void serialize( + Archive & ar, + boost_132::shared_ptr< T > &t, + const unsigned int file_version +){ + // correct shared_ptr serialization depends upon object tracking + // being used. + BOOST_STATIC_ASSERT( + boost::serialization::tracking_level< T >::value + != boost::serialization::track_never + ); + boost::serialization::split_free(ar, t, file_version); +} + +} // serialization +} // namespace boost + +// note: change below uses null_deleter +// This macro is used to export GUIDS for shared pointers to allow +// the serialization system to export them properly. David Tonge +#define BOOST_SHARED_POINTER_EXPORT_GUID(T, K) \ + typedef boost_132::detail::sp_counted_base_impl< \ + T *, \ + boost::checked_deleter< T > \ + > __shared_ptr_ ## T; \ + BOOST_CLASS_EXPORT_GUID(__shared_ptr_ ## T, "__shared_ptr_" K) \ + BOOST_CLASS_EXPORT_GUID(T, K) \ + /**/ + +#define BOOST_SHARED_POINTER_EXPORT(T) \ + BOOST_SHARED_POINTER_EXPORT_GUID( \ + T, \ + BOOST_PP_STRINGIZE(T) \ + ) \ + /**/ + +#endif // BOOST_SERIALIZATION_SHARED_PTR_132_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_helper.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_helper.hpp new file mode 100644 index 00000000000..37c34d6b2c4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_helper.hpp @@ -0,0 +1,209 @@ +#ifndef BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP +#define BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// shared_ptr_helper.hpp: serialization for boost shared pointern + +// (C) Copyright 2004-2009 Robert Ramey, Martin Ecker and Takatoshi Kondo +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include // NULL + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost_132 { + template class shared_ptr; +} +namespace boost { +namespace serialization { + +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS +template class SPT > +void load( + Archive & ar, + SPT< class U > &t, + const unsigned int file_version +); +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// a common class for holding various types of shared pointers + +template class SPT> +class shared_ptr_helper { + typedef std::map< + const void *, // address of object + SPT // address shared ptr to single instance + > object_shared_pointer_map; + + // list of shared_pointers create accessable by raw pointer. This + // is used to "match up" shared pointers loaded at different + // points in the archive. Note, we delay construction until + // it is actually used since this is by default included as + // a "mix-in" even if shared_ptr isn't used. + object_shared_pointer_map * m_o_sp; + + struct null_deleter { + void operator()(void const *) const {} + }; + +#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \ +|| defined(BOOST_MSVC) \ +|| defined(__SUNPRO_CC) +public: +#else + template + friend void boost::serialization::load( + Archive & ar, + SPT< U > &t, + const unsigned int file_version + ); +#endif + + #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP + // list of loaded pointers. This is used to be sure that the pointers + // stay around long enough to be "matched" with other pointers loaded + // by the same archive. These are created with a "null_deleter" so that + // when this list is destroyed - the underlaying raw pointers are not + // destroyed. This has to be done because the pointers are also held by + // new system which is disjoint from this set. This is implemented + // by a change in load_construct_data below. It makes this file suitable + // only for loading pointers into a 1.33 or later boost system. + std::list > * m_pointers_132; + void + append(const boost_132::shared_ptr & t){ + if(NULL == m_pointers_132) + m_pointers_132 = new std::list >; + m_pointers_132->push_back(t); + } + #endif + + struct non_polymorphic { + template + static const boost::serialization::extended_type_info * + get_object_type(U & ){ + return & boost::serialization::singleton< + typename + boost::serialization::type_info_implementation< U >::type + >::get_const_instance(); + } + }; + struct polymorphic { + template + static const boost::serialization::extended_type_info * + get_object_type(U & u){ + return boost::serialization::singleton< + typename + boost::serialization::type_info_implementation< U >::type + >::get_const_instance().get_derived_extended_type_info(u); + } + }; + +public: + template + void reset(SPT< T > & s, T * t){ + if(NULL == t){ + s.reset(); + return; + } + const boost::serialization::extended_type_info * this_type + = & boost::serialization::type_info_implementation< T >::type + ::get_const_instance(); + + // get pointer to the most derived object's eti. This is effectively + // the object type identifer + typedef typename mpl::if_< + is_polymorphic< T >, + polymorphic, + non_polymorphic + >::type type; + + const boost::serialization::extended_type_info * true_type + = type::get_object_type(*t); + + // note:if this exception is thrown, be sure that derived pointern + // is either registered or exported. + if(NULL == true_type) + boost::serialization::throw_exception( + boost::archive::archive_exception( + boost::archive::archive_exception::unregistered_class, + this_type->get_debug_info() + ) + ); + // get void pointer to the most derived type + // this uniquely identifies the object referred to + // oid = "object identifier" + const void * oid = void_downcast( + *true_type, + *this_type, + t + ); + if(NULL == oid) + boost::serialization::throw_exception( + boost::archive::archive_exception( + boost::archive::archive_exception::unregistered_cast, + true_type->get_debug_info(), + this_type->get_debug_info() + ) + ); + + // make tracking array if necessary + if(NULL == m_o_sp) + m_o_sp = new object_shared_pointer_map; + + typename object_shared_pointer_map::iterator i = m_o_sp->find(oid); + + // if it's a new object + if(i == m_o_sp->end()){ + s.reset(t); + std::pair result; + result = m_o_sp->insert(std::make_pair(oid, s)); + BOOST_ASSERT(result.second); + } + // if the object has already been seen + else{ + s = SPT(i->second, t); + } + } + + shared_ptr_helper() : + m_o_sp(NULL) + #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP + , m_pointers_132(NULL) + #endif + {} + virtual ~shared_ptr_helper(){ + if(NULL != m_o_sp) + delete m_o_sp; + #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP + if(NULL != m_pointers_132) + delete m_pointers_132; + #endif + } +}; + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/singleton.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/singleton.hpp new file mode 100644 index 00000000000..b50afedbb92 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/singleton.hpp @@ -0,0 +1,166 @@ +#ifndef BOOST_SERIALIZATION_SINGLETON_HPP +#define BOOST_SERIALIZATION_SINGLETON_HPP + +/////////1/////////2///////// 3/////////4/////////5/////////6/////////7/////////8 +// singleton.hpp +// +// Copyright David Abrahams 2006. Original version +// +// Copyright Robert Ramey 2007. Changes made to permit +// application throughout the serialization library. +// +// Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The intention here is to define a template which will convert +// any class into a singleton with the following features: +// +// a) initialized before first use. +// b) thread-safe for const access to the class +// c) non-locking +// +// In order to do this, +// a) Initialize dynamically when used. +// b) Require that all singletons be initialized before main +// is called or any entry point into the shared library is invoked. +// This guarentees no race condition for initialization. +// In debug mode, we assert that no non-const functions are called +// after main is invoked. +// + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include +#include + +#include +#include +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +namespace boost { +namespace serialization { + +////////////////////////////////////////////////////////////////////// +// Provides a dynamically-initialized (singleton) instance of T in a +// way that avoids LNK1179 on vc6. See http://tinyurl.com/ljdp8 or +// http://lists.boost.org/Archives/boost/2006/05/105286.php for +// details. +// + +// singletons created by this code are guarenteed to be unique +// within the executable or shared library which creates them. +// This is sufficient and in fact ideal for the serialization library. +// The singleton is created when the module is loaded and destroyed +// when the module is unloaded. + +// This base class has two functions. + +// First it provides a module handle for each singleton indicating +// the executable or shared library in which it was created. This +// turns out to be necessary and sufficient to implement the tables +// used by serialization library. + +// Second, it provides a mechanism to detect when a non-const function +// is called after initialization. + +// make a singleton to lock/unlock all singletons for alteration. +// The intent is that all singletons created/used by this code +// are to be initialized before main is called. A test program +// can lock all the singletons when main is entereed. This any +// attempt to retieve a mutable instances while locked will +// generate a assertion if compiled for debug. + +// note usage of BOOST_DLLEXPORT. These functions are in danger of +// being eliminated by the optimizer when building an application in +// release mode. Usage of the macro is meant to signal the compiler/linker +// to avoid dropping these functions which seem to be unreferenced. +// This usage is not related to autolinking. + +class BOOST_SYMBOL_VISIBLE singleton_module : + public boost::noncopyable +{ +private: + BOOST_SERIALIZATION_DECL BOOST_DLLEXPORT static bool & get_lock() BOOST_USED; +public: + BOOST_DLLEXPORT static void lock(){ + get_lock() = true; + } + BOOST_DLLEXPORT static void unlock(){ + get_lock() = false; + } + BOOST_DLLEXPORT static bool is_locked(){ + return get_lock(); + } +}; + +template +class singleton : public singleton_module +{ +private: + static T & m_instance; + // include this to provoke instantiation at pre-execution time + static void use(T const *) {} + static T & get_instance() { + // use a wrapper so that types T with protected constructors + // can be used + class singleton_wrapper : public T {}; + static singleton_wrapper t; + // refer to instance, causing it to be instantiated (and + // initialized at startup on working compilers) + BOOST_ASSERT(! is_destroyed()); + // note that the following is absolutely essential. + // commenting out this statement will cause compilers to fail to + // construct the instance at pre-execution time. This would prevent + // our usage/implementation of "locking" and introduce uncertainty into + // the sequence of object initializaition. + use(& m_instance); + return static_cast(t); + } + static bool & get_is_destroyed(){ + static bool is_destroyed; + return is_destroyed; + } + +public: + BOOST_DLLEXPORT static T & get_mutable_instance(){ + BOOST_ASSERT(! is_locked()); + return get_instance(); + } + BOOST_DLLEXPORT static const T & get_const_instance(){ + return get_instance(); + } + BOOST_DLLEXPORT static bool is_destroyed(){ + return get_is_destroyed(); + } + BOOST_DLLEXPORT singleton(){ + get_is_destroyed() = false; + } + BOOST_DLLEXPORT ~singleton() { + get_is_destroyed() = true; + } +}; + +template +T & singleton< T >::m_instance = singleton< T >::get_instance(); + +} // namespace serialization +} // namespace boost + +#include // pops abi_suffix.hpp pragmas + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#endif // BOOST_SERIALIZATION_SINGLETON_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/slist.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/slist.hpp new file mode 100644 index 00000000000..d9b971bc4f1 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/slist.hpp @@ -0,0 +1,145 @@ +#ifndef BOOST_SERIALIZATION_SLIST_HPP +#define BOOST_SERIALIZATION_SLIST_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// slist.hpp + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#ifdef BOOST_HAS_SLIST +#include BOOST_SLIST_HEADER + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template +inline void save( + Archive & ar, + const BOOST_STD_EXTENSION_NAMESPACE::slist &t, + const unsigned int file_version +){ + boost::serialization::stl::save_collection< + Archive, + BOOST_STD_EXTENSION_NAMESPACE::slist + >(ar, t); +} + +namespace stl { + +template< + class Archive, + class T, + class Allocator +> +typename boost::disable_if< + typename detail::is_default_constructible< + typename BOOST_STD_EXTENSION_NAMESPACE::slist::value_type + >, + void +>::type +collection_load_impl( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::slist &t, + collection_size_type count, + item_version_type item_version +){ + t.clear(); + boost::serialization::detail::stack_construct u(ar, item_version); + ar >> boost::serialization::make_nvp("item", u.reference()); + t.push_front(boost::move(u.reference())); + typename BOOST_STD_EXTENSION_NAMESPACE::slist::iterator last; + last = t.begin(); + ar.reset_object_address(&(*t.begin()) , & u.reference()); + while(--count > 0){ + detail::stack_construct u(ar, item_version); + ar >> boost::serialization::make_nvp("item", u.reference()); + last = t.insert_after(last, boost::move(u.reference())); + ar.reset_object_address(&(*last) , & u.reference()); + } +} + +} // stl + +template +inline void load( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::slist &t, + const unsigned int file_version +){ + const boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + if(detail::is_default_constructible()){ + t.resize(count); + typename BOOST_STD_EXTENSION_NAMESPACE::slist::iterator hint; + hint = t.begin(); + while(count-- > 0){ + ar >> boost::serialization::make_nvp("item", *hint++); + } + } + else{ + t.clear(); + boost::serialization::detail::stack_construct u(ar, item_version); + ar >> boost::serialization::make_nvp("item", u.reference()); + t.push_front(boost::move(u.reference())); + typename BOOST_STD_EXTENSION_NAMESPACE::slist::iterator last; + last = t.begin(); + ar.reset_object_address(&(*t.begin()) , & u.reference()); + while(--count > 0){ + detail::stack_construct u(ar, item_version); + ar >> boost::serialization::make_nvp("item", u.reference()); + last = t.insert_after(last, boost::move(u.reference())); + ar.reset_object_address(&(*last) , & u.reference()); + } + } +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + BOOST_STD_EXTENSION_NAMESPACE::slist &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(BOOST_STD_EXTENSION_NAMESPACE::slist) + +#endif // BOOST_HAS_SLIST +#endif // BOOST_SERIALIZATION_SLIST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/smart_cast.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/smart_cast.hpp new file mode 100644 index 00000000000..563f36aa20b --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/smart_cast.hpp @@ -0,0 +1,275 @@ +#ifndef BOOST_SERIALIZATION_SMART_CAST_HPP +#define BOOST_SERIALIZATION_SMART_CAST_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// smart_cast.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/serialization for updates, documentation, and revision history. + +// casting of pointers and references. + +// In casting between different C++ classes, there are a number of +// rules that have to be kept in mind in deciding whether to use +// static_cast or dynamic_cast. + +// a) dynamic casting can only be applied when one of the types is polymorphic +// Otherwise static_cast must be used. +// b) only dynamic casting can do runtime error checking +// use of static_cast is generally un checked even when compiled for debug +// c) static_cast would be considered faster than dynamic_cast. + +// If casting is applied to a template parameter, there is no apriori way +// to know which of the two casting methods will be permitted or convenient. + +// smart_cast uses C++ type_traits, and program debug mode to select the +// most convenient cast to use. + +#include +#include +#include // NULL + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace serialization { +namespace smart_cast_impl { + + template + struct reference { + + struct polymorphic { + + struct linear { + template + static T cast(U & u){ + return static_cast< T >(u); + } + }; + + struct cross { + template + static T cast(U & u){ + return dynamic_cast< T >(u); + } + }; + + template + static T cast(U & u){ + // if we're in debug mode + #if ! defined(NDEBUG) \ + || defined(__MWERKS__) + // do a checked dynamic cast + return cross::cast(u); + #else + // borland 5.51 chokes here so we can't use it + // note: if remove_reference isn't function for these types + // cross casting will be selected this will work but will + // not be the most efficient method. This will conflict with + // the original smart_cast motivation. + typedef typename mpl::eval_if< + typename mpl::and_< + mpl::not_::type, + U + > >, + mpl::not_::type + > > + >, + // borland chokes w/o full qualification here + mpl::identity, + mpl::identity + >::type typex; + // typex works around gcc 2.95 issue + return typex::cast(u); + #endif + } + }; + + struct non_polymorphic { + template + static T cast(U & u){ + return static_cast< T >(u); + } + }; + template + static T cast(U & u){ + typedef typename mpl::eval_if< + boost::is_polymorphic, + mpl::identity, + mpl::identity + >::type typex; + return typex::cast(u); + } + }; + + template + struct pointer { + + struct polymorphic { + // unfortunately, this below fails to work for virtual base + // classes. need has_virtual_base to do this. + // Subject for further study + #if 0 + struct linear { + template + static T cast(U * u){ + return static_cast< T >(u); + } + }; + + struct cross { + template + static T cast(U * u){ + T tmp = dynamic_cast< T >(u); + #ifndef NDEBUG + if ( tmp == 0 ) throw_exception(std::bad_cast()); + #endif + return tmp; + } + }; + + template + static T cast(U * u){ + typedef + typename mpl::eval_if< + typename mpl::and_< + mpl::not_::type, + U + > >, + mpl::not_::type + > > + >, + // borland chokes w/o full qualification here + mpl::identity, + mpl::identity + >::type typex; + return typex::cast(u); + } + #else + template + static T cast(U * u){ + T tmp = dynamic_cast< T >(u); + #ifndef NDEBUG + if ( tmp == 0 ) throw_exception(std::bad_cast()); + #endif + return tmp; + } + #endif + }; + + struct non_polymorphic { + template + static T cast(U * u){ + return static_cast< T >(u); + } + }; + + template + static T cast(U * u){ + typedef typename mpl::eval_if< + boost::is_polymorphic, + mpl::identity, + mpl::identity + >::type typex; + return typex::cast(u); + } + + }; + + template + struct void_pointer { + template + static TPtr cast(UPtr uptr){ + return static_cast(uptr); + } + }; + + template + struct error { + // if we get here, its because we are using one argument in the + // cast on a system which doesn't support partial template + // specialization + template + static T cast(U){ + BOOST_STATIC_ASSERT(sizeof(T)==0); + return * static_cast(NULL); + } + }; + +} // smart_cast_impl + +// this implements: +// smart_cast(Source * s) +// smart_cast(s) +// note that it will fail with +// smart_cast(s) +template +T smart_cast(U u) { + typedef + typename mpl::eval_if< + typename mpl::or_< + boost::is_same, + boost::is_same, + boost::is_same, + boost::is_same + >, + mpl::identity >, + // else + typename mpl::eval_if, + mpl::identity >, + // else + typename mpl::eval_if, + mpl::identity >, + // else + mpl::identity + > + > + > + >::type typex; + return typex::cast(u); +} + +// this implements: +// smart_cast_reference(Source & s) +template +T smart_cast_reference(U & u) { + return smart_cast_impl::reference< T >::cast(u); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_SMART_CAST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/split_free.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/split_free.hpp new file mode 100644 index 00000000000..85e2f590fe4 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/split_free.hpp @@ -0,0 +1,93 @@ +#ifndef BOOST_SERIALIZATION_SPLIT_FREE_HPP +#define BOOST_SERIALIZATION_SPLIT_FREE_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// split_free.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include + +namespace boost { +namespace archive { + namespace detail { + template class interface_oarchive; + template class interface_iarchive; + } // namespace detail +} // namespace archive + +namespace serialization { + +//namespace detail { +template +struct free_saver { + static void invoke( + Archive & ar, + const T & t, + const unsigned int file_version + ){ + // use function overload (version_type) to workaround + // two-phase lookup issue + const version_type v(file_version); + save(ar, t, v); + } +}; +template +struct free_loader { + static void invoke( + Archive & ar, + T & t, + const unsigned int file_version + ){ + // use function overload (version_type) to workaround + // two-phase lookup issue + const version_type v(file_version); + load(ar, t, v); + } +}; +//} // namespace detail + +template +inline void split_free( + Archive & ar, + T & t, + const unsigned int file_version +){ + typedef typename mpl::eval_if< + typename Archive::is_saving, + mpl::identity >, + mpl::identity > + >::type typex; + typex::invoke(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#define BOOST_SERIALIZATION_SPLIT_FREE(T) \ +namespace boost { namespace serialization { \ +template \ +inline void serialize( \ + Archive & ar, \ + T & t, \ + const unsigned int file_version \ +){ \ + split_free(ar, t, file_version); \ +} \ +}} +/**/ + +#endif // BOOST_SERIALIZATION_SPLIT_FREE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/split_member.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/split_member.hpp new file mode 100644 index 00000000000..5f32520559e --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/split_member.hpp @@ -0,0 +1,86 @@ +#ifndef BOOST_SERIALIZATION_SPLIT_MEMBER_HPP +#define BOOST_SERIALIZATION_SPLIT_MEMBER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// split_member.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include + +#include + +namespace boost { +namespace archive { + namespace detail { + template class interface_oarchive; + template class interface_iarchive; + } // namespace detail +} // namespace archive + +namespace serialization { +namespace detail { + + template + struct member_saver { + static void invoke( + Archive & ar, + const T & t, + const unsigned int file_version + ){ + access::member_save(ar, t, file_version); + } + }; + + template + struct member_loader { + static void invoke( + Archive & ar, + T & t, + const unsigned int file_version + ){ + access::member_load(ar, t, file_version); + } + }; + +} // detail + +template +inline void split_member( + Archive & ar, T & t, const unsigned int file_version +){ + typedef typename mpl::eval_if< + typename Archive::is_saving, + mpl::identity >, + mpl::identity > + >::type typex; + typex::invoke(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +// split member function serialize funcition into save/load +#define BOOST_SERIALIZATION_SPLIT_MEMBER() \ +template \ +void serialize( \ + Archive &ar, \ + const unsigned int file_version \ +){ \ + boost::serialization::split_member(ar, *this, file_version); \ +} \ +/**/ + +#endif // BOOST_SERIALIZATION_SPLIT_MEMBER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/stack.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/stack.hpp new file mode 100644 index 00000000000..96f90fe8767 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/stack.hpp @@ -0,0 +1,76 @@ +#ifndef BOOST_SERIALIZATION_STACK_HPP +#define BOOST_SERIALIZATION_STACK_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// stack.hpp + +// (C) Copyright 2014 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include + +// function specializations must be defined in the appropriate +// namespace - boost::serialization +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +#define STD _STLP_STD +#else +#define STD std +#endif + +namespace boost { +namespace serialization { +namespace detail{ + +template +struct stack_save : public STD::stack { + template + void operator()(Archive & ar, const unsigned int file_version) const { + save(ar, STD::stack::c, file_version); + } +}; +template +struct stack_load : public STD::stack { + template + void operator()(Archive & ar, const unsigned int file_version) { + load(ar, STD::stack::c, file_version); + } +}; + +} // detail + +template +inline void serialize( + Archive & ar, + std::stack< T, C> & t, + const unsigned int file_version +){ + typedef typename mpl::eval_if< + typename Archive::is_saving, + mpl::identity >, + mpl::identity > + >::type typex; + static_cast(t)(ar, file_version); +} + +} // namespace serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::stack) + +#undef STD + +#endif // BOOST_SERIALIZATION_DEQUE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/state_saver.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/state_saver.hpp new file mode 100644 index 00000000000..248b8d91556 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/state_saver.hpp @@ -0,0 +1,96 @@ +#ifndef BOOST_SERIALIZATION_STATE_SAVER_HPP +#define BOOST_SERIALIZATION_STATE_SAVER_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// state_saver.hpp: + +// (C) Copyright 2003-4 Pavel Vozenilek and Robert Ramey - http://www.rrsd.com. +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/serialization for updates, documentation, and revision history. + +// Inspired by Daryle Walker's iostate_saver concept. This saves the original +// value of a variable when a state_saver is constructed and restores +// upon destruction. Useful for being sure that state is restored to +// variables upon exit from scope. + + +#include +#ifndef BOOST_NO_EXCEPTIONS + #include +#endif + +#include +#include +#include +#include + +#include +#include + +namespace boost { +namespace serialization { + +template +// T requirements: +// - POD or object semantic (cannot be reference, function, ...) +// - copy constructor +// - operator = (no-throw one preferred) +class state_saver : private boost::noncopyable +{ +private: + const T previous_value; + T & previous_ref; + + struct restore { + static void invoke(T & previous_ref, const T & previous_value){ + previous_ref = previous_value; // won't throw + } + }; + + struct restore_with_exception { + static void invoke(T & previous_ref, const T & previous_value){ + BOOST_TRY{ + previous_ref = previous_value; + } + BOOST_CATCH(::std::exception &) { + // we must ignore it - we are in destructor + } + BOOST_CATCH_END + } + }; + +public: + state_saver( + T & object + ) : + previous_value(object), + previous_ref(object) + {} + + ~state_saver() { + #ifndef BOOST_NO_EXCEPTIONS + typedef typename mpl::eval_if< + has_nothrow_copy< T >, + mpl::identity, + mpl::identity + >::type typex; + typex::invoke(previous_ref, previous_value); + #else + previous_ref = previous_value; + #endif + } + +}; // state_saver<> + +} // serialization +} // boost + +#endif //BOOST_SERIALIZATION_STATE_SAVER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/static_warning.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/static_warning.hpp new file mode 100644 index 00000000000..1d9238fc4d9 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/static_warning.hpp @@ -0,0 +1,103 @@ +#ifndef BOOST_SERIALIZATION_STATIC_WARNING_HPP +#define BOOST_SERIALIZATION_STATIC_WARNING_HPP + +// (C) Copyright Robert Ramey 2003. Jonathan Turkanis 2004. +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/static_assert for documentation. + +/* + Revision history: + 15 June 2003 - Initial version. + 31 March 2004 - improved diagnostic messages and portability + (Jonathan Turkanis) + 03 April 2004 - works on VC6 at class and namespace scope + - ported to DigitalMars + - static warnings disabled by default; when enabled, + uses pragmas to enable required compiler warnings + on MSVC, Intel, Metrowerks and Borland 5.x. + (Jonathan Turkanis) + 30 May 2004 - tweaked for msvc 7.1 and gcc 3.3 + - static warnings ENabled by default; when enabled, + (Robert Ramey) +*/ + +#include + +// +// Implementation +// Makes use of the following warnings: +// 1. GCC prior to 3.3: division by zero. +// 2. BCC 6.0 preview: unreferenced local variable. +// 3. DigitalMars: returning address of local automatic variable. +// 4. VC6: class previously seen as struct (as in 'boost/mpl/print.hpp') +// 5. All others: deletion of pointer to incomplete type. +// +// The trick is to find code which produces warnings containing the name of +// a structure or variable. Details, with same numbering as above: +// 1. static_warning_impl::value is zero iff B is false, so diving an int +// by this value generates a warning iff B is false. +// 2. static_warning_impl::type has a constructor iff B is true, so an +// unreferenced variable of this type generates a warning iff B is false. +// 3. static_warning_impl::type overloads operator& to return a dynamically +// allocated int pointer only is B is true, so returning the address of an +// automatic variable of this type generates a warning iff B is fasle. +// 4. static_warning_impl::STATIC_WARNING is decalred as a struct iff B is +// false. +// 5. static_warning_impl::type is incomplete iff B is false, so deleting a +// pointer to this type generates a warning iff B is false. +// + +//------------------Enable selected warnings----------------------------------// + +// Enable the warnings relied on by BOOST_STATIC_WARNING, where possible. + +// 6. replaced implementation with one which depends solely on +// mpl::print<>. The previous one was found to fail for functions +// under recent versions of gcc and intel compilers - Robert Ramey + +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template +struct BOOST_SERIALIZATION_STATIC_WARNING_LINE{}; + +template +struct static_warning_test{ + typename boost::mpl::eval_if_c< + B, + boost::mpl::true_, + typename boost::mpl::identity< + boost::mpl::print< + BOOST_SERIALIZATION_STATIC_WARNING_LINE + > + > + >::type type; +}; + +template +struct BOOST_SERIALIZATION_SS {}; + +} // serialization +} // boost + +#define BOOST_SERIALIZATION_BSW(B, L) \ + typedef boost::serialization::BOOST_SERIALIZATION_SS< \ + sizeof( boost::serialization::static_warning_test< B, L > ) \ + > BOOST_JOIN(STATIC_WARNING_LINE, L) BOOST_ATTRIBUTE_UNUSED; +#define BOOST_STATIC_WARNING(B) BOOST_SERIALIZATION_BSW(B, __LINE__) + +#endif // BOOST_SERIALIZATION_STATIC_WARNING_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/string.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/string.hpp new file mode 100644 index 00000000000..76e695d4f3c --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/string.hpp @@ -0,0 +1,30 @@ +#ifndef BOOST_SERIALIZATION_STRING_HPP +#define BOOST_SERIALIZATION_STRING_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization/string.hpp: +// serialization for stl string templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include + +BOOST_CLASS_IMPLEMENTATION(std::string, boost::serialization::primitive_type) +#ifndef BOOST_NO_STD_WSTRING +BOOST_CLASS_IMPLEMENTATION(std::wstring, boost::serialization::primitive_type) +#endif + +#endif // BOOST_SERIALIZATION_STRING_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/strong_typedef.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/strong_typedef.hpp new file mode 100644 index 00000000000..fdd1b24c9cb --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/strong_typedef.hpp @@ -0,0 +1,50 @@ +#ifndef BOOST_SERIALIZATION_STRONG_TYPEDEF_HPP +#define BOOST_SERIALIZATION_STRONG_TYPEDEF_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// strong_typedef.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2016 Ashish Sadanandan +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/serialization for updates, documentation, and revision history. + +// macro used to implement a strong typedef. strong typedef +// guarentees that two types are distinguised even though the +// share the same underlying implementation. typedef does not create +// a new type. BOOST_STRONG_TYPEDEF(T, D) creates a new type named D +// that operates as a type T. + +#include +#include +#include +#include +#include + +#define BOOST_STRONG_TYPEDEF(T, D) \ +struct D \ + : boost::totally_ordered1< D \ + , boost::totally_ordered2< D, T \ + > > \ +{ \ + T t; \ + explicit D(const T& t_) BOOST_NOEXCEPT_IF(boost::has_nothrow_copy_constructor::value) : t(t_) {} \ + D() BOOST_NOEXCEPT_IF(boost::has_nothrow_default_constructor::value) : t() {} \ + D(const D & t_) BOOST_NOEXCEPT_IF(boost::has_nothrow_copy_constructor::value) : t(t_.t) {} \ + D& operator=(const D& rhs) BOOST_NOEXCEPT_IF(boost::has_nothrow_assign::value) {t = rhs.t; return *this;} \ + D& operator=(const T& rhs) BOOST_NOEXCEPT_IF(boost::has_nothrow_assign::value) {t = rhs; return *this;} \ + operator const T&() const {return t;} \ + operator T&() {return t;} \ + bool operator==(const D& rhs) const {return t == rhs.t;} \ + bool operator<(const D& rhs) const {return t < rhs.t;} \ +}; + +#endif // BOOST_SERIALIZATION_STRONG_TYPEDEF_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/throw_exception.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/throw_exception.hpp new file mode 100644 index 00000000000..b67618adc92 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/throw_exception.hpp @@ -0,0 +1,44 @@ +#ifndef BOOST_SERIALIZATION_THROW_EXCEPTION_HPP_INCLUDED +#define BOOST_SERIALIZATION_THROW_EXCEPTION_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) +# pragma once +#endif + +// boost/throw_exception.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +#ifndef BOOST_NO_EXCEPTIONS +#include +#endif + +namespace boost { +namespace serialization { + +#ifdef BOOST_NO_EXCEPTIONS + +inline void throw_exception(std::exception const & e) { + ::boost::throw_exception(e); +} + +#else + +template inline void throw_exception(E const & e){ + throw e; +} + +#endif + +} // namespace serialization +} // namespace boost + +#endif // #ifndef BOOST_SERIALIZATION_THROW_EXCEPTION_HPP_INCLUDED diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/tracking.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/tracking.hpp new file mode 100644 index 00000000000..d5c79b8409d --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/tracking.hpp @@ -0,0 +1,118 @@ +#ifndef BOOST_SERIALIZATION_TRACKING_HPP +#define BOOST_SERIALIZATION_TRACKING_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// tracking.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +struct basic_traits; + +// default tracking level +template +struct tracking_level_impl { + template + struct traits_class_tracking { + typedef typename U::tracking type; + }; + typedef mpl::integral_c_tag tag; + // note: at least one compiler complained w/o the full qualification + // on basic traits below + typedef + typename mpl::eval_if< + is_base_and_derived, + traits_class_tracking< T >, + //else + typename mpl::eval_if< + is_pointer< T >, + // pointers are not tracked by default + mpl::int_, + //else + typename mpl::eval_if< + // for primitives + typename mpl::equal_to< + implementation_level< T >, + mpl::int_ + >, + // is never + mpl::int_, + // otherwise its selective + mpl::int_ + > > >::type type; + BOOST_STATIC_CONSTANT(int, value = type::value); +}; + +template +struct tracking_level : + public tracking_level_impl +{ +}; + +template +inline bool operator>=(tracking_level< T > t, enum tracking_type l) +{ + return t.value >= (int)l; +} + +} // namespace serialization +} // namespace boost + + +// The STATIC_ASSERT is prevents one from setting tracking for a primitive type. +// This almost HAS to be an error. Doing this will effect serialization of all +// char's in your program which is almost certainly what you don't want to do. +// If you want to track all instances of a given primitive type, You'll have to +// wrap it in your own type so its not a primitive anymore. Then it will compile +// without problem. +#define BOOST_CLASS_TRACKING(T, E) \ +namespace boost { \ +namespace serialization { \ +template<> \ +struct tracking_level< T > \ +{ \ + typedef mpl::integral_c_tag tag; \ + typedef mpl::int_< E> type; \ + BOOST_STATIC_CONSTANT( \ + int, \ + value = tracking_level::type::value \ + ); \ + /* tracking for a class */ \ + BOOST_STATIC_ASSERT(( \ + mpl::greater< \ + /* that is a prmitive */ \ + implementation_level< T >, \ + mpl::int_ \ + >::value \ + )); \ +}; \ +}} + +#endif // BOOST_SERIALIZATION_TRACKING_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/tracking_enum.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/tracking_enum.hpp new file mode 100644 index 00000000000..278051e1baf --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/tracking_enum.hpp @@ -0,0 +1,41 @@ +#ifndef BOOST_SERIALIZATION_TRACKING_ENUM_HPP +#define BOOST_SERIALIZATION_TRACKING_ENUM_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// tracking_enum.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +namespace boost { +namespace serialization { + +// addresses of serialized objects may be tracked to avoid saving/loading +// redundant copies. This header defines a class trait that can be used +// to specify when objects should be tracked + +// names for each tracking level +enum tracking_type +{ + // never track this type + track_never = 0, + // track objects of this type if the object is serialized through a + // pointer. + track_selectively = 1, + // always track this type + track_always = 2 +}; + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_TRACKING_ENUM_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/traits.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/traits.hpp new file mode 100644 index 00000000000..9e114fdd3df --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/traits.hpp @@ -0,0 +1,65 @@ +#ifndef BOOST_SERIALIZATION_TRAITS_HPP +#define BOOST_SERIALIZATION_TRAITS_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// traits.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// This header is used to apply serialization traits to templates. The +// standard system can't be used for platforms which don't support +// Partial Templlate Specialization. + +// The motivation for this is the Name-Value Pair (NVP) template. +// it has to work the same on all platforms in order for archives +// to be portable accross platforms. + +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +// common base class used to detect appended traits class +struct basic_traits {}; + +template +struct extended_type_info_impl; + +template< + class T, + int Level, + int Tracking, + unsigned int Version = 0, + class ETII = extended_type_info_impl< T >, + class Wrapper = mpl::false_ +> +struct traits : public basic_traits { + BOOST_STATIC_ASSERT(Version == 0 || Level >= object_class_info); + BOOST_STATIC_ASSERT(Tracking == track_never || Level >= object_serializable); + typedef typename mpl::int_ level; + typedef typename mpl::int_ tracking; + typedef typename mpl::int_ version; + typedef ETII type_info_implementation; + typedef Wrapper is_wrapper; +}; + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_TRAITS_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/type_info_implementation.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/type_info_implementation.hpp new file mode 100644 index 00000000000..24637a8dbb3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/type_info_implementation.hpp @@ -0,0 +1,73 @@ +#ifndef BOOST_SERIALIZATION_TYPE_INFO_IMPLEMENTATION_HPP +#define BOOST_SERIALIZATION_TYPE_INFO_IMPLEMENTATION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// type_info_implementation.hpp: interface for portable version of type_info + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + + +#include +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +// note that T and const T are folded into const T so that +// there is only one table entry per type +template +struct type_info_implementation { + template + struct traits_class_typeinfo_implementation { + typedef typename U::type_info_implementation::type type; + }; + // note: at least one compiler complained w/o the full qualification + // on basic traits below + typedef + typename mpl::eval_if< + is_base_and_derived, + traits_class_typeinfo_implementation< T >, + //else + mpl::identity< + typename extended_type_info_impl< T >::type + > + >::type type; +}; + +} // namespace serialization +} // namespace boost + +// define a macro to assign a particular derivation of extended_type_info +// to a specified a class. +#define BOOST_CLASS_TYPE_INFO(T, ETI) \ +namespace boost { \ +namespace serialization { \ +template<> \ +struct type_info_implementation< T > { \ + typedef ETI type; \ +}; \ +template<> \ +struct type_info_implementation< const T > { \ + typedef ETI type; \ +}; \ +} \ +} \ +/**/ + +#endif /// BOOST_SERIALIZATION_TYPE_INFO_IMPLEMENTATION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unique_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unique_ptr.hpp new file mode 100644 index 00000000000..8d8703ef4f7 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/unique_ptr.hpp @@ -0,0 +1,68 @@ +#ifndef BOOST_SERIALIZATION_UNIQUE_PTR_HPP +#define BOOST_SERIALIZATION_UNIQUE_PTR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// unique_ptr.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. +#include +#include +#include + +namespace boost { +namespace serialization { + +///////////////////////////////////////////////////////////// +// implement serialization for unique_ptr< T > +// note: this must be added to the boost namespace in order to +// be called by the library +template +inline void save( + Archive & ar, + const std::unique_ptr< T > &t, + const unsigned int /*file_version*/ +){ + // only the raw pointer has to be saved + // the ref count is rebuilt automatically on load + const T * const tx = t.get(); + ar << BOOST_SERIALIZATION_NVP(tx); +} + +template +inline void load( + Archive & ar, + std::unique_ptr< T > &t, + const unsigned int /*file_version*/ +){ + T *tx; + ar >> BOOST_SERIALIZATION_NVP(tx); + // note that the reset automagically maintains the reference count + t.reset(tx); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::unique_ptr< T > &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + + +#endif // BOOST_SERIALIZATION_UNIQUE_PTR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_load_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_load_imp.hpp new file mode 100644 index 00000000000..d56a423d180 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_load_imp.hpp @@ -0,0 +1,73 @@ +#ifndef BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_LOAD_IMP_HPP +#define BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_LOAD_IMP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +# pragma warning (disable : 4786) // too long name, harmless warning +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// unordered_collections_load_imp.hpp: serialization for loading stl collections + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2014 Jim Bell +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// helper function templates for serialization of collections + +#include +#include // size_t +#include // msvc 6.0 needs this for warning suppression +#if defined(BOOST_NO_STDC_NAMESPACE) +namespace std{ + using ::size_t; +} // namespace std +#endif +#include + +#include +#include +#include +#include +#include + +namespace boost{ +namespace serialization { +namespace stl { + +////////////////////////////////////////////////////////////////////// +// implementation of serialization for STL containers +// +template +inline void load_unordered_collection(Archive & ar, Container &s) +{ + collection_size_type count; + collection_size_type bucket_count; + boost::serialization::item_version_type item_version(0); + boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + ar >> BOOST_SERIALIZATION_NVP(count); + ar >> BOOST_SERIALIZATION_NVP(bucket_count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + s.clear(); + s.rehash(bucket_count); + InputFunction ifunc; + while(count-- > 0){ + ifunc(ar, s, item_version); + } +} + +} // namespace stl +} // namespace serialization +} // namespace boost + +#endif //BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_LOAD_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_save_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_save_imp.hpp new file mode 100644 index 00000000000..56746ebeaa3 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_save_imp.hpp @@ -0,0 +1,86 @@ +#ifndef BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_SAVE_IMP_HPP +#define BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_SAVE_IMP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// hash_collections_save_imp.hpp: serialization for stl collections + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2014 Jim Bell +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +// helper function templates for serialization of collections + +#include +#include +#include +#include +#include +#include + +namespace boost{ +namespace serialization { +namespace stl { + +////////////////////////////////////////////////////////////////////// +// implementation of serialization for STL containers +// + +template +inline void save_unordered_collection(Archive & ar, const Container &s) +{ + collection_size_type count(s.size()); + const collection_size_type bucket_count(s.bucket_count()); + const item_version_type item_version( + version::value + ); + + #if 0 + /* should only be necessary to create archives of previous versions + * which is not currently supported. So for now comment this out + */ + boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + ar << BOOST_SERIALIZATION_NVP(count); + ar << BOOST_SERIALIZATION_NVP(bucket_count); + if(boost::archive::library_version_type(3) < library_version){ + // record number of elements + // make sure the target type is registered so we can retrieve + // the version when we load + ar << BOOST_SERIALIZATION_NVP(item_version); + } + #else + ar << BOOST_SERIALIZATION_NVP(count); + ar << BOOST_SERIALIZATION_NVP(bucket_count); + ar << BOOST_SERIALIZATION_NVP(item_version); + #endif + + typename Container::const_iterator it = s.begin(); + while(count-- > 0){ + // note borland emits a no-op without the explicit namespace + boost::serialization::save_construct_data_adl( + ar, + &(*it), + boost::serialization::version< + typename Container::value_type + >::value + ); + ar << boost::serialization::make_nvp("item", *it++); + } +} + +} // namespace stl +} // namespace serialization +} // namespace boost + +#endif //BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_SAVE_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_map.hpp new file mode 100644 index 00000000000..4fdbddd7b65 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_map.hpp @@ -0,0 +1,160 @@ +#ifndef BOOST_SERIALIZATION_UNORDERED_MAP_HPP +#define BOOST_SERIALIZATION_UNORDERED_MAP_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization/unordered_map.hpp: +// serialization for stl unordered_map templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2014 Jim Bell +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include + +#include +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const std::unordered_map &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::save_unordered_collection< + Archive, + std::unordered_map + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + std::unordered_map &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::load_unordered_collection< + Archive, + std::unordered_map, + boost::serialization::stl::archive_input_unordered_map< + Archive, + std::unordered_map + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + std::unordered_map &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +// unordered_multimap +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const std::unordered_multimap< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::save_unordered_collection< + Archive, + std::unordered_multimap + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + std::unordered_multimap< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::load_unordered_collection< + Archive, + std::unordered_multimap< + Key, HashFcn, EqualKey, Allocator + >, + boost::serialization::stl::archive_input_unordered_multimap< + Archive, + std::unordered_multimap + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + std::unordered_multimap< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_UNORDERED_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_set.hpp new file mode 100644 index 00000000000..adfee609cbe --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_set.hpp @@ -0,0 +1,162 @@ +#ifndef BOOST_SERIALIZATION_UNORDERED_SET_HPP +#define BOOST_SERIALIZATION_UNORDERED_SET_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// unordered_set.hpp: serialization for stl unordered_set templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// (C) Copyright 2014 Jim Bell +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include + +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const std::unordered_set< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::save_unordered_collection< + Archive, + std::unordered_set + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + std::unordered_set< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::load_unordered_collection< + Archive, + std::unordered_set, + stl::archive_input_unordered_set< + Archive, + std::unordered_set< + Key, HashFcn, EqualKey, Allocator + > + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + std::unordered_set< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int file_version +){ + split_free(ar, t, file_version); +} + +// unordered_multiset +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void save( + Archive & ar, + const std::unordered_multiset< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int /*file_version*/ +){ + stl::save_unordered_collection< + Archive, + std::unordered_multiset + >(ar, t); +} + +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void load( + Archive & ar, + std::unordered_multiset< + Key, HashFcn, EqualKey, Allocator + > &t, + const unsigned int /*file_version*/ +){ + boost::serialization::stl::load_unordered_collection< + Archive, + std::unordered_multiset, + boost::serialization::stl::archive_input_unordered_multiset< + Archive, + std::unordered_multiset + > + >(ar, t); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template< + class Archive, + class Key, + class HashFcn, + class EqualKey, + class Allocator +> +inline void serialize( + Archive & ar, + std::unordered_multiset &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_UNORDERED_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/utility.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/utility.hpp new file mode 100644 index 00000000000..4867a4a12d2 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/utility.hpp @@ -0,0 +1,56 @@ +#ifndef BOOST_SERIALIZATION_UTILITY_HPP +#define BOOST_SERIALIZATION_UTILITY_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// serialization/utility.hpp: +// serialization for stl utility templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace serialization { + +// pair +template +inline void serialize( + Archive & ar, + std::pair & p, + const unsigned int /* file_version */ +){ + // note: we remove any const-ness on the first argument. The reason is that + // for stl maps, the type saved is pair::type typef; + ar & boost::serialization::make_nvp("first", const_cast(p.first)); + ar & boost::serialization::make_nvp("second", p.second); +} + +/// specialization of is_bitwise_serializable for pairs +template +struct is_bitwise_serializable > + : public mpl::and_,is_bitwise_serializable > +{ +}; + +} // serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_UTILITY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/valarray.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/valarray.hpp new file mode 100644 index 00000000000..9eece5c1737 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/valarray.hpp @@ -0,0 +1,86 @@ +#ifndef BOOST_SERIALIZATION_VALARAY_HPP +#define BOOST_SERIALIZATION_VALARAY_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// valarray.hpp: serialization for stl vector templates + +// (C) Copyright 2005 Matthias Troyer . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +#include +#include +#include +#include +#include + +// function specializations must be defined in the appropriate +// namespace - boost::serialization +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +#define STD _STLP_STD +#else +#define STD std +#endif + +namespace boost { +namespace serialization { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// valarray< T > + +template +void save( Archive & ar, const STD::valarray &t, const unsigned int /*file_version*/ ) +{ + const collection_size_type count(t.size()); + ar << BOOST_SERIALIZATION_NVP(count); + if (t.size()){ + // explict template arguments to pass intel C++ compiler + ar << serialization::make_array( + static_cast(&t[0]), + count + ); + } +} + +template +void load( Archive & ar, STD::valarray &t, const unsigned int /*file_version*/ ) +{ + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + t.resize(count); + if (t.size()){ + // explict template arguments to pass intel C++ compiler + ar >> serialization::make_array( + static_cast(&t[0]), + count + ); + } +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( Archive & ar, STD::valarray & t, const unsigned int file_version) +{ + boost::serialization::split_free(ar, t, file_version); +} + +} } // end namespace boost::serialization + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::valarray) +#undef STD + +#endif // BOOST_SERIALIZATION_VALARAY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/variant.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/variant.hpp new file mode 100644 index 00000000000..dce6f3d49e7 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/variant.hpp @@ -0,0 +1,158 @@ +#ifndef BOOST_SERIALIZATION_VARIANT_HPP +#define BOOST_SERIALIZATION_VARIANT_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// variant.hpp - non-intrusive serialization of variant types +// +// copyright (c) 2005 +// troy d. straszheim +// http://www.resophonic.com +// +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org for updates, documentation, and revision history. +// +// thanks to Robert Ramey, Peter Dimov, and Richard Crossley. +// + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include +#include +#include + +namespace boost { +namespace serialization { + +template +struct variant_save_visitor : + boost::static_visitor<> +{ + variant_save_visitor(Archive& ar) : + m_ar(ar) + {} + template + void operator()(T const & value) const + { + m_ar << BOOST_SERIALIZATION_NVP(value); + } +private: + Archive & m_ar; +}; + +template +void save( + Archive & ar, + boost::variant const & v, + unsigned int /*version*/ +){ + int which = v.which(); + ar << BOOST_SERIALIZATION_NVP(which); + variant_save_visitor visitor(ar); + v.apply_visitor(visitor); +} + +template +struct variant_impl { + + struct load_null { + template + static void invoke( + Archive & /*ar*/, + int /*which*/, + V & /*v*/, + const unsigned int /*version*/ + ){} + }; + + struct load_impl { + template + static void invoke( + Archive & ar, + int which, + V & v, + const unsigned int version + ){ + if(which == 0){ + // note: A non-intrusive implementation (such as this one) + // necessary has to copy the value. This wouldn't be necessary + // with an implementation that de-serialized to the address of the + // aligned storage included in the variant. + typedef typename mpl::front::type head_type; + head_type value; + ar >> BOOST_SERIALIZATION_NVP(value); + v = value; + ar.reset_object_address(& boost::get(v), & value); + return; + } + typedef typename mpl::pop_front::type type; + variant_impl::load(ar, which - 1, v, version); + } + }; + + template + static void load( + Archive & ar, + int which, + V & v, + const unsigned int version + ){ + typedef typename mpl::eval_if, + mpl::identity, + mpl::identity + >::type typex; + typex::invoke(ar, which, v, version); + } + +}; + +template +void load( + Archive & ar, + boost::variant& v, + const unsigned int version +){ + int which; + typedef typename boost::variant::types types; + ar >> BOOST_SERIALIZATION_NVP(which); + if(which >= mpl::size::value) + // this might happen if a type was removed from the list of variant types + boost::serialization::throw_exception( + boost::archive::archive_exception( + boost::archive::archive_exception::unsupported_version + ) + ); + variant_impl::load(ar, which, v, version); +} + +template +inline void serialize( + Archive & ar, + boost::variant & v, + const unsigned int file_version +){ + split_free(ar,v,file_version); +} + +} // namespace serialization +} // namespace boost + +#endif //BOOST_SERIALIZATION_VARIANT_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/vector.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/vector.hpp new file mode 100644 index 00000000000..9a114c00e20 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/vector.hpp @@ -0,0 +1,233 @@ +#ifndef BOOST_SERIALIZATION_VECTOR_HPP +#define BOOST_SERIALIZATION_VECTOR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// vector.hpp: serialization for stl vector templates + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// fast array serialization (C) Copyright 2005 Matthias Troyer +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +// default is being compatible with version 1.34.1 files, not 1.35 files +#ifndef BOOST_SERIALIZATION_VECTOR_VERSIONED +#define BOOST_SERIALIZATION_VECTOR_VERSIONED(V) (V==4 || V==5) +#endif + +// function specializations must be defined in the appropriate +// namespace - boost::serialization +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +#define STD _STLP_STD +#else +#define STD std +#endif + +namespace boost { +namespace serialization { + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// vector< T > + +// the default versions + +template +inline void save( + Archive & ar, + const std::vector &t, + const unsigned int /* file_version */, + mpl::false_ +){ + boost::serialization::stl::save_collection >( + ar, t + ); +} + +template +inline void load( + Archive & ar, + std::vector &t, + const unsigned int /* file_version */, + mpl::false_ +){ + const boost::archive::library_version_type library_version( + ar.get_library_version() + ); + // retrieve number of elements + item_version_type item_version(0); + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + if(boost::archive::library_version_type(3) < library_version){ + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + t.reserve(count); + stl::collection_load_impl(ar, t, count, item_version); +} + +// the optimized versions + +template +inline void save( + Archive & ar, + const std::vector &t, + const unsigned int /* file_version */, + mpl::true_ +){ + const collection_size_type count(t.size()); + ar << BOOST_SERIALIZATION_NVP(count); + if (!t.empty()) + // explict template arguments to pass intel C++ compiler + ar << serialization::make_array( + static_cast(&t[0]), + count + ); +} + +template +inline void load( + Archive & ar, + std::vector &t, + const unsigned int /* file_version */, + mpl::true_ +){ + collection_size_type count(t.size()); + ar >> BOOST_SERIALIZATION_NVP(count); + t.resize(count); + unsigned int item_version=0; + if(BOOST_SERIALIZATION_VECTOR_VERSIONED(ar.get_library_version())) { + ar >> BOOST_SERIALIZATION_NVP(item_version); + } + if (!t.empty()) + // explict template arguments to pass intel C++ compiler + ar >> serialization::make_array( + static_cast(&t[0]), + count + ); + } + +// dispatch to either default or optimized versions + +template +inline void save( + Archive & ar, + const std::vector &t, + const unsigned int file_version +){ + typedef typename + boost::serialization::use_array_optimization::template apply< + typename remove_const::type + >::type use_optimized; + save(ar,t,file_version, use_optimized()); +} + +template +inline void load( + Archive & ar, + std::vector &t, + const unsigned int file_version +){ +#ifdef BOOST_SERIALIZATION_VECTOR_135_HPP + if (ar.get_library_version()==boost::archive::library_version_type(5)) + { + load(ar,t,file_version, boost::is_arithmetic()); + return; + } +#endif + typedef typename + boost::serialization::use_array_optimization::template apply< + typename remove_const::type + >::type use_optimized; + load(ar,t,file_version, use_optimized()); +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::vector & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// vector +template +inline void save( + Archive & ar, + const std::vector &t, + const unsigned int /* file_version */ +){ + // record number of elements + collection_size_type count (t.size()); + ar << BOOST_SERIALIZATION_NVP(count); + std::vector::const_iterator it = t.begin(); + while(count-- > 0){ + bool tb = *it++; + ar << boost::serialization::make_nvp("item", tb); + } +} + +template +inline void load( + Archive & ar, + std::vector &t, + const unsigned int /* file_version */ +){ + // retrieve number of elements + collection_size_type count; + ar >> BOOST_SERIALIZATION_NVP(count); + t.resize(count); + for(collection_size_type i = collection_size_type(0); i < count; ++i){ + bool b; + ar >> boost::serialization::make_nvp("item", b); + t[i] = b; + } +} + +// split non-intrusive serialization function member into separate +// non intrusive save/load member functions +template +inline void serialize( + Archive & ar, + std::vector & t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // serialization +} // namespace boost + +#include + +BOOST_SERIALIZATION_COLLECTION_TRAITS(std::vector) +#undef STD + +#endif // BOOST_SERIALIZATION_VECTOR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/vector_135.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/vector_135.hpp new file mode 100644 index 00000000000..fd1a7393d1b --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/vector_135.hpp @@ -0,0 +1,26 @@ +////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// vector_135.hpp: serialization for stl vector templates for compatibility +// with release 1.35, which had a bug + +// (C) Copyright 2008 Matthias Troyer +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + + +#ifndef BOOST_SERIALIZATION_VECTOR_135_HPP +#define BOOST_SERIALIZATION_VECTOR_135_HPP + +#ifdef BOOST_SERIALIZATION_VECTOR_VERSIONED +#if BOOST_SERIALIZATION_VECTOR_VERSION != 4 +#error "Boost.Serialization cannot be compatible with both 1.35 and 1.36-1.40 files" +#endif +#else +#define BOOST_SERIALIZATION_VECTOR_VERSIONED(V) (V>4) +#endif + +#include + +#endif // BOOST_SERIALIZATION_VECTOR_135_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/version.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/version.hpp new file mode 100644 index 00000000000..21a74d73daa --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/version.hpp @@ -0,0 +1,107 @@ +#ifndef BOOST_SERIALIZATION_VERSION_HPP +#define BOOST_SERIALIZATION_VERSION_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// version.hpp: + +// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace serialization { + +struct basic_traits; + +// default version number is 0. Override with higher version +// when class definition changes. +template +struct version +{ + template + struct traits_class_version { + typedef typename U::version type; + }; + + typedef mpl::integral_c_tag tag; + // note: at least one compiler complained w/o the full qualification + // on basic traits below + typedef + typename mpl::eval_if< + is_base_and_derived, + traits_class_version< T >, + mpl::int_<0> + >::type type; + BOOST_STATIC_CONSTANT(int, value = version::type::value); +}; + +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +template +const int version::value; +#endif + +} // namespace serialization +} // namespace boost + +/* note: at first it seemed that this would be a good place to trap + * as an error an attempt to set a version # for a class which doesn't + * save its class information (including version #) in the archive. + * However, this imposes a requirement that the version be set after + * the implemention level which would be pretty confusing. If this + * is to be done, do this check in the input or output operators when + * ALL the serialization traits are available. Included the implementation + * here with this comment as a reminder not to do this! + */ +//#include +//#include + +#include +#include + +// specify the current version number for the class +// version numbers limited to 8 bits !!! +#define BOOST_CLASS_VERSION(T, N) \ +namespace boost { \ +namespace serialization { \ +template<> \ +struct version \ +{ \ + typedef mpl::int_ type; \ + typedef mpl::integral_c_tag tag; \ + BOOST_STATIC_CONSTANT(int, value = version::type::value); \ + BOOST_MPL_ASSERT(( \ + boost::mpl::less< \ + boost::mpl::int_, \ + boost::mpl::int_<256> \ + > \ + )); \ + /* \ + BOOST_MPL_ASSERT(( \ + mpl::equal_to< \ + :implementation_level, \ + mpl::int_ \ + >::value \ + )); \ + */ \ +}; \ +} \ +} + +#endif // BOOST_SERIALIZATION_VERSION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/void_cast.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/void_cast.hpp new file mode 100644 index 00000000000..f1b38286115 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/void_cast.hpp @@ -0,0 +1,298 @@ +#ifndef BOOST_SERIALIZATION_VOID_CAST_HPP +#define BOOST_SERIALIZATION_VOID_CAST_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// void_cast.hpp: interface for run-time casting of void pointers. + +// (C) Copyright 2002-2009 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// gennadiy.rozental@tfn.com + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // for ptrdiff_t +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include // must be the last header + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4251 4231 4660 4275) +#endif + +namespace boost { +namespace serialization { + +class extended_type_info; + +// Given a void *, assume that it really points to an instance of one type +// and alter it so that it would point to an instance of a related type. +// Return the altered pointer. If there exists no sequence of casts that +// can transform from_type to to_type, return a NULL. + +BOOST_SERIALIZATION_DECL void const * +void_upcast( + extended_type_info const & derived, + extended_type_info const & base, + void const * const t +); + +inline void * +void_upcast( + extended_type_info const & derived, + extended_type_info const & base, + void * const t +){ + return const_cast(void_upcast( + derived, + base, + const_cast(t) + )); +} + +BOOST_SERIALIZATION_DECL void const * +void_downcast( + extended_type_info const & derived, + extended_type_info const & base, + void const * const t +); + +inline void * +void_downcast( + extended_type_info const & derived, + extended_type_info const & base, + void * const t +){ + return const_cast(void_downcast( + derived, + base, + const_cast(t) + )); +} + +namespace void_cast_detail { + +class BOOST_SYMBOL_VISIBLE void_caster : + private boost::noncopyable +{ + friend + BOOST_SERIALIZATION_DECL void const * + boost::serialization::void_upcast( + extended_type_info const & derived, + extended_type_info const & base, + void const * const + ); + friend + BOOST_SERIALIZATION_DECL void const * + boost::serialization::void_downcast( + extended_type_info const & derived, + extended_type_info const & base, + void const * const + ); +protected: + BOOST_SERIALIZATION_DECL void recursive_register(bool includes_virtual_base = false) const; + BOOST_SERIALIZATION_DECL void recursive_unregister() const; + virtual bool has_virtual_base() const = 0; +public: + // Data members + const extended_type_info * m_derived; + const extended_type_info * m_base; + /*const*/ std::ptrdiff_t m_difference; + void_caster const * const m_parent; + + // note that void_casters are keyed on value of + // member extended type info records - NOT their + // addresses. This is necessary in order for the + // void cast operations to work across dll and exe + // module boundries. + bool operator<(const void_caster & rhs) const; + + const void_caster & operator*(){ + return *this; + } + // each derived class must re-implement these; + virtual void const * upcast(void const * const t) const = 0; + virtual void const * downcast(void const * const t) const = 0; + // Constructor + void_caster( + extended_type_info const * derived, + extended_type_info const * base, + std::ptrdiff_t difference = 0, + void_caster const * const parent = 0 + ) : + m_derived(derived), + m_base(base), + m_difference(difference), + m_parent(parent) + {} + virtual ~void_caster(){} +}; + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4251 4231 4660 4275 4511 4512) +#endif + +template +class BOOST_SYMBOL_VISIBLE void_caster_primitive : + public void_caster +{ + virtual void const * downcast(void const * const t) const { + const Derived * d = + boost::serialization::smart_cast( + static_cast(t) + ); + return d; + } + virtual void const * upcast(void const * const t) const { + const Base * b = + boost::serialization::smart_cast( + static_cast(t) + ); + return b; + } + virtual bool has_virtual_base() const { + return false; + } +public: + void_caster_primitive(); + virtual ~void_caster_primitive(); +}; + +template +void_caster_primitive::void_caster_primitive() : + void_caster( + & type_info_implementation::type::get_const_instance(), + & type_info_implementation::type::get_const_instance(), + // note:I wanted to displace from 0 here, but at least one compiler + // treated 0 by not shifting it at all. + reinterpret_cast( + static_cast( + reinterpret_cast(8) + ) + ) - 8 + ) +{ + recursive_register(); +} + +template +void_caster_primitive::~void_caster_primitive(){ + recursive_unregister(); +} + +template +class BOOST_SYMBOL_VISIBLE void_caster_virtual_base : + public void_caster +{ + virtual bool has_virtual_base() const { + return true; + } +public: + virtual void const * downcast(void const * const t) const { + const Derived * d = + dynamic_cast( + static_cast(t) + ); + return d; + } + virtual void const * upcast(void const * const t) const { + const Base * b = + dynamic_cast( + static_cast(t) + ); + return b; + } + void_caster_virtual_base(); + virtual ~void_caster_virtual_base(); +}; + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +template +void_caster_virtual_base::void_caster_virtual_base() : + void_caster( + & (type_info_implementation::type::get_const_instance()), + & (type_info_implementation::type::get_const_instance()) + ) +{ + recursive_register(true); +} + +template +void_caster_virtual_base::~void_caster_virtual_base(){ + recursive_unregister(); +} + +template +struct BOOST_SYMBOL_VISIBLE void_caster_base : + public void_caster +{ + typedef + typename mpl::eval_if, + mpl::identity< + void_cast_detail::void_caster_virtual_base + > + ,// else + mpl::identity< + void_cast_detail::void_caster_primitive + > + >::type type; +}; + +} // void_cast_detail + +template +BOOST_DLLEXPORT +inline const void_cast_detail::void_caster & void_cast_register( + Derived const * /* dnull = NULL */, + Base const * /* bnull = NULL */ +){ + typedef + typename mpl::eval_if, + mpl::identity< + void_cast_detail::void_caster_virtual_base + > + ,// else + mpl::identity< + void_cast_detail::void_caster_primitive + > + >::type typex; + return singleton::get_const_instance(); +} + +template +class BOOST_SYMBOL_VISIBLE void_caster : + public void_cast_detail::void_caster_base::type +{ +}; + +} // namespace serialization +} // namespace boost + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#include // pops abi_suffix.hpp pragmas + +#endif // BOOST_SERIALIZATION_VOID_CAST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/void_cast_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/void_cast_fwd.hpp new file mode 100644 index 00000000000..def61d52bb7 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/void_cast_fwd.hpp @@ -0,0 +1,37 @@ +#ifndef BOOST_SERIALIZATION_VOID_CAST_FWD_HPP +#define BOOST_SERIALIZATION_VOID_CAST_FWD_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// void_cast_fwd.hpp: interface for run-time casting of void pointers. + +// (C) Copyright 2005 Robert Ramey - http://www.rrsd.com . +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// gennadiy.rozental@tfn.com + +// See http://www.boost.org for updates, documentation, and revision history. + +#include // NULL +#include + +namespace boost { +namespace serialization { +namespace void_cast_detail{ +class void_caster; +} // namespace void_cast_detail +template +BOOST_DLLEXPORT +inline const void_cast_detail::void_caster & void_cast_register( + const Derived * dnull = NULL, + const Base * bnull = NULL +) BOOST_USED; +} // namespace serialization +} // namespace boost + +#endif // BOOST_SERIALIZATION_VOID_CAST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/weak_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/weak_ptr.hpp new file mode 100644 index 00000000000..6952d24cb37 --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/weak_ptr.hpp @@ -0,0 +1,99 @@ +#ifndef BOOST_SERIALIZATION_WEAK_PTR_HPP +#define BOOST_SERIALIZATION_WEAK_PTR_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 +// weak_ptr.hpp: serialization for boost weak pointer + +// (C) Copyright 2004 Robert Ramey and Martin Ecker +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#include +#include + +namespace boost { +namespace serialization{ + +template +inline void save( + Archive & ar, + const boost::weak_ptr< T > &t, + const unsigned int /* file_version */ +){ + const boost::shared_ptr< T > sp = t.lock(); + ar << boost::serialization::make_nvp("weak_ptr", sp); +} + +template +inline void load( + Archive & ar, + boost::weak_ptr< T > &t, + const unsigned int /* file_version */ +){ + boost::shared_ptr< T > sp; + ar >> boost::serialization::make_nvp("weak_ptr", sp); + t = sp; +} + +template +inline void serialize( + Archive & ar, + boost::weak_ptr< T > &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#ifndef BOOST_NO_CXX11_SMART_PTR +#include + +namespace boost { +namespace serialization{ + +template +inline void save( + Archive & ar, + const std::weak_ptr< T > &t, + const unsigned int /* file_version */ +){ + const std::shared_ptr< T > sp = t.lock(); + ar << boost::serialization::make_nvp("weak_ptr", sp); +} + +template +inline void load( + Archive & ar, + std::weak_ptr< T > &t, + const unsigned int /* file_version */ +){ + std::shared_ptr< T > sp; + ar >> boost::serialization::make_nvp("weak_ptr", sp); + t = sp; +} + +template +inline void serialize( + Archive & ar, + std::weak_ptr< T > &t, + const unsigned int file_version +){ + boost::serialization::split_free(ar, t, file_version); +} + +} // namespace serialization +} // namespace boost + +#endif // BOOST_NO_CXX11_SMART_PTR + +#endif // BOOST_SERIALIZATION_WEAK_PTR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/wrapper.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/wrapper.hpp new file mode 100644 index 00000000000..60d7910b17a --- /dev/null +++ b/contrib/libboost/boost_1_65_0/boost/serialization/wrapper.hpp @@ -0,0 +1,60 @@ +#ifndef BOOST_SERIALIZATION_WRAPPER_HPP +#define BOOST_SERIALIZATION_WRAPPER_HPP + +// (C) Copyright 2005-2006 Matthias Troyer +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include + +namespace boost { namespace serialization { + +/// the base class for serialization wrappers +/// +/// wrappers need to be treated differently at various places in the serialization library, +/// e.g. saving of non-const wrappers has to be possible. Since partial specialization +// is not supported by all compilers, we derive all wrappers from wrapper_traits. + +template< + class T, + int Level = object_serializable, + int Tracking = track_never, + unsigned int Version = 0, + class ETII = extended_type_info_impl< T > +> +struct wrapper_traits : + public traits +{}; + +template +struct is_wrapper_impl : + boost::mpl::eval_if< + boost::is_base_and_derived, + boost::mpl::true_, + boost::mpl::false_ + >::type +{}; + +template +struct is_wrapper { + typedef typename is_wrapper_impl::type type; +}; + +} // serialization +} // boost + +// A macro to define that a class is a wrapper +#define BOOST_CLASS_IS_WRAPPER(T) \ +namespace boost { \ +namespace serialization { \ +template<> \ +struct is_wrapper_impl : boost::mpl::true_ {}; \ +} \ +} \ +/**/ + +#endif //BOOST_SERIALIZATION_WRAPPER_HPP From 1b248be8c9c7109e26205a26d594b1d79657c4b1 Mon Sep 17 00:00:00 2001 From: robot-metrika-test Date: Thu, 30 Nov 2017 20:25:34 +0300 Subject: [PATCH 0017/1165] Auto version update to [54318] --- dbms/cmake/version.cmake | 4 ++-- debian/changelog | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dbms/cmake/version.cmake b/dbms/cmake/version.cmake index be5d4cf6005..6751aebb320 100644 --- a/dbms/cmake/version.cmake +++ b/dbms/cmake/version.cmake @@ -1,6 +1,6 @@ # This strings autochanged from release_lib.sh: -set(VERSION_DESCRIBE v1.1.54310-testing) -set(VERSION_REVISION 54310) +set(VERSION_DESCRIBE v1.1.54318-testing) +set(VERSION_REVISION 54318) # end of autochange set (VERSION_MAJOR 1) diff --git a/debian/changelog b/debian/changelog index cff5905660c..3530f559dc3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -clickhouse (1.1.54310) unstable; urgency=low +clickhouse (1.1.54318) unstable; urgency=low * Modified source code - -- Wed, 01 Nov 2017 08:03:17 +0300 + -- Thu, 30 Nov 2017 20:25:34 +0300 From 632c5427626f27b4ab528653fa44f01003345aee Mon Sep 17 00:00:00 2001 From: Nikita Lapkov Date: Tue, 25 Dec 2018 03:19:17 +0300 Subject: [PATCH 0018/1165] add basic timer with logging for query threads --- dbms/src/Common/ThreadStatus.h | 7 +++ dbms/src/Interpreters/ThreadStatusExt.cpp | 56 +++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/dbms/src/Common/ThreadStatus.h b/dbms/src/Common/ThreadStatus.h index 822e1931447..05994883040 100644 --- a/dbms/src/Common/ThreadStatus.h +++ b/dbms/src/Common/ThreadStatus.h @@ -144,6 +144,10 @@ protected: void initPerformanceCounters(); + void initQueryProfiler(); + + void finalizeQueryProfiler(); + void logToQueryThreadLog(QueryThreadLog & thread_log); void assertState(const std::initializer_list & permitted_states, const char * description = nullptr); @@ -165,6 +169,9 @@ protected: time_t query_start_time = 0; size_t queries_started = 0; + bool has_query_profiler = false; + timer_t query_profiler_timer_id = 0; + Poco::Logger * log = nullptr; friend class CurrentThread; diff --git a/dbms/src/Interpreters/ThreadStatusExt.cpp b/dbms/src/Interpreters/ThreadStatusExt.cpp index eac9251cdf0..ffd12572cf1 100644 --- a/dbms/src/Interpreters/ThreadStatusExt.cpp +++ b/dbms/src/Interpreters/ThreadStatusExt.cpp @@ -5,7 +5,12 @@ #include #include #include +#include +#include +#include +#include +#include /// Implement some methods of ThreadStatus and CurrentThread here to avoid extra linking dependencies in clickhouse_common_io namespace DB @@ -92,6 +97,10 @@ void ThreadStatus::attachQuery(const ThreadGroupStatusPtr & thread_group_, bool } initPerformanceCounters(); + + LOG_INFO(&Logger::get("laplab"), "Attaching"); + initQueryProfiler(); + thread_state = ThreadState::AttachedToQuery; } @@ -119,6 +128,49 @@ void ThreadStatus::finalizePerformanceCounters() } } +namespace { + void queryProfilerTimerHandler(int /* signal */) { + LOG_INFO(&Logger::get("laplab"), "Hello from handler!"); + } +} + +void ThreadStatus::initQueryProfiler() { + sigevent sev; + sev.sigev_notify = SIGEV_THREAD_ID; + sev.sigev_signo = SIGALRM; + sev._sigev_un._tid = os_thread_id; + // TODO(laplab): get clock type from settings + if (timer_create(CLOCK_REALTIME, &sev, &query_profiler_timer_id)) { + LOG_ERROR(log, "Failed to create query profiler timer"); + return; + } + + // TODO(laplab): get period from settings + timespec period{.tv_sec = 10, .tv_nsec = 0}; + itimerspec timer_spec = {.it_interval = period, .it_value = period}; + if (timer_settime(query_profiler_timer_id, 0, &timer_spec, nullptr)) { + LOG_ERROR(log, "Failed to set query profiler timer"); + return; + } + + std::signal(SIGALRM, queryProfilerTimerHandler); + + has_query_profiler = true; +} + +void ThreadStatus::finalizeQueryProfiler() { + if (!has_query_profiler) { + return; + } + + if (timer_delete(query_profiler_timer_id)) { + LOG_ERROR(log, "Failed to delete query profiler timer"); + return; + } + + has_query_profiler = false; +} + void ThreadStatus::detachQuery(bool exit_if_already_detached, bool thread_exits) { if (exit_if_already_detached && thread_state == ThreadState::DetachedFromQuery) @@ -128,6 +180,8 @@ void ThreadStatus::detachQuery(bool exit_if_already_detached, bool thread_exits) } assertState({ThreadState::AttachedToQuery}, __PRETTY_FUNCTION__); + + finalizeQueryProfiler(); finalizePerformanceCounters(); /// Detach from thread group @@ -140,6 +194,8 @@ void ThreadStatus::detachQuery(bool exit_if_already_detached, bool thread_exits) query_context = nullptr; thread_group.reset(); + LOG_INFO(&Logger::get("laplab"), "Detaching"); + thread_state = thread_exits ? ThreadState::Died : ThreadState::DetachedFromQuery; } From 4c55802552557d53f060ef0f8cae0ad23f01883f Mon Sep 17 00:00:00 2001 From: Nikita Lapkov Date: Fri, 18 Jan 2019 13:10:43 +0000 Subject: [PATCH 0019/1165] refactor - add exceptions on timer errors - move from signal to sigaction - extract backtrace collection logic --- dbms/src/Interpreters/ThreadStatusExt.cpp | 53 ++-- libs/libdaemon/CMakeLists.txt | 3 +- libs/libdaemon/include/daemon/Backtrace.h | 78 ++++++ libs/libdaemon/src/Backtrace.cpp | 319 ++++++++++++++++++++++ libs/libdaemon/src/BaseDaemon.cpp | 215 +-------------- 5 files changed, 437 insertions(+), 231 deletions(-) create mode 100644 libs/libdaemon/include/daemon/Backtrace.h create mode 100644 libs/libdaemon/src/Backtrace.cpp diff --git a/dbms/src/Interpreters/ThreadStatusExt.cpp b/dbms/src/Interpreters/ThreadStatusExt.cpp index ffd12572cf1..3f7c77fd006 100644 --- a/dbms/src/Interpreters/ThreadStatusExt.cpp +++ b/dbms/src/Interpreters/ThreadStatusExt.cpp @@ -97,10 +97,8 @@ void ThreadStatus::attachQuery(const ThreadGroupStatusPtr & thread_group_, bool } initPerformanceCounters(); - - LOG_INFO(&Logger::get("laplab"), "Attaching"); initQueryProfiler(); - + thread_state = ThreadState::AttachedToQuery; } @@ -129,31 +127,49 @@ void ThreadStatus::finalizePerformanceCounters() } namespace { - void queryProfilerTimerHandler(int /* signal */) { + void queryProfilerTimerHandler(int /* sig */, siginfo_t * /* info */, void * /* context */) { LOG_INFO(&Logger::get("laplab"), "Hello from handler!"); } } void ThreadStatus::initQueryProfiler() { - sigevent sev; + if (!query_context) { + LOG_INFO(log, "Query profiler disabled - no context"); + return; + } + + struct sigevent sev; sev.sigev_notify = SIGEV_THREAD_ID; sev.sigev_signo = SIGALRM; sev._sigev_un._tid = os_thread_id; // TODO(laplab): get clock type from settings if (timer_create(CLOCK_REALTIME, &sev, &query_profiler_timer_id)) { - LOG_ERROR(log, "Failed to create query profiler timer"); - return; - } - - // TODO(laplab): get period from settings - timespec period{.tv_sec = 10, .tv_nsec = 0}; - itimerspec timer_spec = {.it_interval = period, .it_value = period}; - if (timer_settime(query_profiler_timer_id, 0, &timer_spec, nullptr)) { - LOG_ERROR(log, "Failed to set query profiler timer"); - return; + throw Poco::Exception("Failed to create query profiler timer"); } - std::signal(SIGALRM, queryProfilerTimerHandler); + // TODO(laplab): get period from settings + struct timespec period{.tv_sec = 0, .tv_nsec = 200000000}; + struct itimerspec timer_spec = {.it_interval = period, .it_value = period}; + if (timer_settime(query_profiler_timer_id, 0, &timer_spec, nullptr)) { + throw Poco::Exception("Failed to set query profiler timer"); + } + + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = queryProfilerTimerHandler; + sa.sa_flags = SA_SIGINFO; + + if (sigemptyset(&sa.sa_mask)) { + throw Poco::Exception("Failed to clean signal mask for query profiler"); + } + + if (sigaddset(&sa.sa_mask, SIGALRM)) { + throw Poco::Exception("Failed to add signal to mask for query profiler"); + } + + if (sigaction(SIGALRM, &sa, nullptr)) { + throw Poco::Exception("Failed to setup signal handler for query profiler"); + } has_query_profiler = true; } @@ -164,8 +180,7 @@ void ThreadStatus::finalizeQueryProfiler() { } if (timer_delete(query_profiler_timer_id)) { - LOG_ERROR(log, "Failed to delete query profiler timer"); - return; + throw Poco::Exception("Failed to delete query profiler timer"); } has_query_profiler = false; @@ -194,8 +209,6 @@ void ThreadStatus::detachQuery(bool exit_if_already_detached, bool thread_exits) query_context = nullptr; thread_group.reset(); - LOG_INFO(&Logger::get("laplab"), "Detaching"); - thread_state = thread_exits ? ThreadState::Died : ThreadState::DetachedFromQuery; } diff --git a/libs/libdaemon/CMakeLists.txt b/libs/libdaemon/CMakeLists.txt index b352602f81c..2a9a651cdba 100644 --- a/libs/libdaemon/CMakeLists.txt +++ b/libs/libdaemon/CMakeLists.txt @@ -5,6 +5,7 @@ add_library (daemon ${LINK_MODE} src/OwnPatternFormatter.cpp src/OwnFormattingChannel.cpp src/OwnSplitChannel.cpp + src/Backtrace.cpp include/daemon/BaseDaemon.h include/daemon/GraphiteWriter.h @@ -12,7 +13,7 @@ add_library (daemon ${LINK_MODE} include/daemon/OwnPatternFormatter.h include/daemon/OwnFormattingChannel.h include/daemon/OwnSplitChannel.h -) + include/daemon/Backtrace.h) if (USE_UNWIND) target_compile_definitions (daemon PRIVATE USE_UNWIND=1) diff --git a/libs/libdaemon/include/daemon/Backtrace.h b/libs/libdaemon/include/daemon/Backtrace.h new file mode 100644 index 00000000000..6cadc463642 --- /dev/null +++ b/libs/libdaemon/include/daemon/Backtrace.h @@ -0,0 +1,78 @@ +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if USE_UNWIND +#define UNW_LOCAL_ONLY + #include +#endif + +#ifdef __APPLE__ +// ucontext is not available without _XOPEN_SOURCE +#define _XOPEN_SOURCE +#endif +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +std::string signalToErrorMessage(int sig, siginfo_t & info, ucontext_t & context); + +void * getCallerAddress(ucontext_t & context); + +std::vector getBacktraceFrames(ucontext_t & context); + +std::string backtraceFramesToString(const std::vector & frames); diff --git a/libs/libdaemon/src/Backtrace.cpp b/libs/libdaemon/src/Backtrace.cpp new file mode 100644 index 00000000000..d8ff20d999a --- /dev/null +++ b/libs/libdaemon/src/Backtrace.cpp @@ -0,0 +1,319 @@ +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if USE_UNWIND +#define UNW_LOCAL_ONLY + #include +#endif + +#ifdef __APPLE__ +// ucontext is not available without _XOPEN_SOURCE +#define _XOPEN_SOURCE +#endif +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#if USE_UNWIND +std::vector backtraceLibUnwind(size_t max_frames, ucontext_t & context) +{ + std::vector out_frames; + unw_cursor_t cursor; + + if (unw_init_local2(&cursor, &context, UNW_INIT_SIGNAL_FRAME) >= 0) + { + for (size_t i = 0; i < max_frames; ++i) + { + unw_word_t ip; + unw_get_reg(&cursor, UNW_REG_IP, &ip); + out_frames.push_back(reinterpret_cast(ip)); + + /// NOTE This triggers "AddressSanitizer: stack-buffer-overflow". Looks like false positive. + /// It's Ok, because we use this method if the program is crashed nevertheless. + if (!unw_step(&cursor)) + break; + } + } + + return out_frames; +} +#endif + +std::string signalToErrorMessage(int sig, siginfo_t & info, ucontext_t & context) +{ + std::stringstream error; + switch (sig) + { + case SIGSEGV: + { + /// Print info about address and reason. + if (nullptr == info.si_addr) + error << "Address: NULL pointer."; + else + error << "Address: " << info.si_addr; + +#if defined(__x86_64__) && !defined(__FreeBSD__) && !defined(__APPLE__) + auto err_mask = context.uc_mcontext.gregs[REG_ERR]; + if ((err_mask & 0x02)) + error << " Access: write."; + else + error << " Access: read."; +#endif + + switch (info.si_code) + { + case SEGV_ACCERR: + error << " Attempted access has violated the permissions assigned to the memory area."; + break; + case SEGV_MAPERR: + error << " Address not mapped to object."; + break; + default: + error << " Unknown si_code."; + break; + } + break; + } + + case SIGBUS: + { + switch (info.si_code) + { + case BUS_ADRALN: + error << "Invalid address alignment."; + break; + case BUS_ADRERR: + error << "Non-existant physical address."; + break; + case BUS_OBJERR: + error << "Object specific hardware error."; + break; + + // Linux specific +#if defined(BUS_MCEERR_AR) + case BUS_MCEERR_AR: + error << "Hardware memory error: action required."; + break; +#endif +#if defined(BUS_MCEERR_AO) + case BUS_MCEERR_AO: + error << "Hardware memory error: action optional."; + break; +#endif + + default: + error << "Unknown si_code."; + break; + } + break; + } + + case SIGILL: + { + switch (info.si_code) + { + case ILL_ILLOPC: + error << "Illegal opcode."; + break; + case ILL_ILLOPN: + error << "Illegal operand."; + break; + case ILL_ILLADR: + error << "Illegal addressing mode."; + break; + case ILL_ILLTRP: + error << "Illegal trap."; + break; + case ILL_PRVOPC: + error << "Privileged opcode."; + break; + case ILL_PRVREG: + error << "Privileged register."; + break; + case ILL_COPROC: + error << "Coprocessor error."; + break; + case ILL_BADSTK: + error << "Internal stack error."; + break; + default: + error << "Unknown si_code."; + break; + } + break; + } + + case SIGFPE: + { + switch (info.si_code) + { + case FPE_INTDIV: + error << "Integer divide by zero."; + break; + case FPE_INTOVF: + error << "Integer overflow."; + break; + case FPE_FLTDIV: + error << "Floating point divide by zero."; + break; + case FPE_FLTOVF: + error << "Floating point overflow."; + break; + case FPE_FLTUND: + error << "Floating point underflow."; + break; + case FPE_FLTRES: + error << "Floating point inexact result."; + break; + case FPE_FLTINV: + error << "Floating point invalid operation."; + break; + case FPE_FLTSUB: + error << "Subscript out of range."; + break; + default: + error << "Unknown si_code."; + break; + } + break; + } + } + + return error.str(); +} + +void * getCallerAddress(ucontext_t & context) +{ +#if defined(__x86_64__) + /// Get the address at the time the signal was raised from the RIP (x86-64) +#if defined(__FreeBSD__) + return reinterpret_cast(context.uc_mcontext.mc_rip); +#elif defined(__APPLE__) + return reinterpret_cast(context.uc_mcontext->__ss.__rip); +#else + return reinterpret_cast(context.uc_mcontext.gregs[REG_RIP]); +#endif +#elif defined(__aarch64__) + return reinterpret_cast(context.uc_mcontext.pc); +#endif + + return nullptr; +} + +std::vector getBacktraceFrames(ucontext_t & context) +{ + std::vector frames; + +#if USE_UNWIND + static size_t max_frames = 50; + frames = backtraceLibUnwind(max_frames, context); +#else + /// No libunwind means no backtrace, because we are in a different thread from the one where the signal happened. + /// So at least print the function where the signal happened. + void * caller_address = getCallerAddress(context); + if (caller_address) + frames.push_back(caller_address); +#endif + + return frames; +} + +std::string backtraceFramesToString(const std::vector & frames) +{ + std::stringstream backtrace; + char ** symbols = backtrace_symbols(frames.data(), frames.size()); + + if (!symbols) + { + if (frames.size() > 0) + backtrace << "No symbols could be found for backtrace starting at " << frames[0]; + } + else + { + for (size_t i = 0; i < frames.size(); ++i) + { + /// Perform demangling of names. Name is in parentheses, before '+' character. + + char * name_start = nullptr; + char * name_end = nullptr; + char * demangled_name = nullptr; + int status = 0; + + if (nullptr != (name_start = strchr(symbols[i], '(')) + && nullptr != (name_end = strchr(name_start, '+'))) + { + ++name_start; + *name_end = '\0'; + demangled_name = abi::__cxa_demangle(name_start, 0, 0, &status); + *name_end = '+'; + } + + backtrace << i << ". "; + + if (nullptr != demangled_name && 0 == status) + { + backtrace.write(symbols[i], name_start - symbols[i]); + backtrace << demangled_name << name_end; + } + else + backtrace << symbols[i]; + } + } + + return backtrace.str(); +} diff --git a/libs/libdaemon/src/BaseDaemon.cpp b/libs/libdaemon/src/BaseDaemon.cpp index bad38c78529..09ecfdf89e9 100644 --- a/libs/libdaemon/src/BaseDaemon.cpp +++ b/libs/libdaemon/src/BaseDaemon.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -297,218 +298,12 @@ private: LOG_ERROR(log, "(from thread " << thread_num << ") " << "Received signal " << strsignal(sig) << " (" << sig << ")" << "."); - void * caller_address = nullptr; + LOG_ERROR(log, signalToErrorMessage(sig, info, context)); -#if defined(__x86_64__) - /// Get the address at the time the signal was raised from the RIP (x86-64) - #if defined(__FreeBSD__) - caller_address = reinterpret_cast(context.uc_mcontext.mc_rip); - #elif defined(__APPLE__) - caller_address = reinterpret_cast(context.uc_mcontext->__ss.__rip); - #else - caller_address = reinterpret_cast(context.uc_mcontext.gregs[REG_RIP]); - auto err_mask = context.uc_mcontext.gregs[REG_ERR]; - #endif -#elif defined(__aarch64__) - caller_address = reinterpret_cast(context.uc_mcontext.pc); -#endif + std::vector frames = getBacktraceFrames(context); + std::string backtrace = backtraceFramesToString(frames); - switch (sig) - { - case SIGSEGV: - { - /// Print info about address and reason. - if (nullptr == info.si_addr) - LOG_ERROR(log, "Address: NULL pointer."); - else - LOG_ERROR(log, "Address: " << info.si_addr); - -#if defined(__x86_64__) && !defined(__FreeBSD__) && !defined(__APPLE__) - if ((err_mask & 0x02)) - LOG_ERROR(log, "Access: write."); - else - LOG_ERROR(log, "Access: read."); -#endif - - switch (info.si_code) - { - case SEGV_ACCERR: - LOG_ERROR(log, "Attempted access has violated the permissions assigned to the memory area."); - break; - case SEGV_MAPERR: - LOG_ERROR(log, "Address not mapped to object."); - break; - default: - LOG_ERROR(log, "Unknown si_code."); - break; - } - break; - } - - case SIGBUS: - { - switch (info.si_code) - { - case BUS_ADRALN: - LOG_ERROR(log, "Invalid address alignment."); - break; - case BUS_ADRERR: - LOG_ERROR(log, "Non-existant physical address."); - break; - case BUS_OBJERR: - LOG_ERROR(log, "Object specific hardware error."); - break; - - // Linux specific -#if defined(BUS_MCEERR_AR) - case BUS_MCEERR_AR: - LOG_ERROR(log, "Hardware memory error: action required."); - break; -#endif -#if defined(BUS_MCEERR_AO) - case BUS_MCEERR_AO: - LOG_ERROR(log, "Hardware memory error: action optional."); - break; -#endif - - default: - LOG_ERROR(log, "Unknown si_code."); - break; - } - break; - } - - case SIGILL: - { - switch (info.si_code) - { - case ILL_ILLOPC: - LOG_ERROR(log, "Illegal opcode."); - break; - case ILL_ILLOPN: - LOG_ERROR(log, "Illegal operand."); - break; - case ILL_ILLADR: - LOG_ERROR(log, "Illegal addressing mode."); - break; - case ILL_ILLTRP: - LOG_ERROR(log, "Illegal trap."); - break; - case ILL_PRVOPC: - LOG_ERROR(log, "Privileged opcode."); - break; - case ILL_PRVREG: - LOG_ERROR(log, "Privileged register."); - break; - case ILL_COPROC: - LOG_ERROR(log, "Coprocessor error."); - break; - case ILL_BADSTK: - LOG_ERROR(log, "Internal stack error."); - break; - default: - LOG_ERROR(log, "Unknown si_code."); - break; - } - break; - } - - case SIGFPE: - { - switch (info.si_code) - { - case FPE_INTDIV: - LOG_ERROR(log, "Integer divide by zero."); - break; - case FPE_INTOVF: - LOG_ERROR(log, "Integer overflow."); - break; - case FPE_FLTDIV: - LOG_ERROR(log, "Floating point divide by zero."); - break; - case FPE_FLTOVF: - LOG_ERROR(log, "Floating point overflow."); - break; - case FPE_FLTUND: - LOG_ERROR(log, "Floating point underflow."); - break; - case FPE_FLTRES: - LOG_ERROR(log, "Floating point inexact result."); - break; - case FPE_FLTINV: - LOG_ERROR(log, "Floating point invalid operation."); - break; - case FPE_FLTSUB: - LOG_ERROR(log, "Subscript out of range."); - break; - default: - LOG_ERROR(log, "Unknown si_code."); - break; - } - break; - } - } - - static const int max_frames = 50; - void * frames[max_frames]; - -#if USE_UNWIND - int frames_size = backtraceLibUnwind(frames, max_frames, context); - - if (frames_size) - { -#else - /// No libunwind means no backtrace, because we are in a different thread from the one where the signal happened. - /// So at least print the function where the signal happened. - if (caller_address) - { - frames[0] = caller_address; - int frames_size = 1; -#endif - - char ** symbols = backtrace_symbols(frames, frames_size); - - if (!symbols) - { - if (caller_address) - LOG_ERROR(log, "Caller address: " << caller_address); - } - else - { - for (int i = 0; i < frames_size; ++i) - { - /// Perform demangling of names. Name is in parentheses, before '+' character. - - char * name_start = nullptr; - char * name_end = nullptr; - char * demangled_name = nullptr; - int status = 0; - - if (nullptr != (name_start = strchr(symbols[i], '(')) - && nullptr != (name_end = strchr(name_start, '+'))) - { - ++name_start; - *name_end = '\0'; - demangled_name = abi::__cxa_demangle(name_start, 0, 0, &status); - *name_end = '+'; - } - - std::stringstream res; - - res << i << ". "; - - if (nullptr != demangled_name && 0 == status) - { - res.write(symbols[i], name_start - symbols[i]); - res << demangled_name << name_end; - } - else - res << symbols[i]; - - LOG_ERROR(log, res.rdbuf()); - } - } - } + LOG_ERROR(log, backtrace); } }; From df3db1bff219351a84cb17385afdd8605ccc6acb Mon Sep 17 00:00:00 2001 From: Nikita Lapkov Date: Sun, 3 Feb 2019 09:57:12 +0000 Subject: [PATCH 0020/1165] basic pipe --- dbms/CMakeLists.txt | 2 +- dbms/src/Common/Pipe.h | 65 +++++++++++++++++++ dbms/src/Common/ShellCommand.cpp | 76 +++++------------------ dbms/src/Interpreters/Context.cpp | 11 +++- dbms/src/Interpreters/Context.h | 2 + dbms/src/Interpreters/ThreadStatusExt.cpp | 14 ++++- dbms/src/Interpreters/TraceCollector.cpp | 34 ++++++++++ dbms/src/Interpreters/TraceCollector.h | 25 ++++++++ libs/libdaemon/CMakeLists.txt | 3 +- libs/libdaemon/include/daemon/Backtrace.h | 2 + libs/libdaemon/include/daemon/Pipe.h | 51 +++++++++++++++ libs/libdaemon/src/BaseDaemon.cpp | 50 +-------------- 12 files changed, 221 insertions(+), 114 deletions(-) create mode 100644 dbms/src/Common/Pipe.h create mode 100644 dbms/src/Interpreters/TraceCollector.cpp create mode 100644 dbms/src/Interpreters/TraceCollector.h create mode 100644 libs/libdaemon/include/daemon/Pipe.h diff --git a/dbms/CMakeLists.txt b/dbms/CMakeLists.txt index b7f11731662..90e49aefc02 100644 --- a/dbms/CMakeLists.txt +++ b/dbms/CMakeLists.txt @@ -97,7 +97,7 @@ list (APPEND dbms_headers list (APPEND dbms_sources src/TableFunctions/ITableFunction.cpp src/TableFunctions/TableFunctionFactory.cpp) list (APPEND dbms_headers src/TableFunctions/ITableFunction.h src/TableFunctions/TableFunctionFactory.h) -add_library(clickhouse_common_io ${LINK_MODE} ${clickhouse_common_io_headers} ${clickhouse_common_io_sources}) +add_library(clickhouse_common_io ${LINK_MODE} ${clickhouse_common_io_headers} ${clickhouse_common_io_sources} src/Common/Pipe.h) if (OS_FREEBSD) target_compile_definitions (clickhouse_common_io PUBLIC CLOCK_MONOTONIC_COARSE=CLOCK_MONOTONIC_FAST) diff --git a/dbms/src/Common/Pipe.h b/dbms/src/Common/Pipe.h new file mode 100644 index 00000000000..2aa5f2ef4a6 --- /dev/null +++ b/dbms/src/Common/Pipe.h @@ -0,0 +1,65 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DB { + + struct Pipe + { + union + { + int fds[2]; + struct + { + int read_fd; + int write_fd; + }; + }; + + Pipe() + { + read_fd = -1; + write_fd = -1; + + if (0 != pipe(fds)) + DB::throwFromErrno("Cannot create pipe", 0); + } + + void close() + { + if (-1 != read_fd) + { + ::close(read_fd); + read_fd = -1; + } + + if (-1 != write_fd) + { + ::close(write_fd); + write_fd = -1; + } + + LOG_INFO(&Logger::get("TraceCollector"), "Pipe is closed"); + } + + ~Pipe() + { + close(); + } + }; + + class PipeSingleton : public ext::singleton + { + }; + +} \ No newline at end of file diff --git a/dbms/src/Common/ShellCommand.cpp b/dbms/src/Common/ShellCommand.cpp index 2e19d442f9a..5812cfa9ab8 100644 --- a/dbms/src/Common/ShellCommand.cpp +++ b/dbms/src/Common/ShellCommand.cpp @@ -8,73 +8,29 @@ #include #include #include +#include namespace DB { - namespace ErrorCodes - { - extern const int CANNOT_PIPE; - extern const int CANNOT_DLSYM; - extern const int CANNOT_FORK; - extern const int CANNOT_WAITPID; - extern const int CHILD_WAS_NOT_EXITED_NORMALLY; - extern const int CANNOT_CREATE_CHILD_PROCESS; - } + +namespace ErrorCodes +{ + extern const int CANNOT_DLSYM; + extern const int CANNOT_FORK; + extern const int CANNOT_WAITPID; + extern const int CHILD_WAS_NOT_EXITED_NORMALLY; + extern const int CANNOT_CREATE_CHILD_PROCESS; } - -namespace -{ - struct Pipe - { - union - { - int fds[2]; - struct - { - int read_fd; - int write_fd; - }; - }; - - Pipe() - { - #ifndef __APPLE__ - if (0 != pipe2(fds, O_CLOEXEC)) - DB::throwFromErrno("Cannot create pipe", DB::ErrorCodes::CANNOT_PIPE); - #else - if (0 != pipe(fds)) - DB::throwFromErrno("Cannot create pipe", DB::ErrorCodes::CANNOT_PIPE); - if (0 != fcntl(fds[0], F_SETFD, FD_CLOEXEC)) - DB::throwFromErrno("Cannot create pipe", DB::ErrorCodes::CANNOT_PIPE); - if (0 != fcntl(fds[1], F_SETFD, FD_CLOEXEC)) - DB::throwFromErrno("Cannot create pipe", DB::ErrorCodes::CANNOT_PIPE); - #endif - } - - ~Pipe() - { - if (read_fd >= 0) - close(read_fd); - if (write_fd >= 0) - close(write_fd); - } - }; - - /// By these return codes from the child process, we learn (for sure) about errors when creating it. - enum class ReturnCodes : int - { - CANNOT_DUP_STDIN = 0x55555555, /// The value is not important, but it is chosen so that it's rare to conflict with the program return code. - CANNOT_DUP_STDOUT = 0x55555556, - CANNOT_DUP_STDERR = 0x55555557, - CANNOT_EXEC = 0x55555558, - }; -} - - -namespace DB +/// By these return codes from the child process, we learn (for sure) about errors when creating it. +enum class ReturnCodes : int { + CANNOT_DUP_STDIN = 0x55555555, /// The value is not important, but it is chosen so that it's rare to conflict with the program return code. + CANNOT_DUP_STDOUT = 0x55555556, + CANNOT_DUP_STDERR = 0x55555557, + CANNOT_EXEC = 0x55555558, +}; ShellCommand::ShellCommand(pid_t pid, int in_fd, int out_fd, int err_fd, bool terminate_in_destructor_) : pid(pid) diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index 1e33c90be2c..1f948d78cfb 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -52,6 +52,7 @@ #include #include #include +#include "TraceCollector.h" namespace ProfileEvents @@ -150,6 +151,9 @@ struct ContextShared String format_schema_path; /// Path to a directory that contains schema files used by input formats. ActionLocksManagerPtr action_locks_manager; /// Set of storages' action lockers + Poco::Thread trace_collector_thread; /// Thread collecting traces from threads executing queries + std::unique_ptr trace_collector; + /// Named sessions. The user could specify session identifier to reuse settings and temporary tables in subsequent requests. class SessionKeyHash @@ -267,7 +271,11 @@ struct ContextShared private: void initialize() { - security_manager = runtime_components_factory->createSecurityManager(); + security_manager = runtime_components_factory->createSecurityManager(); + + /// Set up trace collector for query profiler + trace_collector.reset(new TraceCollector()); + trace_collector_thread.start(*trace_collector); } }; @@ -484,7 +492,6 @@ DatabasePtr Context::tryGetDatabase(const String & database_name) return it->second; } - String Context::getPath() const { auto lock = getLock(); diff --git a/dbms/src/Interpreters/Context.h b/dbms/src/Interpreters/Context.h index 6e38e056a0f..d76374dd641 100644 --- a/dbms/src/Interpreters/Context.h +++ b/dbms/src/Interpreters/Context.h @@ -18,6 +18,8 @@ #include #include #include +#include +#include namespace Poco diff --git a/dbms/src/Interpreters/ThreadStatusExt.cpp b/dbms/src/Interpreters/ThreadStatusExt.cpp index 3f7c77fd006..a6a83b96775 100644 --- a/dbms/src/Interpreters/ThreadStatusExt.cpp +++ b/dbms/src/Interpreters/ThreadStatusExt.cpp @@ -5,12 +5,16 @@ #include #include #include +#include +#include +#include #include #include #include #include #include +#include /// Implement some methods of ThreadStatus and CurrentThread here to avoid extra linking dependencies in clickhouse_common_io namespace DB @@ -127,8 +131,16 @@ void ThreadStatus::finalizePerformanceCounters() } namespace { - void queryProfilerTimerHandler(int /* sig */, siginfo_t * /* info */, void * /* context */) { + void queryProfilerTimerHandler(int sig, siginfo_t * /* info */, void * /* context */) { LOG_INFO(&Logger::get("laplab"), "Hello from handler!"); + + char buffer[TraceCollector::buf_size]; + DB::WriteBufferFromFileDescriptor out(PipeSingleton::instance().write_fd, TraceCollector::buf_size, buffer); + + DB::writeBinary(sig, out); + out.next(); + + ::sleep(10); } } diff --git a/dbms/src/Interpreters/TraceCollector.cpp b/dbms/src/Interpreters/TraceCollector.cpp new file mode 100644 index 00000000000..1fde0870744 --- /dev/null +++ b/dbms/src/Interpreters/TraceCollector.cpp @@ -0,0 +1,34 @@ +#include "TraceCollector.h" +#include +#include + +namespace DB { + + const size_t TraceCollector::buf_size = sizeof(int); + + TraceCollector::TraceCollector() + : log(&Logger::get("TraceCollector")) + { + } + + void TraceCollector::run() + { + LOG_INFO(log, "TraceCollector started"); + + char buf[buf_size]; + DB::ReadBufferFromFileDescriptor in(PipeSingleton::instance().read_fd, buf_size, buf); + + LOG_INFO(log, "Preparing to read from: " << PipeSingleton::instance().read_fd); + + while (true) + { + int sig = 0; + DB::readBinary(sig, in); + + LOG_INFO(log, "Received signal: " << sig); + } + + LOG_INFO(log, "TraceCollector exited"); + } + +} diff --git a/dbms/src/Interpreters/TraceCollector.h b/dbms/src/Interpreters/TraceCollector.h new file mode 100644 index 00000000000..745616e122e --- /dev/null +++ b/dbms/src/Interpreters/TraceCollector.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include +#include + +namespace DB +{ + + using Poco::Logger; + + class TraceCollector : public Poco::Runnable + { + private: + Logger * log; + + public: + explicit TraceCollector(); + + void run() override; + + static const size_t buf_size; + }; +} diff --git a/libs/libdaemon/CMakeLists.txt b/libs/libdaemon/CMakeLists.txt index 2a9a651cdba..2fa8b3c488b 100644 --- a/libs/libdaemon/CMakeLists.txt +++ b/libs/libdaemon/CMakeLists.txt @@ -13,7 +13,8 @@ add_library (daemon ${LINK_MODE} include/daemon/OwnPatternFormatter.h include/daemon/OwnFormattingChannel.h include/daemon/OwnSplitChannel.h - include/daemon/Backtrace.h) + include/daemon/Backtrace.h + include/daemon/Pipe.h) if (USE_UNWIND) target_compile_definitions (daemon PRIVATE USE_UNWIND=1) diff --git a/libs/libdaemon/include/daemon/Backtrace.h b/libs/libdaemon/include/daemon/Backtrace.h index 6cadc463642..0cb5973c12e 100644 --- a/libs/libdaemon/include/daemon/Backtrace.h +++ b/libs/libdaemon/include/daemon/Backtrace.h @@ -1,3 +1,5 @@ +#pragma once + #include #include #include diff --git a/libs/libdaemon/include/daemon/Pipe.h b/libs/libdaemon/include/daemon/Pipe.h new file mode 100644 index 00000000000..9a5b1d3afa5 --- /dev/null +++ b/libs/libdaemon/include/daemon/Pipe.h @@ -0,0 +1,51 @@ +#pragma once + +#include + +/** For transferring information from signal handler to a separate thread. + * If you need to do something serious in case of a signal (example: write a message to the log), + * then sending information to a separate thread through pipe and doing all the stuff asynchronously + * - is probably the only safe method for doing it. + * (Because it's only safe to use reentrant functions in signal handlers.) + */ +struct Pipe +{ + union + { + int fds[2]; + struct + { + int read_fd; + int write_fd; + }; + }; + + Pipe() + { + read_fd = -1; + write_fd = -1; + + if (0 != pipe(fds)) + DB::throwFromErrno("Cannot create pipe", 0); + } + + void close() + { + if (-1 != read_fd) + { + ::close(read_fd); + read_fd = -1; + } + + if (-1 != write_fd) + { + ::close(write_fd); + write_fd = -1; + } + } + + ~Pipe() + { + close(); + } +}; \ No newline at end of file diff --git a/libs/libdaemon/src/BaseDaemon.cpp b/libs/libdaemon/src/BaseDaemon.cpp index 09ecfdf89e9..20f6074968d 100644 --- a/libs/libdaemon/src/BaseDaemon.cpp +++ b/libs/libdaemon/src/BaseDaemon.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -70,55 +71,6 @@ #include -/** For transferring information from signal handler to a separate thread. - * If you need to do something serious in case of a signal (example: write a message to the log), - * then sending information to a separate thread through pipe and doing all the stuff asynchronously - * - is probably the only safe method for doing it. - * (Because it's only safe to use reentrant functions in signal handlers.) - */ -struct Pipe -{ - union - { - int fds[2]; - struct - { - int read_fd; - int write_fd; - }; - }; - - Pipe() - { - read_fd = -1; - write_fd = -1; - - if (0 != pipe(fds)) - DB::throwFromErrno("Cannot create pipe", 0); - } - - void close() - { - if (-1 != read_fd) - { - ::close(read_fd); - read_fd = -1; - } - - if (-1 != write_fd) - { - ::close(write_fd); - write_fd = -1; - } - } - - ~Pipe() - { - close(); - } -}; - - Pipe signal_pipe; From 5c54bbb7506803899f45d0e73f8f7a2a9e5b0c4c Mon Sep 17 00:00:00 2001 From: Nikita Lapkov Date: Sun, 3 Feb 2019 21:30:45 +0000 Subject: [PATCH 0021/1165] write traces to trace_log --- CMakeLists.txt | 2 +- dbms/CMakeLists.txt | 2 +- dbms/programs/server/Server.cpp | 3 + dbms/programs/server/config.xml | 8 ++ dbms/src/Common/Pipe.h | 24 +++--- dbms/src/Common/ShellCommand.cpp | 61 +++----------- dbms/src/Interpreters/Context.cpp | 25 +++++- dbms/src/Interpreters/Context.h | 9 ++- .../Interpreters/InterpreterSystemQuery.cpp | 4 +- dbms/src/Interpreters/SystemLog.cpp | 2 + dbms/src/Interpreters/SystemLog.h | 2 + dbms/src/Interpreters/ThreadStatusExt.cpp | 20 ++--- dbms/src/Interpreters/TraceCollector.cpp | 39 ++++++--- dbms/src/Interpreters/TraceCollector.h | 9 ++- dbms/src/Interpreters/TraceLog.cpp | 42 ++++++++++ dbms/src/Interpreters/TraceLog.h | 25 ++++++ libs/libcommon/CMakeLists.txt | 8 ++ .../cmake/find_unwind.cmake | 0 libs/libcommon/include/common/Backtrace.h | 25 ++++++ .../src/Backtrace.cpp | 74 ++--------------- libs/libdaemon/CMakeLists.txt | 11 +-- libs/libdaemon/include/daemon/Backtrace.h | 80 ------------------- libs/libdaemon/src/BaseDaemon.cpp | 34 +------- 23 files changed, 228 insertions(+), 281 deletions(-) create mode 100644 dbms/src/Interpreters/TraceLog.cpp create mode 100644 dbms/src/Interpreters/TraceLog.h rename libs/{libdaemon => libcommon}/cmake/find_unwind.cmake (100%) create mode 100644 libs/libcommon/include/common/Backtrace.h rename libs/{libdaemon => libcommon}/src/Backtrace.cpp (80%) delete mode 100644 libs/libdaemon/include/daemon/Backtrace.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b0aed779dcf..f2d9e30a954 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -273,7 +273,7 @@ include (libs/libcommon/cmake/find_gperftools.cmake) include (libs/libcommon/cmake/find_jemalloc.cmake) include (libs/libcommon/cmake/find_cctz.cmake) include (libs/libmysqlxx/cmake/find_mysqlclient.cmake) -include (libs/libdaemon/cmake/find_unwind.cmake) +include (libs/libcommon/cmake/find_unwind.cmake) include (cmake/print_flags.cmake) diff --git a/dbms/CMakeLists.txt b/dbms/CMakeLists.txt index 8730d1cb909..90e3679eb2c 100644 --- a/dbms/CMakeLists.txt +++ b/dbms/CMakeLists.txt @@ -131,7 +131,7 @@ list (APPEND dbms_headers list (APPEND dbms_sources src/TableFunctions/ITableFunction.cpp src/TableFunctions/TableFunctionFactory.cpp) list (APPEND dbms_headers src/TableFunctions/ITableFunction.h src/TableFunctions/TableFunctionFactory.h) -add_library(clickhouse_common_io ${LINK_MODE} ${clickhouse_common_io_headers} ${clickhouse_common_io_sources} src/Common/Pipe.h) +add_library(clickhouse_common_io ${LINK_MODE} ${clickhouse_common_io_headers} ${clickhouse_common_io_sources}) if (OS_FREEBSD) target_compile_definitions (clickhouse_common_io PUBLIC CLOCK_MONOTONIC_COARSE=CLOCK_MONOTONIC_FAST) diff --git a/dbms/programs/server/Server.cpp b/dbms/programs/server/Server.cpp index c9147ead965..da139ac8a61 100644 --- a/dbms/programs/server/Server.cpp +++ b/dbms/programs/server/Server.cpp @@ -467,6 +467,9 @@ int Server::main(const std::vector & /*args*/) } LOG_DEBUG(log, "Loaded metadata."); + /// Init trace collector only after trace_log system table was created + global_context->initializeTraceCollector(); + global_context->setCurrentDatabase(default_database); SCOPE_EXIT({ diff --git a/dbms/programs/server/config.xml b/dbms/programs/server/config.xml index 108e64e3387..a30f0a3c11e 100644 --- a/dbms/programs/server/config.xml +++ b/dbms/programs/server/config.xml @@ -291,6 +291,14 @@ 7500 + + system + trace_log
+ + toYYYYMM(event_date) + 7500 +
+ | |-+ | +--> - * +-+-+ | +---+ +-+-+ | +---+ - * | ^ | ^ - * | | | | - * | +-+ | +-+ - * | | | | - * v | v | - * --+---+---+---+-- --+---+---+---+-- - * ... | | B1| | ... | | B2| | ... - * --+---+---+---+-- --+---+---+---+-- - * - * - * The fist and last nodes of buckets can be checked with - * - * first node of a bucket: Npn != N - * last node of a bucket: Nnp != N - * - * (n and p short for ->next(), ->prior(), bucket nodes have prior pointers - * only). Pure insert and erase (without lookup) can be unconditionally done - * in O(1). - * For non-unique indices we add the following additional complexity: when - * there is a group of 3 or more equivalent elements, they are linked as - * follows: - * - * +-----------------------+ - * | v - * +---+ | +---+ +---+ +---+ - * | | +-+ | | |<--+ | - * | F | | S | ... | P | | L | - * | +-->| | | +-+ | | - * +---+ +---+ +---+ | +---+ - * ^ | - * +-----------------------+ - * - * F, S, P and L are the first, second, penultimate and last node in the - * group, respectively (S and P can coincide if the group has size 3.) This - * arrangement is used to skip equivalent elements in O(1) when doing lookup, - * while preserving O(1) insert/erase. The following invariants identify - * special positions (some of the operations have to be carefully implemented - * as Xnn is not valid if Xn points to a bucket): - * - * first node of a bucket: Npnp == N - * last node of a bucket: Nnpp == N - * first node of a group: Nnp != N && Nnppn == N - * second node of a group: Npn != N && Nppnn == N - * n-1 node of a group: Nnp != N && Nnnpp == N - * last node of a group: Npn != N && Npnnp == N - * - * The memory overhead is one pointer per bucket plus two pointers per node, - * probably unbeatable. The resulting structure is bidirectonally traversable, - * though currently we are just providing forward iteration. - */ - -template -struct hashed_index_node_impl; - -/* half-header (only prior() pointer) to use for the bucket array */ - -template -struct hashed_index_base_node_impl -{ - typedef typename - boost::detail::allocator::rebind_to< - Allocator,hashed_index_base_node_impl - >::type::pointer base_pointer; - typedef typename - boost::detail::allocator::rebind_to< - Allocator,hashed_index_base_node_impl - >::type::const_pointer const_base_pointer; - typedef typename - boost::detail::allocator::rebind_to< - Allocator, - hashed_index_node_impl - >::type::pointer pointer; - typedef typename - boost::detail::allocator::rebind_to< - Allocator, - hashed_index_node_impl - >::type::const_pointer const_pointer; - - pointer& prior(){return prior_;} - pointer prior()const{return prior_;} - -private: - pointer prior_; -}; - -/* full header (prior() and next()) for the nodes */ - -template -struct hashed_index_node_impl:hashed_index_base_node_impl -{ -private: - typedef hashed_index_base_node_impl super; - -public: - typedef typename super::base_pointer base_pointer; - typedef typename super::const_base_pointer const_base_pointer; - typedef typename super::pointer pointer; - typedef typename super::const_pointer const_pointer; - - base_pointer& next(){return next_;} - base_pointer next()const{return next_;} - - static pointer pointer_from(base_pointer x) - { - return static_cast( - static_cast( - raw_ptr(x))); - } - - static base_pointer base_pointer_from(pointer x) - { - return static_cast( - raw_ptr(x)); - } - -private: - base_pointer next_; -}; - -/* Boost.MultiIndex requires machinery to reverse unlink operations. A simple - * way to make a pointer-manipulation function undoable is to templatize - * its internal pointer assignments with a functor that, besides doing the - * assignment, keeps track of the original pointer values and can later undo - * the operations in reverse order. - */ - -struct default_assigner -{ - template void operator()(T& x,const T& val){x=val;} -}; - -template -struct unlink_undo_assigner -{ - typedef typename Node::base_pointer base_pointer; - typedef typename Node::pointer pointer; - - unlink_undo_assigner():pointer_track_count(0),base_pointer_track_count(0){} - - void operator()(pointer& x,pointer val) - { - pointer_tracks[pointer_track_count].x=&x; - pointer_tracks[pointer_track_count++].val=x; - x=val; - } - - void operator()(base_pointer& x,base_pointer val) - { - base_pointer_tracks[base_pointer_track_count].x=&x; - base_pointer_tracks[base_pointer_track_count++].val=x; - x=val; - } - - void operator()() /* undo op */ - { - /* in the absence of aliasing, restitution order is immaterial */ - - while(pointer_track_count--){ - *(pointer_tracks[pointer_track_count].x)= - pointer_tracks[pointer_track_count].val; - } - while(base_pointer_track_count--){ - *(base_pointer_tracks[base_pointer_track_count].x)= - base_pointer_tracks[base_pointer_track_count].val; - } - } - - struct pointer_track {pointer* x; pointer val;}; - struct base_pointer_track{base_pointer* x; base_pointer val;}; - - /* We know the maximum number of pointer and base pointer assignments that - * the two unlink versions do, so we can statically reserve the needed - * storage. - */ - - pointer_track pointer_tracks[3]; - int pointer_track_count; - base_pointer_track base_pointer_tracks[2]; - int base_pointer_track_count; -}; - -/* algorithmic stuff for unique and non-unique variants */ - -struct hashed_unique_tag{}; -struct hashed_non_unique_tag{}; - -template -struct hashed_index_node_alg; - -template -struct hashed_index_node_alg -{ - typedef typename Node::base_pointer base_pointer; - typedef typename Node::const_base_pointer const_base_pointer; - typedef typename Node::pointer pointer; - typedef typename Node::const_pointer const_pointer; - - static bool is_first_of_bucket(pointer x) - { - return x->prior()->next()!=base_pointer_from(x); - } - - static pointer after(pointer x) - { - return is_last_of_bucket(x)?x->next()->prior():pointer_from(x->next()); - } - - static pointer after_local(pointer x) - { - return is_last_of_bucket(x)?pointer(0):pointer_from(x->next()); - } - - static pointer next_to_inspect(pointer x) - { - return is_last_of_bucket(x)?pointer(0):pointer_from(x->next()); - } - - static void link(pointer x,base_pointer buc,pointer end) - { - if(buc->prior()==pointer(0)){ /* empty bucket */ - x->prior()=end->prior(); - x->next()=end->prior()->next(); - x->prior()->next()=buc; - buc->prior()=x; - end->prior()=x; - } - else{ - x->prior()=buc->prior()->prior(); - x->next()=base_pointer_from(buc->prior()); - buc->prior()=x; - x->next()->prior()=x; - } - } - - static void unlink(pointer x) - { - default_assigner assign; - unlink(x,assign); - } - - typedef unlink_undo_assigner unlink_undo; - - template - static void unlink(pointer x,Assigner& assign) - { - if(is_first_of_bucket(x)){ - if(is_last_of_bucket(x)){ - assign(x->prior()->next()->prior(),pointer(0)); - assign(x->prior()->next(),x->next()); - assign(x->next()->prior()->prior(),x->prior()); - } - else{ - assign(x->prior()->next()->prior(),pointer_from(x->next())); - assign(x->next()->prior(),x->prior()); - } - } - else if(is_last_of_bucket(x)){ - assign(x->prior()->next(),x->next()); - assign(x->next()->prior()->prior(),x->prior()); - } - else{ - assign(x->prior()->next(),x->next()); - assign(x->next()->prior(),x->prior()); - } - } - - /* used only at rehashing */ - - static void append(pointer x,pointer end) - { - x->prior()=end->prior(); - x->next()=end->prior()->next(); - x->prior()->next()=base_pointer_from(x); - end->prior()=x; - } - - static bool unlink_last(pointer end) - { - /* returns true iff bucket is emptied */ - - pointer x=end->prior(); - if(x->prior()->next()==base_pointer_from(x)){ - x->prior()->next()=x->next(); - end->prior()=x->prior(); - return false; - } - else{ - x->prior()->next()->prior()=pointer(0); - x->prior()->next()=x->next(); - end->prior()=x->prior(); - return true; - } - } - -private: - static pointer pointer_from(base_pointer x) - { - return Node::pointer_from(x); - } - - static base_pointer base_pointer_from(pointer x) - { - return Node::base_pointer_from(x); - } - - static bool is_last_of_bucket(pointer x) - { - return x->next()->prior()!=x; - } -}; - -template -struct hashed_index_node_alg -{ - typedef typename Node::base_pointer base_pointer; - typedef typename Node::const_base_pointer const_base_pointer; - typedef typename Node::pointer pointer; - typedef typename Node::const_pointer const_pointer; - - static bool is_first_of_bucket(pointer x) - { - return x->prior()->next()->prior()==x; - } - - static bool is_first_of_group(pointer x) - { - return - x->next()->prior()!=x&& - x->next()->prior()->prior()->next()==base_pointer_from(x); - } - - static pointer after(pointer x) - { - if(x->next()->prior()==x)return pointer_from(x->next()); - if(x->next()->prior()->prior()==x)return x->next()->prior(); - if(x->next()->prior()->prior()->next()==base_pointer_from(x)) - return pointer_from(x->next()); - return pointer_from(x->next())->next()->prior(); - } - - static pointer after_local(pointer x) - { - if(x->next()->prior()==x)return pointer_from(x->next()); - if(x->next()->prior()->prior()==x)return pointer(0); - if(x->next()->prior()->prior()->next()==base_pointer_from(x)) - return pointer_from(x->next()); - return pointer_from(x->next())->next()->prior(); - } - - static pointer next_to_inspect(pointer x) - { - if(x->next()->prior()==x)return pointer_from(x->next()); - if(x->next()->prior()->prior()==x)return pointer(0); - if(x->next()->prior()->next()->prior()!=x->next()->prior()) - return pointer(0); - return pointer_from(x->next()->prior()->next()); - } - - static void link(pointer x,base_pointer buc,pointer end) - { - if(buc->prior()==pointer(0)){ /* empty bucket */ - x->prior()=end->prior(); - x->next()=end->prior()->next(); - x->prior()->next()=buc; - buc->prior()=x; - end->prior()=x; - } - else{ - x->prior()=buc->prior()->prior(); - x->next()=base_pointer_from(buc->prior()); - buc->prior()=x; - x->next()->prior()=x; - } - }; - - static void link(pointer x,pointer first,pointer last) - { - x->prior()=first->prior(); - x->next()=base_pointer_from(first); - if(is_first_of_bucket(first)){ - x->prior()->next()->prior()=x; - } - else{ - x->prior()->next()=base_pointer_from(x); - } - - if(first==last){ - last->prior()=x; - } - else if(first->next()==base_pointer_from(last)){ - first->prior()=last; - first->next()=base_pointer_from(x); - } - else{ - pointer second=pointer_from(first->next()), - lastbutone=last->prior(); - second->prior()=first; - first->prior()=last; - lastbutone->next()=base_pointer_from(x); - } - } - - static void unlink(pointer x) - { - default_assigner assign; - unlink(x,assign); - } - - typedef unlink_undo_assigner unlink_undo; - - template - static void unlink(pointer x,Assigner& assign) - { - if(x->prior()->next()==base_pointer_from(x)){ - if(x->next()->prior()==x){ - left_unlink(x,assign); - right_unlink(x,assign); - } - else if(x->next()->prior()->prior()==x){ /* last of bucket */ - left_unlink(x,assign); - right_unlink_last_of_bucket(x,assign); - } - else if(x->next()->prior()->prior()->next()== - base_pointer_from(x)){ /* first of group size */ - left_unlink(x,assign); - right_unlink_first_of_group(x,assign); - } - else{ /* n-1 of group */ - unlink_last_but_one_of_group(x,assign); - } - } - else if(x->prior()->next()->prior()==x){ /* first of bucket */ - if(x->next()->prior()==x){ - left_unlink_first_of_bucket(x,assign); - right_unlink(x,assign); - } - else if(x->next()->prior()->prior()==x){ /* last of bucket */ - assign(x->prior()->next()->prior(),pointer(0)); - assign(x->prior()->next(),x->next()); - assign(x->next()->prior()->prior(),x->prior()); - } - else{ /* first of group */ - left_unlink_first_of_bucket(x,assign); - right_unlink_first_of_group(x,assign); - } - } - else if(x->next()->prior()->prior()==x){ /* last of group and bucket */ - left_unlink_last_of_group(x,assign); - right_unlink_last_of_bucket(x,assign); - } - else if(pointer_from(x->prior()->prior()->next()) - ->next()==base_pointer_from(x)){ /* second of group */ - unlink_second_of_group(x,assign); - } - else{ /* last of group, ~(last of bucket) */ - left_unlink_last_of_group(x,assign); - right_unlink(x,assign); - } - } - - /* used only at rehashing */ - - static void link_range( - pointer first,pointer last,base_pointer buc,pointer cend) - { - if(buc->prior()==pointer(0)){ /* empty bucket */ - first->prior()=cend->prior(); - last->next()=cend->prior()->next(); - first->prior()->next()=buc; - buc->prior()=first; - cend->prior()=last; - } - else{ - first->prior()=buc->prior()->prior(); - last->next()=base_pointer_from(buc->prior()); - buc->prior()=first; - last->next()->prior()=last; - } - } - - static void append_range(pointer first,pointer last,pointer cend) - { - first->prior()=cend->prior(); - last->next()=cend->prior()->next(); - first->prior()->next()=base_pointer_from(first); - cend->prior()=last; - } - - static std::pair unlink_last_group(pointer end) - { - /* returns first of group true iff bucket is emptied */ - - pointer x=end->prior(); - if(x->prior()->next()==base_pointer_from(x)){ - x->prior()->next()=x->next(); - end->prior()=x->prior(); - return std::make_pair(x,false); - } - else if(x->prior()->next()->prior()==x){ - x->prior()->next()->prior()=pointer(0); - x->prior()->next()=x->next(); - end->prior()=x->prior(); - return std::make_pair(x,true); - } - else{ - pointer y=pointer_from(x->prior()->next()); - - if(y->prior()->next()==base_pointer_from(y)){ - y->prior()->next()=x->next(); - end->prior()=y->prior(); - return std::make_pair(y,false); - } - else{ - y->prior()->next()->prior()=pointer(0); - y->prior()->next()=x->next(); - end->prior()=y->prior(); - return std::make_pair(y,true); - } - } - } - - static void unlink_range(pointer first,pointer last) - { - if(is_first_of_bucket(first)){ - if(is_last_of_bucket(last)){ - first->prior()->next()->prior()=pointer(0); - first->prior()->next()=last->next(); - last->next()->prior()->prior()=first->prior(); - } - else{ - first->prior()->next()->prior()=pointer_from(last->next()); - last->next()->prior()=first->prior(); - } - } - else if(is_last_of_bucket(last)){ - first->prior()->next()=last->next(); - last->next()->prior()->prior()=first->prior(); - } - else{ - first->prior()->next()=last->next(); - last->next()->prior()=first->prior(); - } - } - -private: - static pointer pointer_from(base_pointer x) - { - return Node::pointer_from(x); - } - - static base_pointer base_pointer_from(pointer x) - { - return Node::base_pointer_from(x); - } - - static bool is_last_of_bucket(pointer x) - { - return x->next()->prior()->prior()==x; - } - - template - static void left_unlink(pointer x,Assigner& assign) - { - assign(x->prior()->next(),x->next()); - } - - template - static void right_unlink(pointer x,Assigner& assign) - { - assign(x->next()->prior(),x->prior()); - } - - template - static void left_unlink_first_of_bucket(pointer x,Assigner& assign) - { - assign(x->prior()->next()->prior(),pointer_from(x->next())); - } - - template - static void right_unlink_last_of_bucket(pointer x,Assigner& assign) - { - assign(x->next()->prior()->prior(),x->prior()); - } - - template - static void right_unlink_first_of_group(pointer x,Assigner& assign) - { - pointer second=pointer_from(x->next()), - last=second->prior(), - lastbutone=last->prior(); - if(second==lastbutone){ - assign(second->next(),base_pointer_from(last)); - assign(second->prior(),x->prior()); - } - else{ - assign(lastbutone->next(),base_pointer_from(second)); - assign(second->next()->prior(),last); - assign(second->prior(),x->prior()); - } - } - - template - static void left_unlink_last_of_group(pointer x,Assigner& assign) - { - pointer lastbutone=x->prior(), - first=pointer_from(lastbutone->next()), - second=pointer_from(first->next()); - if(lastbutone==second){ - assign(lastbutone->prior(),first); - assign(lastbutone->next(),x->next()); - } - else{ - assign(second->prior(),lastbutone); - assign(lastbutone->prior()->next(),base_pointer_from(first)); - assign(lastbutone->next(),x->next()); - } - } - - template - static void unlink_last_but_one_of_group(pointer x,Assigner& assign) - { - pointer first=pointer_from(x->next()), - second=pointer_from(first->next()), - last=second->prior(); - if(second==x){ - assign(last->prior(),first); - assign(first->next(),base_pointer_from(last)); - } - else{ - assign(last->prior(),x->prior()); - assign(x->prior()->next(),base_pointer_from(first)); - } - } - - template - static void unlink_second_of_group(pointer x,Assigner& assign) - { - pointer last=x->prior(), - lastbutone=last->prior(), - first=pointer_from(lastbutone->next()); - if(lastbutone==x){ - assign(first->next(),base_pointer_from(last)); - assign(last->prior(),first); - } - else{ - assign(first->next(),x->next()); - assign(x->next()->prior(),last); - } - } -}; - -template -struct hashed_index_node_trampoline: - hashed_index_node_impl< - typename boost::detail::allocator::rebind_to< - typename Super::allocator_type, - char - >::type - > -{ - typedef typename boost::detail::allocator::rebind_to< - typename Super::allocator_type, - char - >::type impl_allocator_type; - typedef hashed_index_node_impl impl_type; -}; - -template -struct hashed_index_node: - Super,hashed_index_node_trampoline -{ -private: - typedef hashed_index_node_trampoline trampoline; - -public: - typedef typename trampoline::impl_type impl_type; - typedef hashed_index_node_alg< - impl_type,Category> node_alg; - typedef typename trampoline::base_pointer impl_base_pointer; - typedef typename trampoline::const_base_pointer const_impl_base_pointer; - typedef typename trampoline::pointer impl_pointer; - typedef typename trampoline::const_pointer const_impl_pointer; - - impl_pointer& prior(){return trampoline::prior();} - impl_pointer prior()const{return trampoline::prior();} - impl_base_pointer& next(){return trampoline::next();} - impl_base_pointer next()const{return trampoline::next();} - - impl_pointer impl() - { - return static_cast( - static_cast(static_cast(this))); - } - - const_impl_pointer impl()const - { - return static_cast( - static_cast(static_cast(this))); - } - - static hashed_index_node* from_impl(impl_pointer x) - { - return - static_cast( - static_cast( - raw_ptr(x))); - } - - static const hashed_index_node* from_impl(const_impl_pointer x) - { - return - static_cast( - static_cast( - raw_ptr(x))); - } - - /* interoperability with hashed_index_iterator */ - - static void increment(hashed_index_node*& x) - { - x=from_impl(node_alg::after(x->impl())); - } - - static void increment_local(hashed_index_node*& x) - { - x=from_impl(node_alg::after_local(x->impl())); - } -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/header_holder.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/header_holder.hpp deleted file mode 100644 index ca8a9b2edb1..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/header_holder.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright 2003-2008 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_HEADER_HOLDER_HPP -#define BOOST_MULTI_INDEX_DETAIL_HEADER_HOLDER_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* A utility class used to hold a pointer to the header node. - * The base from member idiom is used because index classes, which are - * superclasses of multi_index_container, need this header in construction - * time. The allocation is made by the allocator of the multi_index_container - * class --hence, this allocator needs also be stored resorting - * to the base from member trick. - */ - -template -struct header_holder:private noncopyable -{ - header_holder():member(final().allocate_node()){} - ~header_holder(){final().deallocate_node(&*member);} - - NodeTypePtr member; - -private: - Final& final(){return *static_cast(this);} -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ignore_wstrict_aliasing.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ignore_wstrict_aliasing.hpp deleted file mode 100644 index ae398456d1f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ignore_wstrict_aliasing.hpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright 2003-2016 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#include - -#if defined(BOOST_GCC)&&(BOOST_GCC>=4*10000+6*100) -#if !defined(BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wstrict-aliasing" -#else -#pragma GCC diagnostic pop -#endif -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_base.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_base.hpp deleted file mode 100644 index 99000ed4813..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_base.hpp +++ /dev/null @@ -1,293 +0,0 @@ -/* Copyright 2003-2014 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP -#define BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#include -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* The role of this class is threefold: - * - tops the linear hierarchy of indices. - * - terminates some cascading backbone function calls (insert_, etc.), - * - grants access to the backbone functions of the final - * multi_index_container class (for access restriction reasons, these - * cannot be called directly from the index classes.) - */ - -struct lvalue_tag{}; -struct rvalue_tag{}; -struct emplaced_tag{}; - -template -class index_base -{ -protected: - typedef index_node_base node_type; - typedef typename multi_index_node_type< - Value,IndexSpecifierList,Allocator>::type final_node_type; - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> final_type; - typedef tuples::null_type ctor_args_list; - typedef typename - boost::detail::allocator::rebind_to< - Allocator, - typename Allocator::value_type - >::type final_allocator_type; - typedef mpl::vector0<> index_type_list; - typedef mpl::vector0<> iterator_type_list; - typedef mpl::vector0<> const_iterator_type_list; - typedef copy_map< - final_node_type, - final_allocator_type> copy_map_type; - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - typedef index_saver< - node_type, - final_allocator_type> index_saver_type; - typedef index_loader< - node_type, - final_node_type, - final_allocator_type> index_loader_type; -#endif - -private: - typedef Value value_type; - -protected: - explicit index_base(const ctor_args_list&,const Allocator&){} - - index_base( - const index_base&, - do_not_copy_elements_tag) - {} - - void copy_( - const index_base&,const copy_map_type&) - {} - - final_node_type* insert_(const value_type& v,final_node_type*& x,lvalue_tag) - { - x=final().allocate_node(); - BOOST_TRY{ - boost::detail::allocator::construct(&x->value(),v); - } - BOOST_CATCH(...){ - final().deallocate_node(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - return x; - } - - final_node_type* insert_(const value_type& v,final_node_type*& x,rvalue_tag) - { - x=final().allocate_node(); - BOOST_TRY{ - /* This shoud have used a modified, T&&-compatible version of - * boost::detail::allocator::construct, but - * is too old and venerable to - * mess with; besides, it is a general internal utility and the imperfect - * perfect forwarding emulation of Boost.Move might break other libs. - */ - - new (&x->value()) value_type(boost::move(const_cast(v))); - } - BOOST_CATCH(...){ - final().deallocate_node(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - return x; - } - - final_node_type* insert_(const value_type&,final_node_type*& x,emplaced_tag) - { - return x; - } - - final_node_type* insert_( - const value_type& v,node_type*,final_node_type*& x,lvalue_tag) - { - return insert_(v,x,lvalue_tag()); - } - - final_node_type* insert_( - const value_type& v,node_type*,final_node_type*& x,rvalue_tag) - { - return insert_(v,x,rvalue_tag()); - } - - final_node_type* insert_( - const value_type&,node_type*,final_node_type*& x,emplaced_tag) - { - return x; - } - - void erase_(node_type* x) - { - boost::detail::allocator::destroy(&x->value()); - } - - void delete_node_(node_type* x) - { - boost::detail::allocator::destroy(&x->value()); - } - - void clear_(){} - - void swap_(index_base&){} - - void swap_elements_(index_base&){} - - bool replace_(const value_type& v,node_type* x,lvalue_tag) - { - x->value()=v; - return true; - } - - bool replace_(const value_type& v,node_type* x,rvalue_tag) - { - x->value()=boost::move(const_cast(v)); - return true; - } - - bool modify_(node_type*){return true;} - - bool modify_rollback_(node_type*){return true;} - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* serialization */ - - template - void save_(Archive&,const unsigned int,const index_saver_type&)const{} - - template - void load_(Archive&,const unsigned int,const index_loader_type&){} -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - bool invariant_()const{return true;} -#endif - - /* access to backbone memfuns of Final class */ - - final_type& final(){return *static_cast(this);} - const final_type& final()const{return *static_cast(this);} - - final_node_type* final_header()const{return final().header();} - - bool final_empty_()const{return final().empty_();} - std::size_t final_size_()const{return final().size_();} - std::size_t final_max_size_()const{return final().max_size_();} - - std::pair final_insert_(const value_type& x) - {return final().insert_(x);} - std::pair final_insert_rv_(const value_type& x) - {return final().insert_rv_(x);} - template - std::pair final_insert_ref_(const T& t) - {return final().insert_ref_(t);} - template - std::pair final_insert_ref_(T& t) - {return final().insert_ref_(t);} - - template - std::pair final_emplace_( - BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - return final().emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - } - - std::pair final_insert_( - const value_type& x,final_node_type* position) - {return final().insert_(x,position);} - std::pair final_insert_rv_( - const value_type& x,final_node_type* position) - {return final().insert_rv_(x,position);} - template - std::pair final_insert_ref_( - const T& t,final_node_type* position) - {return final().insert_ref_(t,position);} - template - std::pair final_insert_ref_( - T& t,final_node_type* position) - {return final().insert_ref_(t,position);} - - template - std::pair final_emplace_hint_( - final_node_type* position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - return final().emplace_hint_( - position,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - } - - void final_erase_(final_node_type* x){final().erase_(x);} - - void final_delete_node_(final_node_type* x){final().delete_node_(x);} - void final_delete_all_nodes_(){final().delete_all_nodes_();} - void final_clear_(){final().clear_();} - - void final_swap_(final_type& x){final().swap_(x);} - - bool final_replace_( - const value_type& k,final_node_type* x) - {return final().replace_(k,x);} - bool final_replace_rv_( - const value_type& k,final_node_type* x) - {return final().replace_rv_(k,x);} - - template - bool final_modify_(Modifier& mod,final_node_type* x) - {return final().modify_(mod,x);} - - template - bool final_modify_(Modifier& mod,Rollback& back,final_node_type* x) - {return final().modify_(mod,back,x);} - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - void final_check_invariant_()const{final().check_invariant_();} -#endif -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_loader.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_loader.hpp deleted file mode 100644 index 71418a10e19..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_loader.hpp +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP -#define BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Counterpart of index_saver (check index_saver.hpp for serialization - * details.)* multi_index_container is in charge of supplying the info about - * the base sequence, and each index can subsequently load itself using the - * const interface of index_loader. - */ - -template -class index_loader:private noncopyable -{ -public: - index_loader(const Allocator& al,std::size_t size): - spc(al,size),size_(size),n(0),sorted(false) - { - } - - template - void add(Node* node,Archive& ar,const unsigned int) - { - ar>>serialization::make_nvp("position",*node); - entries()[n++]=node; - } - - template - void add_track(Node* node,Archive& ar,const unsigned int) - { - ar>>serialization::make_nvp("position",*node); - } - - /* A rearranger is passed two nodes, and is expected to - * reposition the second after the first. - * If the first node is 0, then the second should be moved - * to the beginning of the sequence. - */ - - template - void load(Rearranger r,Archive& ar,const unsigned int)const - { - FinalNode* prev=unchecked_load_node(ar); - if(!prev)return; - - if(!sorted){ - std::sort(entries(),entries()+size_); - sorted=true; - } - - check_node(prev); - - for(;;){ - for(;;){ - FinalNode* node=load_node(ar); - if(!node)break; - - if(node==prev)prev=0; - r(prev,node); - - prev=node; - } - prev=load_node(ar); - if(!prev)break; - } - } - -private: - Node** entries()const{return raw_ptr(spc.data());} - - /* We try to delay sorting as much as possible just in case it - * is not necessary, hence this version of load_node. - */ - - template - FinalNode* unchecked_load_node(Archive& ar)const - { - Node* node=0; - ar>>serialization::make_nvp("pointer",node); - return static_cast(node); - } - - template - FinalNode* load_node(Archive& ar)const - { - Node* node=0; - ar>>serialization::make_nvp("pointer",node); - check_node(node); - return static_cast(node); - } - - void check_node(Node* node)const - { - if(node!=0&&!std::binary_search(entries(),entries()+size_,node)){ - throw_exception( - archive::archive_exception( - archive::archive_exception::other_exception)); - } - } - - auto_space spc; - std::size_t size_; - std::size_t n; - mutable bool sorted; -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_matcher.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_matcher.hpp deleted file mode 100644 index 34d1f9d5a8d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_matcher.hpp +++ /dev/null @@ -1,249 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_MATCHER_HPP -#define BOOST_MULTI_INDEX_DETAIL_INDEX_MATCHER_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* index_matcher compares a sequence of elements against a - * base sequence, identifying those elements that belong to the - * longest subsequence which is ordered with respect to the base. - * For instance, if the base sequence is: - * - * 0 1 2 3 4 5 6 7 8 9 - * - * and the compared sequence (not necesarilly the same length): - * - * 1 4 2 3 0 7 8 9 - * - * the elements of the longest ordered subsequence are: - * - * 1 2 3 7 8 9 - * - * The algorithm for obtaining such a subsequence is called - * Patience Sorting, described in ch. 1 of: - * Aldous, D., Diaconis, P.: "Longest increasing subsequences: from - * patience sorting to the Baik-Deift-Johansson Theorem", Bulletin - * of the American Mathematical Society, vol. 36, no 4, pp. 413-432, - * July 1999. - * http://www.ams.org/bull/1999-36-04/S0273-0979-99-00796-X/ - * S0273-0979-99-00796-X.pdf - * - * This implementation is not fully generic since it assumes that - * the sequences given are pointed to by index iterators (having a - * get_node() memfun.) - */ - -namespace index_matcher{ - -/* The algorithm stores the nodes of the base sequence and a number - * of "piles" that are dynamically updated during the calculation - * stage. From a logical point of view, nodes form an independent - * sequence from piles. They are stored together so as to minimize - * allocated memory. - */ - -struct entry -{ - entry(void* node_,std::size_t pos_=0):node(node_),pos(pos_){} - - /* node stuff */ - - void* node; - std::size_t pos; - entry* previous; - bool ordered; - - struct less_by_node - { - bool operator()( - const entry& x,const entry& y)const - { - return std::less()(x.node,y.node); - } - }; - - /* pile stuff */ - - std::size_t pile_top; - entry* pile_top_entry; - - struct less_by_pile_top - { - bool operator()( - const entry& x,const entry& y)const - { - return x.pile_top -class algorithm_base:private noncopyable -{ -protected: - algorithm_base(const Allocator& al,std::size_t size): - spc(al,size),size_(size),n_(0),sorted(false) - { - } - - void add(void* node) - { - entries()[n_]=entry(node,n_); - ++n_; - } - - void begin_algorithm()const - { - if(!sorted){ - std::sort(entries(),entries()+size_,entry::less_by_node()); - sorted=true; - } - num_piles=0; - } - - void add_node_to_algorithm(void* node)const - { - entry* ent= - std::lower_bound( - entries(),entries()+size_, - entry(node),entry::less_by_node()); /* localize entry */ - ent->ordered=false; - std::size_t n=ent->pos; /* get its position */ - - entry dummy(0); - dummy.pile_top=n; - - entry* pile_ent= /* find the first available pile */ - std::lower_bound( /* to stack the entry */ - entries(),entries()+num_piles, - dummy,entry::less_by_pile_top()); - - pile_ent->pile_top=n; /* stack the entry */ - pile_ent->pile_top_entry=ent; - - /* if not the first pile, link entry to top of the preceding pile */ - if(pile_ent>&entries()[0]){ - ent->previous=(pile_ent-1)->pile_top_entry; - } - - if(pile_ent==&entries()[num_piles]){ /* new pile? */ - ++num_piles; - } - } - - void finish_algorithm()const - { - if(num_piles>0){ - /* Mark those elements which are in their correct position, i.e. those - * belonging to the longest increasing subsequence. These are those - * elements linked from the top of the last pile. - */ - - entry* ent=entries()[num_piles-1].pile_top_entry; - for(std::size_t n=num_piles;n--;){ - ent->ordered=true; - ent=ent->previous; - } - } - } - - bool is_ordered(void * node)const - { - return std::lower_bound( - entries(),entries()+size_, - entry(node),entry::less_by_node())->ordered; - } - -private: - entry* entries()const{return raw_ptr(spc.data());} - - auto_space spc; - std::size_t size_; - std::size_t n_; - mutable bool sorted; - mutable std::size_t num_piles; -}; - -/* The algorithm has three phases: - * - Initialization, during which the nodes of the base sequence are added. - * - Execution. - * - Results querying, through the is_ordered memfun. - */ - -template -class algorithm:private algorithm_base -{ - typedef algorithm_base super; - -public: - algorithm(const Allocator& al,std::size_t size):super(al,size){} - - void add(Node* node) - { - super::add(node); - } - - template - void execute(IndexIterator first,IndexIterator last)const - { - super::begin_algorithm(); - - for(IndexIterator it=first;it!=last;++it){ - add_node_to_algorithm(get_node(it)); - } - - super::finish_algorithm(); - } - - bool is_ordered(Node* node)const - { - return super::is_ordered(node); - } - -private: - void add_node_to_algorithm(Node* node)const - { - super::add_node_to_algorithm(node); - } - - template - static Node* get_node(IndexIterator it) - { - return static_cast(it.get_node()); - } -}; - -} /* namespace multi_index::detail::index_matcher */ - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_node_base.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_node_base.hpp deleted file mode 100644 index 1a1f0cae4be..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_node_base.hpp +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright 2003-2016 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_NODE_BASE_HPP -#define BOOST_MULTI_INDEX_DETAIL_INDEX_NODE_BASE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#include -#include -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* index_node_base tops the node hierarchy of multi_index_container. It holds - * the value of the element contained. - */ - -template -struct pod_value_holder -{ - typename aligned_storage< - sizeof(Value), - alignment_of::value - >::type space; -}; - -template -struct index_node_base:private pod_value_holder -{ - typedef index_node_base base_type; /* used for serialization purposes */ - typedef Value value_type; - typedef Allocator allocator_type; - -#include - - value_type& value() - { - return *reinterpret_cast(&this->space); - } - - const value_type& value()const - { - return *reinterpret_cast(&this->space); - } - -#include - - static index_node_base* from_value(const value_type* p) - { - return static_cast( - reinterpret_cast*>( /* std 9.2.17 */ - const_cast(p))); - } - -private: -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - friend class boost::serialization::access; - - /* nodes do not emit any kind of serialization info. They are - * fed to Boost.Serialization so that pointers to nodes are - * tracked correctly. - */ - - template - void serialize(Archive&,const unsigned int) - { - } -#endif -}; - -template -Node* node_from_value(const Value* p) -{ - typedef typename Node::allocator_type allocator_type; - return static_cast( - index_node_base::from_value(p)); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -/* Index nodes never get constructed directly by Boost.Serialization, - * as archives are always fed pointers to previously existent - * nodes. So, if this is called it means we are dealing with a - * somehow invalid archive. - */ - -#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) -namespace serialization{ -#else -namespace multi_index{ -namespace detail{ -#endif - -template -inline void load_construct_data( - Archive&,boost::multi_index::detail::index_node_base*, - const unsigned int) -{ - throw_exception( - archive::archive_exception(archive::archive_exception::other_exception)); -} - -#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) -} /* namespace serialization */ -#else -} /* namespace multi_index::detail */ -} /* namespace multi_index */ -#endif - -#endif - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_saver.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_saver.hpp deleted file mode 100644 index ae09d4eba4f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_saver.hpp +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP -#define BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* index_saver accepts a base sequence of previously saved elements - * and saves a possibly reordered subsequence in an efficient manner, - * serializing only the information needed to rearrange the subsequence - * based on the original order of the base. - * multi_index_container is in charge of supplying the info about the - * base sequence, and each index can subsequently save itself using the - * const interface of index_saver. - */ - -template -class index_saver:private noncopyable -{ -public: - index_saver(const Allocator& al,std::size_t size):alg(al,size){} - - template - void add(Node* node,Archive& ar,const unsigned int) - { - ar< - void add_track(Node* node,Archive& ar,const unsigned int) - { - ar< - void save( - IndexIterator first,IndexIterator last,Archive& ar, - const unsigned int)const - { - /* calculate ordered positions */ - - alg.execute(first,last); - - /* Given a consecutive subsequence of displaced elements - * x1,...,xn, the following information is serialized: - * - * p0,p1,...,pn,0 - * - * where pi is a pointer to xi and p0 is a pointer to the element - * preceding x1. Crealy, from this information is possible to - * restore the original order on loading time. If x1 is the first - * element in the sequence, the following is serialized instead: - * - * p1,p1,...,pn,0 - * - * For each subsequence of n elements, n+2 pointers are serialized. - * An optimization policy is applied: consider for instance the - * sequence - * - * a,B,c,D - * - * where B and D are displaced, but c is in its correct position. - * Applying the schema described above we would serialize 6 pointers: - * - * p(a),p(B),0 - * p(c),p(D),0 - * - * but this can be reduced to 5 pointers by treating c as a displaced - * element: - * - * p(a),p(B),p(c),p(D),0 - */ - - std::size_t last_saved=3; /* distance to last pointer saved */ - for(IndexIterator it=first,prev=first;it!=last;prev=it++,++last_saved){ - if(!alg.is_ordered(get_node(it))){ - if(last_saved>1)save_node(get_node(prev),ar); - save_node(get_node(it),ar); - last_saved=0; - } - else if(last_saved==2)save_node(null_node(),ar); - } - if(last_saved<=2)save_node(null_node(),ar); - - /* marks the end of the serialization info for [first,last) */ - - save_node(null_node(),ar); - } - -private: - template - static Node* get_node(IndexIterator it) - { - return it.get_node(); - } - - static Node* null_node(){return 0;} - - template - static void save_node(Node* node,Archive& ar) - { - ar< alg; -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/invariant_assert.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/invariant_assert.hpp deleted file mode 100644 index c6c547c7c33..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/invariant_assert.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_INVARIANT_ASSERT_HPP -#define BOOST_MULTI_INDEX_DETAIL_INVARIANT_ASSERT_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#if !defined(BOOST_MULTI_INDEX_INVARIANT_ASSERT) -#include -#define BOOST_MULTI_INDEX_INVARIANT_ASSERT BOOST_ASSERT -#endif - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_index_list.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_index_list.hpp deleted file mode 100644 index f6a24218b81..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_index_list.hpp +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_IS_INDEX_LIST_HPP -#define BOOST_MULTI_INDEX_DETAIL_IS_INDEX_LIST_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template -struct is_index_list -{ - BOOST_STATIC_CONSTANT(bool,mpl_sequence=mpl::is_sequence::value); - BOOST_STATIC_CONSTANT(bool,non_empty=!mpl::empty::value); - BOOST_STATIC_CONSTANT(bool,value=mpl_sequence&&non_empty); -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_transparent.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_transparent.hpp deleted file mode 100644 index 72036d257e2..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_transparent.hpp +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright 2003-2014 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_IS_TRANSPARENT_HPP -#define BOOST_MULTI_INDEX_DETAIL_IS_TRANSPARENT_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Metafunction that checks if f(arg,arg2) executes without argument type - * conversion. By default (i.e. when it cannot be determined) it evaluates to - * true. - */ - -template -struct is_transparent:mpl::true_{}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#if !defined(BOOST_NO_SFINAE)&&!defined(BOOST_NO_SFINAE_EXPR)&& \ - !defined(BOOST_NO_CXX11_DECLTYPE)&& \ - (defined(BOOST_NO_CXX11_FINAL)||defined(BOOST_IS_FINAL)) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -struct not_is_transparent_result_type{}; - -template -struct is_transparent_class_helper:F -{ - using F::operator(); - template - not_is_transparent_result_type operator()(const T&,const Q&)const; -}; - -template -struct is_transparent_class:mpl::true_{}; - -template -struct is_transparent_class< - F,Arg1,Arg2, - typename enable_if< - is_same< - decltype( - declval >()( - declval(),declval()) - ), - not_is_transparent_result_type - > - >::type ->:mpl::false_{}; - -template -struct is_transparent< - F,Arg1,Arg2, - typename enable_if< - mpl::and_< - is_class, - mpl::not_ > /* is_transparent_class_helper derives from F */ - > - >::type ->:is_transparent_class{}; - -template -struct is_transparent_function:mpl::true_{}; - -template -struct is_transparent_function< - F,Arg1,Arg2, - typename enable_if< - mpl::or_< - mpl::not_::arg1_type,const Arg1&>, - is_same::arg1_type,Arg1> - > >, - mpl::not_::arg2_type,const Arg2&>, - is_same::arg2_type,Arg2> - > > - > - >::type ->:mpl::false_{}; - -template -struct is_transparent< - F,Arg1,Arg2, - typename enable_if< - is_function::type> - >::type ->:is_transparent_function::type,Arg1,Arg2>{}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/iter_adaptor.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/iter_adaptor.hpp deleted file mode 100644 index 7a032350b36..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/iter_adaptor.hpp +++ /dev/null @@ -1,321 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP -#define BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Poor man's version of boost::iterator_adaptor. Used instead of the - * original as compile times for the latter are significantly higher. - * The interface is not replicated exactly, only to the extent necessary - * for internal consumption. - */ - -/* NB. The purpose of the (non-inclass) global operators ==, < and - defined - * above is to partially alleviate a problem of MSVC++ 6.0 by * which - * friend-injected operators on T are not visible if T is instantiated only - * in template code where T is a dependent type. - */ - -class iter_adaptor_access -{ -public: - template - static typename Class::reference dereference(const Class& x) - { - return x.dereference(); - } - - template - static bool equal(const Class& x,const Class& y) - { - return x.equal(y); - } - - template - static void increment(Class& x) - { - x.increment(); - } - - template - static void decrement(Class& x) - { - x.decrement(); - } - - template - static void advance(Class& x,typename Class::difference_type n) - { - x.advance(n); - } - - template - static typename Class::difference_type distance_to( - const Class& x,const Class& y) - { - return x.distance_to(y); - } -}; - -template -struct iter_adaptor_selector; - -template -class forward_iter_adaptor_base: - public forward_iterator_helper< - Derived, - typename Base::value_type, - typename Base::difference_type, - typename Base::pointer, - typename Base::reference> -{ -public: - typedef typename Base::reference reference; - - reference operator*()const - { - return iter_adaptor_access::dereference(final()); - } - - friend bool operator==(const Derived& x,const Derived& y) - { - return iter_adaptor_access::equal(x,y); - } - - Derived& operator++() - { - iter_adaptor_access::increment(final()); - return final(); - } - -private: - Derived& final(){return *static_cast(this);} - const Derived& final()const{return *static_cast(this);} -}; - -template -bool operator==( - const forward_iter_adaptor_base& x, - const forward_iter_adaptor_base& y) -{ - return iter_adaptor_access::equal( - static_cast(x),static_cast(y)); -} - -template<> -struct iter_adaptor_selector -{ - template - struct apply - { - typedef forward_iter_adaptor_base type; - }; -}; - -template -class bidirectional_iter_adaptor_base: - public bidirectional_iterator_helper< - Derived, - typename Base::value_type, - typename Base::difference_type, - typename Base::pointer, - typename Base::reference> -{ -public: - typedef typename Base::reference reference; - - reference operator*()const - { - return iter_adaptor_access::dereference(final()); - } - - friend bool operator==(const Derived& x,const Derived& y) - { - return iter_adaptor_access::equal(x,y); - } - - Derived& operator++() - { - iter_adaptor_access::increment(final()); - return final(); - } - - Derived& operator--() - { - iter_adaptor_access::decrement(final()); - return final(); - } - -private: - Derived& final(){return *static_cast(this);} - const Derived& final()const{return *static_cast(this);} -}; - -template -bool operator==( - const bidirectional_iter_adaptor_base& x, - const bidirectional_iter_adaptor_base& y) -{ - return iter_adaptor_access::equal( - static_cast(x),static_cast(y)); -} - -template<> -struct iter_adaptor_selector -{ - template - struct apply - { - typedef bidirectional_iter_adaptor_base type; - }; -}; - -template -class random_access_iter_adaptor_base: - public random_access_iterator_helper< - Derived, - typename Base::value_type, - typename Base::difference_type, - typename Base::pointer, - typename Base::reference> -{ -public: - typedef typename Base::reference reference; - typedef typename Base::difference_type difference_type; - - reference operator*()const - { - return iter_adaptor_access::dereference(final()); - } - - friend bool operator==(const Derived& x,const Derived& y) - { - return iter_adaptor_access::equal(x,y); - } - - friend bool operator<(const Derived& x,const Derived& y) - { - return iter_adaptor_access::distance_to(x,y)>0; - } - - Derived& operator++() - { - iter_adaptor_access::increment(final()); - return final(); - } - - Derived& operator--() - { - iter_adaptor_access::decrement(final()); - return final(); - } - - Derived& operator+=(difference_type n) - { - iter_adaptor_access::advance(final(),n); - return final(); - } - - Derived& operator-=(difference_type n) - { - iter_adaptor_access::advance(final(),-n); - return final(); - } - - friend difference_type operator-(const Derived& x,const Derived& y) - { - return iter_adaptor_access::distance_to(y,x); - } - -private: - Derived& final(){return *static_cast(this);} - const Derived& final()const{return *static_cast(this);} -}; - -template -bool operator==( - const random_access_iter_adaptor_base& x, - const random_access_iter_adaptor_base& y) -{ - return iter_adaptor_access::equal( - static_cast(x),static_cast(y)); -} - -template -bool operator<( - const random_access_iter_adaptor_base& x, - const random_access_iter_adaptor_base& y) -{ - return iter_adaptor_access::distance_to( - static_cast(x),static_cast(y))>0; -} - -template -typename random_access_iter_adaptor_base::difference_type -operator-( - const random_access_iter_adaptor_base& x, - const random_access_iter_adaptor_base& y) -{ - return iter_adaptor_access::distance_to( - static_cast(y),static_cast(x)); -} - -template<> -struct iter_adaptor_selector -{ - template - struct apply - { - typedef random_access_iter_adaptor_base type; - }; -}; - -template -struct iter_adaptor_base -{ - typedef iter_adaptor_selector< - typename Base::iterator_category> selector; - typedef typename mpl::apply2< - selector,Derived,Base>::type type; -}; - -template -class iter_adaptor:public iter_adaptor_base::type -{ -protected: - iter_adaptor(){} - explicit iter_adaptor(const Base& b_):b(b_){} - - const Base& base_reference()const{return b;} - Base& base_reference(){return b;} - -private: - Base b; -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/modify_key_adaptor.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/modify_key_adaptor.hpp deleted file mode 100644 index 6df89b18386..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/modify_key_adaptor.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_MODIFY_KEY_ADAPTOR_HPP -#define BOOST_MULTI_INDEX_DETAIL_MODIFY_KEY_ADAPTOR_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Functional adaptor to resolve modify_key as a call to modify. - * Preferred over compose_f_gx and stuff cause it eliminates problems - * with references to references, dealing with function pointers, etc. - */ - -template -struct modify_key_adaptor -{ - - modify_key_adaptor(Fun f_,KeyFromValue kfv_):f(f_),kfv(kfv_){} - - void operator()(Value& x) - { - f(kfv(x)); - } - -private: - Fun f; - KeyFromValue kfv; -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/no_duplicate_tags.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/no_duplicate_tags.hpp deleted file mode 100644 index ba216ed82cf..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/no_duplicate_tags.hpp +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_NO_DUPLICATE_TAGS_HPP -#define BOOST_MULTI_INDEX_DETAIL_NO_DUPLICATE_TAGS_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* no_duplicate_tags check at compile-time that a tag list - * has no duplicate tags. - * The algorithm deserves some explanation: tags - * are sequentially inserted into a mpl::set if they were - * not already present. Due to the magic of mpl::set - * (mpl::has_key is contant time), this operation takes linear - * time, and even MSVC++ 6.5 handles it gracefully (other obvious - * solutions are quadratic.) - */ - -struct duplicate_tag_mark{}; - -struct duplicate_tag_marker -{ - template - struct apply - { - typedef mpl::s_item< - typename mpl::if_,duplicate_tag_mark,Tag>::type, - MplSet - > type; - }; -}; - -template -struct no_duplicate_tags -{ - typedef typename mpl::fold< - TagList, - mpl::set0<>, - duplicate_tag_marker - >::type aux; - - BOOST_STATIC_CONSTANT( - bool,value=!(mpl::has_key::value)); -}; - -/* Variant for an index list: duplication is checked - * across all the indices. - */ - -struct duplicate_tag_list_marker -{ - template - struct apply:mpl::fold< - BOOST_DEDUCED_TYPENAME Index::tag_list, - MplSet, - duplicate_tag_marker> - { - }; -}; - -template -struct no_duplicate_tags_in_index_list -{ - typedef typename mpl::fold< - IndexList, - mpl::set0<>, - duplicate_tag_list_marker - >::type aux; - - BOOST_STATIC_CONSTANT( - bool,value=!(mpl::has_key::value)); -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/node_type.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/node_type.hpp deleted file mode 100644 index 7fe85cf968b..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/node_type.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_NODE_TYPE_HPP -#define BOOST_MULTI_INDEX_DETAIL_NODE_TYPE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* MPL machinery to construct the internal node type associated to an - * index list. - */ - -struct index_node_applier -{ - template - struct apply - { - typedef typename mpl::deref::type index_specifier; - typedef typename index_specifier:: - BOOST_NESTED_TEMPLATE node_class::type type; - }; -}; - -template -struct multi_index_node_type -{ - BOOST_STATIC_ASSERT(detail::is_index_list::value); - - typedef typename mpl::reverse_iter_fold< - IndexSpecifierList, - index_node_base, - mpl::bind2 - >::type type; -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_args.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_args.hpp deleted file mode 100644 index 3e2641f2f4d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_args.hpp +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_ARGS_HPP -#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_ARGS_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Oredered index specifiers can be instantiated in two forms: - * - * (ordered_unique|ordered_non_unique)< - * KeyFromValue,Compare=std::less > - * (ordered_unique|ordered_non_unique)< - * TagList,KeyFromValue,Compare=std::less > - * - * index_args implements the machinery to accept this argument-dependent - * polymorphism. - */ - -template -struct index_args_default_compare -{ - typedef std::less type; -}; - -template -struct ordered_index_args -{ - typedef is_tag full_form; - - typedef typename mpl::if_< - full_form, - Arg1, - tag< > >::type tag_list_type; - typedef typename mpl::if_< - full_form, - Arg2, - Arg1>::type key_from_value_type; - typedef typename mpl::if_< - full_form, - Arg3, - Arg2>::type supplied_compare_type; - typedef typename mpl::eval_if< - mpl::is_na, - index_args_default_compare, - mpl::identity - >::type compare_type; - - BOOST_STATIC_ASSERT(is_tag::value); - BOOST_STATIC_ASSERT(!mpl::is_na::value); - BOOST_STATIC_ASSERT(!mpl::is_na::value); -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl.hpp deleted file mode 100644 index 040cb989630..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl.hpp +++ /dev/null @@ -1,1567 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - * - * The internal implementation of red-black trees is based on that of SGI STL - * stl_tree.h file: - * - * Copyright (c) 1996,1997 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_HPP -#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#include -#include -#include -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) -#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) \ - detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(x,&ordered_index_impl::check_invariant_); \ - BOOST_JOIN(check_invariant_,__LINE__).touch(); -#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \ - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(*this) -#else -#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) -#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* ordered_index adds a layer of ordered indexing to a given Super and accepts - * an augmenting policy for optional addition of order statistics. - */ - -/* Most of the implementation of unique and non-unique indices is - * shared. We tell from one another on instantiation time by using - * these tags. - */ - -struct ordered_unique_tag{}; -struct ordered_non_unique_tag{}; - -template< - typename KeyFromValue,typename Compare, - typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy -> -class ordered_index; - -template< - typename KeyFromValue,typename Compare, - typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy -> -class ordered_index_impl: - BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - ,public safe_mode::safe_container< - ordered_index_impl< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy> > -#endif - -{ -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the - * lifetime of const references bound to temporaries --precisely what - * scopeguards are. - */ - -#pragma parse_mfunc_templ off -#endif - - typedef typename SuperMeta::type super; - -protected: - typedef ordered_index_node< - AugmentPolicy,typename super::node_type> node_type; - -protected: /* for the benefit of AugmentPolicy::augmented_interface */ - typedef typename node_type::impl_type node_impl_type; - typedef typename node_impl_type::pointer node_impl_pointer; - -public: - /* types */ - - typedef typename KeyFromValue::result_type key_type; - typedef typename node_type::value_type value_type; - typedef KeyFromValue key_from_value; - typedef Compare key_compare; - typedef value_comparison< - value_type,KeyFromValue,Compare> value_compare; - typedef tuple ctor_args; - typedef typename super::final_allocator_type allocator_type; - typedef typename allocator_type::reference reference; - typedef typename allocator_type::const_reference const_reference; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef safe_mode::safe_iterator< - bidir_node_iterator, - ordered_index_impl> iterator; -#else - typedef bidir_node_iterator iterator; -#endif - - typedef iterator const_iterator; - - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef typename allocator_type::pointer pointer; - typedef typename allocator_type::const_pointer const_pointer; - typedef typename - boost::reverse_iterator reverse_iterator; - typedef typename - boost::reverse_iterator const_reverse_iterator; - typedef TagList tag_list; - -protected: - typedef typename super::final_node_type final_node_type; - typedef tuples::cons< - ctor_args, - typename super::ctor_args_list> ctor_args_list; - typedef typename mpl::push_front< - typename super::index_type_list, - ordered_index< - KeyFromValue,Compare, - SuperMeta,TagList,Category,AugmentPolicy - > >::type index_type_list; - typedef typename mpl::push_front< - typename super::iterator_type_list, - iterator>::type iterator_type_list; - typedef typename mpl::push_front< - typename super::const_iterator_type_list, - const_iterator>::type const_iterator_type_list; - typedef typename super::copy_map_type copy_map_type; - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - typedef typename super::index_saver_type index_saver_type; - typedef typename super::index_loader_type index_loader_type; -#endif - -protected: -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef safe_mode::safe_container< - ordered_index_impl> safe_super; -#endif - - typedef typename call_traits< - value_type>::param_type value_param_type; - typedef typename call_traits< - key_type>::param_type key_param_type; - - /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL - * expansion. - */ - - typedef std::pair emplace_return_type; - -public: - - /* construct/copy/destroy - * Default and copy ctors are in the protected section as indices are - * not supposed to be created on their own. No range ctor either. - * Assignment operators defined at ordered_index rather than here. - */ - - allocator_type get_allocator()const BOOST_NOEXCEPT - { - return this->final().get_allocator(); - } - - /* iterators */ - - iterator - begin()BOOST_NOEXCEPT{return make_iterator(leftmost());} - const_iterator - begin()const BOOST_NOEXCEPT{return make_iterator(leftmost());} - iterator - end()BOOST_NOEXCEPT{return make_iterator(header());} - const_iterator - end()const BOOST_NOEXCEPT{return make_iterator(header());} - reverse_iterator - rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} - const_reverse_iterator - rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} - reverse_iterator - rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} - const_reverse_iterator - rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} - const_iterator - cbegin()const BOOST_NOEXCEPT{return begin();} - const_iterator - cend()const BOOST_NOEXCEPT{return end();} - const_reverse_iterator - crbegin()const BOOST_NOEXCEPT{return rbegin();} - const_reverse_iterator - crend()const BOOST_NOEXCEPT{return rend();} - - iterator iterator_to(const value_type& x) - { - return make_iterator(node_from_value(&x)); - } - - const_iterator iterator_to(const value_type& x)const - { - return make_iterator(node_from_value(&x)); - } - - /* capacity */ - - bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} - size_type size()const BOOST_NOEXCEPT{return this->final_size_();} - size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} - - /* modifiers */ - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( - emplace_return_type,emplace,emplace_impl) - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( - iterator,emplace_hint,emplace_hint_impl,iterator,position) - - std::pair insert(const value_type& x) - { - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_(x); - return std::pair(make_iterator(p.first),p.second); - } - - std::pair insert(BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_rv_(x); - return std::pair(make_iterator(p.first),p.second); - } - - iterator insert(iterator position,const value_type& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_( - x,static_cast(position.get_node())); - return make_iterator(p.first); - } - - iterator insert(iterator position,BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_rv_( - x,static_cast(position.get_node())); - return make_iterator(p.first); - } - - template - void insert(InputIterator first,InputIterator last) - { - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - node_type* hint=header(); /* end() */ - for(;first!=last;++first){ - hint=this->final_insert_ref_( - *first,static_cast(hint)).first; - node_type::increment(hint); - } - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - void insert(std::initializer_list list) - { - insert(list.begin(),list.end()); - } -#endif - - iterator erase(iterator position) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - this->final_erase_(static_cast(position++.get_node())); - return position; - } - - size_type erase(key_param_type x) - { - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - std::pair p=equal_range(x); - size_type s=0; - while(p.first!=p.second){ - p.first=erase(p.first); - ++s; - } - return s; - } - - iterator erase(iterator first,iterator last) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); - BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - while(first!=last){ - first=erase(first); - } - return first; - } - - bool replace(iterator position,const value_type& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - return this->final_replace_( - x,static_cast(position.get_node())); - } - - bool replace(iterator position,BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - return this->final_replace_rv_( - x,static_cast(position.get_node())); - } - - template - bool modify(iterator position,Modifier mod) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer on safe mode code chokes if this - * this is not added. Left it for all compilers as it does no - * harm. - */ - - position.detach(); -#endif - - return this->final_modify_( - mod,static_cast(position.get_node())); - } - - template - bool modify(iterator position,Modifier mod,Rollback back_) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer on safe mode code chokes if this - * this is not added. Left it for all compilers as it does no - * harm. - */ - - position.detach(); -#endif - - return this->final_modify_( - mod,back_,static_cast(position.get_node())); - } - - template - bool modify_key(iterator position,Modifier mod) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - return modify( - position,modify_key_adaptor(mod,key)); - } - - template - bool modify_key(iterator position,Modifier mod,Rollback back_) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - return modify( - position, - modify_key_adaptor(mod,key), - modify_key_adaptor(back_,key)); - } - - void swap( - ordered_index< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x) - { - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x); - this->final_swap_(x.final()); - } - - void clear()BOOST_NOEXCEPT - { - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - this->final_clear_(); - } - - /* observers */ - - key_from_value key_extractor()const{return key;} - key_compare key_comp()const{return comp_;} - value_compare value_comp()const{return value_compare(key,comp_);} - - /* set operations */ - - /* Internally, these ops rely on const_iterator being the same - * type as iterator. - */ - - template - iterator find(const CompatibleKey& x)const - { - return make_iterator(ordered_index_find(root(),header(),key,x,comp_)); - } - - template - iterator find( - const CompatibleKey& x,const CompatibleCompare& comp)const - { - return make_iterator(ordered_index_find(root(),header(),key,x,comp)); - } - - template - size_type count(const CompatibleKey& x)const - { - return count(x,comp_); - } - - template - size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const - { - std::pair p=equal_range(x,comp); - size_type n=std::distance(p.first,p.second); - return n; - } - - template - iterator lower_bound(const CompatibleKey& x)const - { - return make_iterator( - ordered_index_lower_bound(root(),header(),key,x,comp_)); - } - - template - iterator lower_bound( - const CompatibleKey& x,const CompatibleCompare& comp)const - { - return make_iterator( - ordered_index_lower_bound(root(),header(),key,x,comp)); - } - - template - iterator upper_bound(const CompatibleKey& x)const - { - return make_iterator( - ordered_index_upper_bound(root(),header(),key,x,comp_)); - } - - template - iterator upper_bound( - const CompatibleKey& x,const CompatibleCompare& comp)const - { - return make_iterator( - ordered_index_upper_bound(root(),header(),key,x,comp)); - } - - template - std::pair equal_range( - const CompatibleKey& x)const - { - std::pair p= - ordered_index_equal_range(root(),header(),key,x,comp_); - return std::pair( - make_iterator(p.first),make_iterator(p.second)); - } - - template - std::pair equal_range( - const CompatibleKey& x,const CompatibleCompare& comp)const - { - std::pair p= - ordered_index_equal_range(root(),header(),key,x,comp); - return std::pair( - make_iterator(p.first),make_iterator(p.second)); - } - - /* range */ - - template - std::pair - range(LowerBounder lower,UpperBounder upper)const - { - typedef typename mpl::if_< - is_same, - BOOST_DEDUCED_TYPENAME mpl::if_< - is_same, - both_unbounded_tag, - lower_unbounded_tag - >::type, - BOOST_DEDUCED_TYPENAME mpl::if_< - is_same, - upper_unbounded_tag, - none_unbounded_tag - >::type - >::type dispatch; - - return range(lower,upper,dispatch()); - } - -BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: - ordered_index_impl(const ctor_args_list& args_list,const allocator_type& al): - super(args_list.get_tail(),al), - key(tuples::get<0>(args_list.get_head())), - comp_(tuples::get<1>(args_list.get_head())) - { - empty_initialize(); - } - - ordered_index_impl( - const ordered_index_impl< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x): - super(x), - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super(), -#endif - - key(x.key), - comp_(x.comp_) - { - /* Copy ctor just takes the key and compare objects from x. The rest is - * done in a subsequent call to copy_(). - */ - } - - ordered_index_impl( - const ordered_index_impl< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x, - do_not_copy_elements_tag): - super(x,do_not_copy_elements_tag()), - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super(), -#endif - - key(x.key), - comp_(x.comp_) - { - empty_initialize(); - } - - ~ordered_index_impl() - { - /* the container is guaranteed to be empty by now */ - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - iterator make_iterator(node_type* node){return iterator(node,this);} - const_iterator make_iterator(node_type* node)const - {return const_iterator(node,const_cast(this));} -#else - iterator make_iterator(node_type* node){return iterator(node);} - const_iterator make_iterator(node_type* node)const - {return const_iterator(node);} -#endif - - void copy_( - const ordered_index_impl< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x, - const copy_map_type& map) - { - if(!x.root()){ - empty_initialize(); - } - else{ - header()->color()=x.header()->color(); - AugmentPolicy::copy(x.header()->impl(),header()->impl()); - - node_type* root_cpy=map.find(static_cast(x.root())); - header()->parent()=root_cpy->impl(); - - node_type* leftmost_cpy=map.find( - static_cast(x.leftmost())); - header()->left()=leftmost_cpy->impl(); - - node_type* rightmost_cpy=map.find( - static_cast(x.rightmost())); - header()->right()=rightmost_cpy->impl(); - - typedef typename copy_map_type::const_iterator copy_map_iterator; - for(copy_map_iterator it=map.begin(),it_end=map.end();it!=it_end;++it){ - node_type* org=it->first; - node_type* cpy=it->second; - - cpy->color()=org->color(); - AugmentPolicy::copy(org->impl(),cpy->impl()); - - node_impl_pointer parent_org=org->parent(); - if(parent_org==node_impl_pointer(0))cpy->parent()=node_impl_pointer(0); - else{ - node_type* parent_cpy=map.find( - static_cast(node_type::from_impl(parent_org))); - cpy->parent()=parent_cpy->impl(); - if(parent_org->left()==org->impl()){ - parent_cpy->left()=cpy->impl(); - } - else if(parent_org->right()==org->impl()){ - /* header() does not satisfy this nor the previous check */ - parent_cpy->right()=cpy->impl(); - } - } - - if(org->left()==node_impl_pointer(0)) - cpy->left()=node_impl_pointer(0); - if(org->right()==node_impl_pointer(0)) - cpy->right()=node_impl_pointer(0); - } - } - - super::copy_(x,map); - } - - template - final_node_type* insert_( - value_param_type v,final_node_type*& x,Variant variant) - { - link_info inf; - if(!link_point(key(v),inf,Category())){ - return static_cast(node_type::from_impl(inf.pos)); - } - - final_node_type* res=super::insert_(v,x,variant); - if(res==x){ - node_impl_type::link( - static_cast(x)->impl(),inf.side,inf.pos,header()->impl()); - } - return res; - } - - template - final_node_type* insert_( - value_param_type v,node_type* position,final_node_type*& x,Variant variant) - { - link_info inf; - if(!hinted_link_point(key(v),position,inf,Category())){ - return static_cast(node_type::from_impl(inf.pos)); - } - - final_node_type* res=super::insert_(v,position,x,variant); - if(res==x){ - node_impl_type::link( - static_cast(x)->impl(),inf.side,inf.pos,header()->impl()); - } - return res; - } - - void erase_(node_type* x) - { - node_impl_type::rebalance_for_erase( - x->impl(),header()->parent(),header()->left(),header()->right()); - super::erase_(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - } - - void delete_all_nodes_() - { - delete_all_nodes(root()); - } - - void clear_() - { - super::clear_(); - empty_initialize(); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::detach_dereferenceable_iterators(); -#endif - } - - void swap_( - ordered_index_impl< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x) - { - std::swap(key,x.key); - std::swap(comp_,x.comp_); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::swap(x); -#endif - - super::swap_(x); - } - - void swap_elements_( - ordered_index_impl< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x) - { -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::swap(x); -#endif - - super::swap_elements_(x); - } - - template - bool replace_(value_param_type v,node_type* x,Variant variant) - { - if(in_place(v,x,Category())){ - return super::replace_(v,x,variant); - } - - node_type* next=x; - node_type::increment(next); - - node_impl_type::rebalance_for_erase( - x->impl(),header()->parent(),header()->left(),header()->right()); - - BOOST_TRY{ - link_info inf; - if(link_point(key(v),inf,Category())&&super::replace_(v,x,variant)){ - node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); - return true; - } - node_impl_type::restore(x->impl(),next->impl(),header()->impl()); - return false; - } - BOOST_CATCH(...){ - node_impl_type::restore(x->impl(),next->impl(),header()->impl()); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - bool modify_(node_type* x) - { - bool b; - BOOST_TRY{ - b=in_place(x->value(),x,Category()); - } - BOOST_CATCH(...){ - erase_(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - if(!b){ - node_impl_type::rebalance_for_erase( - x->impl(),header()->parent(),header()->left(),header()->right()); - BOOST_TRY{ - link_info inf; - if(!link_point(key(x->value()),inf,Category())){ - super::erase_(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - return false; - } - node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); - } - BOOST_CATCH(...){ - super::erase_(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - BOOST_TRY{ - if(!super::modify_(x)){ - node_impl_type::rebalance_for_erase( - x->impl(),header()->parent(),header()->left(),header()->right()); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - return false; - } - else return true; - } - BOOST_CATCH(...){ - node_impl_type::rebalance_for_erase( - x->impl(),header()->parent(),header()->left(),header()->right()); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - bool modify_rollback_(node_type* x) - { - if(in_place(x->value(),x,Category())){ - return super::modify_rollback_(x); - } - - node_type* next=x; - node_type::increment(next); - - node_impl_type::rebalance_for_erase( - x->impl(),header()->parent(),header()->left(),header()->right()); - - BOOST_TRY{ - link_info inf; - if(link_point(key(x->value()),inf,Category())&& - super::modify_rollback_(x)){ - node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); - return true; - } - node_impl_type::restore(x->impl(),next->impl(),header()->impl()); - return false; - } - BOOST_CATCH(...){ - node_impl_type::restore(x->impl(),next->impl(),header()->impl()); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* serialization */ - - template - void save_( - Archive& ar,const unsigned int version,const index_saver_type& sm)const - { - save_(ar,version,sm,Category()); - } - - template - void load_(Archive& ar,const unsigned int version,const index_loader_type& lm) - { - load_(ar,version,lm,Category()); - } -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - bool invariant_()const - { - if(size()==0||begin()==end()){ - if(size()!=0||begin()!=end()|| - header()->left()!=header()->impl()|| - header()->right()!=header()->impl())return false; - } - else{ - if((size_type)std::distance(begin(),end())!=size())return false; - - std::size_t len=node_impl_type::black_count( - leftmost()->impl(),root()->impl()); - for(const_iterator it=begin(),it_end=end();it!=it_end;++it){ - node_type* x=it.get_node(); - node_type* left_x=node_type::from_impl(x->left()); - node_type* right_x=node_type::from_impl(x->right()); - - if(x->color()==red){ - if((left_x&&left_x->color()==red)|| - (right_x&&right_x->color()==red))return false; - } - if(left_x&&comp_(key(x->value()),key(left_x->value())))return false; - if(right_x&&comp_(key(right_x->value()),key(x->value())))return false; - if(!left_x&&!right_x&& - node_impl_type::black_count(x->impl(),root()->impl())!=len) - return false; - if(!AugmentPolicy::invariant(x->impl()))return false; - } - - if(leftmost()->impl()!=node_impl_type::minimum(root()->impl())) - return false; - if(rightmost()->impl()!=node_impl_type::maximum(root()->impl())) - return false; - } - - return super::invariant_(); - } - - - /* This forwarding function eases things for the boost::mem_fn construct - * in BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT. Actually, - * final_check_invariant is already an inherited member function of - * ordered_index_impl. - */ - void check_invariant_()const{this->final_check_invariant_();} -#endif - -protected: /* for the benefit of AugmentPolicy::augmented_interface */ - node_type* header()const{return this->final_header();} - node_type* root()const{return node_type::from_impl(header()->parent());} - node_type* leftmost()const{return node_type::from_impl(header()->left());} - node_type* rightmost()const{return node_type::from_impl(header()->right());} - -private: - void empty_initialize() - { - header()->color()=red; - /* used to distinguish header() from root, in iterator.operator++ */ - - header()->parent()=node_impl_pointer(0); - header()->left()=header()->impl(); - header()->right()=header()->impl(); - } - - struct link_info - { - /* coverity[uninit_ctor]: suppress warning */ - link_info():side(to_left){} - - ordered_index_side side; - node_impl_pointer pos; - }; - - bool link_point(key_param_type k,link_info& inf,ordered_unique_tag) - { - node_type* y=header(); - node_type* x=root(); - bool c=true; - while(x){ - y=x; - c=comp_(k,key(x->value())); - x=node_type::from_impl(c?x->left():x->right()); - } - node_type* yy=y; - if(c){ - if(yy==leftmost()){ - inf.side=to_left; - inf.pos=y->impl(); - return true; - } - else node_type::decrement(yy); - } - - if(comp_(key(yy->value()),k)){ - inf.side=c?to_left:to_right; - inf.pos=y->impl(); - return true; - } - else{ - inf.pos=yy->impl(); - return false; - } - } - - bool link_point(key_param_type k,link_info& inf,ordered_non_unique_tag) - { - node_type* y=header(); - node_type* x=root(); - bool c=true; - while (x){ - y=x; - c=comp_(k,key(x->value())); - x=node_type::from_impl(c?x->left():x->right()); - } - inf.side=c?to_left:to_right; - inf.pos=y->impl(); - return true; - } - - bool lower_link_point(key_param_type k,link_info& inf,ordered_non_unique_tag) - { - node_type* y=header(); - node_type* x=root(); - bool c=false; - while (x){ - y=x; - c=comp_(key(x->value()),k); - x=node_type::from_impl(c?x->right():x->left()); - } - inf.side=c?to_right:to_left; - inf.pos=y->impl(); - return true; - } - - bool hinted_link_point( - key_param_type k,node_type* position,link_info& inf,ordered_unique_tag) - { - if(position->impl()==header()->left()){ - if(size()>0&&comp_(k,key(position->value()))){ - inf.side=to_left; - inf.pos=position->impl(); - return true; - } - else return link_point(k,inf,ordered_unique_tag()); - } - else if(position==header()){ - if(comp_(key(rightmost()->value()),k)){ - inf.side=to_right; - inf.pos=rightmost()->impl(); - return true; - } - else return link_point(k,inf,ordered_unique_tag()); - } - else{ - node_type* before=position; - node_type::decrement(before); - if(comp_(key(before->value()),k)&&comp_(k,key(position->value()))){ - if(before->right()==node_impl_pointer(0)){ - inf.side=to_right; - inf.pos=before->impl(); - return true; - } - else{ - inf.side=to_left; - inf.pos=position->impl(); - return true; - } - } - else return link_point(k,inf,ordered_unique_tag()); - } - } - - bool hinted_link_point( - key_param_type k,node_type* position,link_info& inf,ordered_non_unique_tag) - { - if(position->impl()==header()->left()){ - if(size()>0&&!comp_(key(position->value()),k)){ - inf.side=to_left; - inf.pos=position->impl(); - return true; - } - else return lower_link_point(k,inf,ordered_non_unique_tag()); - } - else if(position==header()){ - if(!comp_(k,key(rightmost()->value()))){ - inf.side=to_right; - inf.pos=rightmost()->impl(); - return true; - } - else return link_point(k,inf,ordered_non_unique_tag()); - } - else{ - node_type* before=position; - node_type::decrement(before); - if(!comp_(k,key(before->value()))){ - if(!comp_(key(position->value()),k)){ - if(before->right()==node_impl_pointer(0)){ - inf.side=to_right; - inf.pos=before->impl(); - return true; - } - else{ - inf.side=to_left; - inf.pos=position->impl(); - return true; - } - } - else return lower_link_point(k,inf,ordered_non_unique_tag()); - } - else return link_point(k,inf,ordered_non_unique_tag()); - } - } - - void delete_all_nodes(node_type* x) - { - if(!x)return; - - delete_all_nodes(node_type::from_impl(x->left())); - delete_all_nodes(node_type::from_impl(x->right())); - this->final_delete_node_(static_cast(x)); - } - - bool in_place(value_param_type v,node_type* x,ordered_unique_tag) - { - node_type* y; - if(x!=leftmost()){ - y=x; - node_type::decrement(y); - if(!comp_(key(y->value()),key(v)))return false; - } - - y=x; - node_type::increment(y); - return y==header()||comp_(key(v),key(y->value())); - } - - bool in_place(value_param_type v,node_type* x,ordered_non_unique_tag) - { - node_type* y; - if(x!=leftmost()){ - y=x; - node_type::decrement(y); - if(comp_(key(v),key(y->value())))return false; - } - - y=x; - node_type::increment(y); - return y==header()||!comp_(key(y->value()),key(v)); - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - void detach_iterators(node_type* x) - { - iterator it=make_iterator(x); - safe_mode::detach_equivalent_iterators(it); - } -#endif - - template - std::pair emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - std::pairp= - this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - return std::pair(make_iterator(p.first),p.second); - } - - template - iterator emplace_hint_impl( - iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - std::pairp= - this->final_emplace_hint_( - static_cast(position.get_node()), - BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - return make_iterator(p.first); - } - - template - std::pair - range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const - { - node_type* y=header(); - node_type* z=root(); - - while(z){ - if(!lower(key(z->value()))){ - z=node_type::from_impl(z->right()); - } - else if(!upper(key(z->value()))){ - y=z; - z=node_type::from_impl(z->left()); - } - else{ - return std::pair( - make_iterator( - lower_range(node_type::from_impl(z->left()),z,lower)), - make_iterator( - upper_range(node_type::from_impl(z->right()),y,upper))); - } - } - - return std::pair(make_iterator(y),make_iterator(y)); - } - - template - std::pair - range(LowerBounder,UpperBounder upper,lower_unbounded_tag)const - { - return std::pair( - begin(), - make_iterator(upper_range(root(),header(),upper))); - } - - template - std::pair - range(LowerBounder lower,UpperBounder,upper_unbounded_tag)const - { - return std::pair( - make_iterator(lower_range(root(),header(),lower)), - end()); - } - - template - std::pair - range(LowerBounder,UpperBounder,both_unbounded_tag)const - { - return std::pair(begin(),end()); - } - - template - node_type * lower_range(node_type* top,node_type* y,LowerBounder lower)const - { - while(top){ - if(lower(key(top->value()))){ - y=top; - top=node_type::from_impl(top->left()); - } - else top=node_type::from_impl(top->right()); - } - - return y; - } - - template - node_type * upper_range(node_type* top,node_type* y,UpperBounder upper)const - { - while(top){ - if(!upper(key(top->value()))){ - y=top; - top=node_type::from_impl(top->left()); - } - else top=node_type::from_impl(top->right()); - } - - return y; - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - template - void save_( - Archive& ar,const unsigned int version,const index_saver_type& sm, - ordered_unique_tag)const - { - super::save_(ar,version,sm); - } - - template - void load_( - Archive& ar,const unsigned int version,const index_loader_type& lm, - ordered_unique_tag) - { - super::load_(ar,version,lm); - } - - template - void save_( - Archive& ar,const unsigned int version,const index_saver_type& sm, - ordered_non_unique_tag)const - { - typedef duplicates_iterator dup_iterator; - - sm.save( - dup_iterator(begin().get_node(),end().get_node(),value_comp()), - dup_iterator(end().get_node(),value_comp()), - ar,version); - super::save_(ar,version,sm); - } - - template - void load_( - Archive& ar,const unsigned int version,const index_loader_type& lm, - ordered_non_unique_tag) - { - lm.load( - ::boost::bind( - &ordered_index_impl::rearranger,this, - ::boost::arg<1>(),::boost::arg<2>()), - ar,version); - super::load_(ar,version,lm); - } - - void rearranger(node_type* position,node_type *x) - { - if(!position||comp_(key(position->value()),key(x->value()))){ - position=lower_bound(key(x->value())).get_node(); - } - else if(comp_(key(x->value()),key(position->value()))){ - /* inconsistent rearrangement */ - throw_exception( - archive::archive_exception( - archive::archive_exception::other_exception)); - } - else node_type::increment(position); - - if(position!=x){ - node_impl_type::rebalance_for_erase( - x->impl(),header()->parent(),header()->left(),header()->right()); - node_impl_type::restore( - x->impl(),position->impl(),header()->impl()); - } - } -#endif /* serialization */ - -protected: /* for the benefit of AugmentPolicy::augmented_interface */ - key_from_value key; - key_compare comp_; - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -#pragma parse_mfunc_templ reset -#endif -}; - -template< - typename KeyFromValue,typename Compare, - typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy -> -class ordered_index: - public AugmentPolicy::template augmented_interface< - ordered_index_impl< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy - > - >::type -{ - typedef typename AugmentPolicy::template - augmented_interface< - ordered_index_impl< - KeyFromValue,Compare, - SuperMeta,TagList,Category,AugmentPolicy - > - >::type super; -public: - typedef typename super::ctor_args_list ctor_args_list; - typedef typename super::allocator_type allocator_type; - typedef typename super::iterator iterator; - - /* construct/copy/destroy - * Default and copy ctors are in the protected section as indices are - * not supposed to be created on their own. No range ctor either. - */ - - ordered_index& operator=(const ordered_index& x) - { - this->final()=x.final(); - return *this; - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - ordered_index& operator=( - std::initializer_list list) - { - this->final()=list; - return *this; - } -#endif - -protected: - ordered_index( - const ctor_args_list& args_list,const allocator_type& al): - super(args_list,al){} - - ordered_index(const ordered_index& x):super(x){}; - - ordered_index(const ordered_index& x,do_not_copy_elements_tag): - super(x,do_not_copy_elements_tag()){}; -}; - -/* comparison */ - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator==( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) -{ - return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); -} - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator<( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) -{ - return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); -} - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator!=( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) -{ - return !(x==y); -} - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator>( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) -{ - return y -bool operator>=( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) -{ - return !(x -bool operator<=( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) -{ - return !(x>y); -} - -/* specialized algorithms */ - -template< - typename KeyFromValue,typename Compare, - typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy -> -void swap( - ordered_index< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x, - ordered_index< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& y) -{ - x.swap(y); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -/* Boost.Foreach compatibility */ - -template< - typename KeyFromValue,typename Compare, - typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy -> -inline boost::mpl::true_* boost_foreach_is_noncopyable( - boost::multi_index::detail::ordered_index< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>*&, - boost_foreach_argument_dependent_lookup_hack) -{ - return 0; -} - -#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT -#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl_fwd.hpp deleted file mode 100644 index 6590ef05fdd..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl_fwd.hpp +++ /dev/null @@ -1,128 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_FWD_HPP -#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_FWD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template< - typename KeyFromValue,typename Compare, - typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy -> -class ordered_index; - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator==( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator<( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator!=( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator>( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator>=( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator<=( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); - -template< - typename KeyFromValue,typename Compare, - typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy -> -void swap( - ordered_index< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x, - ordered_index< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& y); - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_node.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_node.hpp deleted file mode 100644 index e7af0377fb9..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_node.hpp +++ /dev/null @@ -1,658 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - * - * The internal implementation of red-black trees is based on that of SGI STL - * stl_tree.h file: - * - * Copyright (c) 1996,1997 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_NODE_HPP -#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_NODE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include - -#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES) -#include -#include -#include -#include -#include -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* definition of red-black nodes for ordered_index */ - -enum ordered_index_color{red=false,black=true}; -enum ordered_index_side{to_left=false,to_right=true}; - -template -struct ordered_index_node_impl; /* fwd decl. */ - -template -struct ordered_index_node_std_base -{ - typedef typename - boost::detail::allocator::rebind_to< - Allocator, - ordered_index_node_impl - >::type::pointer pointer; - typedef typename - boost::detail::allocator::rebind_to< - Allocator, - ordered_index_node_impl - >::type::const_pointer const_pointer; - typedef ordered_index_color& color_ref; - typedef pointer& parent_ref; - - ordered_index_color& color(){return color_;} - ordered_index_color color()const{return color_;} - pointer& parent(){return parent_;} - pointer parent()const{return parent_;} - pointer& left(){return left_;} - pointer left()const{return left_;} - pointer& right(){return right_;} - pointer right()const{return right_;} - -private: - ordered_index_color color_; - pointer parent_; - pointer left_; - pointer right_; -}; - -#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES) -/* If ordered_index_node_impl has even alignment, we can use the least - * significant bit of one of the ordered_index_node_impl pointers to - * store color information. This typically reduces the size of - * ordered_index_node_impl by 25%. - */ - -#if defined(BOOST_MSVC) -/* This code casts pointers to an integer type that has been computed - * to be large enough to hold the pointer, however the metaprogramming - * logic is not always spotted by the VC++ code analyser that issues a - * long list of warnings. - */ - -#pragma warning(push) -#pragma warning(disable:4312 4311) -#endif - -template -struct ordered_index_node_compressed_base -{ - typedef ordered_index_node_impl< - AugmentPolicy,Allocator>* pointer; - typedef const ordered_index_node_impl< - AugmentPolicy,Allocator>* const_pointer; - - struct color_ref - { - color_ref(uintptr_type* r_):r(r_){} - - operator ordered_index_color()const - { - return ordered_index_color(*r&uintptr_type(1)); - } - - color_ref& operator=(ordered_index_color c) - { - *r&=~uintptr_type(1); - *r|=uintptr_type(c); - return *this; - } - - color_ref& operator=(const color_ref& x) - { - return operator=(x.operator ordered_index_color()); - } - - private: - uintptr_type* r; - }; - - struct parent_ref - { - parent_ref(uintptr_type* r_):r(r_){} - - operator pointer()const - { - return (pointer)(void*)(*r&~uintptr_type(1)); - } - - parent_ref& operator=(pointer p) - { - *r=((uintptr_type)(void*)p)|(*r&uintptr_type(1)); - return *this; - } - - parent_ref& operator=(const parent_ref& x) - { - return operator=(x.operator pointer()); - } - - pointer operator->()const - { - return operator pointer(); - } - - private: - uintptr_type* r; - }; - - color_ref color(){return color_ref(&parentcolor_);} - ordered_index_color color()const - { - return ordered_index_color(parentcolor_&uintptr_type(1)); - } - - parent_ref parent(){return parent_ref(&parentcolor_);} - pointer parent()const - { - return (pointer)(void*)(parentcolor_&~uintptr_type(1)); - } - - pointer& left(){return left_;} - pointer left()const{return left_;} - pointer& right(){return right_;} - pointer right()const{return right_;} - -private: - uintptr_type parentcolor_; - pointer left_; - pointer right_; -}; -#if defined(BOOST_MSVC) -#pragma warning(pop) -#endif -#endif - -template -struct ordered_index_node_impl_base: - -#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES) - AugmentPolicy::template augmented_node< - typename mpl::if_c< - !(has_uintptr_type::value)|| - (alignment_of< - ordered_index_node_compressed_base - >::value%2)|| - !(is_same< - typename boost::detail::allocator::rebind_to< - Allocator, - ordered_index_node_impl - >::type::pointer, - ordered_index_node_impl*>::value), - ordered_index_node_std_base, - ordered_index_node_compressed_base - >::type - >::type -#else - AugmentPolicy::template augmented_node< - ordered_index_node_std_base - >::type -#endif - -{}; - -template -struct ordered_index_node_impl: - ordered_index_node_impl_base -{ -private: - typedef ordered_index_node_impl_base super; - -public: - typedef typename super::color_ref color_ref; - typedef typename super::parent_ref parent_ref; - typedef typename super::pointer pointer; - typedef typename super::const_pointer const_pointer; - - /* interoperability with bidir_node_iterator */ - - static void increment(pointer& x) - { - if(x->right()!=pointer(0)){ - x=x->right(); - while(x->left()!=pointer(0))x=x->left(); - } - else{ - pointer y=x->parent(); - while(x==y->right()){ - x=y; - y=y->parent(); - } - if(x->right()!=y)x=y; - } - } - - static void decrement(pointer& x) - { - if(x->color()==red&&x->parent()->parent()==x){ - x=x->right(); - } - else if(x->left()!=pointer(0)){ - pointer y=x->left(); - while(y->right()!=pointer(0))y=y->right(); - x=y; - }else{ - pointer y=x->parent(); - while(x==y->left()){ - x=y; - y=y->parent(); - } - x=y; - } - } - - /* algorithmic stuff */ - - static void rotate_left(pointer x,parent_ref root) - { - pointer y=x->right(); - x->right()=y->left(); - if(y->left()!=pointer(0))y->left()->parent()=x; - y->parent()=x->parent(); - - if(x==root) root=y; - else if(x==x->parent()->left())x->parent()->left()=y; - else x->parent()->right()=y; - y->left()=x; - x->parent()=y; - AugmentPolicy::rotate_left(x,y); - } - - static pointer minimum(pointer x) - { - while(x->left()!=pointer(0))x=x->left(); - return x; - } - - static pointer maximum(pointer x) - { - while(x->right()!=pointer(0))x=x->right(); - return x; - } - - static void rotate_right(pointer x,parent_ref root) - { - pointer y=x->left(); - x->left()=y->right(); - if(y->right()!=pointer(0))y->right()->parent()=x; - y->parent()=x->parent(); - - if(x==root) root=y; - else if(x==x->parent()->right())x->parent()->right()=y; - else x->parent()->left()=y; - y->right()=x; - x->parent()=y; - AugmentPolicy::rotate_right(x,y); - } - - static void rebalance(pointer x,parent_ref root) - { - x->color()=red; - while(x!=root&&x->parent()->color()==red){ - if(x->parent()==x->parent()->parent()->left()){ - pointer y=x->parent()->parent()->right(); - if(y!=pointer(0)&&y->color()==red){ - x->parent()->color()=black; - y->color()=black; - x->parent()->parent()->color()=red; - x=x->parent()->parent(); - } - else{ - if(x==x->parent()->right()){ - x=x->parent(); - rotate_left(x,root); - } - x->parent()->color()=black; - x->parent()->parent()->color()=red; - rotate_right(x->parent()->parent(),root); - } - } - else{ - pointer y=x->parent()->parent()->left(); - if(y!=pointer(0)&&y->color()==red){ - x->parent()->color()=black; - y->color()=black; - x->parent()->parent()->color()=red; - x=x->parent()->parent(); - } - else{ - if(x==x->parent()->left()){ - x=x->parent(); - rotate_right(x,root); - } - x->parent()->color()=black; - x->parent()->parent()->color()=red; - rotate_left(x->parent()->parent(),root); - } - } - } - root->color()=black; - } - - static void link( - pointer x,ordered_index_side side,pointer position,pointer header) - { - if(side==to_left){ - position->left()=x; /* also makes leftmost=x when parent==header */ - if(position==header){ - header->parent()=x; - header->right()=x; - } - else if(position==header->left()){ - header->left()=x; /* maintain leftmost pointing to min node */ - } - } - else{ - position->right()=x; - if(position==header->right()){ - header->right()=x; /* maintain rightmost pointing to max node */ - } - } - x->parent()=position; - x->left()=pointer(0); - x->right()=pointer(0); - AugmentPolicy::add(x,pointer(header->parent())); - ordered_index_node_impl::rebalance(x,header->parent()); - } - - static pointer rebalance_for_erase( - pointer z,parent_ref root,pointer& leftmost,pointer& rightmost) - { - pointer y=z; - pointer x=pointer(0); - pointer x_parent=pointer(0); - if(y->left()==pointer(0)){ /* z has at most one non-null child. y==z. */ - x=y->right(); /* x might be null */ - } - else{ - if(y->right()==pointer(0)){ /* z has exactly one non-null child. y==z. */ - x=y->left(); /* x is not null */ - } - else{ /* z has two non-null children. Set y to */ - y=y->right(); /* z's successor. x might be null. */ - while(y->left()!=pointer(0))y=y->left(); - x=y->right(); - } - } - AugmentPolicy::remove(y,pointer(root)); - if(y!=z){ - AugmentPolicy::copy(z,y); - z->left()->parent()=y; /* relink y in place of z. y is z's successor */ - y->left()=z->left(); - if(y!=z->right()){ - x_parent=y->parent(); - if(x!=pointer(0))x->parent()=y->parent(); - y->parent()->left()=x; /* y must be a child of left */ - y->right()=z->right(); - z->right()->parent()=y; - } - else{ - x_parent=y; - } - - if(root==z) root=y; - else if(z->parent()->left()==z)z->parent()->left()=y; - else z->parent()->right()=y; - y->parent()=z->parent(); - ordered_index_color c=y->color(); - y->color()=z->color(); - z->color()=c; - y=z; /* y now points to node to be actually deleted */ - } - else{ /* y==z */ - x_parent=y->parent(); - if(x!=pointer(0))x->parent()=y->parent(); - if(root==z){ - root=x; - } - else{ - if(z->parent()->left()==z)z->parent()->left()=x; - else z->parent()->right()=x; - } - if(leftmost==z){ - if(z->right()==pointer(0)){ /* z->left() must be null also */ - leftmost=z->parent(); - } - else{ - leftmost=minimum(x); /* makes leftmost==header if z==root */ - } - } - if(rightmost==z){ - if(z->left()==pointer(0)){ /* z->right() must be null also */ - rightmost=z->parent(); - } - else{ /* x==z->left() */ - rightmost=maximum(x); /* makes rightmost==header if z==root */ - } - } - } - if(y->color()!=red){ - while(x!=root&&(x==pointer(0)|| x->color()==black)){ - if(x==x_parent->left()){ - pointer w=x_parent->right(); - if(w->color()==red){ - w->color()=black; - x_parent->color()=red; - rotate_left(x_parent,root); - w=x_parent->right(); - } - if((w->left()==pointer(0)||w->left()->color()==black) && - (w->right()==pointer(0)||w->right()->color()==black)){ - w->color()=red; - x=x_parent; - x_parent=x_parent->parent(); - } - else{ - if(w->right()==pointer(0 ) - || w->right()->color()==black){ - if(w->left()!=pointer(0)) w->left()->color()=black; - w->color()=red; - rotate_right(w,root); - w=x_parent->right(); - } - w->color()=x_parent->color(); - x_parent->color()=black; - if(w->right()!=pointer(0))w->right()->color()=black; - rotate_left(x_parent,root); - break; - } - } - else{ /* same as above,with right <-> left */ - pointer w=x_parent->left(); - if(w->color()==red){ - w->color()=black; - x_parent->color()=red; - rotate_right(x_parent,root); - w=x_parent->left(); - } - if((w->right()==pointer(0)||w->right()->color()==black) && - (w->left()==pointer(0)||w->left()->color()==black)){ - w->color()=red; - x=x_parent; - x_parent=x_parent->parent(); - } - else{ - if(w->left()==pointer(0)||w->left()->color()==black){ - if(w->right()!=pointer(0))w->right()->color()=black; - w->color()=red; - rotate_left(w,root); - w=x_parent->left(); - } - w->color()=x_parent->color(); - x_parent->color()=black; - if(w->left()!=pointer(0))w->left()->color()=black; - rotate_right(x_parent,root); - break; - } - } - } - if(x!=pointer(0))x->color()=black; - } - return y; - } - - static void restore(pointer x,pointer position,pointer header) - { - if(position->left()==pointer(0)||position->left()==header){ - link(x,to_left,position,header); - } - else{ - decrement(position); - link(x,to_right,position,header); - } - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - static std::size_t black_count(pointer node,pointer root) - { - if(node==pointer(0))return 0; - std::size_t sum=0; - for(;;){ - if(node->color()==black)++sum; - if(node==root)break; - node=node->parent(); - } - return sum; - } -#endif -}; - -template -struct ordered_index_node_trampoline: - ordered_index_node_impl< - AugmentPolicy, - typename boost::detail::allocator::rebind_to< - typename Super::allocator_type, - char - >::type - > -{ - typedef ordered_index_node_impl< - AugmentPolicy, - typename boost::detail::allocator::rebind_to< - typename Super::allocator_type, - char - >::type - > impl_type; -}; - -template -struct ordered_index_node: - Super,ordered_index_node_trampoline -{ -private: - typedef ordered_index_node_trampoline trampoline; - -public: - typedef typename trampoline::impl_type impl_type; - typedef typename trampoline::color_ref impl_color_ref; - typedef typename trampoline::parent_ref impl_parent_ref; - typedef typename trampoline::pointer impl_pointer; - typedef typename trampoline::const_pointer const_impl_pointer; - - impl_color_ref color(){return trampoline::color();} - ordered_index_color color()const{return trampoline::color();} - impl_parent_ref parent(){return trampoline::parent();} - impl_pointer parent()const{return trampoline::parent();} - impl_pointer& left(){return trampoline::left();} - impl_pointer left()const{return trampoline::left();} - impl_pointer& right(){return trampoline::right();} - impl_pointer right()const{return trampoline::right();} - - impl_pointer impl() - { - return static_cast( - static_cast(static_cast(this))); - } - - const_impl_pointer impl()const - { - return static_cast( - static_cast(static_cast(this))); - } - - static ordered_index_node* from_impl(impl_pointer x) - { - return - static_cast( - static_cast( - raw_ptr(x))); - } - - static const ordered_index_node* from_impl(const_impl_pointer x) - { - return - static_cast( - static_cast( - raw_ptr(x))); - } - - /* interoperability with bidir_node_iterator */ - - static void increment(ordered_index_node*& x) - { - impl_pointer xi=x->impl(); - trampoline::increment(xi); - x=from_impl(xi); - } - - static void decrement(ordered_index_node*& x) - { - impl_pointer xi=x->impl(); - trampoline::decrement(xi); - x=from_impl(xi); - } -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_ops.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_ops.hpp deleted file mode 100644 index 84d5cacae19..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_ops.hpp +++ /dev/null @@ -1,266 +0,0 @@ -/* Copyright 2003-2014 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - * - * The internal implementation of red-black trees is based on that of SGI STL - * stl_tree.h file: - * - * Copyright (c) 1996,1997 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_OPS_HPP -#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_OPS_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Common code for index memfuns having templatized and - * non-templatized versions. - * Implementation note: When CompatibleKey is consistently promoted to - * KeyFromValue::result_type for comparison, the promotion is made once in - * advance to increase efficiency. - */ - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline Node* ordered_index_find( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp) -{ - typedef typename KeyFromValue::result_type key_type; - - return ordered_index_find( - top,y,key,x,comp, - mpl::and_< - promotes_1st_arg, - promotes_2nd_arg >()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleCompare -> -inline Node* ordered_index_find( - Node* top,Node* y,const KeyFromValue& key, - const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, - const CompatibleCompare& comp,mpl::true_) -{ - return ordered_index_find(top,y,key,x,comp,mpl::false_()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline Node* ordered_index_find( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp,mpl::false_) -{ - Node* y0=y; - - while (top){ - if(!comp(key(top->value()),x)){ - y=top; - top=Node::from_impl(top->left()); - } - else top=Node::from_impl(top->right()); - } - - return (y==y0||comp(x,key(y->value())))?y0:y; -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline Node* ordered_index_lower_bound( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp) -{ - typedef typename KeyFromValue::result_type key_type; - - return ordered_index_lower_bound( - top,y,key,x,comp, - promotes_2nd_arg()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleCompare -> -inline Node* ordered_index_lower_bound( - Node* top,Node* y,const KeyFromValue& key, - const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, - const CompatibleCompare& comp,mpl::true_) -{ - return ordered_index_lower_bound(top,y,key,x,comp,mpl::false_()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline Node* ordered_index_lower_bound( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp,mpl::false_) -{ - while(top){ - if(!comp(key(top->value()),x)){ - y=top; - top=Node::from_impl(top->left()); - } - else top=Node::from_impl(top->right()); - } - - return y; -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline Node* ordered_index_upper_bound( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp) -{ - typedef typename KeyFromValue::result_type key_type; - - return ordered_index_upper_bound( - top,y,key,x,comp, - promotes_1st_arg()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleCompare -> -inline Node* ordered_index_upper_bound( - Node* top,Node* y,const KeyFromValue& key, - const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, - const CompatibleCompare& comp,mpl::true_) -{ - return ordered_index_upper_bound(top,y,key,x,comp,mpl::false_()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline Node* ordered_index_upper_bound( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp,mpl::false_) -{ - while(top){ - if(comp(x,key(top->value()))){ - y=top; - top=Node::from_impl(top->left()); - } - else top=Node::from_impl(top->right()); - } - - return y; -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::pair ordered_index_equal_range( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp) -{ - typedef typename KeyFromValue::result_type key_type; - - return ordered_index_equal_range( - top,y,key,x,comp, - mpl::and_< - promotes_1st_arg, - promotes_2nd_arg >()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleCompare -> -inline std::pair ordered_index_equal_range( - Node* top,Node* y,const KeyFromValue& key, - const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, - const CompatibleCompare& comp,mpl::true_) -{ - return ordered_index_equal_range(top,y,key,x,comp,mpl::false_()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::pair ordered_index_equal_range( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp,mpl::false_) -{ - while(top){ - if(comp(key(top->value()),x)){ - top=Node::from_impl(top->right()); - } - else if(comp(x,key(top->value()))){ - y=top; - top=Node::from_impl(top->left()); - } - else{ - return std::pair( - ordered_index_lower_bound( - Node::from_impl(top->left()),top,key,x,comp,mpl::false_()), - ordered_index_upper_bound( - Node::from_impl(top->right()),y,key,x,comp,mpl::false_())); - } - } - - return std::pair(y,y); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/promotes_arg.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/promotes_arg.hpp deleted file mode 100644 index 7a11b6e9fbe..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/promotes_arg.hpp +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright 2003-2017 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_PROMOTES_ARG_HPP -#define BOOST_MULTI_INDEX_DETAIL_PROMOTES_ARG_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include - -/* Metafunctions to check if f(arg1,arg2) promotes either arg1 to the type of - * arg2 or viceversa. By default, (i.e. if it cannot be determined), no - * promotion is assumed. - */ - -#if BOOST_WORKAROUND(BOOST_MSVC,<1400) - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template -struct promotes_1st_arg:mpl::false_{}; - -template -struct promotes_2nd_arg:mpl::false_{}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#else - -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template -struct promotes_1st_arg: - mpl::and_< - mpl::not_ >, - is_convertible, - is_transparent - > -{}; - -template -struct promotes_2nd_arg: - mpl::and_< - mpl::not_ >, - is_convertible, - is_transparent - > -{}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/raw_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/raw_ptr.hpp deleted file mode 100644 index c32007435c0..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/raw_ptr.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_RAW_PTR_HPP -#define BOOST_MULTI_INDEX_DETAIL_RAW_PTR_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* gets the underlying pointer of a pointer-like value */ - -template -inline RawPointer raw_ptr(RawPointer const& p,mpl::true_) -{ - return p; -} - -template -inline RawPointer raw_ptr(Pointer const& p,mpl::false_) -{ - return p==Pointer(0)?0:&*p; -} - -template -inline RawPointer raw_ptr(Pointer const& p) -{ - return raw_ptr(p,is_same()); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/restore_wstrict_aliasing.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/restore_wstrict_aliasing.hpp deleted file mode 100644 index ee2c799d5a8..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/restore_wstrict_aliasing.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright 2003-2016 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#define BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING -#include -#undef BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_loader.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_loader.hpp deleted file mode 100644 index 4b00345a6d9..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_loader.hpp +++ /dev/null @@ -1,173 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_LOADER_HPP -#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_LOADER_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* This class implements a serialization rearranger for random access - * indices. In order to achieve O(n) performance, the following strategy - * is followed: the nodes of the index are handled as if in a bidirectional - * list, where the next pointers are stored in the original - * random_access_index_ptr_array and the prev pointers are stored in - * an auxiliary array. Rearranging of nodes in such a bidirectional list - * is constant time. Once all the arrangements are performed (on destruction - * time) the list is traversed in reverse order and - * pointers are swapped and set accordingly so that they recover its - * original semantics ( *(node->up())==node ) while retaining the - * new order. - */ - -template -class random_access_index_loader_base:private noncopyable -{ -protected: - typedef random_access_index_node_impl< - typename boost::detail::allocator::rebind_to< - Allocator, - char - >::type - > node_impl_type; - typedef typename node_impl_type::pointer node_impl_pointer; - typedef random_access_index_ptr_array ptr_array; - - random_access_index_loader_base(const Allocator& al_,ptr_array& ptrs_): - al(al_), - ptrs(ptrs_), - header(*ptrs.end()), - prev_spc(al,0), - preprocessed(false) - {} - - ~random_access_index_loader_base() - { - if(preprocessed) - { - node_impl_pointer n=header; - next(n)=n; - - for(std::size_t i=ptrs.size();i--;){ - n=prev(n); - std::size_t d=position(n); - if(d!=i){ - node_impl_pointer m=prev(next_at(i)); - std::swap(m->up(),n->up()); - next_at(d)=next_at(i); - std::swap(prev_at(d),prev_at(i)); - } - next(n)=n; - } - } - } - - void rearrange(node_impl_pointer position_,node_impl_pointer x) - { - preprocess(); /* only incur this penalty if rearrange() is ever called */ - if(position_==node_impl_pointer(0))position_=header; - next(prev(x))=next(x); - prev(next(x))=prev(x); - prev(x)=position_; - next(x)=next(position_); - next(prev(x))=prev(next(x))=x; - } - -private: - void preprocess() - { - if(!preprocessed){ - /* get space for the auxiliary prev array */ - auto_space tmp(al,ptrs.size()+1); - prev_spc.swap(tmp); - - /* prev_spc elements point to the prev nodes */ - std::rotate_copy( - &*ptrs.begin(),&*ptrs.end(),&*ptrs.end()+1,&*prev_spc.data()); - - /* ptrs elements point to the next nodes */ - std::rotate(&*ptrs.begin(),&*ptrs.begin()+1,&*ptrs.end()+1); - - preprocessed=true; - } - } - - std::size_t position(node_impl_pointer x)const - { - return (std::size_t)(x->up()-ptrs.begin()); - } - - node_impl_pointer& next_at(std::size_t n)const - { - return *ptrs.at(n); - } - - node_impl_pointer& prev_at(std::size_t n)const - { - return *(prev_spc.data()+n); - } - - node_impl_pointer& next(node_impl_pointer x)const - { - return *(x->up()); - } - - node_impl_pointer& prev(node_impl_pointer x)const - { - return prev_at(position(x)); - } - - Allocator al; - ptr_array& ptrs; - node_impl_pointer header; - auto_space prev_spc; - bool preprocessed; -}; - -template -class random_access_index_loader: - private random_access_index_loader_base -{ - typedef random_access_index_loader_base super; - typedef typename super::node_impl_pointer node_impl_pointer; - typedef typename super::ptr_array ptr_array; - -public: - random_access_index_loader(const Allocator& al_,ptr_array& ptrs_): - super(al_,ptrs_) - {} - - void rearrange(Node* position_,Node *x) - { - super::rearrange( - position_?position_->impl():node_impl_pointer(0),x->impl()); - } -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_node.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_node.hpp deleted file mode 100644 index ad61ea25dda..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_node.hpp +++ /dev/null @@ -1,273 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_NODE_HPP -#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_NODE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template -struct random_access_index_node_impl -{ - typedef typename - boost::detail::allocator::rebind_to< - Allocator,random_access_index_node_impl - >::type::pointer pointer; - typedef typename - boost::detail::allocator::rebind_to< - Allocator,random_access_index_node_impl - >::type::const_pointer const_pointer; - typedef typename - boost::detail::allocator::rebind_to< - Allocator,pointer - >::type::pointer ptr_pointer; - - ptr_pointer& up(){return up_;} - ptr_pointer up()const{return up_;} - - /* interoperability with rnd_node_iterator */ - - static void increment(pointer& x) - { - x=*(x->up()+1); - } - - static void decrement(pointer& x) - { - x=*(x->up()-1); - } - - static void advance(pointer& x,std::ptrdiff_t n) - { - x=*(x->up()+n); - } - - static std::ptrdiff_t distance(pointer x,pointer y) - { - return y->up()-x->up(); - } - - /* algorithmic stuff */ - - static void relocate(ptr_pointer pos,ptr_pointer x) - { - pointer n=*x; - if(xup()=pos-1; - } - else{ - while(x!=pos){ - *x=*(x-1); - (*x)->up()=x; - --x; - } - *pos=n; - n->up()=pos; - } - }; - - static void relocate(ptr_pointer pos,ptr_pointer first,ptr_pointer last) - { - ptr_pointer begin,middle,end; - if(posup()=begin+j; - break; - } - else{ - *(begin+j)=*(begin+k); - (*(begin+j))->up()=begin+j; - } - - if(kup()=begin+k; - break; - } - else{ - *(begin+k)=*(begin+j); - (*(begin+k))->up()=begin+k; - } - } - } - }; - - static void extract(ptr_pointer x,ptr_pointer pend) - { - --pend; - while(x!=pend){ - *x=*(x+1); - (*x)->up()=x; - ++x; - } - } - - static void transfer( - ptr_pointer pbegin0,ptr_pointer pend0,ptr_pointer pbegin1) - { - while(pbegin0!=pend0){ - *pbegin1=*pbegin0++; - (*pbegin1)->up()=pbegin1; - ++pbegin1; - } - } - - static void reverse(ptr_pointer pbegin,ptr_pointer pend) - { - std::ptrdiff_t d=(pend-pbegin)/2; - for(std::ptrdiff_t i=0;iup()=pbegin; - (*pend)->up()=pend; - ++pbegin; - } - } - -private: - ptr_pointer up_; -}; - -template -struct random_access_index_node_trampoline: - random_access_index_node_impl< - typename boost::detail::allocator::rebind_to< - typename Super::allocator_type, - char - >::type - > -{ - typedef random_access_index_node_impl< - typename boost::detail::allocator::rebind_to< - typename Super::allocator_type, - char - >::type - > impl_type; -}; - -template -struct random_access_index_node: - Super,random_access_index_node_trampoline -{ -private: - typedef random_access_index_node_trampoline trampoline; - -public: - typedef typename trampoline::impl_type impl_type; - typedef typename trampoline::pointer impl_pointer; - typedef typename trampoline::const_pointer const_impl_pointer; - typedef typename trampoline::ptr_pointer impl_ptr_pointer; - - impl_ptr_pointer& up(){return trampoline::up();} - impl_ptr_pointer up()const{return trampoline::up();} - - impl_pointer impl() - { - return static_cast( - static_cast(static_cast(this))); - } - - const_impl_pointer impl()const - { - return static_cast( - static_cast(static_cast(this))); - } - - static random_access_index_node* from_impl(impl_pointer x) - { - return - static_cast( - static_cast( - raw_ptr(x))); - } - - static const random_access_index_node* from_impl(const_impl_pointer x) - { - return - static_cast( - static_cast( - raw_ptr(x))); - } - - /* interoperability with rnd_node_iterator */ - - static void increment(random_access_index_node*& x) - { - impl_pointer xi=x->impl(); - trampoline::increment(xi); - x=from_impl(xi); - } - - static void decrement(random_access_index_node*& x) - { - impl_pointer xi=x->impl(); - trampoline::decrement(xi); - x=from_impl(xi); - } - - static void advance(random_access_index_node*& x,std::ptrdiff_t n) - { - impl_pointer xi=x->impl(); - trampoline::advance(xi,n); - x=from_impl(xi); - } - - static std::ptrdiff_t distance( - random_access_index_node* x,random_access_index_node* y) - { - return trampoline::distance(x->impl(),y->impl()); - } -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ops.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ops.hpp deleted file mode 100644 index f5e76e4441f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ops.hpp +++ /dev/null @@ -1,203 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_OPS_HPP -#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_OPS_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Common code for random_access_index memfuns having templatized and - * non-templatized versions. - */ - -template -Node* random_access_index_remove( - random_access_index_ptr_array& ptrs,Predicate pred) -{ - typedef typename Node::value_type value_type; - typedef typename Node::impl_ptr_pointer impl_ptr_pointer; - - impl_ptr_pointer first=ptrs.begin(), - res=first, - last=ptrs.end(); - for(;first!=last;++first){ - if(!pred( - const_cast(Node::from_impl(*first)->value()))){ - if(first!=res){ - std::swap(*first,*res); - (*first)->up()=first; - (*res)->up()=res; - } - ++res; - } - } - return Node::from_impl(*res); -} - -template -Node* random_access_index_unique( - random_access_index_ptr_array& ptrs,BinaryPredicate binary_pred) -{ - typedef typename Node::value_type value_type; - typedef typename Node::impl_ptr_pointer impl_ptr_pointer; - - impl_ptr_pointer first=ptrs.begin(), - res=first, - last=ptrs.end(); - if(first!=last){ - for(;++first!=last;){ - if(!binary_pred( - const_cast(Node::from_impl(*res)->value()), - const_cast(Node::from_impl(*first)->value()))){ - ++res; - if(first!=res){ - std::swap(*first,*res); - (*first)->up()=first; - (*res)->up()=res; - } - } - } - ++res; - } - return Node::from_impl(*res); -} - -template -void random_access_index_inplace_merge( - const Allocator& al, - random_access_index_ptr_array& ptrs, - BOOST_DEDUCED_TYPENAME Node::impl_ptr_pointer first1,Compare comp) -{ - typedef typename Node::value_type value_type; - typedef typename Node::impl_pointer impl_pointer; - typedef typename Node::impl_ptr_pointer impl_ptr_pointer; - - auto_space spc(al,ptrs.size()); - - impl_ptr_pointer first0=ptrs.begin(), - last0=first1, - last1=ptrs.end(), - out=spc.data(); - while(first0!=last0&&first1!=last1){ - if(comp( - const_cast(Node::from_impl(*first1)->value()), - const_cast(Node::from_impl(*first0)->value()))){ - *out++=*first1++; - } - else{ - *out++=*first0++; - } - } - std::copy(&*first0,&*last0,&*out); - std::copy(&*first1,&*last1,&*out); - - first1=ptrs.begin(); - out=spc.data(); - while(first1!=last1){ - *first1=*out++; - (*first1)->up()=first1; - ++first1; - } -} - -/* sorting */ - -/* auxiliary stuff */ - -template -struct random_access_index_sort_compare -{ - typedef typename Node::impl_pointer first_argument_type; - typedef typename Node::impl_pointer second_argument_type; - typedef bool result_type; - - random_access_index_sort_compare(Compare comp_=Compare()):comp(comp_){} - - bool operator()( - typename Node::impl_pointer x,typename Node::impl_pointer y)const - { - typedef typename Node::value_type value_type; - - return comp( - const_cast(Node::from_impl(x)->value()), - const_cast(Node::from_impl(y)->value())); - } - -private: - Compare comp; -}; - -template -void random_access_index_sort( - const Allocator& al, - random_access_index_ptr_array& ptrs, - Compare comp) -{ - /* The implementation is extremely simple: an auxiliary - * array of pointers is sorted using stdlib facilities and - * then used to rearrange the index. This is suboptimal - * in space and time, but has some advantages over other - * possible approaches: - * - Use std::stable_sort() directly on ptrs using some - * special iterator in charge of maintaining pointers - * and up() pointers in sync: we cannot guarantee - * preservation of the container invariants in the face of - * exceptions, if, for instance, std::stable_sort throws - * when ptrs transitorily contains duplicate elements. - * - Rewrite the internal algorithms of std::stable_sort - * adapted for this case: besides being a fair amount of - * work, making a stable sort compatible with Boost.MultiIndex - * invariants (basically, no duplicates or missing elements - * even if an exception is thrown) is complicated, error-prone - * and possibly won't perform much better than the - * solution adopted. - */ - - if(ptrs.size()<=1)return; - - typedef typename Node::impl_pointer impl_pointer; - typedef typename Node::impl_ptr_pointer impl_ptr_pointer; - typedef random_access_index_sort_compare< - Node,Compare> ptr_compare; - - impl_ptr_pointer first=ptrs.begin(); - impl_ptr_pointer last=ptrs.end(); - auto_space< - impl_pointer, - Allocator> spc(al,ptrs.size()); - impl_ptr_pointer buf=spc.data(); - - std::copy(&*first,&*last,&*buf); - std::stable_sort(&*buf,&*buf+ptrs.size(),ptr_compare(comp)); - - while(first!=last){ - *first=*buf++; - (*first)->up()=first; - ++first; - } -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ptr_array.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ptr_array.hpp deleted file mode 100644 index bae1c851b8e..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ptr_array.hpp +++ /dev/null @@ -1,144 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_PTR_ARRAY_HPP -#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_PTR_ARRAY_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* pointer structure for use by random access indices */ - -template -class random_access_index_ptr_array:private noncopyable -{ - typedef random_access_index_node_impl< - typename boost::detail::allocator::rebind_to< - Allocator, - char - >::type - > node_impl_type; - -public: - typedef typename node_impl_type::pointer value_type; - typedef typename boost::detail::allocator::rebind_to< - Allocator,value_type - >::type::pointer pointer; - - random_access_index_ptr_array( - const Allocator& al,value_type end_,std::size_t sz): - size_(sz), - capacity_(sz), - spc(al,capacity_+1) - { - *end()=end_; - end_->up()=end(); - } - - std::size_t size()const{return size_;} - std::size_t capacity()const{return capacity_;} - - void room_for_one() - { - if(size_==capacity_){ - reserve(capacity_<=10?15:capacity_+capacity_/2); - } - } - - void reserve(std::size_t c) - { - if(c>capacity_)set_capacity(c); - } - - void shrink_to_fit() - { - if(capacity_>size_)set_capacity(size_); - } - - pointer begin()const{return ptrs();} - pointer end()const{return ptrs()+size_;} - pointer at(std::size_t n)const{return ptrs()+n;} - - void push_back(value_type x) - { - *(end()+1)=*end(); - (*(end()+1))->up()=end()+1; - *end()=x; - (*end())->up()=end(); - ++size_; - } - - void erase(value_type x) - { - node_impl_type::extract(x->up(),end()+1); - --size_; - } - - void clear() - { - *begin()=*end(); - (*begin())->up()=begin(); - size_=0; - } - - void swap(random_access_index_ptr_array& x) - { - std::swap(size_,x.size_); - std::swap(capacity_,x.capacity_); - spc.swap(x.spc); - } - -private: - std::size_t size_; - std::size_t capacity_; - auto_space spc; - - pointer ptrs()const - { - return spc.data(); - } - - void set_capacity(std::size_t c) - { - auto_space spc1(spc.get_allocator(),c+1); - node_impl_type::transfer(begin(),end()+1,spc1.data()); - spc.swap(spc1); - capacity_=c; - } -}; - -template -void swap( - random_access_index_ptr_array& x, - random_access_index_ptr_array& y) -{ - x.swap(y); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_node_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_node_iterator.hpp deleted file mode 100644 index 48026132fb7..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_node_iterator.hpp +++ /dev/null @@ -1,140 +0,0 @@ -/* Copyright 2003-2014 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_RND_NODE_ITERATOR_HPP -#define BOOST_MULTI_INDEX_DETAIL_RND_NODE_ITERATOR_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#include -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Iterator class for node-based indices with random access iterators. */ - -template -class rnd_node_iterator: - public random_access_iterator_helper< - rnd_node_iterator, - typename Node::value_type, - std::ptrdiff_t, - const typename Node::value_type*, - const typename Node::value_type&> -{ -public: - /* coverity[uninit_ctor]: suppress warning */ - rnd_node_iterator(){} - explicit rnd_node_iterator(Node* node_):node(node_){} - - const typename Node::value_type& operator*()const - { - return node->value(); - } - - rnd_node_iterator& operator++() - { - Node::increment(node); - return *this; - } - - rnd_node_iterator& operator--() - { - Node::decrement(node); - return *this; - } - - rnd_node_iterator& operator+=(std::ptrdiff_t n) - { - Node::advance(node,n); - return *this; - } - - rnd_node_iterator& operator-=(std::ptrdiff_t n) - { - Node::advance(node,-n); - return *this; - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* Serialization. As for why the following is public, - * see explanation in safe_mode_iterator notes in safe_mode.hpp. - */ - - BOOST_SERIALIZATION_SPLIT_MEMBER() - - typedef typename Node::base_type node_base_type; - - template - void save(Archive& ar,const unsigned int)const - { - node_base_type* bnode=node; - ar< - void load(Archive& ar,const unsigned int) - { - node_base_type* bnode; - ar>>serialization::make_nvp("pointer",bnode); - node=static_cast(bnode); - } -#endif - - /* get_node is not to be used by the user */ - - typedef Node node_type; - - Node* get_node()const{return node;} - -private: - Node* node; -}; - -template -bool operator==( - const rnd_node_iterator& x, - const rnd_node_iterator& y) -{ - return x.get_node()==y.get_node(); -} - -template -bool operator<( - const rnd_node_iterator& x, - const rnd_node_iterator& y) -{ - return Node::distance(x.get_node(),y.get_node())>0; -} - -template -std::ptrdiff_t operator-( - const rnd_node_iterator& x, - const rnd_node_iterator& y) -{ - return Node::distance(y.get_node(),x.get_node()); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnk_index_ops.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnk_index_ops.hpp deleted file mode 100644 index fb233cf4973..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnk_index_ops.hpp +++ /dev/null @@ -1,300 +0,0 @@ -/* Copyright 2003-2017 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_RNK_INDEX_OPS_HPP -#define BOOST_MULTI_INDEX_DETAIL_RNK_INDEX_OPS_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Common code for ranked_index memfuns having templatized and - * non-templatized versions. - */ - -template -inline std::size_t ranked_node_size(Pointer x) -{ - return x!=Pointer(0)?x->size:0; -} - -template -inline Pointer ranked_index_nth(std::size_t n,Pointer end_) -{ - Pointer top=end_->parent(); - if(top==Pointer(0)||n>=top->size)return end_; - - for(;;){ - std::size_t s=ranked_node_size(top->left()); - if(n==s)return top; - if(nleft(); - else{ - top=top->right(); - n-=s+1; - } - } -} - -template -inline std::size_t ranked_index_rank(Pointer x,Pointer end_) -{ - Pointer top=end_->parent(); - if(top==Pointer(0))return 0; - if(x==end_)return top->size; - - std::size_t s=ranked_node_size(x->left()); - while(x!=top){ - Pointer z=x->parent(); - if(x==z->right()){ - s+=ranked_node_size(z->left())+1; - } - x=z; - } - return s; -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::size_t ranked_index_find_rank( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp) -{ - typedef typename KeyFromValue::result_type key_type; - - return ranked_index_find_rank( - top,y,key,x,comp, - mpl::and_< - promotes_1st_arg, - promotes_2nd_arg >()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleCompare -> -inline std::size_t ranked_index_find_rank( - Node* top,Node* y,const KeyFromValue& key, - const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, - const CompatibleCompare& comp,mpl::true_) -{ - return ranked_index_find_rank(top,y,key,x,comp,mpl::false_()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::size_t ranked_index_find_rank( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp,mpl::false_) -{ - if(!top)return 0; - - std::size_t s=top->impl()->size, - s0=s; - Node* y0=y; - - do{ - if(!comp(key(top->value()),x)){ - y=top; - s-=ranked_node_size(y->right())+1; - top=Node::from_impl(top->left()); - } - else top=Node::from_impl(top->right()); - }while(top); - - return (y==y0||comp(x,key(y->value())))?s0:s; -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::size_t ranked_index_lower_bound_rank( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp) -{ - typedef typename KeyFromValue::result_type key_type; - - return ranked_index_lower_bound_rank( - top,y,key,x,comp, - promotes_2nd_arg()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleCompare -> -inline std::size_t ranked_index_lower_bound_rank( - Node* top,Node* y,const KeyFromValue& key, - const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, - const CompatibleCompare& comp,mpl::true_) -{ - return ranked_index_lower_bound_rank(top,y,key,x,comp,mpl::false_()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::size_t ranked_index_lower_bound_rank( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp,mpl::false_) -{ - if(!top)return 0; - - std::size_t s=top->impl()->size; - - do{ - if(!comp(key(top->value()),x)){ - y=top; - s-=ranked_node_size(y->right())+1; - top=Node::from_impl(top->left()); - } - else top=Node::from_impl(top->right()); - }while(top); - - return s; -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::size_t ranked_index_upper_bound_rank( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp) -{ - typedef typename KeyFromValue::result_type key_type; - - return ranked_index_upper_bound_rank( - top,y,key,x,comp, - promotes_1st_arg()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleCompare -> -inline std::size_t ranked_index_upper_bound_rank( - Node* top,Node* y,const KeyFromValue& key, - const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, - const CompatibleCompare& comp,mpl::true_) -{ - return ranked_index_upper_bound_rank(top,y,key,x,comp,mpl::false_()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::size_t ranked_index_upper_bound_rank( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp,mpl::false_) -{ - if(!top)return 0; - - std::size_t s=top->impl()->size; - - do{ - if(comp(x,key(top->value()))){ - y=top; - s-=ranked_node_size(y->right())+1; - top=Node::from_impl(top->left()); - } - else top=Node::from_impl(top->right()); - }while(top); - - return s; -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::pair ranked_index_equal_range_rank( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp) -{ - typedef typename KeyFromValue::result_type key_type; - - return ranked_index_equal_range_rank( - top,y,key,x,comp, - mpl::and_< - promotes_1st_arg, - promotes_2nd_arg >()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleCompare -> -inline std::pair ranked_index_equal_range_rank( - Node* top,Node* y,const KeyFromValue& key, - const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, - const CompatibleCompare& comp,mpl::true_) -{ - return ranked_index_equal_range_rank(top,y,key,x,comp,mpl::false_()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::pair ranked_index_equal_range_rank( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp,mpl::false_) -{ - if(!top)return std::pair(0,0); - - std::size_t s=top->impl()->size; - - do{ - if(comp(key(top->value()),x)){ - top=Node::from_impl(top->right()); - } - else if(comp(x,key(top->value()))){ - y=top; - s-=ranked_node_size(y->right())+1; - top=Node::from_impl(top->left()); - } - else{ - return std::pair( - s-top->impl()->size+ - ranked_index_lower_bound_rank( - Node::from_impl(top->left()),top,key,x,comp,mpl::false_()), - s-ranked_node_size(top->right())+ - ranked_index_upper_bound_rank( - Node::from_impl(top->right()),y,key,x,comp,mpl::false_())); - } - }while(top); - - return std::pair(s,s); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/safe_mode.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/safe_mode.hpp deleted file mode 100644 index 905270e9fb3..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/safe_mode.hpp +++ /dev/null @@ -1,588 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_SAFE_MODE_HPP -#define BOOST_MULTI_INDEX_DETAIL_SAFE_MODE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -/* Safe mode machinery, in the spirit of Cay Hortmann's "Safe STL" - * (http://www.horstmann.com/safestl.html). - * In this mode, containers of type Container are derived from - * safe_container, and their corresponding iterators - * are wrapped with safe_iterator. These classes provide - * an internal record of which iterators are at a given moment associated - * to a given container, and properly mark the iterators as invalid - * when the container gets destroyed. - * Iterators are chained in a single attached list, whose header is - * kept by the container. More elaborate data structures would yield better - * performance, but I decided to keep complexity to a minimum since - * speed is not an issue here. - * Safe mode iterators automatically check that only proper operations - * are performed on them: for instance, an invalid iterator cannot be - * dereferenced. Additionally, a set of utilty macros and functions are - * provided that serve to implement preconditions and cooperate with - * the framework within the container. - * Iterators can also be unchecked, i.e. they do not have info about - * which container they belong in. This situation arises when the iterator - * is restored from a serialization archive: only information on the node - * is available, and it is not possible to determine to which container - * the iterator is associated to. The only sensible policy is to assume - * unchecked iterators are valid, though this can certainly generate false - * positive safe mode checks. - * This is not a full-fledged safe mode framework, and is only intended - * for use within the limits of Boost.MultiIndex. - */ - -/* Assertion macros. These resolve to no-ops if - * !defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE). - */ - -#if !defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) -#undef BOOST_MULTI_INDEX_SAFE_MODE_ASSERT -#define BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(expr,error_code) ((void)0) -#else -#if !defined(BOOST_MULTI_INDEX_SAFE_MODE_ASSERT) -#include -#define BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(expr,error_code) BOOST_ASSERT(expr) -#endif -#endif - -#define BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_valid_iterator(it), \ - safe_mode::invalid_iterator); - -#define BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(it) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_dereferenceable_iterator(it), \ - safe_mode::not_dereferenceable_iterator); - -#define BOOST_MULTI_INDEX_CHECK_INCREMENTABLE_ITERATOR(it) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_incrementable_iterator(it), \ - safe_mode::not_incrementable_iterator); - -#define BOOST_MULTI_INDEX_CHECK_DECREMENTABLE_ITERATOR(it) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_decrementable_iterator(it), \ - safe_mode::not_decrementable_iterator); - -#define BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,cont) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_is_owner(it,cont), \ - safe_mode::not_owner); - -#define BOOST_MULTI_INDEX_CHECK_SAME_OWNER(it0,it1) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_same_owner(it0,it1), \ - safe_mode::not_same_owner); - -#define BOOST_MULTI_INDEX_CHECK_VALID_RANGE(it0,it1) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_valid_range(it0,it1), \ - safe_mode::invalid_range); - -#define BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(it,it0,it1) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_outside_range(it,it0,it1), \ - safe_mode::inside_range); - -#define BOOST_MULTI_INDEX_CHECK_IN_BOUNDS(it,n) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_in_bounds(it,n), \ - safe_mode::out_of_bounds); - -#define BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(cont0,cont1) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_different_container(cont0,cont1), \ - safe_mode::same_container); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#include -#endif - -#if defined(BOOST_HAS_THREADS) -#include -#endif - -namespace boost{ - -namespace multi_index{ - -namespace safe_mode{ - -/* Checking routines. Assume the best for unchecked iterators - * (i.e. they pass the checking when there is not enough info - * to know.) - */ - -template -inline bool check_valid_iterator(const Iterator& it) -{ - return it.valid()||it.unchecked(); -} - -template -inline bool check_dereferenceable_iterator(const Iterator& it) -{ - return (it.valid()&&it!=it.owner()->end())||it.unchecked(); -} - -template -inline bool check_incrementable_iterator(const Iterator& it) -{ - return (it.valid()&&it!=it.owner()->end())||it.unchecked(); -} - -template -inline bool check_decrementable_iterator(const Iterator& it) -{ - return (it.valid()&&it!=it.owner()->begin())||it.unchecked(); -} - -template -inline bool check_is_owner( - const Iterator& it,const typename Iterator::container_type& cont) -{ - return (it.valid()&&it.owner()==&cont)||it.unchecked(); -} - -template -inline bool check_same_owner(const Iterator& it0,const Iterator& it1) -{ - return (it0.valid()&&it1.valid()&&it0.owner()==it1.owner())|| - it0.unchecked()||it1.unchecked(); -} - -template -inline bool check_valid_range(const Iterator& it0,const Iterator& it1) -{ - if(!check_same_owner(it0,it1))return false; - - if(it0.valid()){ - Iterator last=it0.owner()->end(); - if(it1==last)return true; - - for(Iterator first=it0;first!=last;++first){ - if(first==it1)return true; - } - return false; - } - return true; -} - -template -inline bool check_outside_range( - const Iterator& it,const Iterator& it0,const Iterator& it1) -{ - if(!check_same_owner(it0,it1))return false; - - if(it0.valid()){ - Iterator last=it0.owner()->end(); - bool found=false; - - Iterator first=it0; - for(;first!=last;++first){ - if(first==it1)break; - - /* crucial that this check goes after previous break */ - - if(first==it)found=true; - } - if(first!=it1)return false; - return !found; - } - return true; -} - -template -inline bool check_in_bounds(const Iterator& it,Difference n) -{ - if(it.unchecked())return true; - if(!it.valid()) return false; - if(n>0) return it.owner()->end()-it>=n; - else return it.owner()->begin()-it<=n; -} - -template -inline bool check_different_container( - const Container& cont0,const Container& cont1) -{ - return &cont0!=&cont1; -} - -/* Invalidates all iterators equivalent to that given. Safe containers - * must call this when deleting elements: the safe mode framework cannot - * perform this operation automatically without outside help. - */ - -template -inline void detach_equivalent_iterators(Iterator& it) -{ - if(it.valid()){ - { -#if defined(BOOST_HAS_THREADS) - boost::detail::lightweight_mutex::scoped_lock lock(it.cont->mutex); -#endif - - Iterator *prev_,*next_; - for( - prev_=static_cast(&it.cont->header); - (next_=static_cast(prev_->next))!=0;){ - if(next_!=&it&&*next_==it){ - prev_->next=next_->next; - next_->cont=0; - } - else prev_=next_; - } - } - it.detach(); - } -} - -template class safe_container; /* fwd decl. */ - -} /* namespace multi_index::safe_mode */ - -namespace detail{ - -class safe_container_base; /* fwd decl. */ - -class safe_iterator_base -{ -public: - bool valid()const{return cont!=0;} - bool unchecked()const{return unchecked_;} - - inline void detach(); - - void uncheck() - { - detach(); - unchecked_=true; - } - -protected: - safe_iterator_base():cont(0),next(0),unchecked_(false){} - - explicit safe_iterator_base(safe_container_base* cont_): - unchecked_(false) - { - attach(cont_); - } - - safe_iterator_base(const safe_iterator_base& it): - unchecked_(it.unchecked_) - { - attach(it.cont); - } - - safe_iterator_base& operator=(const safe_iterator_base& it) - { - unchecked_=it.unchecked_; - safe_container_base* new_cont=it.cont; - if(cont!=new_cont){ - detach(); - attach(new_cont); - } - return *this; - } - - ~safe_iterator_base() - { - detach(); - } - - const safe_container_base* owner()const{return cont;} - -BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS: - friend class safe_container_base; - -#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) - template friend class safe_mode::safe_container; - template friend - void safe_mode::detach_equivalent_iterators(Iterator&); -#endif - - inline void attach(safe_container_base* cont_); - - safe_container_base* cont; - safe_iterator_base* next; - bool unchecked_; -}; - -class safe_container_base:private noncopyable -{ -public: - safe_container_base(){} - -BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: - friend class safe_iterator_base; - -#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) - template friend - void safe_mode::detach_equivalent_iterators(Iterator&); -#endif - - ~safe_container_base() - { - /* Detaches all remaining iterators, which by now will - * be those pointing to the end of the container. - */ - - for(safe_iterator_base* it=header.next;it;it=it->next)it->cont=0; - header.next=0; - } - - void swap(safe_container_base& x) - { - for(safe_iterator_base* it0=header.next;it0;it0=it0->next)it0->cont=&x; - for(safe_iterator_base* it1=x.header.next;it1;it1=it1->next)it1->cont=this; - std::swap(header.cont,x.header.cont); - std::swap(header.next,x.header.next); - } - - safe_iterator_base header; - -#if defined(BOOST_HAS_THREADS) - boost::detail::lightweight_mutex mutex; -#endif -}; - -void safe_iterator_base::attach(safe_container_base* cont_) -{ - cont=cont_; - if(cont){ -#if defined(BOOST_HAS_THREADS) - boost::detail::lightweight_mutex::scoped_lock lock(cont->mutex); -#endif - - next=cont->header.next; - cont->header.next=this; - } -} - -void safe_iterator_base::detach() -{ - if(cont){ -#if defined(BOOST_HAS_THREADS) - boost::detail::lightweight_mutex::scoped_lock lock(cont->mutex); -#endif - - safe_iterator_base *prev_,*next_; - for(prev_=&cont->header;(next_=prev_->next)!=this;prev_=next_){} - prev_->next=next; - cont=0; - } -} - -} /* namespace multi_index::detail */ - -namespace safe_mode{ - -/* In order to enable safe mode on a container: - * - The container must derive from safe_container, - * - iterators must be generated via safe_iterator, which adapts a - * preexistent unsafe iterator class. - */ - -template -class safe_container; - -template -class safe_iterator: - public detail::iter_adaptor,Iterator>, - public detail::safe_iterator_base -{ - typedef detail::iter_adaptor super; - typedef detail::safe_iterator_base safe_super; - -public: - typedef Container container_type; - typedef typename Iterator::reference reference; - typedef typename Iterator::difference_type difference_type; - - safe_iterator(){} - explicit safe_iterator(safe_container* cont_): - safe_super(cont_){} - template - safe_iterator(const T0& t0,safe_container* cont_): - super(Iterator(t0)),safe_super(cont_){} - template - safe_iterator( - const T0& t0,const T1& t1,safe_container* cont_): - super(Iterator(t0,t1)),safe_super(cont_){} - - safe_iterator& operator=(const safe_iterator& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x); - this->base_reference()=x.base_reference(); - safe_super::operator=(x); - return *this; - } - - const container_type* owner()const - { - return - static_cast( - static_cast*>( - this->safe_super::owner())); - } - - /* get_node is not to be used by the user */ - - typedef typename Iterator::node_type node_type; - - node_type* get_node()const{return this->base_reference().get_node();} - -private: - friend class boost::multi_index::detail::iter_adaptor_access; - - reference dereference()const - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(*this); - return *(this->base_reference()); - } - - bool equal(const safe_iterator& x)const - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x); - BOOST_MULTI_INDEX_CHECK_SAME_OWNER(*this,x); - return this->base_reference()==x.base_reference(); - } - - void increment() - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); - BOOST_MULTI_INDEX_CHECK_INCREMENTABLE_ITERATOR(*this); - ++(this->base_reference()); - } - - void decrement() - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); - BOOST_MULTI_INDEX_CHECK_DECREMENTABLE_ITERATOR(*this); - --(this->base_reference()); - } - - void advance(difference_type n) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); - BOOST_MULTI_INDEX_CHECK_IN_BOUNDS(*this,n); - this->base_reference()+=n; - } - - difference_type distance_to(const safe_iterator& x)const - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x); - BOOST_MULTI_INDEX_CHECK_SAME_OWNER(*this,x); - return x.base_reference()-this->base_reference(); - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* Serialization. Note that Iterator::save and Iterator:load - * are assumed to be defined and public: at first sight it seems - * like we could have resorted to the public serialization interface - * for doing the forwarding to the adapted iterator class: - * ar<>base_reference(); - * but this would cause incompatibilities if a saving - * program is in safe mode and the loading program is not, or - * viceversa --in safe mode, the archived iterator data is one layer - * deeper, this is especially relevant with XML archives. - * It'd be nice if Boost.Serialization provided some forwarding - * facility for use by adaptor classes. - */ - - friend class boost::serialization::access; - - BOOST_SERIALIZATION_SPLIT_MEMBER() - - template - void save(Archive& ar,const unsigned int version)const - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); - this->base_reference().save(ar,version); - } - - template - void load(Archive& ar,const unsigned int version) - { - this->base_reference().load(ar,version); - safe_super::uncheck(); - } -#endif -}; - -template -class safe_container:public detail::safe_container_base -{ - typedef detail::safe_container_base super; - -public: - void detach_dereferenceable_iterators() - { - typedef typename Container::iterator iterator; - - iterator end_=static_cast(this)->end(); - iterator *prev_,*next_; - for( - prev_=static_cast(&this->header); - (next_=static_cast(prev_->next))!=0;){ - if(*next_!=end_){ - prev_->next=next_->next; - next_->cont=0; - } - else prev_=next_; - } - } - - void swap(safe_container& x) - { - super::swap(x); - } -}; - -} /* namespace multi_index::safe_mode */ - -} /* namespace multi_index */ - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -namespace serialization{ -template -struct version< - boost::multi_index::safe_mode::safe_iterator -> -{ - BOOST_STATIC_CONSTANT( - int,value=boost::serialization::version::value); -}; -} /* namespace serialization */ -#endif - -} /* namespace boost */ - -#endif /* BOOST_MULTI_INDEX_ENABLE_SAFE_MODE */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/scope_guard.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/scope_guard.hpp deleted file mode 100644 index 116f8f50415..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/scope_guard.hpp +++ /dev/null @@ -1,453 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_SCOPE_GUARD_HPP -#define BOOST_MULTI_INDEX_DETAIL_SCOPE_GUARD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Until some official version of the ScopeGuard idiom makes it into Boost, - * we locally define our own. This is a merely reformated version of - * ScopeGuard.h as defined in: - * Alexandrescu, A., Marginean, P.:"Generic: Change the Way You - * Write Exception-Safe Code - Forever", C/C++ Users Jornal, Dec 2000, - * http://www.drdobbs.com/184403758 - * with the following modifications: - * - General pretty formatting (pretty to my taste at least.) - * - Naming style changed to standard C++ library requirements. - * - Added scope_guard_impl4 and obj_scope_guard_impl3, (Boost.MultiIndex - * needs them). A better design would provide guards for many more - * arguments through the Boost Preprocessor Library. - * - Added scope_guard_impl_base::touch (see below.) - * - Removed RefHolder and ByRef, whose functionality is provided - * already by Boost.Ref. - * - Removed static make_guard's and make_obj_guard's, so that the code - * will work even if BOOST_NO_MEMBER_TEMPLATES is defined. This forces - * us to move some private ctors to public, though. - * - * NB: CodeWarrior Pro 8 seems to have problems looking up safe_execute - * without an explicit qualification. - * - * We also define the following variants of the idiom: - * - * - make_guard_if_c( ... ) - * - make_guard_if( ... ) - * - make_obj_guard_if_c( ... ) - * - make_obj_guard_if( ... ) - * which may be used with a compile-time constant to yield - * a "null_guard" if the boolean compile-time parameter is false, - * or conversely, the guard is only constructed if the constant is true. - * This is useful to avoid extra tagging, because the returned - * null_guard can be optimzed comlpetely away by the compiler. - */ - -class scope_guard_impl_base -{ -public: - scope_guard_impl_base():dismissed_(false){} - void dismiss()const{dismissed_=true;} - - /* This helps prevent some "unused variable" warnings under, for instance, - * GCC 3.2. - */ - void touch()const{} - -protected: - ~scope_guard_impl_base(){} - - scope_guard_impl_base(const scope_guard_impl_base& other): - dismissed_(other.dismissed_) - { - other.dismiss(); - } - - template - static void safe_execute(J& j){ - BOOST_TRY{ - if(!j.dismissed_)j.execute(); - } - BOOST_CATCH(...){} - BOOST_CATCH_END - } - - mutable bool dismissed_; - -private: - scope_guard_impl_base& operator=(const scope_guard_impl_base&); -}; - -typedef const scope_guard_impl_base& scope_guard; - -struct null_guard : public scope_guard_impl_base -{ - template< class T1 > - null_guard( const T1& ) - { } - - template< class T1, class T2 > - null_guard( const T1&, const T2& ) - { } - - template< class T1, class T2, class T3 > - null_guard( const T1&, const T2&, const T3& ) - { } - - template< class T1, class T2, class T3, class T4 > - null_guard( const T1&, const T2&, const T3&, const T4& ) - { } - - template< class T1, class T2, class T3, class T4, class T5 > - null_guard( const T1&, const T2&, const T3&, const T4&, const T5& ) - { } -}; - -template< bool cond, class T > -struct null_guard_return -{ - typedef typename boost::mpl::if_c::type type; -}; - -template -class scope_guard_impl0:public scope_guard_impl_base -{ -public: - scope_guard_impl0(F fun):fun_(fun){} - ~scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);} - void execute(){fun_();} - -protected: - - F fun_; -}; - -template -inline scope_guard_impl0 make_guard(F fun) -{ - return scope_guard_impl0(fun); -} - -template -inline typename null_guard_return >::type -make_guard_if_c(F fun) -{ - return typename null_guard_return >::type(fun); -} - -template -inline typename null_guard_return >::type -make_guard_if(F fun) -{ - return make_guard_if(fun); -} - -template -class scope_guard_impl1:public scope_guard_impl_base -{ -public: - scope_guard_impl1(F fun,P1 p1):fun_(fun),p1_(p1){} - ~scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);} - void execute(){fun_(p1_);} - -protected: - F fun_; - const P1 p1_; -}; - -template -inline scope_guard_impl1 make_guard(F fun,P1 p1) -{ - return scope_guard_impl1(fun,p1); -} - -template -inline typename null_guard_return >::type -make_guard_if_c(F fun,P1 p1) -{ - return typename null_guard_return >::type(fun,p1); -} - -template -inline typename null_guard_return >::type -make_guard_if(F fun,P1 p1) -{ - return make_guard_if_c(fun,p1); -} - -template -class scope_guard_impl2:public scope_guard_impl_base -{ -public: - scope_guard_impl2(F fun,P1 p1,P2 p2):fun_(fun),p1_(p1),p2_(p2){} - ~scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);} - void execute(){fun_(p1_,p2_);} - -protected: - F fun_; - const P1 p1_; - const P2 p2_; -}; - -template -inline scope_guard_impl2 make_guard(F fun,P1 p1,P2 p2) -{ - return scope_guard_impl2(fun,p1,p2); -} - -template -inline typename null_guard_return >::type -make_guard_if_c(F fun,P1 p1,P2 p2) -{ - return typename null_guard_return >::type(fun,p1,p2); -} - -template -inline typename null_guard_return >::type -make_guard_if(F fun,P1 p1,P2 p2) -{ - return make_guard_if_c(fun,p1,p2); -} - -template -class scope_guard_impl3:public scope_guard_impl_base -{ -public: - scope_guard_impl3(F fun,P1 p1,P2 p2,P3 p3):fun_(fun),p1_(p1),p2_(p2),p3_(p3){} - ~scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);} - void execute(){fun_(p1_,p2_,p3_);} - -protected: - F fun_; - const P1 p1_; - const P2 p2_; - const P3 p3_; -}; - -template -inline scope_guard_impl3 make_guard(F fun,P1 p1,P2 p2,P3 p3) -{ - return scope_guard_impl3(fun,p1,p2,p3); -} - -template -inline typename null_guard_return >::type -make_guard_if_c(F fun,P1 p1,P2 p2,P3 p3) -{ - return typename null_guard_return >::type(fun,p1,p2,p3); -} - -template -inline typename null_guard_return< C::value,scope_guard_impl3 >::type -make_guard_if(F fun,P1 p1,P2 p2,P3 p3) -{ - return make_guard_if_c(fun,p1,p2,p3); -} - -template -class scope_guard_impl4:public scope_guard_impl_base -{ -public: - scope_guard_impl4(F fun,P1 p1,P2 p2,P3 p3,P4 p4): - fun_(fun),p1_(p1),p2_(p2),p3_(p3),p4_(p4){} - ~scope_guard_impl4(){scope_guard_impl_base::safe_execute(*this);} - void execute(){fun_(p1_,p2_,p3_,p4_);} - -protected: - F fun_; - const P1 p1_; - const P2 p2_; - const P3 p3_; - const P4 p4_; -}; - -template -inline scope_guard_impl4 make_guard( - F fun,P1 p1,P2 p2,P3 p3,P4 p4) -{ - return scope_guard_impl4(fun,p1,p2,p3,p4); -} - -template -inline typename null_guard_return >::type -make_guard_if_c( - F fun,P1 p1,P2 p2,P3 p3,P4 p4) -{ - return typename null_guard_return >::type(fun,p1,p2,p3,p4); -} - -template -inline typename null_guard_return >::type -make_guard_if( - F fun,P1 p1,P2 p2,P3 p3,P4 p4) -{ - return make_guard_if_c(fun,p1,p2,p3,p4); -} - -template -class obj_scope_guard_impl0:public scope_guard_impl_base -{ -public: - obj_scope_guard_impl0(Obj& obj,MemFun mem_fun):obj_(obj),mem_fun_(mem_fun){} - ~obj_scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);} - void execute(){(obj_.*mem_fun_)();} - -protected: - Obj& obj_; - MemFun mem_fun_; -}; - -template -inline obj_scope_guard_impl0 make_obj_guard(Obj& obj,MemFun mem_fun) -{ - return obj_scope_guard_impl0(obj,mem_fun); -} - -template -inline typename null_guard_return >::type -make_obj_guard_if_c(Obj& obj,MemFun mem_fun) -{ - return typename null_guard_return >::type(obj,mem_fun); -} - -template -inline typename null_guard_return >::type -make_obj_guard_if(Obj& obj,MemFun mem_fun) -{ - return make_obj_guard_if_c(obj,mem_fun); -} - -template -class obj_scope_guard_impl1:public scope_guard_impl_base -{ -public: - obj_scope_guard_impl1(Obj& obj,MemFun mem_fun,P1 p1): - obj_(obj),mem_fun_(mem_fun),p1_(p1){} - ~obj_scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);} - void execute(){(obj_.*mem_fun_)(p1_);} - -protected: - Obj& obj_; - MemFun mem_fun_; - const P1 p1_; -}; - -template -inline obj_scope_guard_impl1 make_obj_guard( - Obj& obj,MemFun mem_fun,P1 p1) -{ - return obj_scope_guard_impl1(obj,mem_fun,p1); -} - -template -inline typename null_guard_return >::type -make_obj_guard_if_c( Obj& obj,MemFun mem_fun,P1 p1) -{ - return typename null_guard_return >::type(obj,mem_fun,p1); -} - -template -inline typename null_guard_return >::type -make_obj_guard_if( Obj& obj,MemFun mem_fun,P1 p1) -{ - return make_obj_guard_if_c(obj,mem_fun,p1); -} - -template -class obj_scope_guard_impl2:public scope_guard_impl_base -{ -public: - obj_scope_guard_impl2(Obj& obj,MemFun mem_fun,P1 p1,P2 p2): - obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2) - {} - ~obj_scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);} - void execute(){(obj_.*mem_fun_)(p1_,p2_);} - -protected: - Obj& obj_; - MemFun mem_fun_; - const P1 p1_; - const P2 p2_; -}; - -template -inline obj_scope_guard_impl2 -make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2) -{ - return obj_scope_guard_impl2(obj,mem_fun,p1,p2); -} - -template -inline typename null_guard_return >::type -make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2) -{ - return typename null_guard_return >::type(obj,mem_fun,p1,p2); -} - -template -inline typename null_guard_return >::type -make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2) -{ - return make_obj_guard_if_c(obj,mem_fun,p1,p2); -} - -template -class obj_scope_guard_impl3:public scope_guard_impl_base -{ -public: - obj_scope_guard_impl3(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3): - obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2),p3_(p3) - {} - ~obj_scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);} - void execute(){(obj_.*mem_fun_)(p1_,p2_,p3_);} - -protected: - Obj& obj_; - MemFun mem_fun_; - const P1 p1_; - const P2 p2_; - const P3 p3_; -}; - -template -inline obj_scope_guard_impl3 -make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3) -{ - return obj_scope_guard_impl3(obj,mem_fun,p1,p2,p3); -} - -template -inline typename null_guard_return >::type -make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3) -{ - return typename null_guard_return >::type(obj,mem_fun,p1,p2,p3); -} - -template -inline typename null_guard_return >::type -make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3) -{ - return make_obj_guard_if_c(obj,mem_fun,p1,p2,p3); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_node.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_node.hpp deleted file mode 100644 index 85b345af938..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_node.hpp +++ /dev/null @@ -1,217 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_NODE_HPP -#define BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_NODE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* doubly-linked node for use by sequenced_index */ - -template -struct sequenced_index_node_impl -{ - typedef typename - boost::detail::allocator::rebind_to< - Allocator,sequenced_index_node_impl - >::type::pointer pointer; - typedef typename - boost::detail::allocator::rebind_to< - Allocator,sequenced_index_node_impl - >::type::const_pointer const_pointer; - - pointer& prior(){return prior_;} - pointer prior()const{return prior_;} - pointer& next(){return next_;} - pointer next()const{return next_;} - - /* interoperability with bidir_node_iterator */ - - static void increment(pointer& x){x=x->next();} - static void decrement(pointer& x){x=x->prior();} - - /* algorithmic stuff */ - - static void link(pointer x,pointer header) - { - x->prior()=header->prior(); - x->next()=header; - x->prior()->next()=x->next()->prior()=x; - }; - - static void unlink(pointer x) - { - x->prior()->next()=x->next(); - x->next()->prior()=x->prior(); - } - - static void relink(pointer position,pointer x) - { - unlink(x); - x->prior()=position->prior(); - x->next()=position; - x->prior()->next()=x->next()->prior()=x; - } - - static void relink(pointer position,pointer x,pointer y) - { - /* position is assumed not to be in [x,y) */ - - if(x!=y){ - pointer z=y->prior(); - x->prior()->next()=y; - y->prior()=x->prior(); - x->prior()=position->prior(); - z->next()=position; - x->prior()->next()=x; - z->next()->prior()=z; - } - } - - static void reverse(pointer header) - { - pointer x=header; - do{ - pointer y=x->next(); - std::swap(x->prior(),x->next()); - x=y; - }while(x!=header); - } - - static void swap(pointer x,pointer y) - { - /* This swap function does not exchange the header nodes, - * but rather their pointers. This is *not* used for implementing - * sequenced_index::swap. - */ - - if(x->next()!=x){ - if(y->next()!=y){ - std::swap(x->next(),y->next()); - std::swap(x->prior(),y->prior()); - x->next()->prior()=x->prior()->next()=x; - y->next()->prior()=y->prior()->next()=y; - } - else{ - y->next()=x->next(); - y->prior()=x->prior(); - x->next()=x->prior()=x; - y->next()->prior()=y->prior()->next()=y; - } - } - else if(y->next()!=y){ - x->next()=y->next(); - x->prior()=y->prior(); - y->next()=y->prior()=y; - x->next()->prior()=x->prior()->next()=x; - } - } - -private: - pointer prior_; - pointer next_; -}; - -template -struct sequenced_index_node_trampoline: - sequenced_index_node_impl< - typename boost::detail::allocator::rebind_to< - typename Super::allocator_type, - char - >::type - > -{ - typedef sequenced_index_node_impl< - typename boost::detail::allocator::rebind_to< - typename Super::allocator_type, - char - >::type - > impl_type; -}; - -template -struct sequenced_index_node:Super,sequenced_index_node_trampoline -{ -private: - typedef sequenced_index_node_trampoline trampoline; - -public: - typedef typename trampoline::impl_type impl_type; - typedef typename trampoline::pointer impl_pointer; - typedef typename trampoline::const_pointer const_impl_pointer; - - impl_pointer& prior(){return trampoline::prior();} - impl_pointer prior()const{return trampoline::prior();} - impl_pointer& next(){return trampoline::next();} - impl_pointer next()const{return trampoline::next();} - - impl_pointer impl() - { - return static_cast( - static_cast(static_cast(this))); - } - - const_impl_pointer impl()const - { - return static_cast( - static_cast(static_cast(this))); - } - - static sequenced_index_node* from_impl(impl_pointer x) - { - return - static_cast( - static_cast( - raw_ptr(x))); - } - - static const sequenced_index_node* from_impl(const_impl_pointer x) - { - return - static_cast( - static_cast( - raw_ptr(x))); - } - - /* interoperability with bidir_node_iterator */ - - static void increment(sequenced_index_node*& x) - { - impl_pointer xi=x->impl(); - trampoline::increment(xi); - x=from_impl(xi); - } - - static void decrement(sequenced_index_node*& x) - { - impl_pointer xi=x->impl(); - trampoline::decrement(xi); - x=from_impl(xi); - } -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_ops.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_ops.hpp deleted file mode 100644 index 142bdd9dd9a..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_ops.hpp +++ /dev/null @@ -1,203 +0,0 @@ -/* Copyright 2003-2016 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_OPS_HPP -#define BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_OPS_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Common code for sequenced_index memfuns having templatized and - * non-templatized versions. - */ - -template -void sequenced_index_remove(SequencedIndex& x,Predicate pred) -{ - typedef typename SequencedIndex::iterator iterator; - iterator first=x.begin(),last=x.end(); - while(first!=last){ - if(pred(*first))x.erase(first++); - else ++first; - } -} - -template -void sequenced_index_unique(SequencedIndex& x,BinaryPredicate binary_pred) -{ - typedef typename SequencedIndex::iterator iterator; - iterator first=x.begin(); - iterator last=x.end(); - if(first!=last){ - for(iterator middle=first;++middle!=last;middle=first){ - if(binary_pred(*middle,*first))x.erase(middle); - else first=middle; - } - } -} - -template -void sequenced_index_merge(SequencedIndex& x,SequencedIndex& y,Compare comp) -{ - typedef typename SequencedIndex::iterator iterator; - if(&x!=&y){ - iterator first0=x.begin(),last0=x.end(); - iterator first1=y.begin(),last1=y.end(); - while(first0!=last0&&first1!=last1){ - if(comp(*first1,*first0))x.splice(first0,y,first1++); - else ++first0; - } - x.splice(last0,y,first1,last1); - } -} - -/* sorting */ - -/* auxiliary stuff */ - -template -void sequenced_index_collate( - BOOST_DEDUCED_TYPENAME Node::impl_type* x, - BOOST_DEDUCED_TYPENAME Node::impl_type* y, - Compare comp) -{ - typedef typename Node::impl_type impl_type; - typedef typename Node::impl_pointer impl_pointer; - - impl_pointer first0=x->next(); - impl_pointer last0=x; - impl_pointer first1=y->next(); - impl_pointer last1=y; - while(first0!=last0&&first1!=last1){ - if(comp( - Node::from_impl(first1)->value(),Node::from_impl(first0)->value())){ - impl_pointer tmp=first1->next(); - impl_type::relink(first0,first1); - first1=tmp; - } - else first0=first0->next(); - } - impl_type::relink(last0,first1,last1); -} - -/* Some versions of CGG require a bogus typename in counter_spc - * inside sequenced_index_sort if the following is defined - * also inside sequenced_index_sort. - */ - -BOOST_STATIC_CONSTANT( - std::size_t, - sequenced_index_sort_max_fill= - (std::size_t)std::numeric_limits::digits+1); - -#include - -template -void sequenced_index_sort(Node* header,Compare comp) -{ - /* Musser's mergesort, see http://www.cs.rpi.edu/~musser/gp/List/lists1.html. - * The implementation is a little convoluted: in the original code - * counter elements and carry are std::lists: here we do not want - * to use multi_index instead, so we do things at a lower level, managing - * directly the internal node representation. - * Incidentally, the implementations I've seen of this algorithm (SGI, - * Dinkumware, STLPort) are not exception-safe: this is. Moreover, we do not - * use any dynamic storage. - */ - - if(header->next()==header->impl()|| - header->next()->next()==header->impl())return; - - typedef typename Node::impl_type impl_type; - typedef typename Node::impl_pointer impl_pointer; - - typedef typename aligned_storage< - sizeof(impl_type), - alignment_of::value - >::type carry_spc_type; - carry_spc_type carry_spc; - impl_type& carry= - *reinterpret_cast(&carry_spc); - typedef typename aligned_storage< - sizeof( - impl_type - [sequenced_index_sort_max_fill]), - alignment_of< - impl_type - [sequenced_index_sort_max_fill] - >::value - >::type counter_spc_type; - counter_spc_type counter_spc; - impl_type* counter= - reinterpret_cast(&counter_spc); - std::size_t fill=0; - - carry.prior()=carry.next()=static_cast(&carry); - counter[0].prior()=counter[0].next()=static_cast(&counter[0]); - - BOOST_TRY{ - while(header->next()!=header->impl()){ - impl_type::relink(carry.next(),header->next()); - std::size_t i=0; - while(i(&counter[i])){ - sequenced_index_collate(&carry,&counter[i++],comp); - } - impl_type::swap( - static_cast(&carry), - static_cast(&counter[i])); - if(i==fill){ - ++fill; - counter[fill].prior()=counter[fill].next()= - static_cast(&counter[fill]); - } - } - - for(std::size_t i=1;i(&counter[i],&counter[i-1],comp); - } - impl_type::swap( - header->impl(),static_cast(&counter[fill-1])); - } - BOOST_CATCH(...) - { - impl_type::relink( - header->impl(),carry.next(),static_cast(&carry)); - for(std::size_t i=0;i<=fill;++i){ - impl_type::relink( - header->impl(),counter[i].next(), - static_cast(&counter[i])); - } - BOOST_RETHROW; - } - BOOST_CATCH_END -} - -#include - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/serialization_version.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/serialization_version.hpp deleted file mode 100644 index ccd8bb4f791..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/serialization_version.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_SERIALIZATION_VERSION_HPP -#define BOOST_MULTI_INDEX_DETAIL_SERIALIZATION_VERSION_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Helper class for storing and retrieving a given type serialization class - * version while avoiding saving the number multiple times in the same - * archive. - * Behavior undefined if template partial specialization is not supported. - */ - -template -struct serialization_version -{ - serialization_version(): - value(boost::serialization::version::value){} - - serialization_version& operator=(unsigned int x){value=x;return *this;}; - - operator unsigned int()const{return value;} - -private: - friend class boost::serialization::access; - - BOOST_SERIALIZATION_SPLIT_MEMBER() - - template - void save(Archive&,const unsigned int)const{} - - template - void load(Archive&,const unsigned int version) - { - this->value=version; - } - - unsigned int value; -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -namespace serialization { -template -struct version > -{ - BOOST_STATIC_CONSTANT(int,value=version::value); -}; -} /* namespace serialization */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/uintptr_type.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/uintptr_type.hpp deleted file mode 100644 index 9c92d01d4de..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/uintptr_type.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_UINTPTR_TYPE_HPP -#define BOOST_MULTI_INDEX_DETAIL_UINTPTR_TYPE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* has_uintptr_type is an MPL integral constant determining whether - * there exists an unsigned integral type with the same size as - * void *. - * uintptr_type is such a type if has_uintptr is true, or unsigned int - * otherwise. - * Note that uintptr_type is more restrictive than C99 uintptr_t, - * where an integral type with size greater than that of void * - * would be conformant. - */ - -templatestruct uintptr_candidates; -template<>struct uintptr_candidates<-1>{typedef unsigned int type;}; -template<>struct uintptr_candidates<0> {typedef unsigned int type;}; -template<>struct uintptr_candidates<1> {typedef unsigned short type;}; -template<>struct uintptr_candidates<2> {typedef unsigned long type;}; - -#if defined(BOOST_HAS_LONG_LONG) -template<>struct uintptr_candidates<3> {typedef boost::ulong_long_type type;}; -#else -template<>struct uintptr_candidates<3> {typedef unsigned int type;}; -#endif - -#if defined(BOOST_HAS_MS_INT64) -template<>struct uintptr_candidates<4> {typedef unsigned __int64 type;}; -#else -template<>struct uintptr_candidates<4> {typedef unsigned int type;}; -#endif - -struct uintptr_aux -{ - BOOST_STATIC_CONSTANT(int,index= - sizeof(void*)==sizeof(uintptr_candidates<0>::type)?0: - sizeof(void*)==sizeof(uintptr_candidates<1>::type)?1: - sizeof(void*)==sizeof(uintptr_candidates<2>::type)?2: - sizeof(void*)==sizeof(uintptr_candidates<3>::type)?3: - sizeof(void*)==sizeof(uintptr_candidates<4>::type)?4:-1); - - BOOST_STATIC_CONSTANT(bool,has_uintptr_type=(index>=0)); - - typedef uintptr_candidates::type type; -}; - -typedef mpl::bool_ has_uintptr_type; -typedef uintptr_aux::type uintptr_type; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/unbounded.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/unbounded.hpp deleted file mode 100644 index dc09be1770d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/unbounded.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_UNBOUNDED_HPP -#define BOOST_MULTI_INDEX_DETAIL_UNBOUNDED_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include - -namespace boost{ - -namespace multi_index{ - -/* dummy type and variable for use in ordered_index::range() */ - -/* ODR-abiding technique shown at the example attached to - * http://lists.boost.org/Archives/boost/2006/07/108355.php - */ - -namespace detail{class unbounded_helper;} - -detail::unbounded_helper unbounded(detail::unbounded_helper); - -namespace detail{ - -class unbounded_helper -{ - unbounded_helper(){} - unbounded_helper(const unbounded_helper&){} - friend unbounded_helper multi_index::unbounded(unbounded_helper); -}; - -typedef unbounded_helper (*unbounded_type)(unbounded_helper); - -} /* namespace multi_index::detail */ - -inline detail::unbounded_helper unbounded(detail::unbounded_helper) -{ - return detail::unbounded_helper(); -} - -/* tags used in the implementation of range */ - -namespace detail{ - -struct none_unbounded_tag{}; -struct lower_unbounded_tag{}; -struct upper_unbounded_tag{}; -struct both_unbounded_tag{}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/value_compare.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/value_compare.hpp deleted file mode 100644 index ac42e8779aa..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/value_compare.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_VALUE_COMPARE_HPP -#define BOOST_MULTI_INDEX_DETAIL_VALUE_COMPARE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template -struct value_comparison -{ - typedef Value first_argument_type; - typedef Value second_argument_type; - typedef bool result_type; - - value_comparison( - const KeyFromValue& key_=KeyFromValue(),const Compare& comp_=Compare()): - key(key_),comp(comp_) - { - } - - bool operator()( - typename call_traits::param_type x, - typename call_traits::param_type y)const - { - return comp(key(x),key(y)); - } - -private: - KeyFromValue key; - Compare comp; -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/vartempl_support.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/vartempl_support.hpp deleted file mode 100644 index 06ff430f4be..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/vartempl_support.hpp +++ /dev/null @@ -1,247 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP -#define BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -/* Utilities for emulation of variadic template functions. Variadic packs are - * replaced by lists of BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS parameters: - * - * - typename... Args --> BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK - * - Args&&... args --> BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK - * - std::forward(args)... --> BOOST_MULTI_INDEX_FORWARD_PARAM_PACK - * - * Forwarding emulated with Boost.Move. A template functions foo_imp - * defined in such way accepts *exactly* BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS - * arguments: variable number of arguments is emulated by providing a set of - * overloads foo forwarding to foo_impl with - * - * BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL - * BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG (initial extra arg) - * - * which fill the extra args with boost::multi_index::detail::noarg's. - * boost::multi_index::detail::vartempl_placement_new works the opposite - * way: it acceps a full a pointer x to Value and a - * BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK and forwards to - * new(x) Value(args) where args is the argument pack after discarding - * noarg's. - * - * Emulation decays to the real thing when the compiler supports variadic - * templates and move semantics natively. - */ - -#include - -#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)||\ - defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS) -#define BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS 5 -#endif - -#define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK \ -BOOST_PP_ENUM_PARAMS( \ - BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,typename T) - -#define BOOST_MULTI_INDEX_VARTEMPL_ARG(z,n,_) \ -BOOST_FWD_REF(BOOST_PP_CAT(T,n)) BOOST_PP_CAT(t,n) - -#define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK \ -BOOST_PP_ENUM( \ - BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ - BOOST_MULTI_INDEX_VARTEMPL_ARG,~) - -#define BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG(z,n,_) \ -boost::forward(BOOST_PP_CAT(t,n)) - -#define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK \ -BOOST_PP_ENUM( \ - BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ - BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) - -namespace boost{namespace multi_index{namespace detail{ -struct noarg{}; -}}} - -/* call vartempl function without args */ - -#define BOOST_MULTI_INDEX_NULL_PARAM_PACK \ -BOOST_PP_ENUM_PARAMS( \ - BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ - boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) - -#define BOOST_MULTI_INDEX_TEMPLATE_N(n) \ -template - -#define BOOST_MULTI_INDEX_TEMPLATE_0(n) - -#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX(z,n,data) \ -BOOST_PP_IF(n, \ - BOOST_MULTI_INDEX_TEMPLATE_N, \ - BOOST_MULTI_INDEX_TEMPLATE_0)(n) \ -BOOST_PP_SEQ_ELEM(0,data) /* ret */ \ -BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \ - BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \ -{ \ - return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \ - BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \ - BOOST_PP_COMMA_IF( \ - BOOST_PP_AND( \ - n,BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n))) \ - BOOST_PP_ENUM_PARAMS( \ - BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ - boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \ - ); \ -} - -#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \ - ret,name_from,name_to) \ -BOOST_PP_REPEAT_FROM_TO( \ - 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX, \ - (ret)(name_from)(name_to)) - -#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX( \ - z,n,data) \ -BOOST_PP_IF(n, \ - BOOST_MULTI_INDEX_TEMPLATE_N, \ - BOOST_MULTI_INDEX_TEMPLATE_0)(n) \ -BOOST_PP_SEQ_ELEM(0,data) /* ret */ \ -BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \ - BOOST_PP_SEQ_ELEM(3,data) BOOST_PP_SEQ_ELEM(4,data) /* extra arg */\ - BOOST_PP_COMMA_IF(n) \ - BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \ -{ \ - return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \ - BOOST_PP_SEQ_ELEM(4,data) /* extra_arg_name */ \ - BOOST_PP_COMMA_IF(n) \ - BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \ - BOOST_PP_COMMA_IF( \ - BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \ - BOOST_PP_ENUM_PARAMS( \ - BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ - boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \ - ); \ -} - -#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \ - ret,name_from,name_to,extra_arg_type,extra_arg_name) \ -BOOST_PP_REPEAT_FROM_TO( \ - 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX, \ - (ret)(name_from)(name_to)(extra_arg_type)(extra_arg_name)) - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -#define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX(z,n,name) \ -template< \ - typename Value \ - BOOST_PP_COMMA_IF(n) \ - BOOST_PP_ENUM_PARAMS(n,typename T) \ -> \ -Value* name( \ - Value* x \ - BOOST_PP_COMMA_IF(n) \ - BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~) \ - BOOST_PP_COMMA_IF( \ - BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \ - BOOST_PP_ENUM_PARAMS( \ - BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ - BOOST_FWD_REF(noarg) BOOST_PP_INTERCEPT)) \ -{ \ - return new(x) Value( \ - BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~)); \ -} - -#define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(name) \ -BOOST_PP_REPEAT_FROM_TO( \ - 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ - BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX, \ - name) - -BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(vartempl_placement_new) - -#undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX -#undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#else - -/* native variadic templates support */ - -#include - -#define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK typename... Args -#define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK Args&&... args -#define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK std::forward(args)... -#define BOOST_MULTI_INDEX_NULL_PARAM_PACK - -#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \ - ret,name_from,name_to) \ -template ret name_from(Args&&... args) \ -{ \ - return name_to(std::forward(args)...); \ -} - -#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \ - ret,name_from,name_to,extra_arg_type,extra_arg_name) \ -template ret name_from( \ - extra_arg_type extra_arg_name,Args&&... args) \ -{ \ - return name_to(extra_arg_name,std::forward(args)...); \ -} - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template -Value* vartempl_placement_new(Value*x,Args&&... args) -{ - return new(x) Value(std::forward(args)...); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/global_fun.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/global_fun.hpp deleted file mode 100644 index 2c13769100c..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/global_fun.hpp +++ /dev/null @@ -1,185 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_GLOBAL_FUN_HPP -#define BOOST_MULTI_INDEX_GLOBAL_FUN_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_NO_SFINAE) -#include -#endif - -namespace boost{ - -template class reference_wrapper; /* fwd decl. */ - -namespace multi_index{ - -namespace detail{ - -/* global_fun is a read-only key extractor from Value based on a given global - * (or static member) function with signature: - * - * Type f([const] Value [&]); - * - * Additionally, global_fun and const_global_fun are overloaded to support - * referece_wrappers of Value and "chained pointers" to Value's. By chained - * pointer to T we mean a type P such that, given a p of Type P - * *...n...*x is convertible to T&, for some n>=1. - * Examples of chained pointers are raw and smart pointers, iterators and - * arbitrary combinations of these (vg. T** or unique_ptr.) - */ - -template -struct const_ref_global_fun_base -{ - typedef typename remove_reference::type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type>::type -#else - Type -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type operator()(Value x)const - { - return PtrToFunction(x); - } - - Type operator()( - const reference_wrapper< - typename remove_reference::type>& x)const - { - return operator()(x.get()); - } - - Type operator()( - const reference_wrapper< - typename remove_const< - typename remove_reference::type>::type>& x - -#if BOOST_WORKAROUND(BOOST_MSVC,==1310) -/* http://lists.boost.org/Archives/boost/2015/10/226135.php */ - ,int=0 -#endif - - )const - { - return operator()(x.get()); - } -}; - -template -struct non_const_ref_global_fun_base -{ - typedef typename remove_reference::type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type>::type -#else - Type -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type operator()(Value x)const - { - return PtrToFunction(x); - } - - Type operator()( - const reference_wrapper< - typename remove_reference::type>& x)const - { - return operator()(x.get()); - } -}; - -template -struct non_ref_global_fun_base -{ - typedef typename remove_reference::type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type>::type -#else - Type -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type operator()(const Value& x)const - { - return PtrToFunction(x); - } - - Type operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } - - Type operator()( - const reference_wrapper::type>& x)const - { - return operator()(x.get()); - } -}; - -} /* namespace multi_index::detail */ - -template -struct global_fun: - mpl::if_c< - is_reference::value, - typename mpl::if_c< - is_const::type>::value, - detail::const_ref_global_fun_base, - detail::non_const_ref_global_fun_base - >::type, - detail::non_ref_global_fun_base - >::type -{ -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index.hpp deleted file mode 100644 index 352d0c13f17..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index.hpp +++ /dev/null @@ -1,1725 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_HASHED_INDEX_HPP -#define BOOST_MULTI_INDEX_HASHED_INDEX_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) -#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x) \ - detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(x,&hashed_index::check_invariant_); \ - BOOST_JOIN(check_invariant_,__LINE__).touch(); -#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT \ - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(*this) -#else -#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x) -#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* hashed_index adds a layer of hashed indexing to a given Super */ - -/* Most of the implementation of unique and non-unique indices is - * shared. We tell from one another on instantiation time by using - * Category tags defined in hash_index_node.hpp. - */ - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -class hashed_index: - BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - ,public safe_mode::safe_container< - hashed_index > -#endif - -{ -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the - * lifetime of const references bound to temporaries --precisely what - * scopeguards are. - */ - -#pragma parse_mfunc_templ off -#endif - - typedef typename SuperMeta::type super; - -protected: - typedef hashed_index_node< - typename super::node_type,Category> node_type; - -private: - typedef typename node_type::node_alg node_alg; - typedef typename node_type::impl_type node_impl_type; - typedef typename node_impl_type::pointer node_impl_pointer; - typedef typename node_impl_type::base_pointer node_impl_base_pointer; - typedef bucket_array< - typename super::final_allocator_type> bucket_array_type; - -public: - /* types */ - - typedef typename KeyFromValue::result_type key_type; - typedef typename node_type::value_type value_type; - typedef KeyFromValue key_from_value; - typedef Hash hasher; - typedef Pred key_equal; - typedef tuple ctor_args; - typedef typename super::final_allocator_type allocator_type; - typedef typename allocator_type::pointer pointer; - typedef typename allocator_type::const_pointer const_pointer; - typedef typename allocator_type::reference reference; - typedef typename allocator_type::const_reference const_reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef safe_mode::safe_iterator< - hashed_index_iterator< - node_type,bucket_array_type, - hashed_index_global_iterator_tag>, - hashed_index> iterator; -#else - typedef hashed_index_iterator< - node_type,bucket_array_type, - hashed_index_global_iterator_tag> iterator; -#endif - - typedef iterator const_iterator; - - typedef hashed_index_iterator< - node_type,bucket_array_type, - hashed_index_local_iterator_tag> local_iterator; - typedef local_iterator const_local_iterator; - - typedef TagList tag_list; - -protected: - typedef typename super::final_node_type final_node_type; - typedef tuples::cons< - ctor_args, - typename super::ctor_args_list> ctor_args_list; - typedef typename mpl::push_front< - typename super::index_type_list, - hashed_index>::type index_type_list; - typedef typename mpl::push_front< - typename super::iterator_type_list, - iterator>::type iterator_type_list; - typedef typename mpl::push_front< - typename super::const_iterator_type_list, - const_iterator>::type const_iterator_type_list; - typedef typename super::copy_map_type copy_map_type; - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - typedef typename super::index_saver_type index_saver_type; - typedef typename super::index_loader_type index_loader_type; -#endif - -private: -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef safe_mode::safe_container< - hashed_index> safe_super; -#endif - - typedef typename call_traits::param_type value_param_type; - typedef typename call_traits< - key_type>::param_type key_param_type; - - /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL - * expansion. - */ - - typedef std::pair emplace_return_type; - -public: - - /* construct/destroy/copy - * Default and copy ctors are in the protected section as indices are - * not supposed to be created on their own. No range ctor either. - */ - - hashed_index& operator=( - const hashed_index& x) - { - this->final()=x.final(); - return *this; - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - hashed_index& operator=( - std::initializer_list list) - { - this->final()=list; - return *this; - } -#endif - - allocator_type get_allocator()const BOOST_NOEXCEPT - { - return this->final().get_allocator(); - } - - /* size and capacity */ - - bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} - size_type size()const BOOST_NOEXCEPT{return this->final_size_();} - size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} - - /* iterators */ - - iterator begin()BOOST_NOEXCEPT - {return make_iterator(node_type::from_impl(header()->next()->prior()));} - const_iterator begin()const BOOST_NOEXCEPT - {return make_iterator(node_type::from_impl(header()->next()->prior()));} - iterator end()BOOST_NOEXCEPT{return make_iterator(header());} - const_iterator end()const BOOST_NOEXCEPT{return make_iterator(header());} - const_iterator cbegin()const BOOST_NOEXCEPT{return begin();} - const_iterator cend()const BOOST_NOEXCEPT{return end();} - - iterator iterator_to(const value_type& x) - { - return make_iterator(node_from_value(&x)); - } - - const_iterator iterator_to(const value_type& x)const - { - return make_iterator(node_from_value(&x)); - } - - /* modifiers */ - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( - emplace_return_type,emplace,emplace_impl) - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( - iterator,emplace_hint,emplace_hint_impl,iterator,position) - - std::pair insert(const value_type& x) - { - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_(x); - return std::pair(make_iterator(p.first),p.second); - } - - std::pair insert(BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_rv_(x); - return std::pair(make_iterator(p.first),p.second); - } - - iterator insert(iterator position,const value_type& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_( - x,static_cast(position.get_node())); - return make_iterator(p.first); - } - - iterator insert(iterator position,BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_rv_( - x,static_cast(position.get_node())); - return make_iterator(p.first); - } - - template - void insert(InputIterator first,InputIterator last) - { - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - for(;first!=last;++first)this->final_insert_ref_(*first); - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - void insert(std::initializer_list list) - { - insert(list.begin(),list.end()); - } -#endif - - iterator erase(iterator position) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - this->final_erase_(static_cast(position++.get_node())); - return position; - } - - size_type erase(key_param_type k) - { - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - - std::size_t buc=buckets.position(hash_(k)); - for(node_impl_pointer x=buckets.at(buc)->prior(); - x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ - if(eq_(k,key(node_type::from_impl(x)->value()))){ - node_impl_pointer y=end_of_range(x); - size_type s=0; - do{ - node_impl_pointer z=node_alg::after(x); - this->final_erase_( - static_cast(node_type::from_impl(x))); - x=z; - ++s; - }while(x!=y); - return s; - } - } - return 0; - } - - iterator erase(iterator first,iterator last) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); - BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - while(first!=last){ - first=erase(first); - } - return first; - } - - bool replace(iterator position,const value_type& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - return this->final_replace_( - x,static_cast(position.get_node())); - } - - bool replace(iterator position,BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - return this->final_replace_rv_( - x,static_cast(position.get_node())); - } - - template - bool modify(iterator position,Modifier mod) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer on safe mode code chokes if this - * this is not added. Left it for all compilers as it does no - * harm. - */ - - position.detach(); -#endif - - return this->final_modify_( - mod,static_cast(position.get_node())); - } - - template - bool modify(iterator position,Modifier mod,Rollback back_) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer on safe mode code chokes if this - * this is not added. Left it for all compilers as it does no - * harm. - */ - - position.detach(); -#endif - - return this->final_modify_( - mod,back_,static_cast(position.get_node())); - } - - template - bool modify_key(iterator position,Modifier mod) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - return modify( - position,modify_key_adaptor(mod,key)); - } - - template - bool modify_key(iterator position,Modifier mod,Rollback back_) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - return modify( - position, - modify_key_adaptor(mod,key), - modify_key_adaptor(back_,key)); - } - - void clear()BOOST_NOEXCEPT - { - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - this->final_clear_(); - } - - void swap(hashed_index& x) - { - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x); - this->final_swap_(x.final()); - } - - /* observers */ - - key_from_value key_extractor()const{return key;} - hasher hash_function()const{return hash_;} - key_equal key_eq()const{return eq_;} - - /* lookup */ - - /* Internally, these ops rely on const_iterator being the same - * type as iterator. - */ - - /* Implementation note: When CompatibleKey is consistently promoted to - * KeyFromValue::result_type for equality comparison, the promotion is made - * once in advance to increase efficiency. - */ - - template - iterator find(const CompatibleKey& k)const - { - return find(k,hash_,eq_); - } - - template< - typename CompatibleKey,typename CompatibleHash,typename CompatiblePred - > - iterator find( - const CompatibleKey& k, - const CompatibleHash& hash,const CompatiblePred& eq)const - { - return find( - k,hash,eq,promotes_1st_arg()); - } - - template - size_type count(const CompatibleKey& k)const - { - return count(k,hash_,eq_); - } - - template< - typename CompatibleKey,typename CompatibleHash,typename CompatiblePred - > - size_type count( - const CompatibleKey& k, - const CompatibleHash& hash,const CompatiblePred& eq)const - { - return count( - k,hash,eq,promotes_1st_arg()); - } - - template - std::pair equal_range(const CompatibleKey& k)const - { - return equal_range(k,hash_,eq_); - } - - template< - typename CompatibleKey,typename CompatibleHash,typename CompatiblePred - > - std::pair equal_range( - const CompatibleKey& k, - const CompatibleHash& hash,const CompatiblePred& eq)const - { - return equal_range( - k,hash,eq,promotes_1st_arg()); - } - - /* bucket interface */ - - size_type bucket_count()const BOOST_NOEXCEPT{return buckets.size();} - size_type max_bucket_count()const BOOST_NOEXCEPT{return static_cast(-1);} - - size_type bucket_size(size_type n)const - { - size_type res=0; - for(node_impl_pointer x=buckets.at(n)->prior(); - x!=node_impl_pointer(0);x=node_alg::after_local(x)){ - ++res; - } - return res; - } - - size_type bucket(key_param_type k)const - { - return buckets.position(hash_(k)); - } - - local_iterator begin(size_type n) - { - return const_cast(this)->begin(n); - } - - const_local_iterator begin(size_type n)const - { - node_impl_pointer x=buckets.at(n)->prior(); - if(x==node_impl_pointer(0))return end(n); - return make_local_iterator(node_type::from_impl(x)); - } - - local_iterator end(size_type n) - { - return const_cast(this)->end(n); - } - - const_local_iterator end(size_type)const - { - return make_local_iterator(0); - } - - const_local_iterator cbegin(size_type n)const{return begin(n);} - const_local_iterator cend(size_type n)const{return end(n);} - - local_iterator local_iterator_to(const value_type& x) - { - return make_local_iterator(node_from_value(&x)); - } - - const_local_iterator local_iterator_to(const value_type& x)const - { - return make_local_iterator(node_from_value(&x)); - } - - /* hash policy */ - - float load_factor()const BOOST_NOEXCEPT - {return static_cast(size())/bucket_count();} - float max_load_factor()const BOOST_NOEXCEPT{return mlf;} - void max_load_factor(float z){mlf=z;calculate_max_load();} - - void rehash(size_type n) - { - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - if(size()<=max_load&&n<=bucket_count())return; - - size_type bc =(std::numeric_limits::max)(); - float fbc=static_cast(1+size()/mlf); - if(bc>fbc){ - bc=static_cast(fbc); - if(bc(std::ceil(static_cast(n)/mlf))); - } - -BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: - hashed_index(const ctor_args_list& args_list,const allocator_type& al): - super(args_list.get_tail(),al), - key(tuples::get<1>(args_list.get_head())), - hash_(tuples::get<2>(args_list.get_head())), - eq_(tuples::get<3>(args_list.get_head())), - buckets(al,header()->impl(),tuples::get<0>(args_list.get_head())), - mlf(1.0f) - { - calculate_max_load(); - } - - hashed_index( - const hashed_index& x): - super(x), - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super(), -#endif - - key(x.key), - hash_(x.hash_), - eq_(x.eq_), - buckets(x.get_allocator(),header()->impl(),x.buckets.size()), - mlf(x.mlf), - max_load(x.max_load) - { - /* Copy ctor just takes the internal configuration objects from x. The rest - * is done in subsequent call to copy_(). - */ - } - - hashed_index( - const hashed_index& x, - do_not_copy_elements_tag): - super(x,do_not_copy_elements_tag()), - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super(), -#endif - - key(x.key), - hash_(x.hash_), - eq_(x.eq_), - buckets(x.get_allocator(),header()->impl(),0), - mlf(1.0f) - { - calculate_max_load(); - } - - ~hashed_index() - { - /* the container is guaranteed to be empty by now */ - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - iterator make_iterator(node_type* node) - { - return iterator(node,this); - } - - const_iterator make_iterator(node_type* node)const - { - return const_iterator(node,const_cast(this)); - } -#else - iterator make_iterator(node_type* node) - { - return iterator(node); - } - - const_iterator make_iterator(node_type* node)const - { - return const_iterator(node); - } -#endif - - local_iterator make_local_iterator(node_type* node) - { - return local_iterator(node); - } - - const_local_iterator make_local_iterator(node_type* node)const - { - return const_local_iterator(node); - } - - void copy_( - const hashed_index& x, - const copy_map_type& map) - { - copy_(x,map,Category()); - } - - void copy_( - const hashed_index& x, - const copy_map_type& map,hashed_unique_tag) - { - if(x.size()!=0){ - node_impl_pointer end_org=x.header()->impl(), - org=end_org, - cpy=header()->impl(); - do{ - node_impl_pointer prev_org=org->prior(), - prev_cpy= - static_cast(map.find(static_cast( - node_type::from_impl(prev_org))))->impl(); - cpy->prior()=prev_cpy; - if(node_alg::is_first_of_bucket(org)){ - node_impl_base_pointer buc_org=prev_org->next(), - buc_cpy= - buckets.begin()+(buc_org-x.buckets.begin()); - prev_cpy->next()=buc_cpy; - buc_cpy->prior()=cpy; - } - else{ - prev_cpy->next()=node_impl_type::base_pointer_from(cpy); - } - org=prev_org; - cpy=prev_cpy; - }while(org!=end_org); - } - - super::copy_(x,map); - } - - void copy_( - const hashed_index& x, - const copy_map_type& map,hashed_non_unique_tag) - { - if(x.size()!=0){ - node_impl_pointer end_org=x.header()->impl(), - org=end_org, - cpy=header()->impl(); - do{ - node_impl_pointer next_org=node_alg::after(org), - next_cpy= - static_cast(map.find(static_cast( - node_type::from_impl(next_org))))->impl(); - if(node_alg::is_first_of_bucket(next_org)){ - node_impl_base_pointer buc_org=org->next(), - buc_cpy= - buckets.begin()+(buc_org-x.buckets.begin()); - cpy->next()=buc_cpy; - buc_cpy->prior()=next_cpy; - next_cpy->prior()=cpy; - } - else{ - if(org->next()==node_impl_type::base_pointer_from(next_org)){ - cpy->next()=node_impl_type::base_pointer_from(next_cpy); - } - else{ - cpy->next()= - node_impl_type::base_pointer_from( - static_cast(map.find(static_cast( - node_type::from_impl( - node_impl_type::pointer_from(org->next())))))->impl()); - } - - if(next_org->prior()!=org){ - next_cpy->prior()= - static_cast(map.find(static_cast( - node_type::from_impl(next_org->prior()))))->impl(); - } - else{ - next_cpy->prior()=cpy; - } - } - org=next_org; - cpy=next_cpy; - }while(org!=end_org); - } - - super::copy_(x,map); - } - - template - final_node_type* insert_( - value_param_type v,final_node_type*& x,Variant variant) - { - reserve_for_insert(size()+1); - - std::size_t buc=find_bucket(v); - link_info pos(buckets.at(buc)); - if(!link_point(v,pos)){ - return static_cast( - node_type::from_impl(node_impl_type::pointer_from(pos))); - } - - final_node_type* res=super::insert_(v,x,variant); - if(res==x)link(static_cast(x),pos); - return res; - } - - template - final_node_type* insert_( - value_param_type v,node_type* position,final_node_type*& x,Variant variant) - { - reserve_for_insert(size()+1); - - std::size_t buc=find_bucket(v); - link_info pos(buckets.at(buc)); - if(!link_point(v,pos)){ - return static_cast( - node_type::from_impl(node_impl_type::pointer_from(pos))); - } - - final_node_type* res=super::insert_(v,position,x,variant); - if(res==x)link(static_cast(x),pos); - return res; - } - - void erase_(node_type* x) - { - unlink(x); - super::erase_(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - } - - void delete_all_nodes_() - { - delete_all_nodes_(Category()); - } - - void delete_all_nodes_(hashed_unique_tag) - { - for(node_impl_pointer x_end=header()->impl(),x=x_end->prior();x!=x_end;){ - node_impl_pointer y=x->prior(); - this->final_delete_node_( - static_cast(node_type::from_impl(x))); - x=y; - } - } - - void delete_all_nodes_(hashed_non_unique_tag) - { - for(node_impl_pointer x_end=header()->impl(),x=x_end->prior();x!=x_end;){ - node_impl_pointer y=x->prior(); - if(y->next()!=node_impl_type::base_pointer_from(x)&& - y->next()->prior()!=x){ /* n-1 of group */ - /* Make the second node prior() pointer back-linked so that it won't - * refer to a deleted node when the time for its own destruction comes. - */ - - node_impl_pointer first=node_impl_type::pointer_from(y->next()); - first->next()->prior()=first; - } - this->final_delete_node_( - static_cast(node_type::from_impl(x))); - x=y; - } - } - - void clear_() - { - super::clear_(); - buckets.clear(header()->impl()); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::detach_dereferenceable_iterators(); -#endif - } - - void swap_( - hashed_index& x) - { - std::swap(key,x.key); - std::swap(hash_,x.hash_); - std::swap(eq_,x.eq_); - buckets.swap(x.buckets); - std::swap(mlf,x.mlf); - std::swap(max_load,x.max_load); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::swap(x); -#endif - - super::swap_(x); - } - - void swap_elements_( - hashed_index& x) - { - buckets.swap(x.buckets); - std::swap(mlf,x.mlf); - std::swap(max_load,x.max_load); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::swap(x); -#endif - - super::swap_elements_(x); - } - - template - bool replace_(value_param_type v,node_type* x,Variant variant) - { - if(eq_(key(v),key(x->value()))){ - return super::replace_(v,x,variant); - } - - unlink_undo undo; - unlink(x,undo); - - BOOST_TRY{ - std::size_t buc=find_bucket(v); - link_info pos(buckets.at(buc)); - if(link_point(v,pos)&&super::replace_(v,x,variant)){ - link(x,pos); - return true; - } - undo(); - return false; - } - BOOST_CATCH(...){ - undo(); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - bool modify_(node_type* x) - { - std::size_t buc; - bool b; - BOOST_TRY{ - buc=find_bucket(x->value()); - b=in_place(x->impl(),key(x->value()),buc); - } - BOOST_CATCH(...){ - erase_(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - if(!b){ - unlink(x); - BOOST_TRY{ - link_info pos(buckets.at(buc)); - if(!link_point(x->value(),pos)){ - super::erase_(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - return false; - } - link(x,pos); - } - BOOST_CATCH(...){ - super::erase_(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - BOOST_TRY{ - if(!super::modify_(x)){ - unlink(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - return false; - } - else return true; - } - BOOST_CATCH(...){ - unlink(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - bool modify_rollback_(node_type* x) - { - std::size_t buc=find_bucket(x->value()); - if(in_place(x->impl(),key(x->value()),buc)){ - return super::modify_rollback_(x); - } - - unlink_undo undo; - unlink(x,undo); - - BOOST_TRY{ - link_info pos(buckets.at(buc)); - if(link_point(x->value(),pos)&&super::modify_rollback_(x)){ - link(x,pos); - return true; - } - undo(); - return false; - } - BOOST_CATCH(...){ - undo(); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - /* comparison */ - -#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) - /* defect macro refers to class, not function, templates, but anyway */ - - template - friend bool operator==( - const hashed_index&,const hashed_index& y); -#endif - - bool equals(const hashed_index& x)const{return equals(x,Category());} - - bool equals(const hashed_index& x,hashed_unique_tag)const - { - if(size()!=x.size())return false; - for(const_iterator it=begin(),it_end=end(),it2_end=x.end(); - it!=it_end;++it){ - const_iterator it2=x.find(key(*it)); - if(it2==it2_end||!(*it==*it2))return false; - } - return true; - } - - bool equals(const hashed_index& x,hashed_non_unique_tag)const - { - if(size()!=x.size())return false; - for(const_iterator it=begin(),it_end=end();it!=it_end;){ - const_iterator it2,it2_last; - boost::tie(it2,it2_last)=x.equal_range(key(*it)); - if(it2==it2_last)return false; - - const_iterator it_last=make_iterator( - node_type::from_impl(end_of_range(it.get_node()->impl()))); - if(std::distance(it,it_last)!=std::distance(it2,it2_last))return false; - - /* From is_permutation code in - * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3068.pdf - */ - - for(;it!=it_last;++it,++it2){ - if(!(*it==*it2))break; - } - if(it!=it_last){ - for(const_iterator scan=it;scan!=it_last;++scan){ - if(std::find(it,scan,*scan)!=scan)continue; - std::ptrdiff_t matches=std::count(it2,it2_last,*scan); - if(matches==0||matches!=std::count(scan,it_last,*scan))return false; - } - it=it_last; - } - } - return true; - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* serialization */ - - template - void save_( - Archive& ar,const unsigned int version,const index_saver_type& sm)const - { - ar< - void load_(Archive& ar,const unsigned int version,const index_loader_type& lm) - { - ar>>serialization::make_nvp("position",buckets); - super::load_(ar,version,lm); - } -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - bool invariant_()const - { - if(size()==0||begin()==end()){ - if(size()!=0||begin()!=end())return false; - } - else{ - size_type s0=0; - for(const_iterator it=begin(),it_end=end();it!=it_end;++it,++s0){} - if(s0!=size())return false; - - size_type s1=0; - for(size_type buc=0;bucfinal_check_invariant_();} -#endif - -private: - node_type* header()const{return this->final_header();} - - std::size_t find_bucket(value_param_type v)const - { - return bucket(key(v)); - } - - struct link_info_non_unique - { - link_info_non_unique(node_impl_base_pointer pos): - first(pos),last(node_impl_base_pointer(0)){} - - operator const node_impl_base_pointer&()const{return this->first;} - - node_impl_base_pointer first,last; - }; - - typedef typename mpl::if_< - is_same, - node_impl_base_pointer, - link_info_non_unique - >::type link_info; - - bool link_point(value_param_type v,link_info& pos) - { - return link_point(v,pos,Category()); - } - - bool link_point( - value_param_type v,node_impl_base_pointer& pos,hashed_unique_tag) - { - for(node_impl_pointer x=pos->prior();x!=node_impl_pointer(0); - x=node_alg::after_local(x)){ - if(eq_(key(v),key(node_type::from_impl(x)->value()))){ - pos=node_impl_type::base_pointer_from(x); - return false; - } - } - return true; - } - - bool link_point( - value_param_type v,link_info_non_unique& pos,hashed_non_unique_tag) - { - for(node_impl_pointer x=pos.first->prior();x!=node_impl_pointer(0); - x=node_alg::next_to_inspect(x)){ - if(eq_(key(v),key(node_type::from_impl(x)->value()))){ - pos.first=node_impl_type::base_pointer_from(x); - pos.last=node_impl_type::base_pointer_from(last_of_range(x)); - return true; - } - } - return true; - } - - node_impl_pointer last_of_range(node_impl_pointer x)const - { - return last_of_range(x,Category()); - } - - node_impl_pointer last_of_range(node_impl_pointer x,hashed_unique_tag)const - { - return x; - } - - node_impl_pointer last_of_range( - node_impl_pointer x,hashed_non_unique_tag)const - { - node_impl_base_pointer y=x->next(); - node_impl_pointer z=y->prior(); - if(z==x){ /* range of size 1 or 2 */ - node_impl_pointer yy=node_impl_type::pointer_from(y); - return - eq_( - key(node_type::from_impl(x)->value()), - key(node_type::from_impl(yy)->value()))?yy:x; - } - else if(z->prior()==x) /* last of bucket */ - return x; - else /* group of size>2 */ - return z; - } - - node_impl_pointer end_of_range(node_impl_pointer x)const - { - return end_of_range(x,Category()); - } - - node_impl_pointer end_of_range(node_impl_pointer x,hashed_unique_tag)const - { - return node_alg::after(last_of_range(x)); - } - - node_impl_pointer end_of_range( - node_impl_pointer x,hashed_non_unique_tag)const - { - node_impl_base_pointer y=x->next(); - node_impl_pointer z=y->prior(); - if(z==x){ /* range of size 1 or 2 */ - node_impl_pointer yy=node_impl_type::pointer_from(y); - if(!eq_( - key(node_type::from_impl(x)->value()), - key(node_type::from_impl(yy)->value())))yy=x; - return yy->next()->prior()==yy? - node_impl_type::pointer_from(yy->next()): - yy->next()->prior(); - } - else if(z->prior()==x) /* last of bucket */ - return z; - else /* group of size>2 */ - return z->next()->prior()==z? - node_impl_type::pointer_from(z->next()): - z->next()->prior(); - } - - void link(node_type* x,const link_info& pos) - { - link(x,pos,Category()); - } - - void link(node_type* x,node_impl_base_pointer pos,hashed_unique_tag) - { - node_alg::link(x->impl(),pos,header()->impl()); - } - - void link(node_type* x,const link_info_non_unique& pos,hashed_non_unique_tag) - { - if(pos.last==node_impl_base_pointer(0)){ - node_alg::link(x->impl(),pos.first,header()->impl()); - } - else{ - node_alg::link( - x->impl(), - node_impl_type::pointer_from(pos.first), - node_impl_type::pointer_from(pos.last)); - } - } - - void unlink(node_type* x) - { - node_alg::unlink(x->impl()); - } - - typedef typename node_alg::unlink_undo unlink_undo; - - void unlink(node_type* x,unlink_undo& undo) - { - node_alg::unlink(x->impl(),undo); - } - - void calculate_max_load() - { - float fml=static_cast(mlf*static_cast(bucket_count())); - max_load=(std::numeric_limits::max)(); - if(max_load>fml)max_load=static_cast(fml); - } - - void reserve_for_insert(size_type n) - { - if(n>max_load){ - size_type bc =(std::numeric_limits::max)(); - float fbc=static_cast(1+static_cast(n)/mlf); - if(bc>fbc)bc =static_cast(fbc); - unchecked_rehash(bc); - } - } - - void unchecked_rehash(size_type n){unchecked_rehash(n,Category());} - - void unchecked_rehash(size_type n,hashed_unique_tag) - { - node_impl_type cpy_end_node; - node_impl_pointer cpy_end=node_impl_pointer(&cpy_end_node), - end_=header()->impl(); - bucket_array_type buckets_cpy(get_allocator(),cpy_end,n); - - if(size()!=0){ - auto_space< - std::size_t,allocator_type> hashes(get_allocator(),size()); - auto_space< - node_impl_pointer,allocator_type> node_ptrs(get_allocator(),size()); - std::size_t i=0,size_=size(); - bool within_bucket=false; - BOOST_TRY{ - for(;i!=size_;++i){ - node_impl_pointer x=end_->prior(); - - /* only this can possibly throw */ - std::size_t h=hash_(key(node_type::from_impl(x)->value())); - - hashes.data()[i]=h; - node_ptrs.data()[i]=x; - within_bucket=!node_alg::unlink_last(end_); - node_alg::link(x,buckets_cpy.at(buckets_cpy.position(h)),cpy_end); - } - } - BOOST_CATCH(...){ - if(i!=0){ - std::size_t prev_buc=buckets.position(hashes.data()[i-1]); - if(!within_bucket)prev_buc=~prev_buc; - - for(std::size_t j=i;j--;){ - std::size_t buc=buckets.position(hashes.data()[j]); - node_impl_pointer x=node_ptrs.data()[j]; - if(buc==prev_buc)node_alg::append(x,end_); - else node_alg::link(x,buckets.at(buc),end_); - prev_buc=buc; - } - } - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - end_->prior()=cpy_end->prior()!=cpy_end?cpy_end->prior():end_; - end_->next()=cpy_end->next(); - end_->prior()->next()->prior()=end_->next()->prior()->prior()=end_; - buckets.swap(buckets_cpy); - calculate_max_load(); - } - - void unchecked_rehash(size_type n,hashed_non_unique_tag) - { - node_impl_type cpy_end_node; - node_impl_pointer cpy_end=node_impl_pointer(&cpy_end_node), - end_=header()->impl(); - bucket_array_type buckets_cpy(get_allocator(),cpy_end,n); - - if(size()!=0){ - auto_space< - std::size_t,allocator_type> hashes(get_allocator(),size()); - auto_space< - node_impl_pointer,allocator_type> node_ptrs(get_allocator(),size()); - std::size_t i=0; - bool within_bucket=false; - BOOST_TRY{ - for(;;++i){ - node_impl_pointer x=end_->prior(); - if(x==end_)break; - - /* only this can possibly throw */ - std::size_t h=hash_(key(node_type::from_impl(x)->value())); - - hashes.data()[i]=h; - node_ptrs.data()[i]=x; - std::pair p= - node_alg::unlink_last_group(end_); - node_alg::link_range( - p.first,x,buckets_cpy.at(buckets_cpy.position(h)),cpy_end); - within_bucket=!(p.second); - } - } - BOOST_CATCH(...){ - if(i!=0){ - std::size_t prev_buc=buckets.position(hashes.data()[i-1]); - if(!within_bucket)prev_buc=~prev_buc; - - for(std::size_t j=i;j--;){ - std::size_t buc=buckets.position(hashes.data()[j]); - node_impl_pointer x=node_ptrs.data()[j], - y= - x->prior()->next()!=node_impl_type::base_pointer_from(x)&& - x->prior()->next()->prior()!=x? - node_impl_type::pointer_from(x->prior()->next()):x; - node_alg::unlink_range(y,x); - if(buc==prev_buc)node_alg::append_range(y,x,end_); - else node_alg::link_range(y,x,buckets.at(buc),end_); - prev_buc=buc; - } - } - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - end_->prior()=cpy_end->prior()!=cpy_end?cpy_end->prior():end_; - end_->next()=cpy_end->next(); - end_->prior()->next()->prior()=end_->next()->prior()->prior()=end_; - buckets.swap(buckets_cpy); - calculate_max_load(); - } - - bool in_place(node_impl_pointer x,key_param_type k,std::size_t buc)const - { - return in_place(x,k,buc,Category()); - } - - bool in_place( - node_impl_pointer x,key_param_type k,std::size_t buc, - hashed_unique_tag)const - { - bool found=false; - for(node_impl_pointer y=buckets.at(buc)->prior(); - y!=node_impl_pointer(0);y=node_alg::after_local(y)){ - if(y==x)found=true; - else if(eq_(k,key(node_type::from_impl(y)->value())))return false; - } - return found; - } - - bool in_place( - node_impl_pointer x,key_param_type k,std::size_t buc, - hashed_non_unique_tag)const - { - bool found=false; - int range_size=0; - for(node_impl_pointer y=buckets.at(buc)->prior();y!=node_impl_pointer(0);){ - if(node_alg::is_first_of_group(y)){ /* group of 3 or more */ - if(y==x){ - /* in place <-> equal to some other member of the group */ - return eq_( - k, - key(node_type::from_impl( - node_impl_type::pointer_from(y->next()))->value())); - } - else{ - node_impl_pointer z= - node_alg::after_local(y->next()->prior()); /* end of range */ - if(eq_(k,key(node_type::from_impl(y)->value()))){ - if(found)return false; /* x lies outside */ - do{ - if(y==x)return true; - y=node_alg::after_local(y); - }while(y!=z); - return false; /* x not found */ - } - else{ - if(range_size==1&&!found)return false; - if(range_size==2)return found; - range_size=0; - y=z; /* skip range (and potentially x, too, which is fine) */ - } - } - } - else{ /* group of 1 or 2 */ - if(y==x){ - if(range_size==1)return true; - range_size=1; - found=true; - } - else if(eq_(k,key(node_type::from_impl(y)->value()))){ - if(range_size==0&&found)return false; - if(range_size==1&&!found)return false; - if(range_size==2)return false; - ++range_size; - } - else{ - if(range_size==1&&!found)return false; - if(range_size==2)return found; - range_size=0; - } - y=node_alg::after_local(y); - } - } - return found; - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - void detach_iterators(node_type* x) - { - iterator it=make_iterator(x); - safe_mode::detach_equivalent_iterators(it); - } -#endif - - template - std::pair emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - std::pairp= - this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - return std::pair(make_iterator(p.first),p.second); - } - - template - iterator emplace_hint_impl( - iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - std::pairp= - this->final_emplace_hint_( - static_cast(position.get_node()), - BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - return make_iterator(p.first); - } - - template< - typename CompatibleHash,typename CompatiblePred - > - iterator find( - const key_type& k, - const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const - { - return find(k,hash,eq,mpl::false_()); - } - - template< - typename CompatibleKey,typename CompatibleHash,typename CompatiblePred - > - iterator find( - const CompatibleKey& k, - const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const - { - std::size_t buc=buckets.position(hash(k)); - for(node_impl_pointer x=buckets.at(buc)->prior(); - x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ - if(eq(k,key(node_type::from_impl(x)->value()))){ - return make_iterator(node_type::from_impl(x)); - } - } - return end(); - } - - template< - typename CompatibleHash,typename CompatiblePred - > - size_type count( - const key_type& k, - const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const - { - return count(k,hash,eq,mpl::false_()); - } - - template< - typename CompatibleKey,typename CompatibleHash,typename CompatiblePred - > - size_type count( - const CompatibleKey& k, - const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const - { - std::size_t buc=buckets.position(hash(k)); - for(node_impl_pointer x=buckets.at(buc)->prior(); - x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ - if(eq(k,key(node_type::from_impl(x)->value()))){ - size_type res=0; - node_impl_pointer y=end_of_range(x); - do{ - ++res; - x=node_alg::after(x); - }while(x!=y); - return res; - } - } - return 0; - } - - template< - typename CompatibleHash,typename CompatiblePred - > - std::pair equal_range( - const key_type& k, - const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const - { - return equal_range(k,hash,eq,mpl::false_()); - } - - template< - typename CompatibleKey,typename CompatibleHash,typename CompatiblePred - > - std::pair equal_range( - const CompatibleKey& k, - const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const - { - std::size_t buc=buckets.position(hash(k)); - for(node_impl_pointer x=buckets.at(buc)->prior(); - x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ - if(eq(k,key(node_type::from_impl(x)->value()))){ - return std::pair( - make_iterator(node_type::from_impl(x)), - make_iterator(node_type::from_impl(end_of_range(x)))); - } - } - return std::pair(end(),end()); - } - - key_from_value key; - hasher hash_; - key_equal eq_; - bucket_array_type buckets; - float mlf; - size_type max_load; - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -#pragma parse_mfunc_templ reset -#endif -}; - -/* comparison */ - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -bool operator==( - const hashed_index& x, - const hashed_index& y) -{ - return x.equals(y); -} - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -bool operator!=( - const hashed_index& x, - const hashed_index& y) -{ - return !(x==y); -} - -/* specialized algorithms */ - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -void swap( - hashed_index& x, - hashed_index& y) -{ - x.swap(y); -} - -} /* namespace multi_index::detail */ - -/* hashed index specifiers */ - -template -struct hashed_unique -{ - typedef typename detail::hashed_index_args< - Arg1,Arg2,Arg3,Arg4> index_args; - typedef typename index_args::tag_list_type::type tag_list_type; - typedef typename index_args::key_from_value_type key_from_value_type; - typedef typename index_args::hash_type hash_type; - typedef typename index_args::pred_type pred_type; - - template - struct node_class - { - typedef detail::hashed_index_node type; - }; - - template - struct index_class - { - typedef detail::hashed_index< - key_from_value_type,hash_type,pred_type, - SuperMeta,tag_list_type,detail::hashed_unique_tag> type; - }; -}; - -template -struct hashed_non_unique -{ - typedef typename detail::hashed_index_args< - Arg1,Arg2,Arg3,Arg4> index_args; - typedef typename index_args::tag_list_type::type tag_list_type; - typedef typename index_args::key_from_value_type key_from_value_type; - typedef typename index_args::hash_type hash_type; - typedef typename index_args::pred_type pred_type; - - template - struct node_class - { - typedef detail::hashed_index_node< - Super,detail::hashed_non_unique_tag> type; - }; - - template - struct index_class - { - typedef detail::hashed_index< - key_from_value_type,hash_type,pred_type, - SuperMeta,tag_list_type,detail::hashed_non_unique_tag> type; - }; -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -/* Boost.Foreach compatibility */ - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -inline boost::mpl::true_* boost_foreach_is_noncopyable( - boost::multi_index::detail::hashed_index< - KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>*&, - boost_foreach_argument_dependent_lookup_hack) -{ - return 0; -} - -#undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT -#undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index_fwd.hpp deleted file mode 100644 index d77e36c321b..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index_fwd.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_HASHED_INDEX_FWD_HPP -#define BOOST_MULTI_INDEX_HASHED_INDEX_FWD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -class hashed_index; - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -bool operator==( - const hashed_index& x, - const hashed_index& y); - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -bool operator!=( - const hashed_index& x, - const hashed_index& y); - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -void swap( - hashed_index& x, - hashed_index& y); - -} /* namespace multi_index::detail */ - -/* hashed_index specifiers */ - -template< - typename Arg1,typename Arg2=mpl::na, - typename Arg3=mpl::na,typename Arg4=mpl::na -> -struct hashed_unique; - -template< - typename Arg1,typename Arg2=mpl::na, - typename Arg3=mpl::na,typename Arg4=mpl::na -> -struct hashed_non_unique; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/identity.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/identity.hpp deleted file mode 100644 index 6c832ce1562..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/identity.hpp +++ /dev/null @@ -1,145 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_IDENTITY_HPP -#define BOOST_MULTI_INDEX_IDENTITY_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_NO_SFINAE) -#include -#endif - -namespace boost{ - -template class reference_wrapper; /* fwd decl. */ - -namespace multi_index{ - -namespace detail{ - -/* identity is a do-nothing key extractor that returns the [const] Type& - * object passed. - * Additionally, identity is overloaded to support referece_wrappers - * of Type and "chained pointers" to Type's. By chained pointer to Type we - * mean a type P such that, given a p of type P - * *...n...*x is convertible to Type&, for some n>=1. - * Examples of chained pointers are raw and smart pointers, iterators and - * arbitrary combinations of these (vg. Type** or unique_ptr.) - */ - -template -struct const_identity_base -{ - typedef Type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if,Type&>::type -#else - Type& -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type& operator()(Type& x)const - { - return x; - } - - Type& operator()(const reference_wrapper& x)const - { - return x.get(); - } - - Type& operator()( - const reference_wrapper::type>& x - -#if BOOST_WORKAROUND(BOOST_MSVC,==1310) -/* http://lists.boost.org/Archives/boost/2015/10/226135.php */ - ,int=0 -#endif - - )const - { - return x.get(); - } -}; - -template -struct non_const_identity_base -{ - typedef Type result_type; - - /* templatized for pointer-like types */ - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type&>::type -#else - Type& -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - const Type& operator()(const Type& x)const - { - return x; - } - - Type& operator()(Type& x)const - { - return x; - } - - const Type& operator()(const reference_wrapper& x)const - { - return x.get(); - } - - Type& operator()(const reference_wrapper& x)const - { - return x.get(); - } -}; - -} /* namespace multi_index::detail */ - -template -struct identity: - mpl::if_c< - is_const::value, - detail::const_identity_base,detail::non_const_identity_base - >::type -{ -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/identity_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/identity_fwd.hpp deleted file mode 100644 index af6bd55ef5f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/identity_fwd.hpp +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_IDENTITY_FWD_HPP -#define BOOST_MULTI_INDEX_IDENTITY_FWD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -namespace boost{ - -namespace multi_index{ - -template struct identity; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/indexed_by.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/indexed_by.hpp deleted file mode 100644 index d2217e39166..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/indexed_by.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_INDEXED_BY_HPP -#define BOOST_MULTI_INDEX_INDEXED_BY_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include - -/* An alias to mpl::vector used to hide MPL from the user. - * indexed_by contains the index specifiers for instantiation - * of a multi_index_container. - */ - -/* This user_definable macro limits the number of elements of an index list; - * useful for shortening resulting symbol names (MSVC++ 6.0, for instance, - * has problems coping with very long symbol names.) - */ - -#if !defined(BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE) -#define BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE BOOST_MPL_LIMIT_VECTOR_SIZE -#endif - -#if BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE -struct indexed_by: - mpl::vector -{ -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#undef BOOST_MULTI_INDEX_INDEXED_BY_TEMPLATE_PARM -#undef BOOST_MULTI_INDEX_INDEXED_BY_SIZE - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/key_extractors.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/key_extractors.hpp deleted file mode 100644 index 60179ba2339..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/key_extractors.hpp +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_KEY_EXTRACTORS_HPP -#define BOOST_MULTI_INDEX_KEY_EXTRACTORS_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include -#include -#include -#include -#include - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/mem_fun.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/mem_fun.hpp deleted file mode 100644 index 111c386c5f5..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/mem_fun.hpp +++ /dev/null @@ -1,205 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_MEM_FUN_HPP -#define BOOST_MULTI_INDEX_MEM_FUN_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include - -#if !defined(BOOST_NO_SFINAE) -#include -#endif - -namespace boost{ - -template class reference_wrapper; /* fwd decl. */ - -namespace multi_index{ - -/* mem_fun implements a read-only key extractor based on a given non-const - * member function of a class. - * const_mem_fun does the same for const member functions. - * Additionally, mem_fun and const_mem_fun are overloaded to support - * referece_wrappers of T and "chained pointers" to T's. By chained pointer - * to T we mean a type P such that, given a p of Type P - * *...n...*x is convertible to T&, for some n>=1. - * Examples of chained pointers are raw and smart pointers, iterators and - * arbitrary combinations of these (vg. T** or unique_ptr.) - */ - -template -struct const_mem_fun -{ - typedef typename remove_reference::type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type>::type -#else - Type -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type operator()(const Class& x)const - { - return (x.*PtrToMemberFunction)(); - } - - Type operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } - - Type operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } -}; - -template -struct mem_fun -{ - typedef typename remove_reference::type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type>::type -#else - Type -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type operator()(Class& x)const - { - return (x.*PtrToMemberFunction)(); - } - - Type operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } -}; - -/* MSVC++ 6.0 has problems with const member functions as non-type template - * parameters, somehow it takes them as non-const. const_mem_fun_explicit - * workarounds this deficiency by accepting an extra type parameter that - * specifies the signature of the member function. The workaround was found at: - * Daniel, C.:"Re: weird typedef problem in VC", - * news:microsoft.public.vc.language, 21st nov 2002, - * http://groups.google.com/groups? - * hl=en&lr=&ie=UTF-8&selm=ukwvg3O0BHA.1512%40tkmsftngp05 - * - * MSVC++ 6.0 support has been dropped and [const_]mem_fun_explicit is - * deprecated. - */ - -template< - class Class,typename Type, - typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction> -struct const_mem_fun_explicit -{ - typedef typename remove_reference::type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type>::type -#else - Type -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type operator()(const Class& x)const - { - return (x.*PtrToMemberFunction)(); - } - - Type operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } - - Type operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } -}; - -template< - class Class,typename Type, - typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction> -struct mem_fun_explicit -{ - typedef typename remove_reference::type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type>::type -#else - Type -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type operator()(Class& x)const - { - return (x.*PtrToMemberFunction)(); - } - - Type operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } -}; - -/* BOOST_MULTI_INDEX_CONST_MEM_FUN and BOOST_MULTI_INDEX_MEM_FUN used to - * resolve to [const_]mem_fun_explicit for MSVC++ 6.0 and to - * [const_]mem_fun otherwise. Support for this compiler having been dropped, - * they are now just wrappers over [const_]mem_fun kept for backwards- - * compatibility reasons. - */ - -#define BOOST_MULTI_INDEX_CONST_MEM_FUN(Class,Type,MemberFunName) \ -::boost::multi_index::const_mem_fun< Class,Type,&Class::MemberFunName > -#define BOOST_MULTI_INDEX_MEM_FUN(Class,Type,MemberFunName) \ -::boost::multi_index::mem_fun< Class,Type,&Class::MemberFunName > - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/member.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/member.hpp deleted file mode 100644 index a8e645074a2..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/member.hpp +++ /dev/null @@ -1,262 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_MEMBER_HPP -#define BOOST_MULTI_INDEX_MEMBER_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include - -#if !defined(BOOST_NO_SFINAE) -#include -#endif - -namespace boost{ - -template class reference_wrapper; /* fwd decl. */ - -namespace multi_index{ - -namespace detail{ - -/* member is a read/write key extractor for accessing a given - * member of a class. - * Additionally, member is overloaded to support referece_wrappers - * of T and "chained pointers" to T's. By chained pointer to T we mean - * a type P such that, given a p of Type P - * *...n...*x is convertible to T&, for some n>=1. - * Examples of chained pointers are raw and smart pointers, iterators and - * arbitrary combinations of these (vg. T** or unique_ptr.) - */ - -template -struct const_member_base -{ - typedef Type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type&>::type -#else - Type& -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type& operator()(const Class& x)const - { - return x.*PtrToMember; - } - - Type& operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } - - Type& operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } -}; - -template -struct non_const_member_base -{ - typedef Type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type&>::type -#else - Type& -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - const Type& operator()(const Class& x)const - { - return x.*PtrToMember; - } - - Type& operator()(Class& x)const - { - return x.*PtrToMember; - } - - const Type& operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } - - Type& operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } -}; - -} /* namespace multi_index::detail */ - -template -struct member: - mpl::if_c< - is_const::value, - detail::const_member_base, - detail::non_const_member_base - >::type -{ -}; - -namespace detail{ - -/* MSVC++ 6.0 does not support properly pointers to members as - * non-type template arguments, as reported in - * http://support.microsoft.com/default.aspx?scid=kb;EN-US;249045 - * A similar problem (though not identical) is shown by MSVC++ 7.0. - * We provide an alternative to member<> accepting offsets instead - * of pointers to members. This happens to work even for non-POD - * types (although the standard forbids use of offsetof on these), - * so it serves as a workaround in this compiler for all practical - * purposes. - * Surprisingly enough, other compilers, like Intel C++ 7.0/7.1 and - * Visual Age 6.0, have similar bugs. This replacement of member<> - * can be used for them too. - * - * Support for such old compilers is dropped and - * [non_]const_member_offset_base is deprecated. - */ - -template -struct const_member_offset_base -{ - typedef Type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type&>::type -#else - Type& -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type& operator()(const Class& x)const - { - return *static_cast( - static_cast( - static_cast( - static_cast(&x))+OffsetOfMember)); - } - - Type& operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } - - Type& operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } -}; - -template -struct non_const_member_offset_base -{ - typedef Type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type&>::type -#else - Type& -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - const Type& operator()(const Class& x)const - { - return *static_cast( - static_cast( - static_cast( - static_cast(&x))+OffsetOfMember)); - } - - Type& operator()(Class& x)const - { - return *static_cast( - static_cast( - static_cast(static_cast(&x))+OffsetOfMember)); - } - - const Type& operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } - - Type& operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } -}; - -} /* namespace multi_index::detail */ - -template -struct member_offset: - mpl::if_c< - is_const::value, - detail::const_member_offset_base, - detail::non_const_member_offset_base - >::type -{ -}; - -/* BOOST_MULTI_INDEX_MEMBER resolves to member in the normal cases, - * and to member_offset as a workaround in those defective compilers for - * which BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS is defined. - */ - -#if defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS) -#define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) \ -::boost::multi_index::member_offset< Class,Type,offsetof(Class,MemberName) > -#else -#define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) \ -::boost::multi_index::member< Class,Type,&Class::MemberName > -#endif - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index.hpp deleted file mode 100644 index 5bcd69de8c9..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index.hpp +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_ORDERED_INDEX_HPP -#define BOOST_MULTI_INDEX_ORDERED_INDEX_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* no augment policy for plain ordered indices */ - -struct null_augment_policy -{ - template - struct augmented_interface - { - typedef OrderedIndexImpl type; - }; - - template - struct augmented_node - { - typedef OrderedIndexNodeImpl type; - }; - - template static void add(Pointer,Pointer){} - template static void remove(Pointer,Pointer){} - template static void copy(Pointer,Pointer){} - template static void rotate_left(Pointer,Pointer){} - template static void rotate_right(Pointer,Pointer){} - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - template static bool invariant(Pointer){return true;} - -#endif -}; - -} /* namespace multi_index::detail */ - -/* ordered_index specifiers */ - -template -struct ordered_unique -{ - typedef typename detail::ordered_index_args< - Arg1,Arg2,Arg3> index_args; - typedef typename index_args::tag_list_type::type tag_list_type; - typedef typename index_args::key_from_value_type key_from_value_type; - typedef typename index_args::compare_type compare_type; - - template - struct node_class - { - typedef detail::ordered_index_node type; - }; - - template - struct index_class - { - typedef detail::ordered_index< - key_from_value_type,compare_type, - SuperMeta,tag_list_type,detail::ordered_unique_tag, - detail::null_augment_policy> type; - }; -}; - -template -struct ordered_non_unique -{ - typedef detail::ordered_index_args< - Arg1,Arg2,Arg3> index_args; - typedef typename index_args::tag_list_type::type tag_list_type; - typedef typename index_args::key_from_value_type key_from_value_type; - typedef typename index_args::compare_type compare_type; - - template - struct node_class - { - typedef detail::ordered_index_node type; - }; - - template - struct index_class - { - typedef detail::ordered_index< - key_from_value_type,compare_type, - SuperMeta,tag_list_type,detail::ordered_non_unique_tag, - detail::null_augment_policy> type; - }; -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index_fwd.hpp deleted file mode 100644 index fe44aaf860d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index_fwd.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_ORDERED_INDEX_FWD_HPP -#define BOOST_MULTI_INDEX_ORDERED_INDEX_FWD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include -#include - -namespace boost{ - -namespace multi_index{ - -/* ordered_index specifiers */ - -template -struct ordered_unique; - -template -struct ordered_non_unique; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index.hpp deleted file mode 100644 index fe1884ddd38..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index.hpp +++ /dev/null @@ -1,1167 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_HPP -#define BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) -#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x) \ - detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(x,&random_access_index::check_invariant_); \ - BOOST_JOIN(check_invariant_,__LINE__).touch(); -#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT \ - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(*this) -#else -#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x) -#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* random_access_index adds a layer of random access indexing - * to a given Super - */ - -template -class random_access_index: - BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - ,public safe_mode::safe_container< - random_access_index > -#endif - -{ -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the - * lifetime of const references bound to temporaries --precisely what - * scopeguards are. - */ - -#pragma parse_mfunc_templ off -#endif - - typedef typename SuperMeta::type super; - -protected: - typedef random_access_index_node< - typename super::node_type> node_type; - -private: - typedef typename node_type::impl_type node_impl_type; - typedef random_access_index_ptr_array< - typename super::final_allocator_type> ptr_array; - typedef typename ptr_array::pointer node_impl_ptr_pointer; - -public: - /* types */ - - typedef typename node_type::value_type value_type; - typedef tuples::null_type ctor_args; - typedef typename super::final_allocator_type allocator_type; - typedef typename allocator_type::reference reference; - typedef typename allocator_type::const_reference const_reference; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef safe_mode::safe_iterator< - rnd_node_iterator, - random_access_index> iterator; -#else - typedef rnd_node_iterator iterator; -#endif - - typedef iterator const_iterator; - - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef typename allocator_type::pointer pointer; - typedef typename allocator_type::const_pointer const_pointer; - typedef typename - boost::reverse_iterator reverse_iterator; - typedef typename - boost::reverse_iterator const_reverse_iterator; - typedef TagList tag_list; - -protected: - typedef typename super::final_node_type final_node_type; - typedef tuples::cons< - ctor_args, - typename super::ctor_args_list> ctor_args_list; - typedef typename mpl::push_front< - typename super::index_type_list, - random_access_index>::type index_type_list; - typedef typename mpl::push_front< - typename super::iterator_type_list, - iterator>::type iterator_type_list; - typedef typename mpl::push_front< - typename super::const_iterator_type_list, - const_iterator>::type const_iterator_type_list; - typedef typename super::copy_map_type copy_map_type; - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - typedef typename super::index_saver_type index_saver_type; - typedef typename super::index_loader_type index_loader_type; -#endif - -private: -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef safe_mode::safe_container< - random_access_index> safe_super; -#endif - - typedef typename call_traits< - value_type>::param_type value_param_type; - - /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL - * expansion. - */ - - typedef std::pair emplace_return_type; - -public: - - /* construct/copy/destroy - * Default and copy ctors are in the protected section as indices are - * not supposed to be created on their own. No range ctor either. - */ - - random_access_index& operator=( - const random_access_index& x) - { - this->final()=x.final(); - return *this; - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - random_access_index& operator=( - std::initializer_list list) - { - this->final()=list; - return *this; - } -#endif - - template - void assign(InputIterator first,InputIterator last) - { - assign_iter(first,last,mpl::not_ >()); - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - void assign(std::initializer_list list) - { - assign(list.begin(),list.end()); - } -#endif - - void assign(size_type n,value_param_type value) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - clear(); - for(size_type i=0;ifinal().get_allocator(); - } - - /* iterators */ - - iterator begin()BOOST_NOEXCEPT - {return make_iterator(node_type::from_impl(*ptrs.begin()));} - const_iterator begin()const BOOST_NOEXCEPT - {return make_iterator(node_type::from_impl(*ptrs.begin()));} - iterator - end()BOOST_NOEXCEPT{return make_iterator(header());} - const_iterator - end()const BOOST_NOEXCEPT{return make_iterator(header());} - reverse_iterator - rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} - const_reverse_iterator - rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} - reverse_iterator - rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} - const_reverse_iterator - rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} - const_iterator - cbegin()const BOOST_NOEXCEPT{return begin();} - const_iterator - cend()const BOOST_NOEXCEPT{return end();} - const_reverse_iterator - crbegin()const BOOST_NOEXCEPT{return rbegin();} - const_reverse_iterator - crend()const BOOST_NOEXCEPT{return rend();} - - iterator iterator_to(const value_type& x) - { - return make_iterator(node_from_value(&x)); - } - - const_iterator iterator_to(const value_type& x)const - { - return make_iterator(node_from_value(&x)); - } - - /* capacity */ - - bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} - size_type size()const BOOST_NOEXCEPT{return this->final_size_();} - size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} - size_type capacity()const BOOST_NOEXCEPT{return ptrs.capacity();} - - void reserve(size_type n) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - ptrs.reserve(n); - } - - void shrink_to_fit() - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - ptrs.shrink_to_fit(); - } - - void resize(size_type n) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - if(n>size()) - for(size_type m=n-size();m--;) - this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK); - else if(nsize())for(size_type m=n-size();m--;)this->final_insert_(x); - else if(nvalue(); - } - - const_reference at(size_type n)const - { - if(n>=size())throw_exception(std::out_of_range("random access index")); - return node_type::from_impl(*ptrs.at(n))->value(); - } - - const_reference front()const{return operator[](0);} - const_reference back()const{return operator[](size()-1);} - - /* modifiers */ - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( - emplace_return_type,emplace_front,emplace_front_impl) - - std::pair push_front(const value_type& x) - {return insert(begin(),x);} - std::pair push_front(BOOST_RV_REF(value_type) x) - {return insert(begin(),boost::move(x));} - void pop_front(){erase(begin());} - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( - emplace_return_type,emplace_back,emplace_back_impl) - - std::pair push_back(const value_type& x) - {return insert(end(),x);} - std::pair push_back(BOOST_RV_REF(value_type) x) - {return insert(end(),boost::move(x));} - void pop_back(){erase(--end());} - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( - emplace_return_type,emplace,emplace_impl,iterator,position) - - std::pair insert(iterator position,const value_type& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_(x); - if(p.second&&position.get_node()!=header()){ - relocate(position.get_node(),p.first); - } - return std::pair(make_iterator(p.first),p.second); - } - - std::pair insert(iterator position,BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_rv_(x); - if(p.second&&position.get_node()!=header()){ - relocate(position.get_node(),p.first); - } - return std::pair(make_iterator(p.first),p.second); - } - - void insert(iterator position,size_type n,value_param_type x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - size_type s=0; - BOOST_TRY{ - while(n--){ - if(push_back(x).second)++s; - } - } - BOOST_CATCH(...){ - relocate(position,end()-s,end()); - BOOST_RETHROW; - } - BOOST_CATCH_END - relocate(position,end()-s,end()); - } - - template - void insert(iterator position,InputIterator first,InputIterator last) - { - insert_iter(position,first,last,mpl::not_ >()); - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - void insert(iterator position,std::initializer_list list) - { - insert(position,list.begin(),list.end()); - } -#endif - - iterator erase(iterator position) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - this->final_erase_(static_cast(position++.get_node())); - return position; - } - - iterator erase(iterator first,iterator last) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); - BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - difference_type n=last-first; - relocate(end(),first,last); - while(n--)pop_back(); - return last; - } - - bool replace(iterator position,const value_type& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - return this->final_replace_( - x,static_cast(position.get_node())); - } - - bool replace(iterator position,BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - return this->final_replace_rv_( - x,static_cast(position.get_node())); - } - - template - bool modify(iterator position,Modifier mod) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer on safe mode code chokes if this - * this is not added. Left it for all compilers as it does no - * harm. - */ - - position.detach(); -#endif - - return this->final_modify_( - mod,static_cast(position.get_node())); - } - - template - bool modify(iterator position,Modifier mod,Rollback back_) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer on safe mode code chokes if this - * this is not added. Left it for all compilers as it does no - * harm. - */ - - position.detach(); -#endif - - return this->final_modify_( - mod,back_,static_cast(position.get_node())); - } - - void swap(random_access_index& x) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x); - this->final_swap_(x.final()); - } - - void clear()BOOST_NOEXCEPT - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - this->final_clear_(); - } - - /* list operations */ - - void splice(iterator position,random_access_index& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(*this,x); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - iterator first=x.begin(),last=x.end(); - size_type n=0; - BOOST_TRY{ - while(first!=last){ - if(push_back(*first).second){ - first=x.erase(first); - ++n; - } - else ++first; - } - } - BOOST_CATCH(...){ - relocate(position,end()-n,end()); - BOOST_RETHROW; - } - BOOST_CATCH_END - relocate(position,end()-n,end()); - } - - void splice( - iterator position,random_access_index& x,iterator i) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - if(&x==this)relocate(position,i); - else{ - if(insert(position,*i).second){ - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following - * workaround is needed. Left it for all compilers as it does no - * harm. - */ - i.detach(); - x.erase(x.make_iterator(i.get_node())); -#else - x.erase(i); -#endif - - } - } - } - - void splice( - iterator position,random_access_index& x, - iterator first,iterator last) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x); - BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - if(&x==this)relocate(position,first,last); - else{ - size_type n=0; - BOOST_TRY{ - while(first!=last){ - if(push_back(*first).second){ - first=x.erase(first); - ++n; - } - else ++first; - } - } - BOOST_CATCH(...){ - relocate(position,end()-n,end()); - BOOST_RETHROW; - } - BOOST_CATCH_END - relocate(position,end()-n,end()); - } - } - - void remove(value_param_type value) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - difference_type n= - end()-make_iterator( - random_access_index_remove( - ptrs, - ::boost::bind(std::equal_to(),::boost::arg<1>(),value))); - while(n--)pop_back(); - } - - template - void remove_if(Predicate pred) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - difference_type n= - end()-make_iterator(random_access_index_remove(ptrs,pred)); - while(n--)pop_back(); - } - - void unique() - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - difference_type n= - end()-make_iterator( - random_access_index_unique( - ptrs,std::equal_to())); - while(n--)pop_back(); - } - - template - void unique(BinaryPredicate binary_pred) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - difference_type n= - end()-make_iterator( - random_access_index_unique(ptrs,binary_pred)); - while(n--)pop_back(); - } - - void merge(random_access_index& x) - { - if(this!=&x){ - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - size_type s=size(); - splice(end(),x); - random_access_index_inplace_merge( - get_allocator(),ptrs,ptrs.at(s),std::less()); - } - } - - template - void merge(random_access_index& x,Compare comp) - { - if(this!=&x){ - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - size_type s=size(); - splice(end(),x); - random_access_index_inplace_merge( - get_allocator(),ptrs,ptrs.at(s),comp); - } - } - - void sort() - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - random_access_index_sort( - get_allocator(),ptrs,std::less()); - } - - template - void sort(Compare comp) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - random_access_index_sort( - get_allocator(),ptrs,comp); - } - - void reverse()BOOST_NOEXCEPT - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - node_impl_type::reverse(ptrs.begin(),ptrs.end()); - } - - /* rearrange operations */ - - void relocate(iterator position,iterator i) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - if(position!=i)relocate(position.get_node(),i.get_node()); - } - - void relocate(iterator position,iterator first,iterator last) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); - BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); - BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - if(position!=last)relocate( - position.get_node(),first.get_node(),last.get_node()); - } - - template - void rearrange(InputIterator first) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - for(node_impl_ptr_pointer p0=ptrs.begin(),p0_end=ptrs.end(); - p0!=p0_end;++first,++p0){ - const value_type& v1=*first; - node_impl_ptr_pointer p1=node_from_value(&v1)->up(); - - std::swap(*p0,*p1); - (*p0)->up()=p0; - (*p1)->up()=p1; - } - } - -BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: - random_access_index( - const ctor_args_list& args_list,const allocator_type& al): - super(args_list.get_tail(),al), - ptrs(al,header()->impl(),0) - { - } - - random_access_index(const random_access_index& x): - super(x), - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super(), -#endif - - ptrs(x.get_allocator(),header()->impl(),x.size()) - { - /* The actual copying takes place in subsequent call to copy_(). - */ - } - - random_access_index( - const random_access_index& x,do_not_copy_elements_tag): - super(x,do_not_copy_elements_tag()), - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super(), -#endif - - ptrs(x.get_allocator(),header()->impl(),0) - { - } - - ~random_access_index() - { - /* the container is guaranteed to be empty by now */ - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - iterator make_iterator(node_type* node){return iterator(node,this);} - const_iterator make_iterator(node_type* node)const - {return const_iterator(node,const_cast(this));} -#else - iterator make_iterator(node_type* node){return iterator(node);} - const_iterator make_iterator(node_type* node)const - {return const_iterator(node);} -#endif - - void copy_( - const random_access_index& x,const copy_map_type& map) - { - for(node_impl_ptr_pointer begin_org=x.ptrs.begin(), - begin_cpy=ptrs.begin(), - end_org=x.ptrs.end(); - begin_org!=end_org;++begin_org,++begin_cpy){ - *begin_cpy= - static_cast( - map.find( - static_cast( - node_type::from_impl(*begin_org))))->impl(); - (*begin_cpy)->up()=begin_cpy; - } - - super::copy_(x,map); - } - - template - final_node_type* insert_( - value_param_type v,final_node_type*& x,Variant variant) - { - ptrs.room_for_one(); - final_node_type* res=super::insert_(v,x,variant); - if(res==x)ptrs.push_back(static_cast(x)->impl()); - return res; - } - - template - final_node_type* insert_( - value_param_type v,node_type* position,final_node_type*& x,Variant variant) - { - ptrs.room_for_one(); - final_node_type* res=super::insert_(v,position,x,variant); - if(res==x)ptrs.push_back(static_cast(x)->impl()); - return res; - } - - void erase_(node_type* x) - { - ptrs.erase(x->impl()); - super::erase_(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - } - - void delete_all_nodes_() - { - for(node_impl_ptr_pointer x=ptrs.begin(),x_end=ptrs.end();x!=x_end;++x){ - this->final_delete_node_( - static_cast(node_type::from_impl(*x))); - } - } - - void clear_() - { - super::clear_(); - ptrs.clear(); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::detach_dereferenceable_iterators(); -#endif - } - - void swap_(random_access_index& x) - { - ptrs.swap(x.ptrs); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::swap(x); -#endif - - super::swap_(x); - } - - void swap_elements_(random_access_index& x) - { - ptrs.swap(x.ptrs); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::swap(x); -#endif - - super::swap_elements_(x); - } - - template - bool replace_(value_param_type v,node_type* x,Variant variant) - { - return super::replace_(v,x,variant); - } - - bool modify_(node_type* x) - { - BOOST_TRY{ - if(!super::modify_(x)){ - ptrs.erase(x->impl()); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - return false; - } - else return true; - } - BOOST_CATCH(...){ - ptrs.erase(x->impl()); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - bool modify_rollback_(node_type* x) - { - return super::modify_rollback_(x); - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* serialization */ - - template - void save_( - Archive& ar,const unsigned int version,const index_saver_type& sm)const - { - sm.save(begin(),end(),ar,version); - super::save_(ar,version,sm); - } - - template - void load_( - Archive& ar,const unsigned int version,const index_loader_type& lm) - { - { - typedef random_access_index_loader loader; - - loader ld(get_allocator(),ptrs); - lm.load( - ::boost::bind( - &loader::rearrange,&ld,::boost::arg<1>(),::boost::arg<2>()), - ar,version); - } /* exit scope so that ld frees its resources */ - super::load_(ar,version,lm); - } -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - bool invariant_()const - { - if(size()>capacity())return false; - if(size()==0||begin()==end()){ - if(size()!=0||begin()!=end())return false; - } - else{ - size_type s=0; - for(const_iterator it=begin(),it_end=end();;++it,++s){ - if(*(it.get_node()->up())!=it.get_node()->impl())return false; - if(it==it_end)break; - } - if(s!=size())return false; - } - - return super::invariant_(); - } - - /* This forwarding function eases things for the boost::mem_fn construct - * in BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT. Actually, - * final_check_invariant is already an inherited member function of index. - */ - void check_invariant_()const{this->final_check_invariant_();} -#endif - -private: - node_type* header()const{return this->final_header();} - - static void relocate(node_type* position,node_type* x) - { - node_impl_type::relocate(position->up(),x->up()); - } - - static void relocate(node_type* position,node_type* first,node_type* last) - { - node_impl_type::relocate( - position->up(),first->up(),last->up()); - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - void detach_iterators(node_type* x) - { - iterator it=make_iterator(x); - safe_mode::detach_equivalent_iterators(it); - } -#endif - - template - void assign_iter(InputIterator first,InputIterator last,mpl::true_) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - clear(); - for(;first!=last;++first)this->final_insert_ref_(*first); - } - - void assign_iter(size_type n,value_param_type value,mpl::false_) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - clear(); - for(size_type i=0;i - void insert_iter( - iterator position,InputIterator first,InputIterator last,mpl::true_) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - size_type s=0; - BOOST_TRY{ - for(;first!=last;++first){ - if(this->final_insert_ref_(*first).second)++s; - } - } - BOOST_CATCH(...){ - relocate(position,end()-s,end()); - BOOST_RETHROW; - } - BOOST_CATCH_END - relocate(position,end()-s,end()); - } - - void insert_iter( - iterator position,size_type n,value_param_type x,mpl::false_) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - size_type s=0; - BOOST_TRY{ - while(n--){ - if(push_back(x).second)++s; - } - } - BOOST_CATCH(...){ - relocate(position,end()-s,end()); - BOOST_RETHROW; - } - BOOST_CATCH_END - relocate(position,end()-s,end()); - } - - template - std::pair emplace_front_impl( - BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - } - - template - std::pair emplace_back_impl( - BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - } - - template - std::pair emplace_impl( - iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - std::pair p= - this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - if(p.second&&position.get_node()!=header()){ - relocate(position.get_node(),p.first); - } - return std::pair(make_iterator(p.first),p.second); - } - - ptr_array ptrs; - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -#pragma parse_mfunc_templ reset -#endif -}; - -/* comparison */ - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator==( - const random_access_index& x, - const random_access_index& y) -{ - return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); -} - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator<( - const random_access_index& x, - const random_access_index& y) -{ - return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); -} - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator!=( - const random_access_index& x, - const random_access_index& y) -{ - return !(x==y); -} - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator>( - const random_access_index& x, - const random_access_index& y) -{ - return y -bool operator>=( - const random_access_index& x, - const random_access_index& y) -{ - return !(x -bool operator<=( - const random_access_index& x, - const random_access_index& y) -{ - return !(x>y); -} - -/* specialized algorithms */ - -template -void swap( - random_access_index& x, - random_access_index& y) -{ - x.swap(y); -} - -} /* namespace multi_index::detail */ - -/* random access index specifier */ - -template -struct random_access -{ - BOOST_STATIC_ASSERT(detail::is_tag::value); - - template - struct node_class - { - typedef detail::random_access_index_node type; - }; - - template - struct index_class - { - typedef detail::random_access_index< - SuperMeta,typename TagList::type> type; - }; -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -/* Boost.Foreach compatibility */ - -template -inline boost::mpl::true_* boost_foreach_is_noncopyable( - boost::multi_index::detail::random_access_index*&, - boost_foreach_argument_dependent_lookup_hack) -{ - return 0; -} - -#undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT -#undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index_fwd.hpp deleted file mode 100644 index 2ea19295426..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index_fwd.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_FWD_HPP -#define BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_FWD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template -class random_access_index; - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator==( - const random_access_index& x, - const random_access_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator<( - const random_access_index& x, - const random_access_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator!=( - const random_access_index& x, - const random_access_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator>( - const random_access_index& x, - const random_access_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator>=( - const random_access_index& x, - const random_access_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator<=( - const random_access_index& x, - const random_access_index& y); - -template -void swap( - random_access_index& x, - random_access_index& y); - -} /* namespace multi_index::detail */ - -/* index specifiers */ - -template > -struct random_access; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index.hpp deleted file mode 100644 index 4b24c4f5937..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index.hpp +++ /dev/null @@ -1,382 +0,0 @@ -/* Copyright 2003-2017 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_RANKED_INDEX_HPP -#define BOOST_MULTI_INDEX_RANKED_INDEX_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* ranked_index augments a given ordered index to provide rank operations */ - -template -struct ranked_node:OrderedIndexNodeImpl -{ - std::size_t size; -}; - -template -class ranked_index:public OrderedIndexImpl -{ - typedef OrderedIndexImpl super; - -protected: - typedef typename super::node_type node_type; - typedef typename super::node_impl_pointer node_impl_pointer; - -public: - typedef typename super::ctor_args_list ctor_args_list; - typedef typename super::allocator_type allocator_type; - typedef typename super::iterator iterator; - - /* rank operations */ - - iterator nth(std::size_t n)const - { - return this->make_iterator(node_type::from_impl( - ranked_index_nth(n,this->header()->impl()))); - } - - std::size_t rank(iterator position)const - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - - return ranked_index_rank( - position.get_node()->impl(),this->header()->impl()); - } - - template - std::size_t find_rank(const CompatibleKey& x)const - { - return ranked_index_find_rank( - this->root(),this->header(),this->key,x,this->comp_); - } - - template - std::size_t find_rank( - const CompatibleKey& x,const CompatibleCompare& comp)const - { - return ranked_index_find_rank( - this->root(),this->header(),this->key,x,comp); - } - - template - std::size_t lower_bound_rank(const CompatibleKey& x)const - { - return ranked_index_lower_bound_rank( - this->root(),this->header(),this->key,x,this->comp_); - } - - template - std::size_t lower_bound_rank( - const CompatibleKey& x,const CompatibleCompare& comp)const - { - return ranked_index_lower_bound_rank( - this->root(),this->header(),this->key,x,comp); - } - - template - std::size_t upper_bound_rank(const CompatibleKey& x)const - { - return ranked_index_upper_bound_rank( - this->root(),this->header(),this->key,x,this->comp_); - } - - template - std::size_t upper_bound_rank( - const CompatibleKey& x,const CompatibleCompare& comp)const - { - return ranked_index_upper_bound_rank( - this->root(),this->header(),this->key,x,comp); - } - - template - std::pair equal_range_rank( - const CompatibleKey& x)const - { - return ranked_index_equal_range_rank( - this->root(),this->header(),this->key,x,this->comp_); - } - - template - std::pair equal_range_rank( - const CompatibleKey& x,const CompatibleCompare& comp)const - { - return ranked_index_equal_range_rank( - this->root(),this->header(),this->key,x,comp); - } - - template - std::pair - range_rank(LowerBounder lower,UpperBounder upper)const - { - typedef typename mpl::if_< - is_same, - BOOST_DEDUCED_TYPENAME mpl::if_< - is_same, - both_unbounded_tag, - lower_unbounded_tag - >::type, - BOOST_DEDUCED_TYPENAME mpl::if_< - is_same, - upper_unbounded_tag, - none_unbounded_tag - >::type - >::type dispatch; - - return range_rank(lower,upper,dispatch()); - } - -protected: - ranked_index(const ranked_index& x):super(x){}; - - ranked_index(const ranked_index& x,do_not_copy_elements_tag): - super(x,do_not_copy_elements_tag()){}; - - ranked_index( - const ctor_args_list& args_list,const allocator_type& al): - super(args_list,al){} - -private: - template - std::pair - range_rank(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const - { - node_type* y=this->header(); - node_type* z=this->root(); - - if(!z)return std::pair(0,0); - - std::size_t s=z->impl()->size; - - do{ - if(!lower(this->key(z->value()))){ - z=node_type::from_impl(z->right()); - } - else if(!upper(this->key(z->value()))){ - y=z; - s-=ranked_node_size(y->right())+1; - z=node_type::from_impl(z->left()); - } - else{ - return std::pair( - s-z->impl()->size+ - lower_range_rank(node_type::from_impl(z->left()),z,lower), - s-ranked_node_size(z->right())+ - upper_range_rank(node_type::from_impl(z->right()),y,upper)); - } - }while(z); - - return std::pair(s,s); - } - - template - std::pair - range_rank(LowerBounder,UpperBounder upper,lower_unbounded_tag)const - { - return std::pair( - 0, - upper_range_rank(this->root(),this->header(),upper)); - } - - template - std::pair - range_rank(LowerBounder lower,UpperBounder,upper_unbounded_tag)const - { - return std::pair( - lower_range_rank(this->root(),this->header(),lower), - this->size()); - } - - template - std::pair - range_rank(LowerBounder,UpperBounder,both_unbounded_tag)const - { - return std::pair(0,this->size()); - } - - template - std::size_t - lower_range_rank(node_type* top,node_type* y,LowerBounder lower)const - { - if(!top)return 0; - - std::size_t s=top->impl()->size; - - do{ - if(lower(this->key(top->value()))){ - y=top; - s-=ranked_node_size(y->right())+1; - top=node_type::from_impl(top->left()); - } - else top=node_type::from_impl(top->right()); - }while(top); - - return s; - } - - template - std::size_t - upper_range_rank(node_type* top,node_type* y,UpperBounder upper)const - { - if(!top)return 0; - - std::size_t s=top->impl()->size; - - do{ - if(!upper(this->key(top->value()))){ - y=top; - s-=ranked_node_size(y->right())+1; - top=node_type::from_impl(top->left()); - } - else top=node_type::from_impl(top->right()); - }while(top); - - return s; - } -}; - -/* augmenting policy for ordered_index */ - -struct rank_policy -{ - template - struct augmented_node - { - typedef ranked_node type; - }; - - template - struct augmented_interface - { - typedef ranked_index type; - }; - - /* algorithmic stuff */ - - template - static void add(Pointer x,Pointer root) - { - x->size=1; - while(x!=root){ - x=x->parent(); - ++(x->size); - } - } - - template - static void remove(Pointer x,Pointer root) - { - while(x!=root){ - x=x->parent(); - --(x->size); - } - } - - template - static void copy(Pointer x,Pointer y) - { - y->size=x->size; - } - - template - static void rotate_left(Pointer x,Pointer y) /* in: x==y->left() */ - { - y->size=x->size; - x->size=ranked_node_size(x->left())+ranked_node_size(x->right())+1; - } - - template - static void rotate_right(Pointer x,Pointer y) /* in: x==y->right() */ - { - rotate_left(x,y); - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - template - static bool invariant(Pointer x) - { - return x->size==ranked_node_size(x->left())+ranked_node_size(x->right())+1; - } -#endif -}; - -} /* namespace multi_index::detail */ - -/* ranked_index specifiers */ - -template -struct ranked_unique -{ - typedef typename detail::ordered_index_args< - Arg1,Arg2,Arg3> index_args; - typedef typename index_args::tag_list_type::type tag_list_type; - typedef typename index_args::key_from_value_type key_from_value_type; - typedef typename index_args::compare_type compare_type; - - template - struct node_class - { - typedef detail::ordered_index_node type; - }; - - template - struct index_class - { - typedef detail::ordered_index< - key_from_value_type,compare_type, - SuperMeta,tag_list_type,detail::ordered_unique_tag, - detail::rank_policy> type; - }; -}; - -template -struct ranked_non_unique -{ - typedef detail::ordered_index_args< - Arg1,Arg2,Arg3> index_args; - typedef typename index_args::tag_list_type::type tag_list_type; - typedef typename index_args::key_from_value_type key_from_value_type; - typedef typename index_args::compare_type compare_type; - - template - struct node_class - { - typedef detail::ordered_index_node type; - }; - - template - struct index_class - { - typedef detail::ordered_index< - key_from_value_type,compare_type, - SuperMeta,tag_list_type,detail::ordered_non_unique_tag, - detail::rank_policy> type; - }; -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index_fwd.hpp deleted file mode 100644 index 380d3480736..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index_fwd.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_RANKED_INDEX_FWD_HPP -#define BOOST_MULTI_INDEX_RANKED_INDEX_FWD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include -#include - -namespace boost{ - -namespace multi_index{ - -/* ranked_index specifiers */ - -template -struct ranked_unique; - -template -struct ranked_non_unique; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/safe_mode_errors.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/safe_mode_errors.hpp deleted file mode 100644 index 1904706edec..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/safe_mode_errors.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_SAFE_MODE_ERRORS_HPP -#define BOOST_MULTI_INDEX_SAFE_MODE_ERRORS_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -namespace boost{ - -namespace multi_index{ - -namespace safe_mode{ - -/* Error codes for Boost.MultiIndex safe mode. These go in a separate - * header so that the user can include it when redefining - * BOOST_MULTI_INDEX_SAFE_MODE_ASSERT prior to the inclusion of - * any other header of Boost.MultiIndex. - */ - -enum error_code -{ - invalid_iterator=0, - not_dereferenceable_iterator, - not_incrementable_iterator, - not_decrementable_iterator, - not_owner, - not_same_owner, - invalid_range, - inside_range, - out_of_bounds, - same_container -}; - -} /* namespace multi_index::safe_mode */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index.hpp deleted file mode 100644 index 424eebc376d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index.hpp +++ /dev/null @@ -1,1062 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_SEQUENCED_INDEX_HPP -#define BOOST_MULTI_INDEX_SEQUENCED_INDEX_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) -#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) \ - detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(x,&sequenced_index::check_invariant_); \ - BOOST_JOIN(check_invariant_,__LINE__).touch(); -#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT \ - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(*this) -#else -#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) -#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* sequenced_index adds a layer of sequenced indexing to a given Super */ - -template -class sequenced_index: - BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - ,public safe_mode::safe_container< - sequenced_index > -#endif - -{ -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the - * lifetime of const references bound to temporaries --precisely what - * scopeguards are. - */ - -#pragma parse_mfunc_templ off -#endif - - typedef typename SuperMeta::type super; - -protected: - typedef sequenced_index_node< - typename super::node_type> node_type; - -private: - typedef typename node_type::impl_type node_impl_type; - -public: - /* types */ - - typedef typename node_type::value_type value_type; - typedef tuples::null_type ctor_args; - typedef typename super::final_allocator_type allocator_type; - typedef typename allocator_type::reference reference; - typedef typename allocator_type::const_reference const_reference; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef safe_mode::safe_iterator< - bidir_node_iterator, - sequenced_index> iterator; -#else - typedef bidir_node_iterator iterator; -#endif - - typedef iterator const_iterator; - - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef typename allocator_type::pointer pointer; - typedef typename allocator_type::const_pointer const_pointer; - typedef typename - boost::reverse_iterator reverse_iterator; - typedef typename - boost::reverse_iterator const_reverse_iterator; - typedef TagList tag_list; - -protected: - typedef typename super::final_node_type final_node_type; - typedef tuples::cons< - ctor_args, - typename super::ctor_args_list> ctor_args_list; - typedef typename mpl::push_front< - typename super::index_type_list, - sequenced_index>::type index_type_list; - typedef typename mpl::push_front< - typename super::iterator_type_list, - iterator>::type iterator_type_list; - typedef typename mpl::push_front< - typename super::const_iterator_type_list, - const_iterator>::type const_iterator_type_list; - typedef typename super::copy_map_type copy_map_type; - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - typedef typename super::index_saver_type index_saver_type; - typedef typename super::index_loader_type index_loader_type; -#endif - -private: -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef safe_mode::safe_container< - sequenced_index> safe_super; -#endif - - typedef typename call_traits::param_type value_param_type; - - /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL - * expansion. - */ - - typedef std::pair emplace_return_type; - -public: - - /* construct/copy/destroy - * Default and copy ctors are in the protected section as indices are - * not supposed to be created on their own. No range ctor either. - */ - - sequenced_index& operator=( - const sequenced_index& x) - { - this->final()=x.final(); - return *this; - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - sequenced_index& operator=( - std::initializer_list list) - { - this->final()=list; - return *this; - } -#endif - - template - void assign(InputIterator first,InputIterator last) - { - assign_iter(first,last,mpl::not_ >()); - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - void assign(std::initializer_list list) - { - assign(list.begin(),list.end()); - } -#endif - - void assign(size_type n,value_param_type value) - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - clear(); - for(size_type i=0;ifinal().get_allocator(); - } - - /* iterators */ - - iterator begin()BOOST_NOEXCEPT - {return make_iterator(node_type::from_impl(header()->next()));} - const_iterator begin()const BOOST_NOEXCEPT - {return make_iterator(node_type::from_impl(header()->next()));} - iterator - end()BOOST_NOEXCEPT{return make_iterator(header());} - const_iterator - end()const BOOST_NOEXCEPT{return make_iterator(header());} - reverse_iterator - rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} - const_reverse_iterator - rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} - reverse_iterator - rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} - const_reverse_iterator - rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} - const_iterator - cbegin()const BOOST_NOEXCEPT{return begin();} - const_iterator - cend()const BOOST_NOEXCEPT{return end();} - const_reverse_iterator - crbegin()const BOOST_NOEXCEPT{return rbegin();} - const_reverse_iterator - crend()const BOOST_NOEXCEPT{return rend();} - - iterator iterator_to(const value_type& x) - { - return make_iterator(node_from_value(&x)); - } - - const_iterator iterator_to(const value_type& x)const - { - return make_iterator(node_from_value(&x)); - } - - /* capacity */ - - bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} - size_type size()const BOOST_NOEXCEPT{return this->final_size_();} - size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} - - void resize(size_type n) - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - if(n>size()){ - for(size_type m=n-size();m--;) - this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK); - } - else if(nsize())insert(end(),n-size(),x); - else if(n push_front(const value_type& x) - {return insert(begin(),x);} - std::pair push_front(BOOST_RV_REF(value_type) x) - {return insert(begin(),boost::move(x));} - void pop_front(){erase(begin());} - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( - emplace_return_type,emplace_back,emplace_back_impl) - - std::pair push_back(const value_type& x) - {return insert(end(),x);} - std::pair push_back(BOOST_RV_REF(value_type) x) - {return insert(end(),boost::move(x));} - void pop_back(){erase(--end());} - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( - emplace_return_type,emplace,emplace_impl,iterator,position) - - std::pair insert(iterator position,const value_type& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_(x); - if(p.second&&position.get_node()!=header()){ - relink(position.get_node(),p.first); - } - return std::pair(make_iterator(p.first),p.second); - } - - std::pair insert(iterator position,BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_rv_(x); - if(p.second&&position.get_node()!=header()){ - relink(position.get_node(),p.first); - } - return std::pair(make_iterator(p.first),p.second); - } - - void insert(iterator position,size_type n,value_param_type x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - for(size_type i=0;i - void insert(iterator position,InputIterator first,InputIterator last) - { - insert_iter(position,first,last,mpl::not_ >()); - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - void insert(iterator position,std::initializer_list list) - { - insert(position,list.begin(),list.end()); - } -#endif - - iterator erase(iterator position) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - this->final_erase_(static_cast(position++.get_node())); - return position; - } - - iterator erase(iterator first,iterator last) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); - BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - while(first!=last){ - first=erase(first); - } - return first; - } - - bool replace(iterator position,const value_type& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - return this->final_replace_( - x,static_cast(position.get_node())); - } - - bool replace(iterator position,BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - return this->final_replace_rv_( - x,static_cast(position.get_node())); - } - - template - bool modify(iterator position,Modifier mod) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer on safe mode code chokes if this - * this is not added. Left it for all compilers as it does no - * harm. - */ - - position.detach(); -#endif - - return this->final_modify_( - mod,static_cast(position.get_node())); - } - - template - bool modify(iterator position,Modifier mod,Rollback back_) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer on safe mode code chokes if this - * this is not added. Left it for all compilers as it does no - * harm. - */ - - position.detach(); -#endif - - return this->final_modify_( - mod,back_,static_cast(position.get_node())); - } - - void swap(sequenced_index& x) - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x); - this->final_swap_(x.final()); - } - - void clear()BOOST_NOEXCEPT - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - this->final_clear_(); - } - - /* list operations */ - - void splice(iterator position,sequenced_index& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(*this,x); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - iterator first=x.begin(),last=x.end(); - while(first!=last){ - if(insert(position,*first).second)first=x.erase(first); - else ++first; - } - } - - void splice(iterator position,sequenced_index& x,iterator i) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - if(&x==this){ - if(position!=i)relink(position.get_node(),i.get_node()); - } - else{ - if(insert(position,*i).second){ - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following - * workaround is needed. Left it for all compilers as it does no - * harm. - */ - i.detach(); - x.erase(x.make_iterator(i.get_node())); -#else - x.erase(i); -#endif - - } - } - } - - void splice( - iterator position,sequenced_index& x, - iterator first,iterator last) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x); - BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - if(&x==this){ - BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last); - if(position!=last)relink( - position.get_node(),first.get_node(),last.get_node()); - } - else{ - while(first!=last){ - if(insert(position,*first).second)first=x.erase(first); - else ++first; - } - } - } - - void remove(value_param_type value) - { - sequenced_index_remove( - *this, - ::boost::bind(std::equal_to(),::boost::arg<1>(),value)); - } - - template - void remove_if(Predicate pred) - { - sequenced_index_remove(*this,pred); - } - - void unique() - { - sequenced_index_unique(*this,std::equal_to()); - } - - template - void unique(BinaryPredicate binary_pred) - { - sequenced_index_unique(*this,binary_pred); - } - - void merge(sequenced_index& x) - { - sequenced_index_merge(*this,x,std::less()); - } - - template - void merge(sequenced_index& x,Compare comp) - { - sequenced_index_merge(*this,x,comp); - } - - void sort() - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - sequenced_index_sort(header(),std::less()); - } - - template - void sort(Compare comp) - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - sequenced_index_sort(header(),comp); - } - - void reverse()BOOST_NOEXCEPT - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - node_impl_type::reverse(header()->impl()); - } - - /* rearrange operations */ - - void relocate(iterator position,iterator i) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - if(position!=i)relink(position.get_node(),i.get_node()); - } - - void relocate(iterator position,iterator first,iterator last) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); - BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); - BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - if(position!=last)relink( - position.get_node(),first.get_node(),last.get_node()); - } - - template - void rearrange(InputIterator first) - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - node_type* pos=header(); - for(size_type s=size();s--;){ - const value_type& v=*first++; - relink(pos,node_from_value(&v)); - } - } - -BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: - sequenced_index(const ctor_args_list& args_list,const allocator_type& al): - super(args_list.get_tail(),al) - { - empty_initialize(); - } - - sequenced_index(const sequenced_index& x): - super(x) - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - ,safe_super() -#endif - - { - /* the actual copying takes place in subsequent call to copy_() */ - } - - sequenced_index( - const sequenced_index& x,do_not_copy_elements_tag): - super(x,do_not_copy_elements_tag()) - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - ,safe_super() -#endif - - { - empty_initialize(); - } - - ~sequenced_index() - { - /* the container is guaranteed to be empty by now */ - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - iterator make_iterator(node_type* node){return iterator(node,this);} - const_iterator make_iterator(node_type* node)const - {return const_iterator(node,const_cast(this));} -#else - iterator make_iterator(node_type* node){return iterator(node);} - const_iterator make_iterator(node_type* node)const - {return const_iterator(node);} -#endif - - void copy_( - const sequenced_index& x,const copy_map_type& map) - { - node_type* org=x.header(); - node_type* cpy=header(); - do{ - node_type* next_org=node_type::from_impl(org->next()); - node_type* next_cpy=map.find(static_cast(next_org)); - cpy->next()=next_cpy->impl(); - next_cpy->prior()=cpy->impl(); - org=next_org; - cpy=next_cpy; - }while(org!=x.header()); - - super::copy_(x,map); - } - - template - final_node_type* insert_( - value_param_type v,final_node_type*& x,Variant variant) - { - final_node_type* res=super::insert_(v,x,variant); - if(res==x)link(static_cast(x)); - return res; - } - - template - final_node_type* insert_( - value_param_type v,node_type* position,final_node_type*& x,Variant variant) - { - final_node_type* res=super::insert_(v,position,x,variant); - if(res==x)link(static_cast(x)); - return res; - } - - void erase_(node_type* x) - { - unlink(x); - super::erase_(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - } - - void delete_all_nodes_() - { - for(node_type* x=node_type::from_impl(header()->next());x!=header();){ - node_type* y=node_type::from_impl(x->next()); - this->final_delete_node_(static_cast(x)); - x=y; - } - } - - void clear_() - { - super::clear_(); - empty_initialize(); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::detach_dereferenceable_iterators(); -#endif - } - - void swap_(sequenced_index& x) - { -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::swap(x); -#endif - - super::swap_(x); - } - - void swap_elements_(sequenced_index& x) - { -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::swap(x); -#endif - - super::swap_elements_(x); - } - - template - bool replace_(value_param_type v,node_type* x,Variant variant) - { - return super::replace_(v,x,variant); - } - - bool modify_(node_type* x) - { - BOOST_TRY{ - if(!super::modify_(x)){ - unlink(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - return false; - } - else return true; - } - BOOST_CATCH(...){ - unlink(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - bool modify_rollback_(node_type* x) - { - return super::modify_rollback_(x); - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* serialization */ - - template - void save_( - Archive& ar,const unsigned int version,const index_saver_type& sm)const - { - sm.save(begin(),end(),ar,version); - super::save_(ar,version,sm); - } - - template - void load_( - Archive& ar,const unsigned int version,const index_loader_type& lm) - { - lm.load( - ::boost::bind( - &sequenced_index::rearranger,this,::boost::arg<1>(),::boost::arg<2>()), - ar,version); - super::load_(ar,version,lm); - } -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - bool invariant_()const - { - if(size()==0||begin()==end()){ - if(size()!=0||begin()!=end()|| - header()->next()!=header()->impl()|| - header()->prior()!=header()->impl())return false; - } - else{ - size_type s=0; - for(const_iterator it=begin(),it_end=end();it!=it_end;++it,++s){ - if(it.get_node()->next()->prior()!=it.get_node()->impl())return false; - if(it.get_node()->prior()->next()!=it.get_node()->impl())return false; - } - if(s!=size())return false; - } - - return super::invariant_(); - } - - /* This forwarding function eases things for the boost::mem_fn construct - * in BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT. Actually, - * final_check_invariant is already an inherited member function of index. - */ - void check_invariant_()const{this->final_check_invariant_();} -#endif - -private: - node_type* header()const{return this->final_header();} - - void empty_initialize() - { - header()->prior()=header()->next()=header()->impl(); - } - - void link(node_type* x) - { - node_impl_type::link(x->impl(),header()->impl()); - }; - - static void unlink(node_type* x) - { - node_impl_type::unlink(x->impl()); - } - - static void relink(node_type* position,node_type* x) - { - node_impl_type::relink(position->impl(),x->impl()); - } - - static void relink(node_type* position,node_type* first,node_type* last) - { - node_impl_type::relink( - position->impl(),first->impl(),last->impl()); - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - void rearranger(node_type* position,node_type *x) - { - if(!position)position=header(); - node_type::increment(position); - if(position!=x)relink(position,x); - } -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - void detach_iterators(node_type* x) - { - iterator it=make_iterator(x); - safe_mode::detach_equivalent_iterators(it); - } -#endif - - template - void assign_iter(InputIterator first,InputIterator last,mpl::true_) - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - clear(); - for(;first!=last;++first)this->final_insert_ref_(*first); - } - - void assign_iter(size_type n,value_param_type value,mpl::false_) - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - clear(); - for(size_type i=0;i - void insert_iter( - iterator position,InputIterator first,InputIterator last,mpl::true_) - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - for(;first!=last;++first){ - std::pair p= - this->final_insert_ref_(*first); - if(p.second&&position.get_node()!=header()){ - relink(position.get_node(),p.first); - } - } - } - - void insert_iter( - iterator position,size_type n,value_param_type x,mpl::false_) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - for(size_type i=0;i - std::pair emplace_front_impl( - BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - } - - template - std::pair emplace_back_impl( - BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - } - - template - std::pair emplace_impl( - iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - std::pair p= - this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - if(p.second&&position.get_node()!=header()){ - relink(position.get_node(),p.first); - } - return std::pair(make_iterator(p.first),p.second); - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -#pragma parse_mfunc_templ reset -#endif -}; - -/* comparison */ - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator==( - const sequenced_index& x, - const sequenced_index& y) -{ - return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); -} - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator<( - const sequenced_index& x, - const sequenced_index& y) -{ - return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); -} - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator!=( - const sequenced_index& x, - const sequenced_index& y) -{ - return !(x==y); -} - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator>( - const sequenced_index& x, - const sequenced_index& y) -{ - return y -bool operator>=( - const sequenced_index& x, - const sequenced_index& y) -{ - return !(x -bool operator<=( - const sequenced_index& x, - const sequenced_index& y) -{ - return !(x>y); -} - -/* specialized algorithms */ - -template -void swap( - sequenced_index& x, - sequenced_index& y) -{ - x.swap(y); -} - -} /* namespace multi_index::detail */ - -/* sequenced index specifier */ - -template -struct sequenced -{ - BOOST_STATIC_ASSERT(detail::is_tag::value); - - template - struct node_class - { - typedef detail::sequenced_index_node type; - }; - - template - struct index_class - { - typedef detail::sequenced_index type; - }; -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -/* Boost.Foreach compatibility */ - -template -inline boost::mpl::true_* boost_foreach_is_noncopyable( - boost::multi_index::detail::sequenced_index*&, - boost_foreach_argument_dependent_lookup_hack) -{ - return 0; -} - -#undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT -#undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index_fwd.hpp deleted file mode 100644 index a019f2a6d2f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index_fwd.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_SEQUENCED_INDEX_FWD_HPP -#define BOOST_MULTI_INDEX_SEQUENCED_INDEX_FWD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template -class sequenced_index; - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator==( - const sequenced_index& x, - const sequenced_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator<( - const sequenced_index& x, - const sequenced_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator!=( - const sequenced_index& x, - const sequenced_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator>( - const sequenced_index& x, - const sequenced_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator>=( - const sequenced_index& x, - const sequenced_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator<=( - const sequenced_index& x, - const sequenced_index& y); - -template -void swap( - sequenced_index& x, - sequenced_index& y); - -} /* namespace multi_index::detail */ - -/* index specifiers */ - -template > -struct sequenced; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/tag.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/tag.hpp deleted file mode 100644 index ce51f8241ee..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/tag.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_TAG_HPP -#define BOOST_MULTI_INDEX_TAG_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* A wrapper of mpl::vector used to hide MPL from the user. - * tag contains types used as tag names for indices in get() functions. - */ - -/* This user_definable macro limits the number of elements of a tag; - * useful for shortening resulting symbol names (MSVC++ 6.0, for instance, - * has problems coping with very long symbol names.) - */ - -#if !defined(BOOST_MULTI_INDEX_LIMIT_TAG_SIZE) -#define BOOST_MULTI_INDEX_LIMIT_TAG_SIZE BOOST_MPL_LIMIT_VECTOR_SIZE -#endif - -#if BOOST_MULTI_INDEX_LIMIT_TAG_SIZE -struct is_tag -{ - BOOST_STATIC_CONSTANT(bool,value=(is_base_and_derived::value)); -}; - -} /* namespace multi_index::detail */ - -template< - BOOST_PP_ENUM_BINARY_PARAMS( - BOOST_MULTI_INDEX_TAG_SIZE, - typename T, - =mpl::na BOOST_PP_INTERCEPT) -> -struct tag:private detail::tag_marker -{ - /* The mpl::transform pass produces shorter symbols (without - * trailing mpl::na's.) - */ - - typedef typename mpl::transform< - mpl::vector, - mpl::identity - >::type type; - - BOOST_STATIC_ASSERT(detail::no_duplicate_tags::value); -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#undef BOOST_MULTI_INDEX_TAG_SIZE - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index_container.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index_container.hpp deleted file mode 100644 index 9993a8dfa10..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index_container.hpp +++ /dev/null @@ -1,1362 +0,0 @@ -/* Multiply indexed container. - * - * Copyright 2003-2014 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_HPP -#define BOOST_MULTI_INDEX_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#include -#include -#include -#include -#include -#include -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) -#include -#define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x) \ - detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(x,&multi_index_container::check_invariant_); \ - BOOST_JOIN(check_invariant_,__LINE__).touch(); -#define BOOST_MULTI_INDEX_CHECK_INVARIANT \ - BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(*this) -#else -#define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x) -#define BOOST_MULTI_INDEX_CHECK_INVARIANT -#endif - -namespace boost{ - -namespace multi_index{ - -#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500)) -#pragma warning(push) -#pragma warning(disable:4522) /* spurious warning on multiple operator=()'s */ -#endif - -template -class multi_index_container: - private ::boost::base_from_member< - typename boost::detail::allocator::rebind_to< - Allocator, - typename detail::multi_index_node_type< - Value,IndexSpecifierList,Allocator>::type - >::type>, - BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS detail::header_holder< - typename boost::detail::allocator::rebind_to< - Allocator, - typename detail::multi_index_node_type< - Value,IndexSpecifierList,Allocator>::type - >::type::pointer, - multi_index_container >, - public detail::multi_index_base_type< - Value,IndexSpecifierList,Allocator>::type -{ -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the - * lifetime of const references bound to temporaries --precisely what - * scopeguards are. - */ - -#pragma parse_mfunc_templ off -#endif - -private: - BOOST_COPYABLE_AND_MOVABLE(multi_index_container) - -#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) - template friend class detail::index_base; - template friend struct detail::header_holder; - template friend struct detail::converter; -#endif - - typedef typename detail::multi_index_base_type< - Value,IndexSpecifierList,Allocator>::type super; - typedef typename - boost::detail::allocator::rebind_to< - Allocator, - typename super::node_type - >::type node_allocator; - typedef ::boost::base_from_member< - node_allocator> bfm_allocator; - typedef detail::header_holder< - typename node_allocator::pointer, - multi_index_container> bfm_header; - - -public: - /* All types are inherited from super, a few are explicitly - * brought forward here to save us some typename's. - */ - - typedef typename super::ctor_args_list ctor_args_list; - typedef IndexSpecifierList index_specifier_type_list; - - typedef typename super::index_type_list index_type_list; - - typedef typename super::iterator_type_list iterator_type_list; - typedef typename super::const_iterator_type_list const_iterator_type_list; - typedef typename super::value_type value_type; - typedef typename super::final_allocator_type allocator_type; - typedef typename super::iterator iterator; - typedef typename super::const_iterator const_iterator; - - BOOST_STATIC_ASSERT( - detail::no_duplicate_tags_in_index_list::value); - - /* global project() needs to see this publicly */ - - typedef typename super::node_type node_type; - - /* construct/copy/destroy */ - - explicit multi_index_container( - -#if BOOST_WORKAROUND(__IBMCPP__,<=600) - /* VisualAge seems to have an ETI issue with the default values - * for arguments args_list and al. - */ - - const ctor_args_list& args_list= - typename mpl::identity::type:: - ctor_args_list(), - const allocator_type& al= - typename mpl::identity::type:: - allocator_type()): -#else - const ctor_args_list& args_list=ctor_args_list(), - const allocator_type& al=allocator_type()): -#endif - - bfm_allocator(al), - super(args_list,bfm_allocator::member), - node_count(0) - { - BOOST_MULTI_INDEX_CHECK_INVARIANT; - } - - explicit multi_index_container(const allocator_type& al): - bfm_allocator(al), - super(ctor_args_list(),bfm_allocator::member), - node_count(0) - { - BOOST_MULTI_INDEX_CHECK_INVARIANT; - } - - template - multi_index_container( - InputIterator first,InputIterator last, - -#if BOOST_WORKAROUND(__IBMCPP__,<=600) - /* VisualAge seems to have an ETI issue with the default values - * for arguments args_list and al. - */ - - const ctor_args_list& args_list= - typename mpl::identity::type:: - ctor_args_list(), - const allocator_type& al= - typename mpl::identity::type:: - allocator_type()): -#else - const ctor_args_list& args_list=ctor_args_list(), - const allocator_type& al=allocator_type()): -#endif - - bfm_allocator(al), - super(args_list,bfm_allocator::member), - node_count(0) - { - BOOST_MULTI_INDEX_CHECK_INVARIANT; - BOOST_TRY{ - iterator hint=super::end(); - for(;first!=last;++first){ - hint=super::make_iterator( - insert_ref_(*first,hint.get_node()).first); - ++hint; - } - } - BOOST_CATCH(...){ - clear_(); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - multi_index_container( - std::initializer_list list, - const ctor_args_list& args_list=ctor_args_list(), - const allocator_type& al=allocator_type()): - bfm_allocator(al), - super(args_list,bfm_allocator::member), - node_count(0) - { - BOOST_MULTI_INDEX_CHECK_INVARIANT; - BOOST_TRY{ - typedef const Value* init_iterator; - - iterator hint=super::end(); - for(init_iterator first=list.begin(),last=list.end(); - first!=last;++first){ - hint=super::make_iterator(insert_(*first,hint.get_node()).first); - ++hint; - } - } - BOOST_CATCH(...){ - clear_(); - BOOST_RETHROW; - } - BOOST_CATCH_END - } -#endif - - multi_index_container( - const multi_index_container& x): - bfm_allocator(x.bfm_allocator::member), - bfm_header(), - super(x), - node_count(0) - { - copy_map_type map(bfm_allocator::member,x.size(),x.header(),header()); - for(const_iterator it=x.begin(),it_end=x.end();it!=it_end;++it){ - map.clone(it.get_node()); - } - super::copy_(x,map); - map.release(); - node_count=x.size(); - - /* Not until this point are the indices required to be consistent, - * hence the position of the invariant checker. - */ - - BOOST_MULTI_INDEX_CHECK_INVARIANT; - } - - multi_index_container(BOOST_RV_REF(multi_index_container) x): - bfm_allocator(x.bfm_allocator::member), - bfm_header(), - super(x,detail::do_not_copy_elements_tag()), - node_count(0) - { - BOOST_MULTI_INDEX_CHECK_INVARIANT; - BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x); - swap_elements_(x); - } - - ~multi_index_container() - { - delete_all_nodes_(); - } - -#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - /* As per http://www.boost.org/doc/html/move/emulation_limitations.html - * #move.emulation_limitations.assignment_operator - */ - - multi_index_container& operator=( - const multi_index_container& x) - { - multi_index_container y(x); - this->swap(y); - return *this; - } -#endif - - multi_index_container& operator=( - BOOST_COPY_ASSIGN_REF(multi_index_container) x) - { - multi_index_container y(x); - this->swap(y); - return *this; - } - - multi_index_container& operator=( - BOOST_RV_REF(multi_index_container) x) - { - this->swap(x); - return *this; - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - multi_index_container& operator=( - std::initializer_list list) - { - BOOST_MULTI_INDEX_CHECK_INVARIANT; - typedef const Value* init_iterator; - - multi_index_container x(*this,detail::do_not_copy_elements_tag()); - iterator hint=x.end(); - for(init_iterator first=list.begin(),last=list.end(); - first!=last;++first){ - hint=x.make_iterator(x.insert_(*first,hint.get_node()).first); - ++hint; - } - x.swap_elements_(*this); - return*this; - } -#endif - - allocator_type get_allocator()const BOOST_NOEXCEPT - { - return allocator_type(bfm_allocator::member); - } - - /* retrieval of indices by number */ - -#if !defined(BOOST_NO_MEMBER_TEMPLATES) - template - struct nth_index - { - BOOST_STATIC_ASSERT(N>=0&&N::type::value); - typedef typename mpl::at_c::type type; - }; - - template - typename nth_index::type& get()BOOST_NOEXCEPT - { - BOOST_STATIC_ASSERT(N>=0&&N::type::value); - return *this; - } - - template - const typename nth_index::type& get()const BOOST_NOEXCEPT - { - BOOST_STATIC_ASSERT(N>=0&&N::type::value); - return *this; - } -#endif - - /* retrieval of indices by tag */ - -#if !defined(BOOST_NO_MEMBER_TEMPLATES) - template - struct index - { - typedef typename mpl::find_if< - index_type_list, - detail::has_tag - >::type iter; - - BOOST_STATIC_CONSTANT( - bool,index_found=!(is_same::type >::value)); - BOOST_STATIC_ASSERT(index_found); - - typedef typename mpl::deref::type type; - }; - - template - typename index::type& get()BOOST_NOEXCEPT - { - return *this; - } - - template - const typename index::type& get()const BOOST_NOEXCEPT - { - return *this; - } -#endif - - /* projection of iterators by number */ - -#if !defined(BOOST_NO_MEMBER_TEMPLATES) - template - struct nth_index_iterator - { - typedef typename nth_index::type::iterator type; - }; - - template - struct nth_index_const_iterator - { - typedef typename nth_index::type::const_iterator type; - }; - - template - typename nth_index_iterator::type project(IteratorType it) - { - typedef typename nth_index::type index_type; - -#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ - BOOST_STATIC_ASSERT( - (mpl::contains::value)); -#endif - - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); - BOOST_MULTI_INDEX_CHECK_IS_OWNER( - it,static_cast(*this)); - - return index_type::make_iterator(static_cast(it.get_node())); - } - - template - typename nth_index_const_iterator::type project(IteratorType it)const - { - typedef typename nth_index::type index_type; - -#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ - BOOST_STATIC_ASSERT(( - mpl::contains::value|| - mpl::contains::value)); -#endif - - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); - BOOST_MULTI_INDEX_CHECK_IS_OWNER( - it,static_cast(*this)); - return index_type::make_iterator(static_cast(it.get_node())); - } -#endif - - /* projection of iterators by tag */ - -#if !defined(BOOST_NO_MEMBER_TEMPLATES) - template - struct index_iterator - { - typedef typename index::type::iterator type; - }; - - template - struct index_const_iterator - { - typedef typename index::type::const_iterator type; - }; - - template - typename index_iterator::type project(IteratorType it) - { - typedef typename index::type index_type; - -#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ - BOOST_STATIC_ASSERT( - (mpl::contains::value)); -#endif - - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); - BOOST_MULTI_INDEX_CHECK_IS_OWNER( - it,static_cast(*this)); - return index_type::make_iterator(static_cast(it.get_node())); - } - - template - typename index_const_iterator::type project(IteratorType it)const - { - typedef typename index::type index_type; - -#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ - BOOST_STATIC_ASSERT(( - mpl::contains::value|| - mpl::contains::value)); -#endif - - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); - BOOST_MULTI_INDEX_CHECK_IS_OWNER( - it,static_cast(*this)); - return index_type::make_iterator(static_cast(it.get_node())); - } -#endif - -BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: - typedef typename super::copy_map_type copy_map_type; - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - multi_index_container( - const multi_index_container& x, - detail::do_not_copy_elements_tag): - bfm_allocator(x.bfm_allocator::member), - bfm_header(), - super(x,detail::do_not_copy_elements_tag()), - node_count(0) - { - BOOST_MULTI_INDEX_CHECK_INVARIANT; - } -#endif - - node_type* header()const - { - return &*bfm_header::member; - } - - node_type* allocate_node() - { - return &*bfm_allocator::member.allocate(1); - } - - void deallocate_node(node_type* x) - { - typedef typename node_allocator::pointer node_pointer; - bfm_allocator::member.deallocate(static_cast(x),1); - } - - bool empty_()const - { - return node_count==0; - } - - std::size_t size_()const - { - return node_count; - } - - std::size_t max_size_()const - { - return static_cast(-1); - } - - template - std::pair insert_(const Value& v,Variant variant) - { - node_type* x=0; - node_type* res=super::insert_(v,x,variant); - if(res==x){ - ++node_count; - return std::pair(res,true); - } - else{ - return std::pair(res,false); - } - } - - std::pair insert_(const Value& v) - { - return insert_(v,detail::lvalue_tag()); - } - - std::pair insert_rv_(const Value& v) - { - return insert_(v,detail::rvalue_tag()); - } - - template - std::pair insert_ref_(T& t) - { - node_type* x=allocate_node(); - BOOST_TRY{ - new(&x->value()) value_type(t); - BOOST_TRY{ - node_type* res=super::insert_(x->value(),x,detail::emplaced_tag()); - if(res==x){ - ++node_count; - return std::pair(res,true); - } - else{ - boost::detail::allocator::destroy(&x->value()); - deallocate_node(x); - return std::pair(res,false); - } - } - BOOST_CATCH(...){ - boost::detail::allocator::destroy(&x->value()); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - BOOST_CATCH(...){ - deallocate_node(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - std::pair insert_ref_(const value_type& x) - { - return insert_(x); - } - - std::pair insert_ref_(value_type& x) - { - return insert_(x); - } - - template - std::pair emplace_( - BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - node_type* x=allocate_node(); - BOOST_TRY{ - detail::vartempl_placement_new( - &x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - BOOST_TRY{ - node_type* res=super::insert_(x->value(),x,detail::emplaced_tag()); - if(res==x){ - ++node_count; - return std::pair(res,true); - } - else{ - boost::detail::allocator::destroy(&x->value()); - deallocate_node(x); - return std::pair(res,false); - } - } - BOOST_CATCH(...){ - boost::detail::allocator::destroy(&x->value()); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - BOOST_CATCH(...){ - deallocate_node(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - template - std::pair insert_( - const Value& v,node_type* position,Variant variant) - { - node_type* x=0; - node_type* res=super::insert_(v,position,x,variant); - if(res==x){ - ++node_count; - return std::pair(res,true); - } - else{ - return std::pair(res,false); - } - } - - std::pair insert_(const Value& v,node_type* position) - { - return insert_(v,position,detail::lvalue_tag()); - } - - std::pair insert_rv_(const Value& v,node_type* position) - { - return insert_(v,position,detail::rvalue_tag()); - } - - template - std::pair insert_ref_( - T& t,node_type* position) - { - node_type* x=allocate_node(); - BOOST_TRY{ - new(&x->value()) value_type(t); - BOOST_TRY{ - node_type* res=super::insert_( - x->value(),position,x,detail::emplaced_tag()); - if(res==x){ - ++node_count; - return std::pair(res,true); - } - else{ - boost::detail::allocator::destroy(&x->value()); - deallocate_node(x); - return std::pair(res,false); - } - } - BOOST_CATCH(...){ - boost::detail::allocator::destroy(&x->value()); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - BOOST_CATCH(...){ - deallocate_node(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - std::pair insert_ref_( - const value_type& x,node_type* position) - { - return insert_(x,position); - } - - std::pair insert_ref_( - value_type& x,node_type* position) - { - return insert_(x,position); - } - - template - std::pair emplace_hint_( - node_type* position, - BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - node_type* x=allocate_node(); - BOOST_TRY{ - detail::vartempl_placement_new( - &x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - BOOST_TRY{ - node_type* res=super::insert_( - x->value(),position,x,detail::emplaced_tag()); - if(res==x){ - ++node_count; - return std::pair(res,true); - } - else{ - boost::detail::allocator::destroy(&x->value()); - deallocate_node(x); - return std::pair(res,false); - } - } - BOOST_CATCH(...){ - boost::detail::allocator::destroy(&x->value()); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - BOOST_CATCH(...){ - deallocate_node(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - void erase_(node_type* x) - { - --node_count; - super::erase_(x); - deallocate_node(x); - } - - void delete_node_(node_type* x) - { - super::delete_node_(x); - deallocate_node(x); - } - - void delete_all_nodes_() - { - super::delete_all_nodes_(); - } - - void clear_() - { - delete_all_nodes_(); - super::clear_(); - node_count=0; - } - - void swap_(multi_index_container& x) - { - if(bfm_allocator::member!=x.bfm_allocator::member){ - detail::adl_swap(bfm_allocator::member,x.bfm_allocator::member); - } - std::swap(bfm_header::member,x.bfm_header::member); - super::swap_(x); - std::swap(node_count,x.node_count); - } - - void swap_elements_( - multi_index_container& x) - { - std::swap(bfm_header::member,x.bfm_header::member); - super::swap_elements_(x); - std::swap(node_count,x.node_count); - } - - bool replace_(const Value& k,node_type* x) - { - return super::replace_(k,x,detail::lvalue_tag()); - } - - bool replace_rv_(const Value& k,node_type* x) - { - return super::replace_(k,x,detail::rvalue_tag()); - } - - template - bool modify_(Modifier& mod,node_type* x) - { - mod(const_cast(x->value())); - - BOOST_TRY{ - if(!super::modify_(x)){ - deallocate_node(x); - --node_count; - return false; - } - else return true; - } - BOOST_CATCH(...){ - deallocate_node(x); - --node_count; - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - template - bool modify_(Modifier& mod,Rollback& back_,node_type* x) - { - mod(const_cast(x->value())); - - bool b; - BOOST_TRY{ - b=super::modify_rollback_(x); - } - BOOST_CATCH(...){ - BOOST_TRY{ - back_(const_cast(x->value())); - BOOST_RETHROW; - } - BOOST_CATCH(...){ - this->erase_(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - BOOST_CATCH_END - - BOOST_TRY{ - if(!b){ - back_(const_cast(x->value())); - return false; - } - else return true; - } - BOOST_CATCH(...){ - this->erase_(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* serialization */ - - friend class boost::serialization::access; - - BOOST_SERIALIZATION_SPLIT_MEMBER() - - typedef typename super::index_saver_type index_saver_type; - typedef typename super::index_loader_type index_loader_type; - - template - void save(Archive& ar,const unsigned int version)const - { - const serialization::collection_size_type s(size_()); - const detail::serialization_version value_version; - ar< - void load(Archive& ar,const unsigned int version) - { - BOOST_MULTI_INDEX_CHECK_INVARIANT; - - clear_(); - serialization::collection_size_type s; - detail::serialization_version value_version; - if(version<1){ - std::size_t sz; - ar>>serialization::make_nvp("count",sz); - s=static_cast(sz); - } - else{ - ar>>serialization::make_nvp("count",s); - } - if(version<2){ - value_version=0; - } - else{ - ar>>serialization::make_nvp("value_version",value_version); - } - - index_loader_type lm(bfm_allocator::member,s); - - for(std::size_t n=0;n value("item",ar,value_version); - std::pair p=insert_( - value.get(),super::end().get_node()); - if(!p.second)throw_exception( - archive::archive_exception( - archive::archive_exception::other_exception)); - ar.reset_object_address(&p.first->value(),&value.get()); - lm.add(p.first,ar,version); - } - lm.add_track(header(),ar,version); - - super::load_(ar,version,lm); - } -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - bool invariant_()const - { - return super::invariant_(); - } - - void check_invariant_()const - { - BOOST_MULTI_INDEX_INVARIANT_ASSERT(invariant_()); - } -#endif - -private: - std::size_t node_count; - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -#pragma parse_mfunc_templ reset -#endif -}; - -#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500)) -#pragma warning(pop) /* C4522 */ -#endif - -/* retrieval of indices by number */ - -template -struct nth_index -{ - BOOST_STATIC_CONSTANT( - int, - M=mpl::size::type::value); - BOOST_STATIC_ASSERT(N>=0&&N::type type; -}; - -template -typename nth_index< - multi_index_container,N>::type& -get( - multi_index_container& m)BOOST_NOEXCEPT -{ - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> multi_index_type; - typedef typename nth_index< - multi_index_container< - Value,IndexSpecifierList,Allocator>, - N - >::type index_type; - - BOOST_STATIC_ASSERT(N>=0&& - N< - mpl::size< - BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list - >::type::value); - - return detail::converter::index(m); -} - -template -const typename nth_index< - multi_index_container,N>::type& -get( - const multi_index_container& m -)BOOST_NOEXCEPT -{ - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> multi_index_type; - typedef typename nth_index< - multi_index_container< - Value,IndexSpecifierList,Allocator>, - N - >::type index_type; - - BOOST_STATIC_ASSERT(N>=0&& - N< - mpl::size< - BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list - >::type::value); - - return detail::converter::index(m); -} - -/* retrieval of indices by tag */ - -template -struct index -{ - typedef typename MultiIndexContainer::index_type_list index_type_list; - - typedef typename mpl::find_if< - index_type_list, - detail::has_tag - >::type iter; - - BOOST_STATIC_CONSTANT( - bool,index_found=!(is_same::type >::value)); - BOOST_STATIC_ASSERT(index_found); - - typedef typename mpl::deref::type type; -}; - -template< - typename Tag,typename Value,typename IndexSpecifierList,typename Allocator -> -typename ::boost::multi_index::index< - multi_index_container,Tag>::type& -get( - multi_index_container& m)BOOST_NOEXCEPT -{ - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> multi_index_type; - typedef typename ::boost::multi_index::index< - multi_index_container< - Value,IndexSpecifierList,Allocator>, - Tag - >::type index_type; - - return detail::converter::index(m); -} - -template< - typename Tag,typename Value,typename IndexSpecifierList,typename Allocator -> -const typename ::boost::multi_index::index< - multi_index_container,Tag>::type& -get( - const multi_index_container& m -)BOOST_NOEXCEPT -{ - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> multi_index_type; - typedef typename ::boost::multi_index::index< - multi_index_container< - Value,IndexSpecifierList,Allocator>, - Tag - >::type index_type; - - return detail::converter::index(m); -} - -/* projection of iterators by number */ - -template -struct nth_index_iterator -{ - typedef typename nth_index::type::iterator type; -}; - -template -struct nth_index_const_iterator -{ - typedef typename nth_index::type::const_iterator type; -}; - -template< - int N,typename IteratorType, - typename Value,typename IndexSpecifierList,typename Allocator> -typename nth_index_iterator< - multi_index_container,N>::type -project( - multi_index_container& m, - IteratorType it) -{ - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> multi_index_type; - typedef typename nth_index::type index_type; - -#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */ - BOOST_STATIC_ASSERT(( - mpl::contains< - BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list, - IteratorType>::value)); -#endif - - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef detail::converter< - multi_index_type, - BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter; - BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m)); -#endif - - return detail::converter::iterator( - m,static_cast(it.get_node())); -} - -template< - int N,typename IteratorType, - typename Value,typename IndexSpecifierList,typename Allocator> -typename nth_index_const_iterator< - multi_index_container,N>::type -project( - const multi_index_container& m, - IteratorType it) -{ - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> multi_index_type; - typedef typename nth_index::type index_type; - -#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */ - BOOST_STATIC_ASSERT(( - mpl::contains< - BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list, - IteratorType>::value|| - mpl::contains< - BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list, - IteratorType>::value)); -#endif - - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef detail::converter< - multi_index_type, - BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter; - BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m)); -#endif - - return detail::converter::const_iterator( - m,static_cast(it.get_node())); -} - -/* projection of iterators by tag */ - -template -struct index_iterator -{ - typedef typename ::boost::multi_index::index< - MultiIndexContainer,Tag>::type::iterator type; -}; - -template -struct index_const_iterator -{ - typedef typename ::boost::multi_index::index< - MultiIndexContainer,Tag>::type::const_iterator type; -}; - -template< - typename Tag,typename IteratorType, - typename Value,typename IndexSpecifierList,typename Allocator> -typename index_iterator< - multi_index_container,Tag>::type -project( - multi_index_container& m, - IteratorType it) -{ - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> multi_index_type; - typedef typename ::boost::multi_index::index< - multi_index_type,Tag>::type index_type; - -#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */ - BOOST_STATIC_ASSERT(( - mpl::contains< - BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list, - IteratorType>::value)); -#endif - - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef detail::converter< - multi_index_type, - BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter; - BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m)); -#endif - - return detail::converter::iterator( - m,static_cast(it.get_node())); -} - -template< - typename Tag,typename IteratorType, - typename Value,typename IndexSpecifierList,typename Allocator> -typename index_const_iterator< - multi_index_container,Tag>::type -project( - const multi_index_container& m, - IteratorType it) -{ - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> multi_index_type; - typedef typename ::boost::multi_index::index< - multi_index_type,Tag>::type index_type; - -#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */ - BOOST_STATIC_ASSERT(( - mpl::contains< - BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list, - IteratorType>::value|| - mpl::contains< - BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list, - IteratorType>::value)); -#endif - - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef detail::converter< - multi_index_type, - BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter; - BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m)); -#endif - - return detail::converter::const_iterator( - m,static_cast(it.get_node())); -} - -/* Comparison. Simple forward to first index. */ - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator==( - const multi_index_container& x, - const multi_index_container& y) -{ - return get<0>(x)==get<0>(y); -} - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator<( - const multi_index_container& x, - const multi_index_container& y) -{ - return get<0>(x)(y); -} - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator!=( - const multi_index_container& x, - const multi_index_container& y) -{ - return get<0>(x)!=get<0>(y); -} - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator>( - const multi_index_container& x, - const multi_index_container& y) -{ - return get<0>(x)>get<0>(y); -} - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator>=( - const multi_index_container& x, - const multi_index_container& y) -{ - return get<0>(x)>=get<0>(y); -} - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator<=( - const multi_index_container& x, - const multi_index_container& y) -{ - return get<0>(x)<=get<0>(y); -} - -/* specialized algorithms */ - -template -void swap( - multi_index_container& x, - multi_index_container& y) -{ - x.swap(y); -} - -} /* namespace multi_index */ - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -/* class version = 1 : we now serialize the size through - * boost::serialization::collection_size_type. - * class version = 2 : proper use of {save|load}_construct_data. - */ - -namespace serialization { -template -struct version< - boost::multi_index_container -> -{ - BOOST_STATIC_CONSTANT(int,value=2); -}; -} /* namespace serialization */ -#endif - -/* Associated global functions are promoted to namespace boost, except - * comparison operators and swap, which are meant to be Koenig looked-up. - */ - -using multi_index::get; -using multi_index::project; - -} /* namespace boost */ - -#undef BOOST_MULTI_INDEX_CHECK_INVARIANT -#undef BOOST_MULTI_INDEX_CHECK_INVARIANT_OF - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index_container_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index_container_fwd.hpp deleted file mode 100644 index b35acad407a..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index_container_fwd.hpp +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_FWD_HPP -#define BOOST_MULTI_INDEX_FWD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -/* Default value for IndexSpecifierList specifies a container - * equivalent to std::set. - */ - -template< - typename Value, - typename IndexSpecifierList=indexed_by > >, - typename Allocator=std::allocator > -class multi_index_container; - -template -struct nth_index; - -template -struct index; - -template -struct nth_index_iterator; - -template -struct nth_index_const_iterator; - -template -struct index_iterator; - -template -struct index_const_iterator; - -/* get and project functions not fwd declared due to problems - * with dependent typenames - */ - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator==( - const multi_index_container& x, - const multi_index_container& y); - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator<( - const multi_index_container& x, - const multi_index_container& y); - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator!=( - const multi_index_container& x, - const multi_index_container& y); - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator>( - const multi_index_container& x, - const multi_index_container& y); - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator>=( - const multi_index_container& x, - const multi_index_container& y); - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator<=( - const multi_index_container& x, - const multi_index_container& y); - -template -void swap( - multi_index_container& x, - multi_index_container& y); - -} /* namespace multi_index */ - -/* multi_index_container, being the main type of this library, is promoted to - * namespace boost. - */ - -using multi_index::multi_index_container; - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/access.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/access.hpp deleted file mode 100644 index f6581accc91..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/access.hpp +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ACCESS_HPP -#define BOOST_SERIALIZATION_ACCESS_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// access.hpp: interface for serialization system. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -namespace boost { - -namespace archive { -namespace detail { - template - class iserializer; - template - class oserializer; -} // namespace detail -} // namespace archive - -namespace serialization { - -// forward declarations -template -inline void serialize_adl(Archive &, T &, const unsigned int); -namespace detail { - template - struct member_saver; - template - struct member_loader; -} // namespace detail - -// use an "accessor class so that we can use: -// "friend class boost::serialization::access;" -// in any serialized class to permit clean, safe access to private class members -// by the serialization system - -class access { -public: - // grant access to "real" serialization defaults -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else - template - friend struct detail::member_saver; - template - friend struct detail::member_loader; - template - friend class archive::detail::iserializer; - template - friend class archive::detail::oserializer; - template - friend inline void serialize( - Archive & ar, - T & t, - const unsigned int file_version - ); - template - friend inline void save_construct_data( - Archive & ar, - const T * t, - const unsigned int file_version - ); - template - friend inline void load_construct_data( - Archive & ar, - T * t, - const unsigned int file_version - ); -#endif - - // pass calls to users's class implementation - template - static void member_save( - Archive & ar, - //const T & t, - T & t, - const unsigned int file_version - ){ - t.save(ar, file_version); - } - template - static void member_load( - Archive & ar, - T & t, - const unsigned int file_version - ){ - t.load(ar, file_version); - } - template - static void serialize( - Archive & ar, - T & t, - const unsigned int file_version - ){ - // note: if you get a compile time error here with a - // message something like: - // cannot convert parameter 1 from to - // a likely possible cause is that the class T contains a - // serialize function - but that serialize function isn't - // a template and corresponds to a file type different than - // the class Archive. To resolve this, don't include an - // archive type other than that for which the serialization - // function is defined!!! - t.serialize(ar, file_version); - } - template - static void destroy( const T * t) // const appropriate here? - { - // the const business is an MSVC 6.0 hack that should be - // benign on everything else - delete const_cast(t); - } - template - static void construct(T * t){ - // default is inplace invocation of default constructor - // Note the :: before the placement new. Required if the - // class doesn't have a class-specific placement new defined. - ::new(t)T; - } - template - static T & cast_reference(U & u){ - return static_cast(u); - } - template - static T * cast_pointer(U * u){ - return static_cast(u); - } -}; - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_ACCESS_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_map.hpp deleted file mode 100644 index ccf806b1813..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_map.hpp +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_MAP_HPP -#define BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_MAP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization/unordered_map.hpp: -// serialization for stl unordered_map templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2014 Jim Bell -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { -namespace stl { - -// map input -template -struct archive_input_unordered_map -{ - inline void operator()( - Archive &ar, - Container &s, - const unsigned int v - ){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, v); - ar >> boost::serialization::make_nvp("item", t.reference()); - std::pair result = - s.insert(boost::move(t.reference())); - // note: the following presumes that the map::value_type was NOT tracked - // in the archive. This is the usual case, but here there is no way - // to determine that. - if(result.second){ - ar.reset_object_address( - & (result.first->second), - & t.reference().second - ); - } - } -}; - -// multimap input -template -struct archive_input_unordered_multimap -{ - inline void operator()( - Archive &ar, - Container &s, - const unsigned int v - ){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, v); - ar >> boost::serialization::make_nvp("item", t.reference()); - typename Container::const_iterator result = - s.insert(t.reference()); - // note: the following presumes that the map::value_type was NOT tracked - // in the archive. This is the usual case, but here there is no way - // to determine that. - ar.reset_object_address( - & result->second, - & t.reference() - ); - } -}; - -} // stl -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_set.hpp deleted file mode 100644 index 7f0003cc6a4..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_set.hpp +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_SET_HPP -#define BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_SET_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// archive_input_unordered_set.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2014 Jim Bell -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -namespace stl { - -// unordered_set input -template -struct archive_input_unordered_set -{ - inline void operator()( - Archive &ar, - Container &s, - const unsigned int v - ){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, v); - // borland fails silently w/o full namespace - ar >> boost::serialization::make_nvp("item", t.reference()); - std::pair result = - s.insert(boost::move(t.reference())); - if(result.second) - ar.reset_object_address(& (* result.first), & t.reference()); - } -}; - -// unordered_multiset input -template -struct archive_input_unordered_multiset -{ - inline void operator()( - Archive &ar, - Container &s, - const unsigned int v - ){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, v); - ar >> boost::serialization::make_nvp("item", t.reference()); - typename Container::const_iterator result = - s.insert(boost::move(t.reference())); - ar.reset_object_address(& (* result), & t.reference()); - } -}; - -} // stl -} // serialization -} // boost - -#endif // BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/array.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/array.hpp deleted file mode 100644 index 612d1a61985..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/array.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ARRAY_HPP -#define BOOST_SERIALIZATION_ARRAY_HPP - -// (C) Copyright 2005 Matthias Troyer and Dave Abrahams -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// for serialization of . If not supported by the standard -// library - this file becomes empty. This is to avoid breaking backward -// compatibiliy for applications which used this header to support -// serialization of native arrays. Code to serialize native arrays is -// now always include by default. RR - -#include // msvc 6.0 needs this for warning suppression - -#if defined(BOOST_NO_STDC_NAMESPACE) - -#include -#include // std::size_t -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include - -#ifndef BOOST_NO_CXX11_HDR_ARRAY - -#include -#include - -namespace boost { namespace serialization { - -template -void serialize(Archive& ar, std::array& a, const unsigned int /* version */) -{ - ar & boost::serialization::make_nvp( - "elems", - *static_cast(static_cast(a.data())) - ); - -} -} } // end namespace boost::serialization - -#endif // BOOST_NO_CXX11_HDR_ARRAY - -#endif //BOOST_SERIALIZATION_ARRAY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/array_optimization.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/array_optimization.hpp deleted file mode 100644 index 40dffba871a..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/array_optimization.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ARRAY_OPTIMIZATON_HPP -#define BOOST_SERIALIZATION_ARRAY_OPTIMIZATON_HPP - -// (C) Copyright 2005 Matthias Troyer and Dave Abrahams -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include // msvc 6.0 needs this for warning suppression - -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include -#include -#include - -namespace boost { namespace serialization { - -template -struct use_array_optimization : boost::mpl::always {}; - -} } // end namespace boost::serialization - -#define BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(Archive) \ -namespace boost { namespace serialization { \ -template <> struct use_array_optimization { \ - template \ - struct apply : boost::mpl::apply1::type \ - >::type {}; \ -}; }} - -#endif //BOOST_SERIALIZATION_ARRAY_OPTIMIZATON_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/array_wrapper.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/array_wrapper.hpp deleted file mode 100644 index adf436e15b4..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/array_wrapper.hpp +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ARRAY_WRAPPER_HPP -#define BOOST_SERIALIZATION_ARRAY_WRAPPER_HPP - -// (C) Copyright 2005 Matthias Troyer and Dave Abrahams -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -//#include - -#include // msvc 6.0 needs this for warning suppression - -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace serialization { - -template -class array_wrapper : - public wrapper_traits > -{ -private: - array_wrapper & operator=(const array_wrapper & rhs); - // note: I would like to make the copy constructor private but this breaks - // make_array. So I make make_array a friend - template - friend const boost::serialization::array_wrapper make_array(Tx * t, S s); -public: - - array_wrapper(const array_wrapper & rhs) : - m_t(rhs.m_t), - m_element_count(rhs.m_element_count) - {} -public: - array_wrapper(T * t, std::size_t s) : - m_t(t), - m_element_count(s) - {} - - // default implementation - template - void serialize_optimized(Archive &ar, const unsigned int, mpl::false_ ) const - { - // default implemention does the loop - std::size_t c = count(); - T * t = address(); - while(0 < c--) - ar & boost::serialization::make_nvp("item", *t++); - } - - // optimized implementation - template - void serialize_optimized(Archive &ar, const unsigned int version, mpl::true_ ) - { - boost::serialization::split_member(ar, *this, version); - } - - // default implementation - template - void save(Archive &ar, const unsigned int version) const - { - ar.save_array(*this,version); - } - - // default implementation - template - void load(Archive &ar, const unsigned int version) - { - ar.load_array(*this,version); - } - - // default implementation - template - void serialize(Archive &ar, const unsigned int version) - { - typedef typename - boost::serialization::use_array_optimization::template apply< - typename remove_const< T >::type - >::type use_optimized; - serialize_optimized(ar,version,use_optimized()); - } - - T * address() const - { - return m_t; - } - - std::size_t count() const - { - return m_element_count; - } - -private: - T * const m_t; - const std::size_t m_element_count; -}; - -template -inline -const array_wrapper< T > make_array(T* t, S s){ - const array_wrapper< T > a(t, s); - return a; -} - -} } // end namespace boost::serialization - - -#endif //BOOST_SERIALIZATION_ARRAY_WRAPPER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/assume_abstract.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/assume_abstract.hpp deleted file mode 100644 index 632f9312f5f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/assume_abstract.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP -#define BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// assume_abstract_class.hpp: - -// (C) Copyright 2008 Robert Ramey -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// this is useful for compilers which don't support the boost::is_abstract - -#include -#include - -#ifndef BOOST_NO_IS_ABSTRACT - -// if there is an intrinsic is_abstract defined, we don't have to do anything -#define BOOST_SERIALIZATION_ASSUME_ABSTRACT(T) - -// but forward to the "official" is_abstract -namespace boost { -namespace serialization { - template - struct is_abstract : boost::is_abstract< T > {} ; -} // namespace serialization -} // namespace boost - -#else -// we have to "make" one - -namespace boost { -namespace serialization { - template - struct is_abstract : boost::false_type {}; -} // namespace serialization -} // namespace boost - -// define a macro to make explicit designation of this more transparent -#define BOOST_SERIALIZATION_ASSUME_ABSTRACT(T) \ -namespace boost { \ -namespace serialization { \ -template<> \ -struct is_abstract< T > : boost::true_type {}; \ -template<> \ -struct is_abstract< const T > : boost::true_type {}; \ -}} \ -/**/ - -#endif // BOOST_NO_IS_ABSTRACT - -#endif //BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/base_object.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/base_object.hpp deleted file mode 100644 index 1a82cecd4b5..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/base_object.hpp +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef BOOST_SERIALIZATION_BASE_OBJECT_HPP -#define BOOST_SERIALIZATION_BASE_OBJECT_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// base_object.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// if no archive headers have been included this is a no op -// this is to permit BOOST_EXPORT etc to be included in a -// file declaration header - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -namespace detail -{ - // get the base type for a given derived type - // preserving the const-ness - template - struct base_cast - { - typedef typename - mpl::if_< - is_const, - const B, - B - >::type type; - BOOST_STATIC_ASSERT(is_const::value == is_const::value); - }; - - // only register void casts if the types are polymorphic - template - struct base_register - { - struct polymorphic { - static void const * invoke(){ - Base const * const b = 0; - Derived const * const d = 0; - return & void_cast_register(d, b); - } - }; - struct non_polymorphic { - static void const * invoke(){ - return 0; - } - }; - static void const * invoke(){ - typedef typename mpl::eval_if< - is_polymorphic, - mpl::identity, - mpl::identity - >::type type; - return type::invoke(); - } - }; - -} // namespace detail -template -typename detail::base_cast::type & -base_object(Derived &d) -{ - BOOST_STATIC_ASSERT(( is_base_and_derived::value)); - BOOST_STATIC_ASSERT(! is_pointer::value); - typedef typename detail::base_cast::type type; - detail::base_register::invoke(); - return access::cast_reference(d); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_BASE_OBJECT_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/binary_object.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/binary_object.hpp deleted file mode 100644 index 5c9038e5a9f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/binary_object.hpp +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef BOOST_SERIALIZATION_BINARY_OBJECT_HPP -#define BOOST_SERIALIZATION_BINARY_OBJECT_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// nvp.hpp: interface for serialization system. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include // std::size_t -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -struct binary_object : - public wrapper_traits > -{ - void const * m_t; - std::size_t m_size; - template - void save(Archive & ar, const unsigned int /* file_version */) const { - ar.save_binary(m_t, m_size); - } - template - void load(Archive & ar, const unsigned int /* file_version */) const { - ar.load_binary(const_cast(m_t), m_size); - } - BOOST_SERIALIZATION_SPLIT_MEMBER() - binary_object & operator=(const binary_object & rhs) { - m_t = rhs.m_t; - m_size = rhs.m_size; - return *this; - } - binary_object(const void * const t, std::size_t size) : - m_t(t), - m_size(size) - {} - binary_object(const binary_object & rhs) : - m_t(rhs.m_t), - m_size(rhs.m_size) - {} -}; - -// just a little helper to support the convention that all serialization -// wrappers follow the naming convention make_xxxxx -inline -const binary_object -make_binary_object(const void * t, std::size_t size){ - return binary_object(t, size); -} - -} // namespace serialization -} // boost - -#endif // BOOST_SERIALIZATION_BINARY_OBJECT_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/bitset.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/bitset.hpp deleted file mode 100644 index 78f9bd74336..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/bitset.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/*! - * \file bitset.hpp - * \brief Provides Boost.Serialization support for std::bitset - * \author Brian Ravnsgaard Riis - * \author Kenneth Riddile - * \date 16.09.2004, updated 04.03.2009 - * \copyright 2004 Brian Ravnsgaard Riis - * \license Boost Software License 1.0 - */ -#ifndef BOOST_SERIALIZATION_BITSET_HPP -#define BOOST_SERIALIZATION_BITSET_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -#include -#include // size_t - -#include -#include -#include -#include - -namespace boost{ -namespace serialization{ - -template -inline void save( - Archive & ar, - std::bitset const & t, - const unsigned int /* version */ -){ - const std::string bits = t.template to_string< - std::string::value_type, - std::string::traits_type, - std::string::allocator_type - >(); - ar << BOOST_SERIALIZATION_NVP( bits ); -} - -template -inline void load( - Archive & ar, - std::bitset & t, - const unsigned int /* version */ -){ - std::string bits; - ar >> BOOST_SERIALIZATION_NVP( bits ); - t = std::bitset(bits); -} - -template -inline void serialize( - Archive & ar, - std::bitset & t, - const unsigned int version -){ - boost::serialization::split_free( ar, t, version ); -} - -// don't track bitsets since that would trigger tracking -// all over the program - which probably would be a surprise. -// also, tracking would be hard to implement since, we're -// serialization a representation of the data rather than -// the data itself. -template -struct tracking_level > - : mpl::int_ {} ; - -} //serialization -} //boost - -#endif // BOOST_SERIALIZATION_BITSET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/boost_array.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/boost_array.hpp deleted file mode 100644 index d564ff15de0..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/boost_array.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ARRAY_HPP -#define BOOST_SERIALIZATION_ARRAY_HPP - -// (C) Copyright 2005 Matthias Troyer and Dave Abrahams -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -//#include - -#include // msvc 6.0 needs this for warning suppression - -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include -#include - -namespace boost { namespace serialization { -// implement serialization for boost::array -template -void serialize(Archive& ar, boost::array& a, const unsigned int /* version */) -{ - ar & boost::serialization::make_nvp("elems", a.elems); -} - -} } // end namespace boost::serialization - - -#endif //BOOST_SERIALIZATION_ARRAY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_map.hpp deleted file mode 100644 index 8913b31f9e6..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_map.hpp +++ /dev/null @@ -1,154 +0,0 @@ -#ifndef BOOST_SERIALIZATION_UNORDERED_MAP_HPP -#define BOOST_SERIALIZATION_UNORDERED_MAP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization/unordered_map.hpp: -// serialization for stl unordered_map templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2014 Jim Bell -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include - -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const boost::unordered_map &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::save_unordered_collection< - Archive, - boost::unordered_map - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - boost::unordered_map &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::load_unordered_collection< - Archive, - boost::unordered_map, - boost::serialization::stl::archive_input_unordered_map< - Archive, - boost::unordered_map - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - boost::unordered_map &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -// unordered_multimap -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const boost::unordered_multimap &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::save_unordered_collection< - Archive, - boost::unordered_multimap - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - boost::unordered_multimap< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::load_unordered_collection< - Archive, - boost::unordered_multimap, - boost::serialization::stl::archive_input_unordered_multimap< - Archive, - boost::unordered_multimap - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - boost::unordered_multimap &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_UNORDERED_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_set.hpp deleted file mode 100644 index 307c7819cbd..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_set.hpp +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef BOOST_SERIALIZATION_BOOST_UNORDERED_SET_HPP -#define BOOST_SERIALIZATION_BOOST_UNORDERED_SET_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// unordered_set.hpp: serialization for boost unordered_set templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2014 Jim Bell -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include - -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const boost::unordered_set &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::save_unordered_collection< - Archive, - boost::unordered_set - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - boost::unordered_set &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::load_unordered_collection< - Archive, - boost::unordered_set, - boost::serialization::stl::archive_input_unordered_set< - Archive, - boost::unordered_set - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - boost::unordered_set &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -// unordered_multiset -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const boost::unordered_multiset &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::save_unordered_collection< - Archive, - boost::unordered_multiset - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - boost::unordered_multiset &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::load_unordered_collection< - Archive, - boost::unordered_multiset, - boost::serialization::stl::archive_input_unordered_multiset< - Archive, - boost::unordered_multiset - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - boost::unordered_multiset &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_BOOST_UNORDERED_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/collection_size_type.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/collection_size_type.hpp deleted file mode 100644 index 2dd8fa72584..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/collection_size_type.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef BOOST_SERIALIZATION_COLLECTION_SIZE_TYPE_HPP -#define BOOST_SERIALIZATION_COLLECTION_SIZE_TYPE_HPP - -// (C) Copyright 2005 Matthias Troyer -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include // size_t -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -//BOOST_STRONG_TYPEDEF(std::size_t, collection_size_type) - -class collection_size_type { -private: - typedef std::size_t base_type; - base_type t; -public: - collection_size_type(): t(0) {}; - explicit collection_size_type(const std::size_t & t_) : - t(t_) - {} - collection_size_type(const collection_size_type & t_) : - t(t_.t) - {} - collection_size_type & operator=(const collection_size_type & rhs){ - t = rhs.t; - return *this; - } - collection_size_type & operator=(const unsigned int & rhs){ - t = rhs; - return *this; - } - // used for text output - operator base_type () const { - return t; - } - // used for text input - operator base_type & () { - return t; - } - bool operator==(const collection_size_type & rhs) const { - return t == rhs.t; - } - bool operator<(const collection_size_type & rhs) const { - return t < rhs.t; - } -}; - - -} } // end namespace boost::serialization - -BOOST_CLASS_IMPLEMENTATION(collection_size_type, primitive_type) -BOOST_IS_BITWISE_SERIALIZABLE(collection_size_type) - -#endif //BOOST_SERIALIZATION_COLLECTION_SIZE_TYPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/collection_traits.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/collection_traits.hpp deleted file mode 100644 index 3ec9401eff0..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/collection_traits.hpp +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef BOOST_SERIALIZATION_COLLECTION_TRAITS_HPP -#define BOOST_SERIALIZATION_COLLECTION_TRAITS_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// collection_traits.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// This header assigns a level implemenation trait to a collection type -// for all primitives. It is needed so that archives which are meant to be -// portable don't write class information in the archive. Since, not all -// compiles recognize the same set of primitive types, the possibility -// exists for archives to be non-portable if class information for primitive -// types is included. This is addressed by the following macros. -#include -//#include -#include - -#include -#include -#include // ULONG_MAX -#include - -#define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(T, C) \ -template<> \ -struct implementation_level< C < T > > { \ - typedef mpl::integral_c_tag tag; \ - typedef mpl::int_ type; \ - BOOST_STATIC_CONSTANT(int, value = object_serializable); \ -}; \ -/**/ - -#if defined(BOOST_NO_CWCHAR) || defined(BOOST_NO_INTRINSIC_WCHAR_T) - #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C) -#else - #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(wchar_t, C) \ - /**/ -#endif - -#if defined(BOOST_HAS_LONG_LONG) - #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(boost::long_long_type, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(boost::ulong_long_type, C) \ - /**/ -#else - #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C) -#endif - -#define BOOST_SERIALIZATION_COLLECTION_TRAITS(C) \ - namespace boost { namespace serialization { \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(bool, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(char, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed char, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned char, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed int, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned int, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed long, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned long, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(float, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(double, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned short, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed short, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C) \ - } } \ - /**/ - -#endif // BOOST_SERIALIZATION_COLLECTION_TRAITS diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/collections_load_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/collections_load_imp.hpp deleted file mode 100644 index e042c0c130d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/collections_load_imp.hpp +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef BOOST_SERIALIZATION_COLLECTIONS_LOAD_IMP_HPP -#define BOOST_SERIALIZATION_COLLECTIONS_LOAD_IMP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -#if defined(_MSC_VER) && (_MSC_VER <= 1020) -# pragma warning (disable : 4786) // too long name, harmless warning -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// collections_load_imp.hpp: serialization for loading stl collections - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// helper function templates for serialization of collections - -#include -#include // size_t -#include // msvc 6.0 needs this for warning suppression -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost{ -namespace serialization { -namespace stl { - -////////////////////////////////////////////////////////////////////// -// implementation of serialization for STL containers -// - -template< - class Archive, - class T -> -typename boost::enable_if< - typename detail::is_default_constructible< - typename T::value_type - >, - void ->::type -collection_load_impl( - Archive & ar, - T & t, - collection_size_type count, - item_version_type /*item_version*/ -){ - t.resize(count); - typename T::iterator hint; - hint = t.begin(); - while(count-- > 0){ - ar >> boost::serialization::make_nvp("item", *hint++); - } -} - -template< - class Archive, - class T -> -typename boost::disable_if< - typename detail::is_default_constructible< - typename T::value_type - >, - void ->::type -collection_load_impl( - Archive & ar, - T & t, - collection_size_type count, - item_version_type item_version -){ - t.clear(); - while(count-- > 0){ - detail::stack_construct u(ar, item_version); - ar >> boost::serialization::make_nvp("item", u.reference()); - t.push_back(boost::move(u.reference())); - ar.reset_object_address(& t.back() , & u.reference()); - } -} - -} // namespace stl -} // namespace serialization -} // namespace boost - -#endif //BOOST_SERIALIZATION_COLLECTIONS_LOAD_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/collections_save_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/collections_save_imp.hpp deleted file mode 100644 index f3cabfcf3f5..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/collections_save_imp.hpp +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef BOOST_SERIALIZATION_COLLECTIONS_SAVE_IMP_HPP -#define BOOST_SERIALIZATION_COLLECTIONS_SAVE_IMP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// collections_save_imp.hpp: serialization for stl collections - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// helper function templates for serialization of collections - -#include -#include -#include -#include -#include -#include - -namespace boost{ -namespace serialization { -namespace stl { - -////////////////////////////////////////////////////////////////////// -// implementation of serialization for STL containers -// - -template -inline void save_collection( - Archive & ar, - const Container &s, - collection_size_type count) -{ - ar << BOOST_SERIALIZATION_NVP(count); - // record number of elements - const item_version_type item_version( - version::value - ); - #if 0 - boost::archive::library_version_type library_version( - ar.get_library_version() - ); - if(boost::archive::library_version_type(3) < library_version){ - ar << BOOST_SERIALIZATION_NVP(item_version); - } - #else - ar << BOOST_SERIALIZATION_NVP(item_version); - #endif - - typename Container::const_iterator it = s.begin(); - while(count-- > 0){ - // note borland emits a no-op without the explicit namespace - boost::serialization::save_construct_data_adl( - ar, - &(*it), - item_version - ); - ar << boost::serialization::make_nvp("item", *it++); - } -} - -template -inline void save_collection(Archive & ar, const Container &s) -{ - // record number of elements - collection_size_type count(s.size()); - save_collection(ar, s, count); -} - -} // namespace stl -} // namespace serialization -} // namespace boost - -#endif //BOOST_SERIALIZATION_COLLECTIONS_SAVE_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/complex.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/complex.hpp deleted file mode 100644 index b4ef44cf973..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/complex.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef BOOST_SERIALIZATION_COMPLEX_HPP -#define BOOST_SERIALIZATION_COMPLEX_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization/utility.hpp: -// serialization for stl utility templates - -// (C) Copyright 2007 Matthias Troyer . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -#include -#include -#include - -namespace boost { -namespace serialization { - -template -inline void serialize( - Archive & ar, - std::complex< T > & t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -template -inline void save( - Archive & ar, - std::complex< T > const & t, - const unsigned int /* file_version */ -){ - const T re = t.real(); - const T im = t.imag(); - ar << boost::serialization::make_nvp("real", re); - ar << boost::serialization::make_nvp("imag", im); -} - -template -inline void load( - Archive & ar, - std::complex< T >& t, - const unsigned int /* file_version */ -){ - T re; - T im; - ar >> boost::serialization::make_nvp("real", re); - ar >> boost::serialization::make_nvp("imag", im); - t = std::complex< T >(re,im); -} - -// specialization of serialization traits for complex -template -struct is_bitwise_serializable > - : public is_bitwise_serializable< T > {}; - -template -struct implementation_level > - : mpl::int_ {} ; - -// treat complex just like builtin arithmetic types for tracking -template -struct tracking_level > - : mpl::int_ {} ; - -} // serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_COMPLEX_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/config.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/config.hpp deleted file mode 100644 index ea8cb9239ed..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/config.hpp +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef BOOST_SERIALIZATION_CONFIG_HPP -#define BOOST_SERIALIZATION_CONFIG_HPP - -// config.hpp ---------------------------------------------// - -// (c) Copyright Robert Ramey 2004 -// Use, modification, and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See library home page at http://www.boost.org/libs/serialization - -//----------------------------------------------------------------------------// - -// This header implements separate compilation features as described in -// http://www.boost.org/more/separate_compilation.html - -#include -#include - -// note: this version incorporates the related code into the the -// the same library as BOOST_ARCHIVE. This could change some day in the -// future - -// if BOOST_SERIALIZATION_DECL is defined undefine it now: -#ifdef BOOST_SERIALIZATION_DECL - #undef BOOST_SERIALIZATION_DECL -#endif - -// we need to import/export our code only if the user has specifically -// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost -// libraries to be dynamically linked, or BOOST_SERIALIZATION_DYN_LINK -// if they want just this one to be dynamically liked: -#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) - #if !defined(BOOST_DYN_LINK) - #define BOOST_DYN_LINK - #endif - // export if this is our own source, otherwise import: - #if defined(BOOST_SERIALIZATION_SOURCE) - #define BOOST_SERIALIZATION_DECL BOOST_SYMBOL_EXPORT - #else - #define BOOST_SERIALIZATION_DECL BOOST_SYMBOL_IMPORT - #endif // defined(BOOST_SERIALIZATION_SOURCE) -#endif // defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) - -// if BOOST_SERIALIZATION_DECL isn't defined yet define it now: -#ifndef BOOST_SERIALIZATION_DECL - #define BOOST_SERIALIZATION_DECL -#endif - -// enable automatic library variant selection ------------------------------// - -#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) \ -&& !defined(BOOST_ARCHIVE_SOURCE) && !defined(BOOST_WARCHIVE_SOURCE) \ -&& !defined(BOOST_SERIALIZATION_SOURCE) - // - // Set the name of our library, this will get undef'ed by auto_link.hpp - // once it's done with it: - // - #define BOOST_LIB_NAME boost_serialization - // - // If we're importing code from a dll, then tell auto_link.hpp about it: - // - #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) - # define BOOST_DYN_LINK - #endif - // - // And include the header that does the work: - // - #include - -#endif - -#endif // BOOST_SERIALIZATION_CONFIG_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/deque.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/deque.hpp deleted file mode 100644 index bba81364ce2..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/deque.hpp +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef BOOST_SERIALIZATION_DEQUE_HPP -#define BOOST_SERIALIZATION_DEQUE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// deque.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include - -#include - -#include -#include -#include - -namespace boost { -namespace serialization { - -template -inline void save( - Archive & ar, - const std::deque &t, - const unsigned int /* file_version */ -){ - boost::serialization::stl::save_collection< - Archive, std::deque - >(ar, t); -} - -template -inline void load( - Archive & ar, - std::deque &t, - const unsigned int /* file_version */ -){ - const boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - item_version_type item_version(0); - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - stl::collection_load_impl(ar, t, count, item_version); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::deque &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(std::deque) - -#endif // BOOST_SERIALIZATION_DEQUE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/is_default_constructible.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/is_default_constructible.hpp deleted file mode 100644 index 4d20b13bf3e..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/detail/is_default_constructible.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef BOOST_SERIALIZATION_DETAIL_IS_DEFAULT_CONSTRUCTIBLE_HPP -#define BOOST_SERIALIZATION_DETAIL_IS_DEFAULT_CONSTRUCTIBLE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// is_default_constructible.hpp: serialization for loading stl collections -// -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#if ! defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) - #include - namespace boost{ - namespace serialization { - namespace detail { - - template - struct is_default_constructible : public std::is_default_constructible {}; - - } // detail - } // serializaition - } // boost -#else - // we don't have standard library support for is_default_constructible - // so we fake it by using boost::has_trivial_construtor. But this is not - // actually correct because it's possible that a default constructor - // to be non trivial. So when using this, make sure you're not using your - // own definition of of T() but are using the actual default one! - #include - namespace boost{ - namespace serialization { - namespace detail { - - template - struct is_default_constructible : public boost::has_trivial_constructor {}; - - } // detail - } // serializaition - } // boost - -#endif - - -#endif // BOOST_SERIALIZATION_DETAIL_IS_DEFAULT_CONSTRUCTIBLE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_count_132.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_count_132.hpp deleted file mode 100644 index a5872557cf2..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_count_132.hpp +++ /dev/null @@ -1,551 +0,0 @@ -#ifndef BOOST_DETAIL_SHARED_COUNT_132_HPP_INCLUDED -#define BOOST_DETAIL_SHARED_COUNT_132_HPP_INCLUDED - -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) -# pragma once -#endif - -// -// detail/shared_count.hpp -// -// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// - -#include - -#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR) -# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible. -#endif - -#include -#include -#include - -#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) -#include -#endif - -#include // std::auto_ptr, std::allocator -#include // std::less -#include // std::exception -#include // std::bad_alloc -#include // std::type_info in get_deleter -#include // std::size_t - -#include // msvc 6.0 needs this for warning suppression -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -namespace boost_132 { - -// Debug hooks - -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - -void sp_scalar_constructor_hook(void * px, std::size_t size, void * pn); -void sp_array_constructor_hook(void * px); -void sp_scalar_destructor_hook(void * px, std::size_t size, void * pn); -void sp_array_destructor_hook(void * px); - -#endif - - -// The standard library that comes with Borland C++ 5.5.1 -// defines std::exception and its members as having C calling -// convention (-pc). When the definition of bad_weak_ptr -// is compiled with -ps, the compiler issues an error. -// Hence, the temporary #pragma option -pc below. The version -// check is deliberately conservative. - -class bad_weak_ptr: public std::exception -{ -public: - - virtual char const * what() const throw() - { - return "boost::bad_weak_ptr"; - } -}; - -namespace detail{ - -class sp_counted_base -{ -//private: - - typedef boost::detail::lightweight_mutex mutex_type; - -public: - - sp_counted_base(): use_count_(1), weak_count_(1) - { - } - - virtual ~sp_counted_base() // nothrow - { - } - - // dispose() is called when use_count_ drops to zero, to release - // the resources managed by *this. - - virtual void dispose() = 0; // nothrow - - // destruct() is called when weak_count_ drops to zero. - - virtual void destruct() // nothrow - { - delete this; - } - - virtual void * get_deleter(std::type_info const & ti) = 0; - - void add_ref_copy() - { -#if defined(BOOST_HAS_THREADS) - mutex_type::scoped_lock lock(mtx_); -#endif - ++use_count_; - } - - void add_ref_lock() - { -#if defined(BOOST_HAS_THREADS) - mutex_type::scoped_lock lock(mtx_); -#endif - if(use_count_ == 0) boost::serialization::throw_exception(bad_weak_ptr()); - ++use_count_; - } - - void release() // nothrow - { - { -#if defined(BOOST_HAS_THREADS) - mutex_type::scoped_lock lock(mtx_); -#endif - long new_use_count = --use_count_; - - if(new_use_count != 0) return; - } - - dispose(); - weak_release(); - } - - void weak_add_ref() // nothrow - { -#if defined(BOOST_HAS_THREADS) - mutex_type::scoped_lock lock(mtx_); -#endif - ++weak_count_; - } - - void weak_release() // nothrow - { - long new_weak_count; - - { -#if defined(BOOST_HAS_THREADS) - mutex_type::scoped_lock lock(mtx_); -#endif - new_weak_count = --weak_count_; - } - - if(new_weak_count == 0) - { - destruct(); - } - } - - long use_count() const // nothrow - { -#if defined(BOOST_HAS_THREADS) - mutex_type::scoped_lock lock(mtx_); -#endif - return use_count_; - } - -//private: -public: - sp_counted_base(sp_counted_base const &); - sp_counted_base & operator= (sp_counted_base const &); - - long use_count_; // #shared - long weak_count_; // #weak + (#shared != 0) - -#if defined(BOOST_HAS_THREADS) || defined(BOOST_LWM_WIN32) - mutable mutex_type mtx_; -#endif -}; - -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - -template void cbi_call_constructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &) -{ - boost::sp_scalar_constructor_hook(px, sizeof(T), pn); -} - -template void cbi_call_constructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &) -{ - boost::sp_array_constructor_hook(px); -} - -template void cbi_call_constructor_hook(sp_counted_base *, P const &, D const &, long) -{ -} - -template void cbi_call_destructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &) -{ - boost::sp_scalar_destructor_hook(px, sizeof(T), pn); -} - -template void cbi_call_destructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &) -{ - boost::sp_array_destructor_hook(px); -} - -template void cbi_call_destructor_hook(sp_counted_base *, P const &, D const &, long) -{ -} - -#endif - -// -// Borland's Codeguard trips up over the -Vx- option here: -// -#ifdef __CODEGUARD__ -# pragma option push -Vx- -#endif - -template class sp_counted_base_impl: public sp_counted_base -{ -//private: -public: - P ptr; // copy constructor must not throw - D del; // copy constructor must not throw - - sp_counted_base_impl(sp_counted_base_impl const &); - sp_counted_base_impl & operator= (sp_counted_base_impl const &); - - typedef sp_counted_base_impl this_type; - -public: - - // pre: initial_use_count <= initial_weak_count, d(p) must not throw - - sp_counted_base_impl(P p, D d): ptr(p), del(d) - { -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - detail::cbi_call_constructor_hook(this, p, d, 0); -#endif - } - - virtual void dispose() // nothrow - { -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - detail::cbi_call_destructor_hook(this, ptr, del, 0); -#endif - del(ptr); - } - - virtual void * get_deleter(std::type_info const & ti) - { - return ti == typeid(D)? &del: 0; - } - -#if defined(BOOST_SP_USE_STD_ALLOCATOR) - - void * operator new(std::size_t) - { - return std::allocator().allocate(1, static_cast(0)); - } - - void operator delete(void * p) - { - std::allocator().deallocate(static_cast(p), 1); - } - -#endif - -#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) - - void * operator new(std::size_t) - { - return boost::detail::quick_allocator::alloc(); - } - - void operator delete(void * p) - { - boost::detail::quick_allocator::dealloc(p); - } - -#endif -}; - -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - -int const shared_count_id = 0x2C35F101; -int const weak_count_id = 0x298C38A4; - -#endif - -class weak_count; - -class shared_count -{ -//private: -public: - sp_counted_base * pi_; - -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - int id_; -#endif - - friend class weak_count; - -public: - - shared_count(): pi_(0) // nothrow -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(shared_count_id) -#endif - { - } - - template shared_count(P p, D d): pi_(0) -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(shared_count_id) -#endif - { -#ifndef BOOST_NO_EXCEPTIONS - - try - { - pi_ = new sp_counted_base_impl(p, d); - } - catch(...) - { - d(p); // delete p - throw; - } - -#else - - pi_ = new sp_counted_base_impl(p, d); - - if(pi_ == 0) - { - d(p); // delete p - boost::serialization::throw_exception(std::bad_alloc()); - } - -#endif - } - -#ifndef BOOST_NO_AUTO_PTR - - // auto_ptr is special cased to provide the strong guarantee - - template - explicit shared_count(std::auto_ptr & r): pi_( - new sp_counted_base_impl< - Y *, - boost::checked_deleter - >(r.get(), boost::checked_deleter())) -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(shared_count_id) -#endif - { - r.release(); - } - -#endif - - ~shared_count() // nothrow - { - if(pi_ != 0) pi_->release(); -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - id_ = 0; -#endif - } - - shared_count(shared_count const & r): pi_(r.pi_) // nothrow -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(shared_count_id) -#endif - { - if(pi_ != 0) pi_->add_ref_copy(); - } - - explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0 - - shared_count & operator= (shared_count const & r) // nothrow - { - sp_counted_base * tmp = r.pi_; - - if(tmp != pi_) - { - if(tmp != 0) tmp->add_ref_copy(); - if(pi_ != 0) pi_->release(); - pi_ = tmp; - } - - return *this; - } - - void swap(shared_count & r) // nothrow - { - sp_counted_base * tmp = r.pi_; - r.pi_ = pi_; - pi_ = tmp; - } - - long use_count() const // nothrow - { - return pi_ != 0? pi_->use_count(): 0; - } - - bool unique() const // nothrow - { - return use_count() == 1; - } - - friend inline bool operator==(shared_count const & a, shared_count const & b) - { - return a.pi_ == b.pi_; - } - - friend inline bool operator<(shared_count const & a, shared_count const & b) - { - return std::less()(a.pi_, b.pi_); - } - - void * get_deleter(std::type_info const & ti) const - { - return pi_? pi_->get_deleter(ti): 0; - } -}; - -#ifdef __CODEGUARD__ -# pragma option pop -#endif - - -class weak_count -{ -private: - - sp_counted_base * pi_; - -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - int id_; -#endif - - friend class shared_count; - -public: - - weak_count(): pi_(0) // nothrow -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(weak_count_id) -#endif - { - } - - weak_count(shared_count const & r): pi_(r.pi_) // nothrow -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(shared_count_id) -#endif - { - if(pi_ != 0) pi_->weak_add_ref(); - } - - weak_count(weak_count const & r): pi_(r.pi_) // nothrow -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(shared_count_id) -#endif - { - if(pi_ != 0) pi_->weak_add_ref(); - } - - ~weak_count() // nothrow - { - if(pi_ != 0) pi_->weak_release(); -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - id_ = 0; -#endif - } - - weak_count & operator= (shared_count const & r) // nothrow - { - sp_counted_base * tmp = r.pi_; - if(tmp != 0) tmp->weak_add_ref(); - if(pi_ != 0) pi_->weak_release(); - pi_ = tmp; - - return *this; - } - - weak_count & operator= (weak_count const & r) // nothrow - { - sp_counted_base * tmp = r.pi_; - if(tmp != 0) tmp->weak_add_ref(); - if(pi_ != 0) pi_->weak_release(); - pi_ = tmp; - - return *this; - } - - void swap(weak_count & r) // nothrow - { - sp_counted_base * tmp = r.pi_; - r.pi_ = pi_; - pi_ = tmp; - } - - long use_count() const // nothrow - { - return pi_ != 0? pi_->use_count(): 0; - } - - friend inline bool operator==(weak_count const & a, weak_count const & b) - { - return a.pi_ == b.pi_; - } - - friend inline bool operator<(weak_count const & a, weak_count const & b) - { - return std::less()(a.pi_, b.pi_); - } -}; - -inline shared_count::shared_count(weak_count const & r): pi_(r.pi_) -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(shared_count_id) -#endif -{ - if(pi_ != 0) - { - pi_->add_ref_lock(); - } - else - { - boost::serialization::throw_exception(bad_weak_ptr()); - } -} - -} // namespace detail - -} // namespace boost - -BOOST_SERIALIZATION_ASSUME_ABSTRACT(boost_132::detail::sp_counted_base) - -#endif // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_132.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_132.hpp deleted file mode 100644 index ee98b7b9449..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_132.hpp +++ /dev/null @@ -1,443 +0,0 @@ -#ifndef BOOST_SHARED_PTR_132_HPP_INCLUDED -#define BOOST_SHARED_PTR_132_HPP_INCLUDED - -// -// shared_ptr.hpp -// -// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. -// Copyright (c) 2001, 2002, 2003 Peter Dimov -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation. -// - -#include // for broken compiler workarounds - -#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) -#include -#else - -#include -#include -#include -#include - -#include -#include - -#include // for std::auto_ptr -#include // for std::swap -#include // for std::less -#include // for std::bad_cast -#include // for std::basic_ostream - -#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash -# pragma warning(push) -# pragma warning(disable:4284) // odd return type for operator-> -#endif - -namespace boost_132 { - -template class weak_ptr; -template class enable_shared_from_this; - -namespace detail -{ - -struct static_cast_tag {}; -struct const_cast_tag {}; -struct dynamic_cast_tag {}; -struct polymorphic_cast_tag {}; - -template struct shared_ptr_traits -{ - typedef T & reference; -}; - -template<> struct shared_ptr_traits -{ - typedef void reference; -}; - -#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) - -template<> struct shared_ptr_traits -{ - typedef void reference; -}; - -template<> struct shared_ptr_traits -{ - typedef void reference; -}; - -template<> struct shared_ptr_traits -{ - typedef void reference; -}; - -#endif - -// enable_shared_from_this support - -template void sp_enable_shared_from_this( shared_count const & pn, enable_shared_from_this< T > const * pe, Y const * px ) -{ - if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast(px), pn); -} - -inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... ) -{ -} - -} // namespace detail - - -// -// shared_ptr -// -// An enhanced relative of scoped_ptr with reference counted copy semantics. -// The object pointed to is deleted when the last shared_ptr pointing to it -// is destroyed or reset. -// - -template class shared_ptr -{ -private: - // Borland 5.5.1 specific workaround - typedef shared_ptr< T > this_type; - -public: - - typedef T element_type; - typedef T value_type; - typedef T * pointer; - typedef typename detail::shared_ptr_traits< T >::reference reference; - - shared_ptr(): px(0), pn() // never throws in 1.30+ - { - } - - template - explicit shared_ptr(Y * p): px(p), pn(p, boost::checked_deleter()) // Y must be complete - { - detail::sp_enable_shared_from_this( pn, p, p ); - } - - // - // Requirements: D's copy constructor must not throw - // - // shared_ptr will release p by calling d(p) - // - - template shared_ptr(Y * p, D d): px(p), pn(p, d) - { - detail::sp_enable_shared_from_this( pn, p, p ); - } - -// generated copy constructor, assignment, destructor are fine... - -// except that Borland C++ has a bug, and g++ with -Wsynth warns -#if defined(__GNUC__) - shared_ptr & operator=(shared_ptr const & r) // never throws - { - px = r.px; - pn = r.pn; // shared_count::op= doesn't throw - return *this; - } -#endif - - template - explicit shared_ptr(weak_ptr const & r): pn(r.pn) // may throw - { - // it is now safe to copy r.px, as pn(r.pn) did not throw - px = r.px; - } - - template - shared_ptr(shared_ptr const & r): px(r.px), pn(r.pn) // never throws - { - } - - template - shared_ptr(shared_ptr const & r, detail::static_cast_tag): px(static_cast(r.px)), pn(r.pn) - { - } - - template - shared_ptr(shared_ptr const & r, detail::const_cast_tag): px(const_cast(r.px)), pn(r.pn) - { - } - - template - shared_ptr(shared_ptr const & r, detail::dynamic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) - { - if(px == 0) // need to allocate new counter -- the cast failed - { - pn = detail::shared_count(); - } - } - - template - shared_ptr(shared_ptr const & r, detail::polymorphic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) - { - if(px == 0) - { - boost::serialization::throw_exception(std::bad_cast()); - } - } - -#ifndef BOOST_NO_AUTO_PTR - - template - explicit shared_ptr(std::auto_ptr & r): px(r.get()), pn() - { - Y * tmp = r.get(); - pn = detail::shared_count(r); - detail::sp_enable_shared_from_this( pn, tmp, tmp ); - } - -#endif - -#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200) - - template - shared_ptr & operator=(shared_ptr const & r) // never throws - { - px = r.px; - pn = r.pn; // shared_count::op= doesn't throw - return *this; - } - -#endif - -#ifndef BOOST_NO_AUTO_PTR - - template - shared_ptr & operator=(std::auto_ptr & r) - { - this_type(r).swap(*this); - return *this; - } - -#endif - - void reset() // never throws in 1.30+ - { - this_type().swap(*this); - } - - template void reset(Y * p) // Y must be complete - { - BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors - this_type(p).swap(*this); - } - - template void reset(Y * p, D d) - { - this_type(p, d).swap(*this); - } - - reference operator* () const // never throws - { - BOOST_ASSERT(px != 0); - return *px; - } - - T * operator-> () const // never throws - { - BOOST_ASSERT(px != 0); - return px; - } - - T * get() const // never throws - { - return px; - } - - // implicit conversion to "bool" - -#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530) - - operator bool () const - { - return px != 0; - } - -#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) - typedef T * (this_type::*unspecified_bool_type)() const; - - operator unspecified_bool_type() const // never throws - { - return px == 0? 0: &this_type::get; - } - -#else - - typedef T * this_type::*unspecified_bool_type; - - operator unspecified_bool_type() const // never throws - { - return px == 0? 0: &this_type::px; - } - -#endif - - // operator! is redundant, but some compilers need it - - bool operator! () const // never throws - { - return px == 0; - } - - bool unique() const // never throws - { - return pn.unique(); - } - - long use_count() const // never throws - { - return pn.use_count(); - } - - void swap(shared_ptr< T > & other) // never throws - { - std::swap(px, other.px); - pn.swap(other.pn); - } - - template bool _internal_less(shared_ptr const & rhs) const - { - return pn < rhs.pn; - } - - void * _internal_get_deleter(std::type_info const & ti) const - { - return pn.get_deleter(ti); - } - -// Tasteless as this may seem, making all members public allows member templates -// to work in the absence of member template friends. (Matthew Langston) - -#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS - -private: - - template friend class shared_ptr; - template friend class weak_ptr; - - -#endif -public: // for serialization - T * px; // contained pointer - detail::shared_count pn; // reference counter - -}; // shared_ptr - -template inline bool operator==(shared_ptr< T > const & a, shared_ptr const & b) -{ - return a.get() == b.get(); -} - -template inline bool operator!=(shared_ptr< T > const & a, shared_ptr const & b) -{ - return a.get() != b.get(); -} - -template inline bool operator<(shared_ptr< T > const & a, shared_ptr const & b) -{ - return a._internal_less(b); -} - -template inline void swap(shared_ptr< T > & a, shared_ptr< T > & b) -{ - a.swap(b); -} - -template shared_ptr< T > static_pointer_cast(shared_ptr const & r) -{ - return shared_ptr< T >(r, detail::static_cast_tag()); -} - -template shared_ptr< T > const_pointer_cast(shared_ptr const & r) -{ - return shared_ptr< T >(r, detail::const_cast_tag()); -} - -template shared_ptr< T > dynamic_pointer_cast(shared_ptr const & r) -{ - return shared_ptr< T >(r, detail::dynamic_cast_tag()); -} - -// shared_*_cast names are deprecated. Use *_pointer_cast instead. - -template shared_ptr< T > shared_static_cast(shared_ptr const & r) -{ - return shared_ptr< T >(r, detail::static_cast_tag()); -} - -template shared_ptr< T > shared_dynamic_cast(shared_ptr const & r) -{ - return shared_ptr< T >(r, detail::dynamic_cast_tag()); -} - -template shared_ptr< T > shared_polymorphic_cast(shared_ptr const & r) -{ - return shared_ptr< T >(r, detail::polymorphic_cast_tag()); -} - -template shared_ptr< T > shared_polymorphic_downcast(shared_ptr const & r) -{ - BOOST_ASSERT(dynamic_cast(r.get()) == r.get()); - return shared_static_cast< T >(r); -} - -// get_pointer() enables boost::mem_fn to recognize shared_ptr - -template inline T * get_pointer(shared_ptr< T > const & p) -{ - return p.get(); -} - -// operator<< - - -template std::basic_ostream & operator<< (std::basic_ostream & os, shared_ptr const & p) -{ - os << p.get(); - return os; -} - -// get_deleter (experimental) - -#if defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238) - -// g++ 2.9x doesn't allow static_cast(void *) -// apparently EDG 2.38 also doesn't accept it - -template D * get_deleter(shared_ptr< T > const & p) -{ - void const * q = p._internal_get_deleter(typeid(D)); - return const_cast(static_cast(q)); -} - -#else - -template D * get_deleter(shared_ptr< T > const & p) -{ - return static_cast(p._internal_get_deleter(typeid(D))); -} - -#endif - -} // namespace boost - -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif - -#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) - -#endif // #ifndef BOOST_SHARED_PTR_132_HPP_INCLUDED diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_nmt_132.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_nmt_132.hpp deleted file mode 100644 index 490e7ddd3d0..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_nmt_132.hpp +++ /dev/null @@ -1,182 +0,0 @@ -#ifndef BOOST_DETAIL_SHARED_PTR_NMT_132_HPP_INCLUDED -#define BOOST_DETAIL_SHARED_PTR_NMT_132_HPP_INCLUDED - -// -// detail/shared_ptr_nmt.hpp - shared_ptr.hpp without member templates -// -// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. -// Copyright (c) 2001, 2002 Peter Dimov -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation. -// - -#include -#include -#include -#include - -#ifndef BOOST_NO_AUTO_PTR -# include // for std::auto_ptr -#endif - -#include // for std::swap -#include // for std::less -#include // for std::bad_alloc - -namespace boost -{ - -template class shared_ptr -{ -private: - - typedef detail::atomic_count count_type; - -public: - - typedef T element_type; - typedef T value_type; - - explicit shared_ptr(T * p = 0): px(p) - { -#ifndef BOOST_NO_EXCEPTIONS - - try // prevent leak if new throws - { - pn = new count_type(1); - } - catch(...) - { - boost::checked_delete(p); - throw; - } - -#else - - pn = new count_type(1); - - if(pn == 0) - { - boost::checked_delete(p); - boost::serialization::throw_exception(std::bad_alloc()); - } - -#endif - } - - ~shared_ptr() - { - if(--*pn == 0) - { - boost::checked_delete(px); - delete pn; - } - } - - shared_ptr(shared_ptr const & r): px(r.px) // never throws - { - pn = r.pn; - ++*pn; - } - - shared_ptr & operator=(shared_ptr const & r) - { - shared_ptr(r).swap(*this); - return *this; - } - -#ifndef BOOST_NO_AUTO_PTR - - explicit shared_ptr(std::auto_ptr< T > & r) - { - pn = new count_type(1); // may throw - px = r.release(); // fix: moved here to stop leak if new throws - } - - shared_ptr & operator=(std::auto_ptr< T > & r) - { - shared_ptr(r).swap(*this); - return *this; - } - -#endif - - void reset(T * p = 0) - { - BOOST_ASSERT(p == 0 || p != px); - shared_ptr(p).swap(*this); - } - - T & operator*() const // never throws - { - BOOST_ASSERT(px != 0); - return *px; - } - - T * operator->() const // never throws - { - BOOST_ASSERT(px != 0); - return px; - } - - T * get() const // never throws - { - return px; - } - - long use_count() const // never throws - { - return *pn; - } - - bool unique() const // never throws - { - return *pn == 1; - } - - void swap(shared_ptr< T > & other) // never throws - { - std::swap(px, other.px); - std::swap(pn, other.pn); - } - -private: - - T * px; // contained pointer - count_type * pn; // ptr to reference counter -}; - -template inline bool operator==(shared_ptr< T > const & a, shared_ptr const & b) -{ - return a.get() == b.get(); -} - -template inline bool operator!=(shared_ptr< T > const & a, shared_ptr const & b) -{ - return a.get() != b.get(); -} - -template inline bool operator<(shared_ptr< T > const & a, shared_ptr< T > const & b) -{ - return std::less()(a.get(), b.get()); -} - -template void swap(shared_ptr< T > & a, shared_ptr< T > & b) -{ - a.swap(b); -} - -// get_pointer() enables boost::mem_fn to recognize shared_ptr - -template inline T * get_pointer(shared_ptr< T > const & p) -{ - return p.get(); -} - -} // namespace boost - -#endif // #ifndef BOOST_DETAIL_SHARED_PTR_NMT_132_HPP_INCLUDED diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/stack_constructor.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/stack_constructor.hpp deleted file mode 100644 index ae14832c6db..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/detail/stack_constructor.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef BOOST_SERIALIZATION_DETAIL_STACK_CONSTRUCTOR_HPP -#define BOOST_SERIALIZATION_DETAIL_STACK_CONSTRUCTOR_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// stack_constructor.hpp: serialization for loading stl collections - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -namespace boost{ -namespace serialization { -namespace detail { - -// reserve space on stack for an object of type T without actually -// construction such an object -template -struct stack_allocate -{ - T * address() { - return static_cast(storage_.address()); - } - T & reference() { - return * address(); - } -private: - typedef typename boost::aligned_storage< - sizeof(T), - boost::alignment_of::value - > type; - type storage_; -}; - -// construct element on the stack -template -struct stack_construct : public stack_allocate -{ - stack_construct(Archive & ar, const unsigned int version){ - // note borland emits a no-op without the explicit namespace - boost::serialization::load_construct_data_adl( - ar, - this->address(), - version - ); - } - ~stack_construct(){ - this->address()->~T(); // undo load_construct_data above - } -}; - -} // detail -} // serializaition -} // boost - -#endif // BOOST_SERIALIZATION_DETAIL_STACH_CONSTRUCTOR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/ephemeral.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/ephemeral.hpp deleted file mode 100644 index 3a422c30a35..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/ephemeral.hpp +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef BOOST_SERIALIZATION_EPHEMERAL_HPP -#define BOOST_SERIALIZATION_EPHEMERAL_HPP - -// MS compatible compilers support -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// ephemeral_object.hpp: interface for serialization system. - -// (C) Copyright 2007 Matthias Troyer. -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template -struct ephemeral_object : - public wrapper_traits > -{ - explicit ephemeral_object(T& t) : - val(t) - {} - - T & value() const { - return val; - } - - const T & const_value() const { - return val; - } - - template - void serialize(Archive &ar, const unsigned int) const - { - ar & val; - } - -private: - T & val; -}; - -template -inline -const ephemeral_object ephemeral(const char * name, T & t){ - return ephemeral_object(name, t); -} - -} // seralization -} // boost - -#endif // BOOST_SERIALIZATION_EPHEMERAL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/export.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/export.hpp deleted file mode 100644 index 9eef440df42..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/export.hpp +++ /dev/null @@ -1,225 +0,0 @@ -#ifndef BOOST_SERIALIZATION_EXPORT_HPP -#define BOOST_SERIALIZATION_EXPORT_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// export.hpp: set traits of classes to be serialized - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// (C) Copyright 2006 David Abrahams - http://www.boost.org. -// implementation of class export functionality. This is an alternative to -// "forward declaration" method to provoke instantiation of derived classes -// that are to be serialized through pointers. - -#include -#include // NULL - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include // for guid_defined only -#include -#include -#include -#include - -#include - -#include - -namespace boost { -namespace archive { -namespace detail { - -class basic_pointer_iserializer; -class basic_pointer_oserializer; - -template -class pointer_iserializer; -template -class pointer_oserializer; - -template -struct export_impl -{ - static const basic_pointer_iserializer & - enable_load(mpl::true_){ - return boost::serialization::singleton< - pointer_iserializer - >::get_const_instance(); - } - - static const basic_pointer_oserializer & - enable_save(mpl::true_){ - return boost::serialization::singleton< - pointer_oserializer - >::get_const_instance(); - } - inline static void enable_load(mpl::false_) {} - inline static void enable_save(mpl::false_) {} -}; - -// On many platforms, naming a specialization of this template is -// enough to cause its argument to be instantiated. -template -struct instantiate_function {}; - -template -struct ptr_serialization_support -{ -# if defined(BOOST_MSVC) || defined(__SUNPRO_CC) - virtual BOOST_DLLEXPORT void instantiate() BOOST_USED; -# else - static BOOST_DLLEXPORT void instantiate() BOOST_USED; - typedef instantiate_function< - &ptr_serialization_support::instantiate - > x; -# endif -}; - -template -BOOST_DLLEXPORT void -ptr_serialization_support::instantiate() -{ - export_impl::enable_save( - typename Archive::is_saving() - ); - - export_impl::enable_load( - typename Archive::is_loading() - ); -} - -// Note INTENTIONAL usage of anonymous namespace in header. -// This was made this way so that export.hpp could be included -// in other headers. This is still under study. - -namespace extra_detail { - -template -struct guid_initializer -{ - void export_guid(mpl::false_) const { - // generates the statically-initialized objects whose constructors - // register the information allowing serialization of T objects - // through pointers to their base classes. - instantiate_ptr_serialization((T*)0, 0, adl_tag()); - } - void export_guid(mpl::true_) const { - } - guid_initializer const & export_guid() const { - BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); - // note: exporting an abstract base class will have no effect - // and cannot be used to instantitiate serialization code - // (one might be using this in a DLL to instantiate code) - //BOOST_STATIC_WARNING(! boost::serialization::is_abstract< T >::value); - export_guid(boost::serialization::is_abstract< T >()); - return *this; - } -}; - -template -struct init_guid; - -} // anonymous -} // namespace detail -} // namespace archive -} // namespace boost - -#define BOOST_CLASS_EXPORT_IMPLEMENT(T) \ - namespace boost { \ - namespace archive { \ - namespace detail { \ - namespace extra_detail { \ - template<> \ - struct init_guid< T > { \ - static guid_initializer< T > const & g; \ - }; \ - guid_initializer< T > const & init_guid< T >::g = \ - ::boost::serialization::singleton< \ - guid_initializer< T > \ - >::get_mutable_instance().export_guid(); \ - }}}} \ -/**/ - -#define BOOST_CLASS_EXPORT_KEY2(T, K) \ -namespace boost { \ -namespace serialization { \ -template<> \ -struct guid_defined< T > : boost::mpl::true_ {}; \ -template<> \ -inline const char * guid< T >(){ \ - return K; \ -} \ -} /* serialization */ \ -} /* boost */ \ -/**/ - -#define BOOST_CLASS_EXPORT_KEY(T) \ - BOOST_CLASS_EXPORT_KEY2(T, BOOST_PP_STRINGIZE(T)) \ -/**/ - -#define BOOST_CLASS_EXPORT_GUID(T, K) \ -BOOST_CLASS_EXPORT_KEY2(T, K) \ -BOOST_CLASS_EXPORT_IMPLEMENT(T) \ -/**/ - -#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) - -// CodeWarrior fails to construct static members of class templates -// when they are instantiated from within templates, so on that -// compiler we ask users to specifically register base/derived class -// relationships for exported classes. On all other compilers, use of -// this macro is entirely optional. -# define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived) \ -namespace { \ - static int BOOST_PP_CAT(boost_serialization_mwerks_init_, __LINE__) = \ - (::boost::archive::detail::instantiate_ptr_serialization((Derived*)0,0), 3); \ - static int BOOST_PP_CAT(boost_serialization_mwerks_init2_, __LINE__) = ( \ - ::boost::serialization::void_cast_register((Derived*)0,(Base*)0) \ - , 3); \ -} - -#else - -# define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived) - -#endif - -// check for unnecessary export. T isn't polymorphic so there is no -// need to export it. -#define BOOST_CLASS_EXPORT_CHECK(T) \ - BOOST_STATIC_WARNING( \ - boost::is_polymorphic::value \ - ); \ - /**/ - -// the default exportable class identifier is the class name -// the default list of archives types for which code id generated -// are the originally included with this serialization system -#define BOOST_CLASS_EXPORT(T) \ - BOOST_CLASS_EXPORT_GUID( \ - T, \ - BOOST_PP_STRINGIZE(T) \ - ) \ - /**/ - -#endif // BOOST_SERIALIZATION_EXPORT_HPP - diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info.hpp deleted file mode 100644 index bb2a190d465..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info.hpp +++ /dev/null @@ -1,116 +0,0 @@ -#ifndef BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_HPP -#define BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// extended_type_info.hpp: interface for portable version of type_info - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// for now, extended type info is part of the serialization libraries -// this could change in the future. -#include -#include -#include // NULL -#include -#include -#include - -#include -#include // must be the last header -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4251 4231 4660 4275) -#endif - -#define BOOST_SERIALIZATION_MAX_KEY_SIZE 128 - -namespace boost { -namespace serialization { - -namespace void_cast_detail{ - class void_caster; -} - -class BOOST_SYMBOL_VISIBLE extended_type_info : - private boost::noncopyable -{ -private: - friend class boost::serialization::void_cast_detail::void_caster; - - // used to uniquely identify the type of class derived from this one - // so that different derivations of this class can be simultaneously - // included in implementation of sets and maps. - const unsigned int m_type_info_key; - virtual bool is_less_than(const extended_type_info & /*rhs*/) const = 0; - virtual bool is_equal(const extended_type_info & /*rhs*/) const = 0; - const char * m_key; - -protected: - BOOST_SERIALIZATION_DECL void key_unregister() const; - BOOST_SERIALIZATION_DECL void key_register() const; - // this class can't be used as is. It's just the - // common functionality for all type_info replacement - // systems. Hence, make these protected - BOOST_SERIALIZATION_DECL extended_type_info( - const unsigned int type_info_key, - const char * key - ); - virtual BOOST_SERIALIZATION_DECL ~extended_type_info(); -public: - const char * get_key() const { - return m_key; - } - virtual const char * get_debug_info() const = 0; - BOOST_SERIALIZATION_DECL bool operator<(const extended_type_info &rhs) const; - BOOST_SERIALIZATION_DECL bool operator==(const extended_type_info &rhs) const; - bool operator!=(const extended_type_info &rhs) const { - return !(operator==(rhs)); - } - // note explicit "export" of static function to work around - // gcc 4.5 mingw error - static BOOST_SERIALIZATION_DECL const extended_type_info * - find(const char *key); - // for plugins - virtual void * construct(unsigned int /*count*/ = 0, ...) const = 0; - virtual void destroy(void const * const /*p*/) const = 0; -}; - -template -struct guid_defined : boost::mpl::false_ {}; - -namespace ext { - template - struct guid_impl - { - static inline const char * call() - { - return NULL; - } - }; -} - -template -inline const char * guid(){ - return ext::guid_impl::call(); -} - -} // namespace serialization -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_no_rtti.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_no_rtti.hpp deleted file mode 100644 index aaa8b44459b..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_no_rtti.hpp +++ /dev/null @@ -1,182 +0,0 @@ -#ifndef BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP -#define BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -// extended_type_info_no_rtti.hpp: implementation for version that depends -// on runtime typing (rtti - typeid) but uses a user specified string -// as the portable class identifier. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -// hijack serialization access -#include - -#include // must be the last header -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4251 4231 4660 4275 4511 4512) -#endif - -namespace boost { -namespace serialization { -/////////////////////////////////////////////////////////////////////// -// define a special type_info that doesn't depend on rtti which is not -// available in all situations. - -namespace no_rtti_system { - -// common base class to share type_info_key. This is used to -// identify the method used to keep track of the extended type -class BOOST_SYMBOL_VISIBLE extended_type_info_no_rtti_0 : - public extended_type_info -{ -protected: - BOOST_SERIALIZATION_DECL extended_type_info_no_rtti_0(const char * key); - BOOST_SERIALIZATION_DECL ~extended_type_info_no_rtti_0(); -public: - virtual BOOST_SERIALIZATION_DECL bool - is_less_than(const boost::serialization::extended_type_info &rhs) const ; - virtual BOOST_SERIALIZATION_DECL bool - is_equal(const boost::serialization::extended_type_info &rhs) const ; -}; - -} // no_rtti_system - -template -class extended_type_info_no_rtti : - public no_rtti_system::extended_type_info_no_rtti_0, - public singleton > -{ - template - struct action { - struct defined { - static const char * invoke(){ - return guid< T >(); - } - }; - struct undefined { - // if your program traps here - you failed to - // export a guid for this type. the no_rtti - // system requires export for types serialized - // as pointers. - BOOST_STATIC_ASSERT(0 == sizeof(T)); - static const char * invoke(); - }; - static const char * invoke(){ - typedef - typename boost::mpl::if_c< - tf, - defined, - undefined - >::type type; - return type::invoke(); - } - }; -public: - extended_type_info_no_rtti() : - no_rtti_system::extended_type_info_no_rtti_0(get_key()) - { - key_register(); - } - ~extended_type_info_no_rtti(){ - key_unregister(); - } - const extended_type_info * - get_derived_extended_type_info(const T & t) const { - // find the type that corresponds to the most derived type. - // this implementation doesn't depend on typeid() but assumes - // that the specified type has a function of the following signature. - // A common implemention of such a function is to define as a virtual - // function. So if the is not a polymporphic type it's likely an error - BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); - const char * derived_key = t.get_key(); - BOOST_ASSERT(NULL != derived_key); - return boost::serialization::extended_type_info::find(derived_key); - } - const char * get_key() const{ - return action::value >::invoke(); - } - virtual const char * get_debug_info() const{ - return action::value >::invoke(); - } - virtual void * construct(unsigned int count, ...) const{ - // count up the arguments - std::va_list ap; - va_start(ap, count); - switch(count){ - case 0: - return factory::type, 0>(ap); - case 1: - return factory::type, 1>(ap); - case 2: - return factory::type, 2>(ap); - case 3: - return factory::type, 3>(ap); - case 4: - return factory::type, 4>(ap); - default: - BOOST_ASSERT(false); // too many arguments - // throw exception here? - return NULL; - } - } - virtual void destroy(void const * const p) const{ - boost::serialization::access::destroy( - static_cast(p) - ); - //delete static_cast(p) ; - } -}; - -} // namespace serialization -} // namespace boost - -/////////////////////////////////////////////////////////////////////////////// -// If no other implementation has been designated as default, -// use this one. To use this implementation as the default, specify it -// before any of the other headers. - -#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO - #define BOOST_SERIALIZATION_DEFAULT_TYPE_INFO - namespace boost { - namespace serialization { - template - struct extended_type_info_impl { - typedef typename - boost::serialization::extended_type_info_no_rtti< T > type; - }; - } // namespace serialization - } // namespace boost -#endif - -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_typeid.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_typeid.hpp deleted file mode 100644 index 8ee591b3169..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_typeid.hpp +++ /dev/null @@ -1,167 +0,0 @@ -#ifndef BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_TYPEID_HPP -#define BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_TYPEID_HPP - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -// extended_type_info_typeid.hpp: implementation for version that depends -// on runtime typing (rtti - typeid) but uses a user specified string -// as the portable class identifier. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -// hijack serialization access -#include - -#include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4251 4231 4660 4275 4511 4512) -#endif - -namespace boost { -namespace serialization { -namespace typeid_system { - -class BOOST_SYMBOL_VISIBLE extended_type_info_typeid_0 : - public extended_type_info -{ - virtual const char * get_debug_info() const { - if(static_cast(0) == m_ti) - return static_cast(0); - return m_ti->name(); - } -protected: - const std::type_info * m_ti; - BOOST_SERIALIZATION_DECL extended_type_info_typeid_0(const char * key); - BOOST_SERIALIZATION_DECL ~extended_type_info_typeid_0(); - BOOST_SERIALIZATION_DECL void type_register(const std::type_info & ti); - BOOST_SERIALIZATION_DECL void type_unregister(); - BOOST_SERIALIZATION_DECL const extended_type_info * - get_extended_type_info(const std::type_info & ti) const; -public: - virtual BOOST_SERIALIZATION_DECL bool - is_less_than(const extended_type_info &rhs) const; - virtual BOOST_SERIALIZATION_DECL bool - is_equal(const extended_type_info &rhs) const; - const std::type_info & get_typeid() const { - return *m_ti; - } -}; - -} // typeid_system - -template -class extended_type_info_typeid : - public typeid_system::extended_type_info_typeid_0, - public singleton > -{ -public: - extended_type_info_typeid() : - typeid_system::extended_type_info_typeid_0( - boost::serialization::guid< T >() - ) - { - type_register(typeid(T)); - key_register(); - } - ~extended_type_info_typeid(){ - key_unregister(); - type_unregister(); - } - // get the eti record for the true type of this record - // relying upon standard type info implemenation (rtti) - const extended_type_info * - get_derived_extended_type_info(const T & t) const { - // note: this implementation - based on usage of typeid (rtti) - // only does something if the class has at least one virtual function. - BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); - return - typeid_system::extended_type_info_typeid_0::get_extended_type_info( - typeid(t) - ); - } - const char * get_key() const { - return boost::serialization::guid< T >(); - } - virtual void * construct(unsigned int count, ...) const{ - // count up the arguments - std::va_list ap; - va_start(ap, count); - switch(count){ - case 0: - return factory::type, 0>(ap); - case 1: - return factory::type, 1>(ap); - case 2: - return factory::type, 2>(ap); - case 3: - return factory::type, 3>(ap); - case 4: - return factory::type, 4>(ap); - default: - BOOST_ASSERT(false); // too many arguments - // throw exception here? - return NULL; - } - } - virtual void destroy(void const * const p) const { - boost::serialization::access::destroy( - static_cast(p) - ); - //delete static_cast(p); - } -}; - -} // namespace serialization -} // namespace boost - -/////////////////////////////////////////////////////////////////////////////// -// If no other implementation has been designated as default, -// use this one. To use this implementation as the default, specify it -// before any of the other headers. -#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO - #define BOOST_SERIALIZATION_DEFAULT_TYPE_INFO - namespace boost { - namespace serialization { - template - struct extended_type_info_impl { - typedef typename - boost::serialization::extended_type_info_typeid< T > type; - }; - } // namespace serialization - } // namespace boost -#endif - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_TYPEID_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/factory.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/factory.hpp deleted file mode 100644 index 2db7e7e36c3..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/factory.hpp +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef BOOST_SERIALIZATION_FACTORY_HPP -#define BOOST_SERIALIZATION_FACTORY_HPP - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -// factory.hpp: create an instance from an extended_type_info instance. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // valist -#include // NULL - -#include -#include -#include - -namespace std{ - #if defined(__LIBCOMO__) - using ::va_list; - #endif -} // namespace std - -namespace boost { -namespace serialization { - -// default implementation does nothing. -template -T * factory(std::va_list){ - BOOST_ASSERT(false); - // throw exception here? - return NULL; -} - -} // namespace serialization -} // namespace boost - -#define BOOST_SERIALIZATION_FACTORY(N, T, A0, A1, A2, A3) \ -namespace boost { \ -namespace serialization { \ - template<> \ - T * factory(std::va_list ap){ \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 0) \ - , A0 a0 = va_arg(ap, A0);, BOOST_PP_EMPTY()) \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 1) \ - , A1 a1 = va_arg(ap, A1);, BOOST_PP_EMPTY()) \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 2) \ - , A2 a2 = va_arg(ap, A2);, BOOST_PP_EMPTY()) \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 3) \ - , A3 a3 = va_arg(ap, A3);, BOOST_PP_EMPTY()) \ - return new T( \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 0) \ - , a0, BOOST_PP_EMPTY()) \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 1)) \ - , BOOST_PP_COMMA, BOOST_PP_EMPTY)() \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 1) \ - , a1, BOOST_PP_EMPTY()) \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 2)) \ - , BOOST_PP_COMMA, BOOST_PP_EMPTY)() \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 2) \ - , a2, BOOST_PP_EMPTY()) \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 3)) \ - , BOOST_PP_COMMA, BOOST_PP_EMPTY)() \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 3) \ - , a3, BOOST_PP_EMPTY()) \ - ); \ - } \ -} \ -} /**/ - -#define BOOST_SERIALIZATION_FACTORY_4(T, A0, A1, A2, A3) \ - BOOST_SERIALIZATION_FACTORY(4, T, A0, A1, A2, A3) - -#define BOOST_SERIALIZATION_FACTORY_3(T, A0, A1, A2) \ - BOOST_SERIALIZATION_FACTORY(3, T, A0, A1, A2, 0) - -#define BOOST_SERIALIZATION_FACTORY_2(T, A0, A1) \ - BOOST_SERIALIZATION_FACTORY(2, T, A0, A1, 0, 0) - -#define BOOST_SERIALIZATION_FACTORY_1(T, A0) \ - BOOST_SERIALIZATION_FACTORY(1, T, A0, 0, 0, 0) - -#define BOOST_SERIALIZATION_FACTORY_0(T) \ -namespace boost { \ -namespace serialization { \ - template<> \ - T * factory(std::va_list){ \ - return new T(); \ - } \ -} \ -} \ -/**/ - -#endif // BOOST_SERIALIZATION_FACTORY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/force_include.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/force_include.hpp deleted file mode 100644 index 55ab79d0d58..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/force_include.hpp +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef BOOST_SERIALIZATION_FORCE_INCLUDE_HPP -#define BOOST_SERIALIZATION_FORCE_INCLUDE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// force_include.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -// the following help macro is to guarentee that certain coded -// is not removed by over-eager linker optimiser. In certain cases -// we create static objects must be created but are actually never -// referenced - creation has a side-effect such as global registration -// which is important to us. We make an effort to refer these objects -// so that a smart linker won't remove them as being unreferenced. -// In microsoft compilers, inlining the code that does the referring -// means the code gets lost and the static object is not included -// in the library and hence never registered. This manifests itself -// in an ungraceful crash at runtime when (and only when) built in -// release mode. - -#if defined(BOOST_HAS_DECLSPEC) && !defined(__COMO__) -# define BOOST_DLLEXPORT __declspec(dllexport) -#elif ! defined(_WIN32) && ! defined(_WIN64) -# if defined(__MWERKS__) -# define BOOST_DLLEXPORT __declspec(dllexport) -# elif defined(__GNUC__) && (__GNUC__ >= 3) -# define BOOST_USED __attribute__ ((__used__)) -# elif defined(__IBMCPP__) && (__IBMCPP__ >= 1110) -# define BOOST_USED __attribute__ ((__used__)) -# elif defined(__INTEL_COMPILER) && (BOOST_INTEL_CXX_VERSION >= 800) -# define BOOST_USED __attribute__ ((__used__)) -# endif -#endif - -#ifndef BOOST_USED -# define BOOST_USED -#endif - -#ifndef BOOST_DLLEXPORT -# define BOOST_DLLEXPORT -#endif - -#endif // BOOST_SERIALIZATION_FORCE_INCLUDE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/forward_list.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/forward_list.hpp deleted file mode 100644 index b8a3c20a6ea..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/forward_list.hpp +++ /dev/null @@ -1,124 +0,0 @@ -#ifndef BOOST_SERIALIZATION_FORWARD_LIST_HPP -#define BOOST_SERIALIZATION_FORWARD_LIST_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// forward_list.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include // distance - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template -inline void save( - Archive & ar, - const std::forward_list &t, - const unsigned int /*file_version*/ -){ - const collection_size_type count(std::distance(t.cbegin(), t.cend())); - boost::serialization::stl::save_collection< - Archive, - std::forward_list - >(ar, t, count); -} - -namespace stl { - -template< - class Archive, - class T, - class Allocator -> -typename boost::disable_if< - typename detail::is_default_constructible< - typename std::forward_list::value_type - >, - void ->::type -collection_load_impl( - Archive & ar, - std::forward_list &t, - collection_size_type count, - item_version_type item_version -){ - t.clear(); - boost::serialization::detail::stack_construct u(ar, item_version); - ar >> boost::serialization::make_nvp("item", u.reference()); - t.push_front(boost::move(u.reference())); - typename std::forward_list::iterator last; - last = t.begin(); - ar.reset_object_address(&(*t.begin()) , & u.reference()); - while(--count > 0){ - detail::stack_construct u(ar, item_version); - ar >> boost::serialization::make_nvp("item", u.reference()); - last = t.insert_after(last, boost::move(u.reference())); - ar.reset_object_address(&(*last) , & u.reference()); - } -} - -} // stl - -template -inline void load( - Archive & ar, - std::forward_list &t, - const unsigned int /*file_version*/ -){ - const boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - item_version_type item_version(0); - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - stl::collection_load_impl(ar, t, count, item_version); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::forward_list &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(std::forward_list) - -#endif // BOOST_SERIALIZATION_FORWARD_LIST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_load_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_load_imp.hpp deleted file mode 100644 index 88def8f1aa4..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_load_imp.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef BOOST_SERIALIZATION_HASH_COLLECTIONS_LOAD_IMP_HPP -#define BOOST_SERIALIZATION_HASH_COLLECTIONS_LOAD_IMP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -# pragma warning (disable : 4786) // too long name, harmless warning -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// hash_collections_load_imp.hpp: serialization for loading stl collections - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// helper function templates for serialization of hashed collections -#include -#include -#include -#include -#include - -namespace boost{ -namespace serialization { -namespace stl { - -////////////////////////////////////////////////////////////////////// -// implementation of serialization for STL containers -// -template -inline void load_hash_collection(Archive & ar, Container &s) -{ - collection_size_type count; - collection_size_type bucket_count; - boost::serialization::item_version_type item_version(0); - boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - if(boost::archive::library_version_type(6) != library_version){ - ar >> BOOST_SERIALIZATION_NVP(count); - ar >> BOOST_SERIALIZATION_NVP(bucket_count); - } - else{ - // note: fixup for error in version 6. collection size was - // changed to size_t BUT for hashed collections it was implemented - // as an unsigned int. This should be a problem only on win64 machines - // but I'll leave it for everyone just in case. - unsigned int c; - unsigned int bc; - ar >> BOOST_SERIALIZATION_NVP(c); - count = c; - ar >> BOOST_SERIALIZATION_NVP(bc); - bucket_count = bc; - } - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - s.clear(); - #if ! defined(__MWERKS__) - s.resize(bucket_count); - #endif - InputFunction ifunc; - while(count-- > 0){ - ifunc(ar, s, item_version); - } -} - -} // namespace stl -} // namespace serialization -} // namespace boost - -#endif //BOOST_SERIALIZATION_HASH_COLLECTIONS_LOAD_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_save_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_save_imp.hpp deleted file mode 100644 index 65dfe83f16e..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_save_imp.hpp +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef BOOST_SERIALIZATION_HASH_COLLECTIONS_SAVE_IMP_HPP -#define BOOST_SERIALIZATION_HASH_COLLECTIONS_SAVE_IMP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// hash_collections_save_imp.hpp: serialization for stl collections - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// helper function templates for serialization of collections - -#include -#include -#include -#include -#include -#include - -namespace boost{ -namespace serialization { -namespace stl { - -////////////////////////////////////////////////////////////////////// -// implementation of serialization for STL containers -// - -template -inline void save_hash_collection(Archive & ar, const Container &s) -{ - collection_size_type count(s.size()); - const collection_size_type bucket_count(s.bucket_count()); - const item_version_type item_version( - version::value - ); - - #if 0 - /* should only be necessary to create archives of previous versions - * which is not currently supported. So for now comment this out - */ - boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - if(boost::archive::library_version_type(6) != library_version){ - ar << BOOST_SERIALIZATION_NVP(count); - ar << BOOST_SERIALIZATION_NVP(bucket_count); - } - else{ - // note: fixup for error in version 6. collection size was - // changed to size_t BUT for hashed collections it was implemented - // as an unsigned int. This should be a problem only on win64 machines - // but I'll leave it for everyone just in case. - const unsigned int c = count; - const unsigned int bc = bucket_count; - ar << BOOST_SERIALIZATION_NVP(c); - ar << BOOST_SERIALIZATION_NVP(bc); - } - if(boost::archive::library_version_type(3) < library_version){ - // record number of elements - // make sure the target type is registered so we can retrieve - // the version when we load - ar << BOOST_SERIALIZATION_NVP(item_version); - } - #else - ar << BOOST_SERIALIZATION_NVP(count); - ar << BOOST_SERIALIZATION_NVP(bucket_count); - ar << BOOST_SERIALIZATION_NVP(item_version); - #endif - - typename Container::const_iterator it = s.begin(); - while(count-- > 0){ - // note borland emits a no-op without the explicit namespace - boost::serialization::save_construct_data_adl( - ar, - &(*it), - boost::serialization::version< - typename Container::value_type - >::value - ); - ar << boost::serialization::make_nvp("item", *it++); - } -} - -} // namespace stl -} // namespace serialization -} // namespace boost - -#endif //BOOST_SERIALIZATION_HASH_COLLECTIONS_SAVE_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/hash_map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/hash_map.hpp deleted file mode 100644 index 22626db6838..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/hash_map.hpp +++ /dev/null @@ -1,232 +0,0 @@ -#ifndef BOOST_SERIALIZATION_HASH_MAP_HPP -#define BOOST_SERIALIZATION_HASH_MAP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization/hash_map.hpp: -// serialization for stl hash_map templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifdef BOOST_HAS_HASH -#include BOOST_HASH_MAP_HEADER - -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -namespace stl { - -// map input -template -struct archive_input_hash_map -{ - inline void operator()( - Archive &ar, - Container &s, - const unsigned int v - ){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, v); - // borland fails silently w/o full namespace - ar >> boost::serialization::make_nvp("item", t.reference()); - std::pair result = - s.insert(boost::move(t.reference())); - // note: the following presumes that the map::value_type was NOT tracked - // in the archive. This is the usual case, but here there is no way - // to determine that. - if(result.second){ - ar.reset_object_address( - & (result.first->second), - & t.reference().second - ); - } - } -}; - -// multimap input -template -struct archive_input_hash_multimap -{ - inline void operator()( - Archive &ar, - Container &s, - const unsigned int v - ){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, v); - // borland fails silently w/o full namespace - ar >> boost::serialization::make_nvp("item", t.reference()); - typename Container::const_iterator result - = s.insert(boost::move(t.reference())); - // note: the following presumes that the map::value_type was NOT tracked - // in the archive. This is the usual case, but here there is no way - // to determine that. - ar.reset_object_address( - & result->second, - & t.reference() - ); - } -}; - -} // stl - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const BOOST_STD_EXTENSION_NAMESPACE::hash_map< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::stl::save_hash_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_map< - Key, HashFcn, EqualKey, Allocator - > - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::hash_map< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::stl::load_hash_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_map< - Key, HashFcn, EqualKey, Allocator - >, - boost::serialization::stl::archive_input_hash_map< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_map< - Key, HashFcn, EqualKey, Allocator - > - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::hash_map< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -// hash_multimap -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::stl::save_hash_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< - Key, HashFcn, EqualKey, Allocator - > - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::stl::load_hash_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< - Key, HashFcn, EqualKey, Allocator - >, - boost::serialization::stl::archive_input_hash_multimap< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< - Key, HashFcn, EqualKey, Allocator - > - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_HAS_HASH -#endif // BOOST_SERIALIZATION_HASH_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/hash_set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/hash_set.hpp deleted file mode 100644 index 0c72c18457e..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/hash_set.hpp +++ /dev/null @@ -1,222 +0,0 @@ -#ifndef BOOST_SERIALIZATION_HASH_SET_HPP -#define BOOST_SERIALIZATION_HASH_SET_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// hash_set.hpp: serialization for stl hash_set templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifdef BOOST_HAS_HASH -#include BOOST_HASH_SET_HEADER - -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -namespace stl { - -// hash_set input -template -struct archive_input_hash_set -{ - inline void operator()( - Archive &ar, - Container &s, - const unsigned int v - ){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, v); - // borland fails silently w/o full namespace - ar >> boost::serialization::make_nvp("item", t.reference()); - std::pair result = - s.insert(boost::move(t.reference())); - if(result.second) - ar.reset_object_address(& (* result.first), & t.reference()); - } -}; - -// hash_multiset input -template -struct archive_input_hash_multiset -{ - inline void operator()( - Archive &ar, - Container &s, - const unsigned int v - ){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, v); - // borland fails silently w/o full namespace - ar >> boost::serialization::make_nvp("item", t.reference()); - typename Container::const_iterator result - = s.insert(boost::move(t.reference())); - ar.reset_object_address(& (* result), & t.reference()); - } -}; - -} // stl - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const BOOST_STD_EXTENSION_NAMESPACE::hash_set< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::stl::save_hash_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_set< - Key, HashFcn, EqualKey, Allocator - > - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::hash_set< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::stl::load_hash_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_set< - Key, HashFcn, EqualKey, Allocator - >, - boost::serialization::stl::archive_input_hash_set< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_set< - Key, HashFcn, EqualKey, Allocator - > - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::hash_set< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -// hash_multiset -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::stl::save_hash_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< - Key, HashFcn, EqualKey, Allocator - > - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::stl::load_hash_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< - Key, HashFcn, EqualKey, Allocator - >, - boost::serialization::stl::archive_input_hash_multiset< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< - Key, HashFcn, EqualKey, Allocator - > - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< - Key, HashFcn, EqualKey, Allocator - > & t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(BOOST_STD_EXTENSION_NAMESPACE::hash_set) -BOOST_SERIALIZATION_COLLECTION_TRAITS(BOOST_STD_EXTENSION_NAMESPACE::hash_multiset) - -#endif // BOOST_HAS_HASH -#endif // BOOST_SERIALIZATION_HASH_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/is_bitwise_serializable.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/is_bitwise_serializable.hpp deleted file mode 100644 index 7e24a2cb6d8..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/is_bitwise_serializable.hpp +++ /dev/null @@ -1,46 +0,0 @@ -// (C) Copyright 2007 Matthias Troyer - -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// Authors: Matthias Troyer - -/** @file is_bitwise_serializable.hpp - * - * This header provides a traits class for determining whether a class - * can be serialized (in a non-portable way) just by copying the bits. - */ - - -#ifndef BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP -#define BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -#include -#include - -namespace boost { -namespace serialization { - template - struct is_bitwise_serializable - : public is_arithmetic< T > - {}; -} // namespace serialization -} // namespace boost - - -// define a macro to make explicit designation of this more transparent -#define BOOST_IS_BITWISE_SERIALIZABLE(T) \ -namespace boost { \ -namespace serialization { \ -template<> \ -struct is_bitwise_serializable< T > : mpl::true_ {}; \ -}} \ -/**/ - -#endif //BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/item_version_type.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/item_version_type.hpp deleted file mode 100644 index f3e5adac6f8..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/item_version_type.hpp +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ITEM_VERSION_TYPE_HPP -#define BOOST_SERIALIZATION_ITEM_VERSION_TYPE_HPP - -// (C) Copyright 2010 Robert Ramey -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include // uint_least8_t -#include -#include -#include - -// fixes broken example build on x86_64-linux-gnu-gcc-4.6.0 -#include - -namespace boost { -namespace serialization { - -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4244 4267 ) -#endif - -class item_version_type { -private: - typedef unsigned int base_type; - base_type t; -public: - // should be private - but MPI fails if it's not!!! - item_version_type(): t(0) {}; - explicit item_version_type(const unsigned int t_) : t(t_){ - BOOST_ASSERT(t_ <= boost::integer_traits::const_max); - } - item_version_type(const item_version_type & t_) : - t(t_.t) - {} - item_version_type & operator=(item_version_type rhs){ - t = rhs.t; - return *this; - } - // used for text output - operator base_type () const { - return t; - } - // used for text input - operator base_type & () { - return t; - } - bool operator==(const item_version_type & rhs) const { - return t == rhs.t; - } - bool operator<(const item_version_type & rhs) const { - return t < rhs.t; - } -}; - -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - -} } // end namespace boost::serialization - -BOOST_IS_BITWISE_SERIALIZABLE(item_version_type) - -BOOST_CLASS_IMPLEMENTATION(item_version_type, primitive_type) - -#endif //BOOST_SERIALIZATION_ITEM_VERSION_TYPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/level.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/level.hpp deleted file mode 100644 index f6a84d10422..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/level.hpp +++ /dev/null @@ -1,116 +0,0 @@ -#ifndef BOOST_SERIALIZATION_LEVEL_HPP -#define BOOST_SERIALIZATION_LEVEL_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// level.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -namespace boost { -namespace serialization { - -struct basic_traits; - -// default serialization implementation level -template -struct implementation_level_impl { - template - struct traits_class_level { - typedef typename U::level type; - }; - - typedef mpl::integral_c_tag tag; - // note: at least one compiler complained w/o the full qualification - // on basic traits below - typedef - typename mpl::eval_if< - is_base_and_derived, - traits_class_level< T >, - //else - typename mpl::eval_if< - is_fundamental< T >, - mpl::int_, - //else - typename mpl::eval_if< - is_class< T >, - mpl::int_, - //else - typename mpl::eval_if< - is_array< T >, - mpl::int_, - //else - typename mpl::eval_if< - is_enum< T >, - mpl::int_, - //else - mpl::int_ - > - > - > - > - >::type type; - // vc 7.1 doesn't like enums here - BOOST_STATIC_CONSTANT(int, value = type::value); -}; - -template -struct implementation_level : - public implementation_level_impl -{ -}; - -template -inline bool operator>=(implementation_level< T > t, enum level_type l) -{ - return t.value >= (int)l; -} - -} // namespace serialization -} // namespace boost - -// specify the level of serialization implementation for the class -// require that class info saved when versioning is used -#define BOOST_CLASS_IMPLEMENTATION(T, E) \ - namespace boost { \ - namespace serialization { \ - template <> \ - struct implementation_level_impl< const T > \ - { \ - typedef mpl::integral_c_tag tag; \ - typedef mpl::int_< E > type; \ - BOOST_STATIC_CONSTANT( \ - int, \ - value = implementation_level_impl::type::value \ - ); \ - }; \ - } \ - } - /**/ - -#endif // BOOST_SERIALIZATION_LEVEL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/level_enum.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/level_enum.hpp deleted file mode 100644 index baf64e04f31..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/level_enum.hpp +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef BOOST_SERIALIZATION_LEVEL_ENUM_HPP -#define BOOST_SERIALIZATION_LEVEL_ENUM_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// level_enum.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -namespace boost { -namespace serialization { - -// for each class used in the program, specify which level -// of serialization should be implemented - -// names for each level -enum level_type -{ - // Don't serialize this type. An attempt to do so should - // invoke a compile time assertion. - not_serializable = 0, - // write/read this type directly to the archive. In this case - // serialization code won't be called. This is the default - // case for fundamental types. It presumes a member function or - // template in the archive class that can handle this type. - // there is no runtime overhead associated reading/writing - // instances of this level - primitive_type = 1, - // Serialize the objects of this type using the objects "serialize" - // function or template. This permits values to be written/read - // to/from archives but includes no class or version information. - object_serializable = 2, - /////////////////////////////////////////////////////////////////// - // once an object is serialized at one of the above levels, the - // corresponding archives cannot be read if the implementation level - // for the archive object is changed. - /////////////////////////////////////////////////////////////////// - // Add class information to the archive. Class information includes - // implementation level, class version and class name if available - object_class_info = 3 -}; - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_LEVEL_ENUM_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/list.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/list.hpp deleted file mode 100644 index 5fdc114d7ed..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/list.hpp +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef BOOST_SERIALIZATION_LIST_HPP -#define BOOST_SERIALIZATION_LIST_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// list.hpp: serialization for stl list templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template -inline void save( - Archive & ar, - const std::list &t, - const unsigned int /* file_version */ -){ - boost::serialization::stl::save_collection< - Archive, - std::list - >(ar, t); -} - -template -inline void load( - Archive & ar, - std::list &t, - const unsigned int /* file_version */ -){ - const boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - item_version_type item_version(0); - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - stl::collection_load_impl(ar, t, count, item_version); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::list & t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(std::list) - -#endif // BOOST_SERIALIZATION_LIST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/map.hpp deleted file mode 100644 index 9209864c8cf..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/map.hpp +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef BOOST_SERIALIZATION_MAP_HPP -#define BOOST_SERIALIZATION_MAP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization/map.hpp: -// serialization for stl map templates - -// (C) Copyright 2002-2014 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// implementation of serialization for map and mult-map STL containers - -template -inline void load_map_collection(Archive & ar, Container &s) -{ - s.clear(); - const boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - item_version_type item_version(0); - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - typename Container::iterator hint; - hint = s.begin(); - while(count-- > 0){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, item_version); - ar >> boost::serialization::make_nvp("item", t.reference()); - typename Container::iterator result = - s.insert(hint, boost::move(t.reference())); - ar.reset_object_address(& (result->second), & t.reference().second); - hint = result; - ++hint; - } -} - -// map -template -inline void save( - Archive & ar, - const std::map &t, - const unsigned int /* file_version */ -){ - boost::serialization::stl::save_collection< - Archive, - std::map - >(ar, t); -} - -template -inline void load( - Archive & ar, - std::map &t, - const unsigned int /* file_version */ -){ - load_map_collection(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::map &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -// multimap -template -inline void save( - Archive & ar, - const std::multimap &t, - const unsigned int /* file_version */ -){ - boost::serialization::stl::save_collection< - Archive, - std::multimap - >(ar, t); -} - -template -inline void load( - Archive & ar, - std::multimap &t, - const unsigned int /* file_version */ -){ - load_map_collection(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::multimap &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/nvp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/nvp.hpp deleted file mode 100644 index 4e2297b3cc9..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/nvp.hpp +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef BOOST_SERIALIZATION_NVP_HPP -#define BOOST_SERIALIZATION_NVP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// nvp.hpp: interface for serialization system. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template -struct nvp : - public std::pair, - public wrapper_traits > -{ -//private: - nvp(const nvp & rhs) : - std::pair(rhs.first, rhs.second) - {} -public: - explicit nvp(const char * name_, T & t) : - // note: added _ to suppress useless gcc warning - std::pair(name_, & t) - {} - - const char * name() const { - return this->first; - } - T & value() const { - return *(this->second); - } - - const T & const_value() const { - return *(this->second); - } - - template - void save( - Archive & ar, - const unsigned int /* file_version */ - ) const { - ar.operator<<(const_value()); - } - template - void load( - Archive & ar, - const unsigned int /* file_version */ - ){ - ar.operator>>(value()); - } - BOOST_SERIALIZATION_SPLIT_MEMBER() -}; - -template -inline -const nvp< T > make_nvp(const char * name, T & t){ - return nvp< T >(name, t); -} - -// to maintain efficiency and portability, we want to assign -// specific serialization traits to all instances of this wrappers. -// we can't strait forward method below as it depends upon -// Partial Template Specialization and doing so would mean that wrappers -// wouldn't be treated the same on different platforms. This would -// break archive portability. Leave this here as reminder not to use it !!! - -template -struct implementation_level > -{ - typedef mpl::integral_c_tag tag; - typedef mpl::int_ type; - BOOST_STATIC_CONSTANT(int, value = implementation_level::type::value); -}; - -// nvp objects are generally created on the stack and are never tracked -template -struct tracking_level > -{ - typedef mpl::integral_c_tag tag; - typedef mpl::int_ type; - BOOST_STATIC_CONSTANT(int, value = tracking_level::type::value); -}; - -} // seralization -} // boost - -#include - -#define BOOST_SERIALIZATION_NVP(name) \ - boost::serialization::make_nvp(BOOST_PP_STRINGIZE(name), name) -/**/ - -#define BOOST_SERIALIZATION_BASE_OBJECT_NVP(name) \ - boost::serialization::make_nvp( \ - BOOST_PP_STRINGIZE(name), \ - boost::serialization::base_object(*this) \ - ) -/**/ - -#endif // BOOST_SERIALIZATION_NVP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/optional.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/optional.hpp deleted file mode 100644 index d6ff830a8c3..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/optional.hpp +++ /dev/null @@ -1,107 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 - -// (C) Copyright 2002-4 Pavel Vozenilek . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// Provides non-intrusive serialization for boost::optional. - -#ifndef BOOST_SERIALIZATION_OPTIONAL_HPP_ -#define BOOST_SERIALIZATION_OPTIONAL_HPP_ - -#if defined(_MSC_VER) -# pragma once -#endif - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// function specializations must be defined in the appropriate -// namespace - boost::serialization -namespace boost { -namespace serialization { - -template -void save( - Archive & ar, - const boost::optional< T > & t, - const unsigned int /*version*/ -){ - // It is an inherent limitation to the serialization of optional.hpp - // that the underlying type must be either a pointer or must have a - // default constructor. It's possible that this could change sometime - // in the future, but for now, one will have to work around it. This can - // be done by serialization the optional as optional - #if ! defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) - BOOST_STATIC_ASSERT( - boost::serialization::detail::is_default_constructible::value - || boost::is_pointer::value - ); - #endif - const bool tflag = t.is_initialized(); - ar << boost::serialization::make_nvp("initialized", tflag); - if (tflag){ - ar << boost::serialization::make_nvp("value", *t); - } -} - -template -void load( - Archive & ar, - boost::optional< T > & t, - const unsigned int version -){ - bool tflag; - ar >> boost::serialization::make_nvp("initialized", tflag); - if(! tflag){ - t.reset(); - return; - } - - if(0 == version){ - boost::serialization::item_version_type item_version(0); - boost::archive::library_version_type library_version( - ar.get_library_version() - ); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - } - if(! t.is_initialized()) - t = T(); - ar >> boost::serialization::make_nvp("value", *t); -} - -template -void serialize( - Archive & ar, - boost::optional< T > & t, - const unsigned int version -){ - boost::serialization::split_free(ar, t, version); -} - -template -struct version > { - BOOST_STATIC_CONSTANT(int, value = 1); -}; - -} // serialization -} // boost - -#endif // BOOST_SERIALIZATION_OPTIONAL_HPP_ diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/priority_queue.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/priority_queue.hpp deleted file mode 100644 index 5b08ffd1e82..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/priority_queue.hpp +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef BOOST_SERIALIZATION_PRIORITY_QUEUE_HPP -#define BOOST_SERIALIZATION_PRIORITY_QUEUE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// priority_queue.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include - -// function specializations must be defined in the appropriate -// namespace - boost::serialization -#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) -#define STD _STLP_STD -#else -#define STD std -#endif - -namespace boost { -namespace serialization { -namespace detail{ - -template -struct priority_queue_save : public STD::priority_queue { - template - void operator()(Archive & ar, const unsigned int file_version) const { - save(ar, STD::priority_queue::c, file_version); - } -}; -template -struct priority_queue_load : public STD::priority_queue { - template - void operator()(Archive & ar, const unsigned int file_version) { - load(ar, STD::priority_queue::c, file_version); - } -}; - -} // detail - -template -inline void serialize( - Archive & ar, - std::priority_queue< T, Container, Compare> & t, - const unsigned int file_version -){ - typedef typename mpl::eval_if< - typename Archive::is_saving, - mpl::identity >, - mpl::identity > - >::type typex; - static_cast(t)(ar, file_version); -} - -} // namespace serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::priority_queue) - -#undef STD - -#endif // BOOST_SERIALIZATION_PRIORITY_QUEUE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/queue.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/queue.hpp deleted file mode 100644 index b22745215d9..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/queue.hpp +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef BOOST_SERIALIZATION_QUEUE_HPP -#define BOOST_SERIALIZATION_QUEUE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// queue.hpp - -// (C) Copyright 2014 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include - -// function specializations must be defined in the appropriate -// namespace - boost::serialization -#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) -#define STD _STLP_STD -#else -#define STD std -#endif - -namespace boost { -namespace serialization { -namespace detail { - -template -struct queue_save : public STD::queue { - template - void operator()(Archive & ar, const unsigned int file_version) const { - save(ar, STD::queue::c, file_version); - } -}; -template -struct queue_load : public STD::queue { - template - void operator()(Archive & ar, const unsigned int file_version) { - load(ar, STD::queue::c, file_version); - } -}; - -} // detail - -template -inline void serialize( - Archive & ar, - std::queue< T, C> & t, - const unsigned int file_version -){ - typedef typename mpl::eval_if< - typename Archive::is_saving, - mpl::identity >, - mpl::identity > - >::type typex; - static_cast(t)(ar, file_version); -} - -} // namespace serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::queue) - -#undef STD - -#endif // BOOST_SERIALIZATION_QUEUE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/scoped_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/scoped_ptr.hpp deleted file mode 100644 index 0d11f8436e0..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/scoped_ptr.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SCOPED_PTR_HPP_VP_2003_10_30 -#define BOOST_SERIALIZATION_SCOPED_PTR_HPP_VP_2003_10_30 - -#if defined(_MSC_VER) -# pragma once -#endif - -// Copyright (c) 2003 Vladimir Prus. -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// Provides non-intrusive serialization for boost::scoped_ptr -// Does not allow to serialize scoped_ptr's to builtin types. - -#include - -#include -#include -#include - -namespace boost { -namespace serialization { - - template - void save( - Archive & ar, - const boost::scoped_ptr< T > & t, - const unsigned int /* version */ - ){ - T* r = t.get(); - ar << boost::serialization::make_nvp("scoped_ptr", r); - } - - template - void load( - Archive & ar, - boost::scoped_ptr< T > & t, - const unsigned int /* version */ - ){ - T* r; - ar >> boost::serialization::make_nvp("scoped_ptr", r); - t.reset(r); - } - - template - void serialize( - Archive& ar, - boost::scoped_ptr< T >& t, - const unsigned int version - ){ - boost::serialization::split_free(ar, t, version); - } - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_SCOPED_PTR_HPP_VP_2003_10_30 diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/serialization.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/serialization.hpp deleted file mode 100644 index a4d04723c75..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/serialization.hpp +++ /dev/null @@ -1,154 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SERIALIZATION_HPP -#define BOOST_SERIALIZATION_SERIALIZATION_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -#if defined(_MSC_VER) -# pragma warning (disable : 4675) // suppress ADL warning -#endif - -#include -#include - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization.hpp: interface for serialization system. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -////////////////////////////////////////////////////////////////////// -// public interface to serialization. - -///////////////////////////////////////////////////////////////////////////// -// layer 0 - intrusive verison -// declared and implemented for each user defined class to be serialized -// -// template -// serialize(Archive &ar, const unsigned int file_version){ -// ar & base_object(*this) & member1 & member2 ... ; -// } - -///////////////////////////////////////////////////////////////////////////// -// layer 1 - layer that routes member access through the access class. -// this is what permits us to grant access to private class member functions -// by specifying friend class boost::serialization::access - -#include - -///////////////////////////////////////////////////////////////////////////// -// layer 2 - default implementation of non-intrusive serialization. -// -// note the usage of function overloading to compensate that C++ does not -// currently support Partial Template Specialization for function templates -// We have declared the version number as "const unsigned long". -// Overriding templates for specific data types should declare the version -// number as "const unsigned int". Template matching will first be applied -// to functions with the same version types - that is the overloads. -// If there is no declared function prototype that matches, the second argument -// will be converted to "const unsigned long" and a match will be made with -// one of the default template functions below. - -namespace boost { -namespace serialization { - -BOOST_STRONG_TYPEDEF(unsigned int, version_type) - -// default implementation - call the member function "serialize" -template -inline void serialize( - Archive & ar, T & t, const unsigned int file_version -){ - access::serialize(ar, t, static_cast(file_version)); -} - -// save data required for construction -template -inline void save_construct_data( - Archive & /*ar*/, - const T * /*t*/, - const unsigned int /*file_version */ -){ - // default is to save no data because default constructor - // requires no arguments. -} - -// load data required for construction and invoke constructor in place -template -inline void load_construct_data( - Archive & /*ar*/, - T * t, - const unsigned int /*file_version*/ -){ - // default just uses the default constructor. going - // through access permits usage of otherwise private default - // constructor - access::construct(t); -} - -///////////////////////////////////////////////////////////////////////////// -// layer 3 - move call into serialization namespace so that ADL will function -// in the manner we desire. -// -// on compilers which don't implement ADL. only the current namespace -// i.e. boost::serialization will be searched. -// -// on compilers which DO implement ADL -// serialize overrides can be in any of the following -// -// 1) same namepace as Archive -// 2) same namespace as T -// 3) boost::serialization -// -// Due to Martin Ecker - -template -inline void serialize_adl( - Archive & ar, - T & t, - const unsigned int file_version -){ - // note usage of function overloading to delay final resolution - // until the point of instantiation. This works around the two-phase - // lookup "feature" which inhibits redefintion of a default function - // template implementation. Due to Robert Ramey - // - // Note that this trick generates problems for compiles which don't support - // PFTO, suppress it here. As far as we know, there are no compilers - // which fail to support PFTO while supporting two-phase lookup. - const version_type v(file_version); - serialize(ar, t, v); -} - -template -inline void save_construct_data_adl( - Archive & ar, - const T * t, - const unsigned int file_version -){ - // see above - const version_type v(file_version); - save_construct_data(ar, t, v); -} - -template -inline void load_construct_data_adl( - Archive & ar, - T * t, - const unsigned int file_version -){ - // see above comment - const version_type v(file_version); - load_construct_data(ar, t, v); -} - -} // namespace serialization -} // namespace boost - -#endif //BOOST_SERIALIZATION_SERIALIZATION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/set.hpp deleted file mode 100644 index 643906c5aac..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/set.hpp +++ /dev/null @@ -1,137 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SET_HPP -#define BOOST_SERIALIZATION_SET_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// set.hpp: serialization for stl set templates - -// (C) Copyright 2002-2014 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace boost { -namespace serialization { - -template -inline void load_set_collection(Archive & ar, Container &s) -{ - s.clear(); - const boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - item_version_type item_version(0); - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - typename Container::iterator hint; - hint = s.begin(); - while(count-- > 0){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, item_version); - // borland fails silently w/o full namespace - ar >> boost::serialization::make_nvp("item", t.reference()); - typename Container::iterator result = - s.insert(hint, boost::move(t.reference())); - ar.reset_object_address(& (* result), & t.reference()); - hint = result; - } -} - -template -inline void save( - Archive & ar, - const std::set &t, - const unsigned int /* file_version */ -){ - boost::serialization::stl::save_collection< - Archive, std::set - >(ar, t); -} - -template -inline void load( - Archive & ar, - std::set &t, - const unsigned int /* file_version */ -){ - load_set_collection(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::set & t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -// multiset -template -inline void save( - Archive & ar, - const std::multiset &t, - const unsigned int /* file_version */ -){ - boost::serialization::stl::save_collection< - Archive, - std::multiset - >(ar, t); -} - -template -inline void load( - Archive & ar, - std::multiset &t, - const unsigned int /* file_version */ -){ - load_set_collection(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::multiset & t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(std::set) -BOOST_SERIALIZATION_COLLECTION_TRAITS(std::multiset) - -#endif // BOOST_SERIALIZATION_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr.hpp deleted file mode 100644 index 0d4c5ae6056..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr.hpp +++ /dev/null @@ -1,281 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SHARED_PTR_HPP -#define BOOST_SERIALIZATION_SHARED_PTR_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// shared_ptr.hpp: serialization for boost shared pointer - -// (C) Copyright 2004 Robert Ramey and Martin Ecker -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // NULL -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// boost:: shared_ptr serialization traits -// version 1 to distinguish from boost 1.32 version. Note: we can only do this -// for a template when the compiler supports partial template specialization - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - namespace boost { - namespace serialization{ - template - struct version< ::boost::shared_ptr< T > > { - typedef mpl::integral_c_tag tag; - #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) - typedef typename mpl::int_<1> type; - #else - typedef mpl::int_<1> type; - #endif - BOOST_STATIC_CONSTANT(int, value = type::value); - }; - // don't track shared pointers - template - struct tracking_level< ::boost::shared_ptr< T > > { - typedef mpl::integral_c_tag tag; - #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) - typedef typename mpl::int_< ::boost::serialization::track_never> type; - #else - typedef mpl::int_< ::boost::serialization::track_never> type; - #endif - BOOST_STATIC_CONSTANT(int, value = type::value); - }; - }} - #define BOOST_SERIALIZATION_SHARED_PTR(T) -#else - // define macro to let users of these compilers do this - #define BOOST_SERIALIZATION_SHARED_PTR(T) \ - BOOST_CLASS_VERSION( \ - ::boost::shared_ptr< T >, \ - 1 \ - ) \ - BOOST_CLASS_TRACKING( \ - ::boost::shared_ptr< T >, \ - ::boost::serialization::track_never \ - ) \ - /**/ -#endif - -namespace boost { -namespace serialization{ - -struct null_deleter { - void operator()(void const *) const {} -}; - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization for boost::shared_ptr - -// Using a constant means that all shared pointers are held in the same set. -// Thus we detect handle multiple pointers to the same value instances -// in the archive. -void * const shared_ptr_helper_id = 0; - -template -inline void save( - Archive & ar, - const boost::shared_ptr< T > &t, - const unsigned int /* file_version */ -){ - // The most common cause of trapping here would be serializing - // something like shared_ptr. This occurs because int - // is never tracked by default. Wrap int in a trackable type - BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); - const T * t_ptr = t.get(); - ar << boost::serialization::make_nvp("px", t_ptr); -} - -#ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP -template -inline void load( - Archive & ar, - boost::shared_ptr< T > &t, - const unsigned int file_version -){ - // something like shared_ptr. This occurs because int - // is never tracked by default. Wrap int in a trackable type - BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); - T* r; - if(file_version < 1){ - ar.register_type(static_cast< - boost_132::detail::sp_counted_base_impl * - >(NULL)); - boost_132::shared_ptr< T > sp; - ar >> boost::serialization::make_nvp("px", sp.px); - ar >> boost::serialization::make_nvp("pn", sp.pn); - // got to keep the sps around so the sp.pns don't disappear - boost::serialization::shared_ptr_helper & h = - ar.template get_helper< shared_ptr_helper >( - shared_ptr_helper_id - ); - h.append(sp); - r = sp.get(); - } - else{ - ar >> boost::serialization::make_nvp("px", r); - } - shared_ptr_helper & h = - ar.template get_helper >( - shared_ptr_helper_id - ); - h.reset(t,r); -} -#else - -template -inline void load( - Archive & ar, - boost::shared_ptr< T > &t, - const unsigned int /*file_version*/ -){ - // The most common cause of trapping here would be serializing - // something like shared_ptr. This occurs because int - // is never tracked by default. Wrap int in a trackable type - BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); - T* r; - ar >> boost::serialization::make_nvp("px", r); - - boost::serialization::shared_ptr_helper & h = - ar.template get_helper >( - shared_ptr_helper_id - ); - h.reset(t,r); -} -#endif - -template -inline void serialize( - Archive & ar, - boost::shared_ptr< T > &t, - const unsigned int file_version -){ - // correct shared_ptr serialization depends upon object tracking - // being used. - BOOST_STATIC_ASSERT( - boost::serialization::tracking_level< T >::value - != boost::serialization::track_never - ); - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// std::shared_ptr serialization traits -// version 1 to distinguish from boost 1.32 version. Note: we can only do this -// for a template when the compiler supports partial template specialization - -#ifndef BOOST_NO_CXX11_SMART_PTR -#include - -// note: we presume that any compiler/library which supports C++11 -// std::pointers also supports template partial specialization -// trap here if such presumption were to turn out to wrong!!! -#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - BOOST_STATIC_ASSERT(false); -#endif - -namespace boost { -namespace serialization{ - template - struct version< ::std::shared_ptr< T > > { - typedef mpl::integral_c_tag tag; - typedef mpl::int_<1> type; - BOOST_STATIC_CONSTANT(int, value = type::value); - }; - // don't track shared pointers - template - struct tracking_level< ::std::shared_ptr< T > > { - typedef mpl::integral_c_tag tag; - typedef mpl::int_< ::boost::serialization::track_never> type; - BOOST_STATIC_CONSTANT(int, value = type::value); - }; -}} -// the following just keeps older programs from breaking -#define BOOST_SERIALIZATION_SHARED_PTR(T) - -namespace boost { -namespace serialization{ - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization for std::shared_ptr - -template -inline void save( - Archive & ar, - const std::shared_ptr< T > &t, - const unsigned int /* file_version */ -){ - // The most common cause of trapping here would be serializing - // something like shared_ptr. This occurs because int - // is never tracked by default. Wrap int in a trackable type - BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); - const T * t_ptr = t.get(); - ar << boost::serialization::make_nvp("px", t_ptr); -} - -template -inline void load( - Archive & ar, - std::shared_ptr< T > &t, - const unsigned int /*file_version*/ -){ - // The most common cause of trapping here would be serializing - // something like shared_ptr. This occurs because int - // is never tracked by default. Wrap int in a trackable type - BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); - T* r; - ar >> boost::serialization::make_nvp("px", r); - //void (* const id)(Archive &, std::shared_ptr< T > &, const unsigned int) = & load; - boost::serialization::shared_ptr_helper & h = - ar.template get_helper< - shared_ptr_helper - >( - shared_ptr_helper_id - ); - h.reset(t,r); -} - -template -inline void serialize( - Archive & ar, - std::shared_ptr< T > &t, - const unsigned int file_version -){ - // correct shared_ptr serialization depends upon object tracking - // being used. - BOOST_STATIC_ASSERT( - boost::serialization::tracking_level< T >::value - != boost::serialization::track_never - ); - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_NO_CXX11_SMART_PTR - -#endif // BOOST_SERIALIZATION_SHARED_PTR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_132.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_132.hpp deleted file mode 100644 index 3dfaba4d69a..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_132.hpp +++ /dev/null @@ -1,222 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SHARED_PTR_132_HPP -#define BOOST_SERIALIZATION_SHARED_PTR_132_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// shared_ptr.hpp: serialization for boost shared pointer - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// note: totally unadvised hack to gain access to private variables -// in shared_ptr and shared_count. Unfortunately its the only way to -// do this without changing shared_ptr and shared_count -// the best we can do is to detect a conflict here -#include - -#include -#include // NULL - -#include -#include -#include -#include -#include - -// mark base class as an (uncreatable) base class -#include - -///////////////////////////////////////////////////////////// -// Maintain a couple of lists of loaded shared pointers of the old previous -// version (1.32) - -namespace boost_132 { -namespace serialization { -namespace detail { - -struct null_deleter { - void operator()(void const *) const {} -}; - -} // namespace detail -} // namespace serialization -} // namespace boost_132 - -///////////////////////////////////////////////////////////// -// sp_counted_base_impl serialization - -namespace boost { -namespace serialization { - -template -inline void serialize( - Archive & /* ar */, - boost_132::detail::sp_counted_base_impl & /* t */, - const unsigned int /*file_version*/ -){ - // register the relationship between each derived class - // its polymorphic base - boost::serialization::void_cast_register< - boost_132::detail::sp_counted_base_impl, - boost_132::detail::sp_counted_base - >( - static_cast *>(NULL), - static_cast(NULL) - ); -} - -template -inline void save_construct_data( - Archive & ar, - const - boost_132::detail::sp_counted_base_impl *t, - const unsigned int /* file_version */ -){ - // variables used for construction - ar << boost::serialization::make_nvp("ptr", t->ptr); -} - -template -inline void load_construct_data( - Archive & ar, - boost_132::detail::sp_counted_base_impl * t, - const unsigned int /* file_version */ -){ - P ptr_; - ar >> boost::serialization::make_nvp("ptr", ptr_); - // ::new(t)boost_132::detail::sp_counted_base_impl(ptr_, D()); - // placement - // note: the original ::new... above is replaced by the one here. This one - // creates all new objects with a null_deleter so that after the archive - // is finished loading and the shared_ptrs are destroyed - the underlying - // raw pointers are NOT deleted. This is necessary as they are used by the - // new system as well. - ::new(t)boost_132::detail::sp_counted_base_impl< - P, - boost_132::serialization::detail::null_deleter - >( - ptr_, boost_132::serialization::detail::null_deleter() - ); // placement new - // compensate for that fact that a new shared count always is - // initialized with one. the add_ref_copy below will increment it - // every time its serialized so without this adjustment - // the use and weak counts will be off by one. - t->use_count_ = 0; -} - -} // serialization -} // namespace boost - -///////////////////////////////////////////////////////////// -// shared_count serialization - -namespace boost { -namespace serialization { - -template -inline void save( - Archive & ar, - const boost_132::detail::shared_count &t, - const unsigned int /* file_version */ -){ - ar << boost::serialization::make_nvp("pi", t.pi_); -} - -template -inline void load( - Archive & ar, - boost_132::detail::shared_count &t, - const unsigned int /* file_version */ -){ - ar >> boost::serialization::make_nvp("pi", t.pi_); - if(NULL != t.pi_) - t.pi_->add_ref_copy(); -} - -} // serialization -} // namespace boost - -BOOST_SERIALIZATION_SPLIT_FREE(boost_132::detail::shared_count) - -///////////////////////////////////////////////////////////// -// implement serialization for shared_ptr< T > - -namespace boost { -namespace serialization { - -template -inline void save( - Archive & ar, - const boost_132::shared_ptr< T > &t, - const unsigned int /* file_version */ -){ - // only the raw pointer has to be saved - // the ref count is maintained automatically as shared pointers are loaded - ar.register_type(static_cast< - boost_132::detail::sp_counted_base_impl > * - >(NULL)); - ar << boost::serialization::make_nvp("px", t.px); - ar << boost::serialization::make_nvp("pn", t.pn); -} - -template -inline void load( - Archive & ar, - boost_132::shared_ptr< T > &t, - const unsigned int /* file_version */ -){ - // only the raw pointer has to be saved - // the ref count is maintained automatically as shared pointers are loaded - ar.register_type(static_cast< - boost_132::detail::sp_counted_base_impl > * - >(NULL)); - ar >> boost::serialization::make_nvp("px", t.px); - ar >> boost::serialization::make_nvp("pn", t.pn); -} - -template -inline void serialize( - Archive & ar, - boost_132::shared_ptr< T > &t, - const unsigned int file_version -){ - // correct shared_ptr serialization depends upon object tracking - // being used. - BOOST_STATIC_ASSERT( - boost::serialization::tracking_level< T >::value - != boost::serialization::track_never - ); - boost::serialization::split_free(ar, t, file_version); -} - -} // serialization -} // namespace boost - -// note: change below uses null_deleter -// This macro is used to export GUIDS for shared pointers to allow -// the serialization system to export them properly. David Tonge -#define BOOST_SHARED_POINTER_EXPORT_GUID(T, K) \ - typedef boost_132::detail::sp_counted_base_impl< \ - T *, \ - boost::checked_deleter< T > \ - > __shared_ptr_ ## T; \ - BOOST_CLASS_EXPORT_GUID(__shared_ptr_ ## T, "__shared_ptr_" K) \ - BOOST_CLASS_EXPORT_GUID(T, K) \ - /**/ - -#define BOOST_SHARED_POINTER_EXPORT(T) \ - BOOST_SHARED_POINTER_EXPORT_GUID( \ - T, \ - BOOST_PP_STRINGIZE(T) \ - ) \ - /**/ - -#endif // BOOST_SERIALIZATION_SHARED_PTR_132_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_helper.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_helper.hpp deleted file mode 100644 index 37c34d6b2c4..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_helper.hpp +++ /dev/null @@ -1,209 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP -#define BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// shared_ptr_helper.hpp: serialization for boost shared pointern - -// (C) Copyright 2004-2009 Robert Ramey, Martin Ecker and Takatoshi Kondo -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include // NULL - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace boost_132 { - template class shared_ptr; -} -namespace boost { -namespace serialization { - -#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -template class SPT > -void load( - Archive & ar, - SPT< class U > &t, - const unsigned int file_version -); -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// a common class for holding various types of shared pointers - -template class SPT> -class shared_ptr_helper { - typedef std::map< - const void *, // address of object - SPT // address shared ptr to single instance - > object_shared_pointer_map; - - // list of shared_pointers create accessable by raw pointer. This - // is used to "match up" shared pointers loaded at different - // points in the archive. Note, we delay construction until - // it is actually used since this is by default included as - // a "mix-in" even if shared_ptr isn't used. - object_shared_pointer_map * m_o_sp; - - struct null_deleter { - void operator()(void const *) const {} - }; - -#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \ -|| defined(BOOST_MSVC) \ -|| defined(__SUNPRO_CC) -public: -#else - template - friend void boost::serialization::load( - Archive & ar, - SPT< U > &t, - const unsigned int file_version - ); -#endif - - #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP - // list of loaded pointers. This is used to be sure that the pointers - // stay around long enough to be "matched" with other pointers loaded - // by the same archive. These are created with a "null_deleter" so that - // when this list is destroyed - the underlaying raw pointers are not - // destroyed. This has to be done because the pointers are also held by - // new system which is disjoint from this set. This is implemented - // by a change in load_construct_data below. It makes this file suitable - // only for loading pointers into a 1.33 or later boost system. - std::list > * m_pointers_132; - void - append(const boost_132::shared_ptr & t){ - if(NULL == m_pointers_132) - m_pointers_132 = new std::list >; - m_pointers_132->push_back(t); - } - #endif - - struct non_polymorphic { - template - static const boost::serialization::extended_type_info * - get_object_type(U & ){ - return & boost::serialization::singleton< - typename - boost::serialization::type_info_implementation< U >::type - >::get_const_instance(); - } - }; - struct polymorphic { - template - static const boost::serialization::extended_type_info * - get_object_type(U & u){ - return boost::serialization::singleton< - typename - boost::serialization::type_info_implementation< U >::type - >::get_const_instance().get_derived_extended_type_info(u); - } - }; - -public: - template - void reset(SPT< T > & s, T * t){ - if(NULL == t){ - s.reset(); - return; - } - const boost::serialization::extended_type_info * this_type - = & boost::serialization::type_info_implementation< T >::type - ::get_const_instance(); - - // get pointer to the most derived object's eti. This is effectively - // the object type identifer - typedef typename mpl::if_< - is_polymorphic< T >, - polymorphic, - non_polymorphic - >::type type; - - const boost::serialization::extended_type_info * true_type - = type::get_object_type(*t); - - // note:if this exception is thrown, be sure that derived pointern - // is either registered or exported. - if(NULL == true_type) - boost::serialization::throw_exception( - boost::archive::archive_exception( - boost::archive::archive_exception::unregistered_class, - this_type->get_debug_info() - ) - ); - // get void pointer to the most derived type - // this uniquely identifies the object referred to - // oid = "object identifier" - const void * oid = void_downcast( - *true_type, - *this_type, - t - ); - if(NULL == oid) - boost::serialization::throw_exception( - boost::archive::archive_exception( - boost::archive::archive_exception::unregistered_cast, - true_type->get_debug_info(), - this_type->get_debug_info() - ) - ); - - // make tracking array if necessary - if(NULL == m_o_sp) - m_o_sp = new object_shared_pointer_map; - - typename object_shared_pointer_map::iterator i = m_o_sp->find(oid); - - // if it's a new object - if(i == m_o_sp->end()){ - s.reset(t); - std::pair result; - result = m_o_sp->insert(std::make_pair(oid, s)); - BOOST_ASSERT(result.second); - } - // if the object has already been seen - else{ - s = SPT(i->second, t); - } - } - - shared_ptr_helper() : - m_o_sp(NULL) - #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP - , m_pointers_132(NULL) - #endif - {} - virtual ~shared_ptr_helper(){ - if(NULL != m_o_sp) - delete m_o_sp; - #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP - if(NULL != m_pointers_132) - delete m_pointers_132; - #endif - } -}; - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/singleton.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/singleton.hpp deleted file mode 100644 index b50afedbb92..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/singleton.hpp +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SINGLETON_HPP -#define BOOST_SERIALIZATION_SINGLETON_HPP - -/////////1/////////2///////// 3/////////4/////////5/////////6/////////7/////////8 -// singleton.hpp -// -// Copyright David Abrahams 2006. Original version -// -// Copyright Robert Ramey 2007. Changes made to permit -// application throughout the serialization library. -// -// Distributed under the Boost -// Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// The intention here is to define a template which will convert -// any class into a singleton with the following features: -// -// a) initialized before first use. -// b) thread-safe for const access to the class -// c) non-locking -// -// In order to do this, -// a) Initialize dynamically when used. -// b) Require that all singletons be initialized before main -// is called or any entry point into the shared library is invoked. -// This guarentees no race condition for initialization. -// In debug mode, we assert that no non-const functions are called -// after main is invoked. -// - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -#include -#include -#include -#include - -#include -#include -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace serialization { - -////////////////////////////////////////////////////////////////////// -// Provides a dynamically-initialized (singleton) instance of T in a -// way that avoids LNK1179 on vc6. See http://tinyurl.com/ljdp8 or -// http://lists.boost.org/Archives/boost/2006/05/105286.php for -// details. -// - -// singletons created by this code are guarenteed to be unique -// within the executable or shared library which creates them. -// This is sufficient and in fact ideal for the serialization library. -// The singleton is created when the module is loaded and destroyed -// when the module is unloaded. - -// This base class has two functions. - -// First it provides a module handle for each singleton indicating -// the executable or shared library in which it was created. This -// turns out to be necessary and sufficient to implement the tables -// used by serialization library. - -// Second, it provides a mechanism to detect when a non-const function -// is called after initialization. - -// make a singleton to lock/unlock all singletons for alteration. -// The intent is that all singletons created/used by this code -// are to be initialized before main is called. A test program -// can lock all the singletons when main is entereed. This any -// attempt to retieve a mutable instances while locked will -// generate a assertion if compiled for debug. - -// note usage of BOOST_DLLEXPORT. These functions are in danger of -// being eliminated by the optimizer when building an application in -// release mode. Usage of the macro is meant to signal the compiler/linker -// to avoid dropping these functions which seem to be unreferenced. -// This usage is not related to autolinking. - -class BOOST_SYMBOL_VISIBLE singleton_module : - public boost::noncopyable -{ -private: - BOOST_SERIALIZATION_DECL BOOST_DLLEXPORT static bool & get_lock() BOOST_USED; -public: - BOOST_DLLEXPORT static void lock(){ - get_lock() = true; - } - BOOST_DLLEXPORT static void unlock(){ - get_lock() = false; - } - BOOST_DLLEXPORT static bool is_locked(){ - return get_lock(); - } -}; - -template -class singleton : public singleton_module -{ -private: - static T & m_instance; - // include this to provoke instantiation at pre-execution time - static void use(T const *) {} - static T & get_instance() { - // use a wrapper so that types T with protected constructors - // can be used - class singleton_wrapper : public T {}; - static singleton_wrapper t; - // refer to instance, causing it to be instantiated (and - // initialized at startup on working compilers) - BOOST_ASSERT(! is_destroyed()); - // note that the following is absolutely essential. - // commenting out this statement will cause compilers to fail to - // construct the instance at pre-execution time. This would prevent - // our usage/implementation of "locking" and introduce uncertainty into - // the sequence of object initializaition. - use(& m_instance); - return static_cast(t); - } - static bool & get_is_destroyed(){ - static bool is_destroyed; - return is_destroyed; - } - -public: - BOOST_DLLEXPORT static T & get_mutable_instance(){ - BOOST_ASSERT(! is_locked()); - return get_instance(); - } - BOOST_DLLEXPORT static const T & get_const_instance(){ - return get_instance(); - } - BOOST_DLLEXPORT static bool is_destroyed(){ - return get_is_destroyed(); - } - BOOST_DLLEXPORT singleton(){ - get_is_destroyed() = false; - } - BOOST_DLLEXPORT ~singleton() { - get_is_destroyed() = true; - } -}; - -template -T & singleton< T >::m_instance = singleton< T >::get_instance(); - -} // namespace serialization -} // namespace boost - -#include // pops abi_suffix.hpp pragmas - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_SERIALIZATION_SINGLETON_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/slist.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/slist.hpp deleted file mode 100644 index d9b971bc4f1..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/slist.hpp +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SLIST_HPP -#define BOOST_SERIALIZATION_SLIST_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// slist.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifdef BOOST_HAS_SLIST -#include BOOST_SLIST_HEADER - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template -inline void save( - Archive & ar, - const BOOST_STD_EXTENSION_NAMESPACE::slist &t, - const unsigned int file_version -){ - boost::serialization::stl::save_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::slist - >(ar, t); -} - -namespace stl { - -template< - class Archive, - class T, - class Allocator -> -typename boost::disable_if< - typename detail::is_default_constructible< - typename BOOST_STD_EXTENSION_NAMESPACE::slist::value_type - >, - void ->::type -collection_load_impl( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::slist &t, - collection_size_type count, - item_version_type item_version -){ - t.clear(); - boost::serialization::detail::stack_construct u(ar, item_version); - ar >> boost::serialization::make_nvp("item", u.reference()); - t.push_front(boost::move(u.reference())); - typename BOOST_STD_EXTENSION_NAMESPACE::slist::iterator last; - last = t.begin(); - ar.reset_object_address(&(*t.begin()) , & u.reference()); - while(--count > 0){ - detail::stack_construct u(ar, item_version); - ar >> boost::serialization::make_nvp("item", u.reference()); - last = t.insert_after(last, boost::move(u.reference())); - ar.reset_object_address(&(*last) , & u.reference()); - } -} - -} // stl - -template -inline void load( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::slist &t, - const unsigned int file_version -){ - const boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - item_version_type item_version(0); - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - if(detail::is_default_constructible()){ - t.resize(count); - typename BOOST_STD_EXTENSION_NAMESPACE::slist::iterator hint; - hint = t.begin(); - while(count-- > 0){ - ar >> boost::serialization::make_nvp("item", *hint++); - } - } - else{ - t.clear(); - boost::serialization::detail::stack_construct u(ar, item_version); - ar >> boost::serialization::make_nvp("item", u.reference()); - t.push_front(boost::move(u.reference())); - typename BOOST_STD_EXTENSION_NAMESPACE::slist::iterator last; - last = t.begin(); - ar.reset_object_address(&(*t.begin()) , & u.reference()); - while(--count > 0){ - detail::stack_construct u(ar, item_version); - ar >> boost::serialization::make_nvp("item", u.reference()); - last = t.insert_after(last, boost::move(u.reference())); - ar.reset_object_address(&(*last) , & u.reference()); - } - } -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::slist &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(BOOST_STD_EXTENSION_NAMESPACE::slist) - -#endif // BOOST_HAS_SLIST -#endif // BOOST_SERIALIZATION_SLIST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/smart_cast.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/smart_cast.hpp deleted file mode 100644 index 563f36aa20b..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/smart_cast.hpp +++ /dev/null @@ -1,275 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SMART_CAST_HPP -#define BOOST_SERIALIZATION_SMART_CAST_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// smart_cast.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org/libs/serialization for updates, documentation, and revision history. - -// casting of pointers and references. - -// In casting between different C++ classes, there are a number of -// rules that have to be kept in mind in deciding whether to use -// static_cast or dynamic_cast. - -// a) dynamic casting can only be applied when one of the types is polymorphic -// Otherwise static_cast must be used. -// b) only dynamic casting can do runtime error checking -// use of static_cast is generally un checked even when compiled for debug -// c) static_cast would be considered faster than dynamic_cast. - -// If casting is applied to a template parameter, there is no apriori way -// to know which of the two casting methods will be permitted or convenient. - -// smart_cast uses C++ type_traits, and program debug mode to select the -// most convenient cast to use. - -#include -#include -#include // NULL - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace serialization { -namespace smart_cast_impl { - - template - struct reference { - - struct polymorphic { - - struct linear { - template - static T cast(U & u){ - return static_cast< T >(u); - } - }; - - struct cross { - template - static T cast(U & u){ - return dynamic_cast< T >(u); - } - }; - - template - static T cast(U & u){ - // if we're in debug mode - #if ! defined(NDEBUG) \ - || defined(__MWERKS__) - // do a checked dynamic cast - return cross::cast(u); - #else - // borland 5.51 chokes here so we can't use it - // note: if remove_reference isn't function for these types - // cross casting will be selected this will work but will - // not be the most efficient method. This will conflict with - // the original smart_cast motivation. - typedef typename mpl::eval_if< - typename mpl::and_< - mpl::not_::type, - U - > >, - mpl::not_::type - > > - >, - // borland chokes w/o full qualification here - mpl::identity, - mpl::identity - >::type typex; - // typex works around gcc 2.95 issue - return typex::cast(u); - #endif - } - }; - - struct non_polymorphic { - template - static T cast(U & u){ - return static_cast< T >(u); - } - }; - template - static T cast(U & u){ - typedef typename mpl::eval_if< - boost::is_polymorphic, - mpl::identity, - mpl::identity - >::type typex; - return typex::cast(u); - } - }; - - template - struct pointer { - - struct polymorphic { - // unfortunately, this below fails to work for virtual base - // classes. need has_virtual_base to do this. - // Subject for further study - #if 0 - struct linear { - template - static T cast(U * u){ - return static_cast< T >(u); - } - }; - - struct cross { - template - static T cast(U * u){ - T tmp = dynamic_cast< T >(u); - #ifndef NDEBUG - if ( tmp == 0 ) throw_exception(std::bad_cast()); - #endif - return tmp; - } - }; - - template - static T cast(U * u){ - typedef - typename mpl::eval_if< - typename mpl::and_< - mpl::not_::type, - U - > >, - mpl::not_::type - > > - >, - // borland chokes w/o full qualification here - mpl::identity, - mpl::identity - >::type typex; - return typex::cast(u); - } - #else - template - static T cast(U * u){ - T tmp = dynamic_cast< T >(u); - #ifndef NDEBUG - if ( tmp == 0 ) throw_exception(std::bad_cast()); - #endif - return tmp; - } - #endif - }; - - struct non_polymorphic { - template - static T cast(U * u){ - return static_cast< T >(u); - } - }; - - template - static T cast(U * u){ - typedef typename mpl::eval_if< - boost::is_polymorphic, - mpl::identity, - mpl::identity - >::type typex; - return typex::cast(u); - } - - }; - - template - struct void_pointer { - template - static TPtr cast(UPtr uptr){ - return static_cast(uptr); - } - }; - - template - struct error { - // if we get here, its because we are using one argument in the - // cast on a system which doesn't support partial template - // specialization - template - static T cast(U){ - BOOST_STATIC_ASSERT(sizeof(T)==0); - return * static_cast(NULL); - } - }; - -} // smart_cast_impl - -// this implements: -// smart_cast(Source * s) -// smart_cast(s) -// note that it will fail with -// smart_cast(s) -template -T smart_cast(U u) { - typedef - typename mpl::eval_if< - typename mpl::or_< - boost::is_same, - boost::is_same, - boost::is_same, - boost::is_same - >, - mpl::identity >, - // else - typename mpl::eval_if, - mpl::identity >, - // else - typename mpl::eval_if, - mpl::identity >, - // else - mpl::identity - > - > - > - >::type typex; - return typex::cast(u); -} - -// this implements: -// smart_cast_reference(Source & s) -template -T smart_cast_reference(U & u) { - return smart_cast_impl::reference< T >::cast(u); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_SMART_CAST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/split_free.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/split_free.hpp deleted file mode 100644 index 85e2f590fe4..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/split_free.hpp +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SPLIT_FREE_HPP -#define BOOST_SERIALIZATION_SPLIT_FREE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// split_free.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include - -namespace boost { -namespace archive { - namespace detail { - template class interface_oarchive; - template class interface_iarchive; - } // namespace detail -} // namespace archive - -namespace serialization { - -//namespace detail { -template -struct free_saver { - static void invoke( - Archive & ar, - const T & t, - const unsigned int file_version - ){ - // use function overload (version_type) to workaround - // two-phase lookup issue - const version_type v(file_version); - save(ar, t, v); - } -}; -template -struct free_loader { - static void invoke( - Archive & ar, - T & t, - const unsigned int file_version - ){ - // use function overload (version_type) to workaround - // two-phase lookup issue - const version_type v(file_version); - load(ar, t, v); - } -}; -//} // namespace detail - -template -inline void split_free( - Archive & ar, - T & t, - const unsigned int file_version -){ - typedef typename mpl::eval_if< - typename Archive::is_saving, - mpl::identity >, - mpl::identity > - >::type typex; - typex::invoke(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#define BOOST_SERIALIZATION_SPLIT_FREE(T) \ -namespace boost { namespace serialization { \ -template \ -inline void serialize( \ - Archive & ar, \ - T & t, \ - const unsigned int file_version \ -){ \ - split_free(ar, t, file_version); \ -} \ -}} -/**/ - -#endif // BOOST_SERIALIZATION_SPLIT_FREE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/split_member.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/split_member.hpp deleted file mode 100644 index 5f32520559e..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/split_member.hpp +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SPLIT_MEMBER_HPP -#define BOOST_SERIALIZATION_SPLIT_MEMBER_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// split_member.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include - -#include - -namespace boost { -namespace archive { - namespace detail { - template class interface_oarchive; - template class interface_iarchive; - } // namespace detail -} // namespace archive - -namespace serialization { -namespace detail { - - template - struct member_saver { - static void invoke( - Archive & ar, - const T & t, - const unsigned int file_version - ){ - access::member_save(ar, t, file_version); - } - }; - - template - struct member_loader { - static void invoke( - Archive & ar, - T & t, - const unsigned int file_version - ){ - access::member_load(ar, t, file_version); - } - }; - -} // detail - -template -inline void split_member( - Archive & ar, T & t, const unsigned int file_version -){ - typedef typename mpl::eval_if< - typename Archive::is_saving, - mpl::identity >, - mpl::identity > - >::type typex; - typex::invoke(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -// split member function serialize funcition into save/load -#define BOOST_SERIALIZATION_SPLIT_MEMBER() \ -template \ -void serialize( \ - Archive &ar, \ - const unsigned int file_version \ -){ \ - boost::serialization::split_member(ar, *this, file_version); \ -} \ -/**/ - -#endif // BOOST_SERIALIZATION_SPLIT_MEMBER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/stack.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/stack.hpp deleted file mode 100644 index 96f90fe8767..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/stack.hpp +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef BOOST_SERIALIZATION_STACK_HPP -#define BOOST_SERIALIZATION_STACK_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// stack.hpp - -// (C) Copyright 2014 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include - -// function specializations must be defined in the appropriate -// namespace - boost::serialization -#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) -#define STD _STLP_STD -#else -#define STD std -#endif - -namespace boost { -namespace serialization { -namespace detail{ - -template -struct stack_save : public STD::stack { - template - void operator()(Archive & ar, const unsigned int file_version) const { - save(ar, STD::stack::c, file_version); - } -}; -template -struct stack_load : public STD::stack { - template - void operator()(Archive & ar, const unsigned int file_version) { - load(ar, STD::stack::c, file_version); - } -}; - -} // detail - -template -inline void serialize( - Archive & ar, - std::stack< T, C> & t, - const unsigned int file_version -){ - typedef typename mpl::eval_if< - typename Archive::is_saving, - mpl::identity >, - mpl::identity > - >::type typex; - static_cast(t)(ar, file_version); -} - -} // namespace serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::stack) - -#undef STD - -#endif // BOOST_SERIALIZATION_DEQUE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/state_saver.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/state_saver.hpp deleted file mode 100644 index 248b8d91556..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/state_saver.hpp +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef BOOST_SERIALIZATION_STATE_SAVER_HPP -#define BOOST_SERIALIZATION_STATE_SAVER_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// state_saver.hpp: - -// (C) Copyright 2003-4 Pavel Vozenilek and Robert Ramey - http://www.rrsd.com. -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org/libs/serialization for updates, documentation, and revision history. - -// Inspired by Daryle Walker's iostate_saver concept. This saves the original -// value of a variable when a state_saver is constructed and restores -// upon destruction. Useful for being sure that state is restored to -// variables upon exit from scope. - - -#include -#ifndef BOOST_NO_EXCEPTIONS - #include -#endif - -#include -#include -#include -#include - -#include -#include - -namespace boost { -namespace serialization { - -template -// T requirements: -// - POD or object semantic (cannot be reference, function, ...) -// - copy constructor -// - operator = (no-throw one preferred) -class state_saver : private boost::noncopyable -{ -private: - const T previous_value; - T & previous_ref; - - struct restore { - static void invoke(T & previous_ref, const T & previous_value){ - previous_ref = previous_value; // won't throw - } - }; - - struct restore_with_exception { - static void invoke(T & previous_ref, const T & previous_value){ - BOOST_TRY{ - previous_ref = previous_value; - } - BOOST_CATCH(::std::exception &) { - // we must ignore it - we are in destructor - } - BOOST_CATCH_END - } - }; - -public: - state_saver( - T & object - ) : - previous_value(object), - previous_ref(object) - {} - - ~state_saver() { - #ifndef BOOST_NO_EXCEPTIONS - typedef typename mpl::eval_if< - has_nothrow_copy< T >, - mpl::identity, - mpl::identity - >::type typex; - typex::invoke(previous_ref, previous_value); - #else - previous_ref = previous_value; - #endif - } - -}; // state_saver<> - -} // serialization -} // boost - -#endif //BOOST_SERIALIZATION_STATE_SAVER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/static_warning.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/static_warning.hpp deleted file mode 100644 index 1d9238fc4d9..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/static_warning.hpp +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef BOOST_SERIALIZATION_STATIC_WARNING_HPP -#define BOOST_SERIALIZATION_STATIC_WARNING_HPP - -// (C) Copyright Robert Ramey 2003. Jonathan Turkanis 2004. -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org/libs/static_assert for documentation. - -/* - Revision history: - 15 June 2003 - Initial version. - 31 March 2004 - improved diagnostic messages and portability - (Jonathan Turkanis) - 03 April 2004 - works on VC6 at class and namespace scope - - ported to DigitalMars - - static warnings disabled by default; when enabled, - uses pragmas to enable required compiler warnings - on MSVC, Intel, Metrowerks and Borland 5.x. - (Jonathan Turkanis) - 30 May 2004 - tweaked for msvc 7.1 and gcc 3.3 - - static warnings ENabled by default; when enabled, - (Robert Ramey) -*/ - -#include - -// -// Implementation -// Makes use of the following warnings: -// 1. GCC prior to 3.3: division by zero. -// 2. BCC 6.0 preview: unreferenced local variable. -// 3. DigitalMars: returning address of local automatic variable. -// 4. VC6: class previously seen as struct (as in 'boost/mpl/print.hpp') -// 5. All others: deletion of pointer to incomplete type. -// -// The trick is to find code which produces warnings containing the name of -// a structure or variable. Details, with same numbering as above: -// 1. static_warning_impl::value is zero iff B is false, so diving an int -// by this value generates a warning iff B is false. -// 2. static_warning_impl::type has a constructor iff B is true, so an -// unreferenced variable of this type generates a warning iff B is false. -// 3. static_warning_impl::type overloads operator& to return a dynamically -// allocated int pointer only is B is true, so returning the address of an -// automatic variable of this type generates a warning iff B is fasle. -// 4. static_warning_impl::STATIC_WARNING is decalred as a struct iff B is -// false. -// 5. static_warning_impl::type is incomplete iff B is false, so deleting a -// pointer to this type generates a warning iff B is false. -// - -//------------------Enable selected warnings----------------------------------// - -// Enable the warnings relied on by BOOST_STATIC_WARNING, where possible. - -// 6. replaced implementation with one which depends solely on -// mpl::print<>. The previous one was found to fail for functions -// under recent versions of gcc and intel compilers - Robert Ramey - -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template -struct BOOST_SERIALIZATION_STATIC_WARNING_LINE{}; - -template -struct static_warning_test{ - typename boost::mpl::eval_if_c< - B, - boost::mpl::true_, - typename boost::mpl::identity< - boost::mpl::print< - BOOST_SERIALIZATION_STATIC_WARNING_LINE - > - > - >::type type; -}; - -template -struct BOOST_SERIALIZATION_SS {}; - -} // serialization -} // boost - -#define BOOST_SERIALIZATION_BSW(B, L) \ - typedef boost::serialization::BOOST_SERIALIZATION_SS< \ - sizeof( boost::serialization::static_warning_test< B, L > ) \ - > BOOST_JOIN(STATIC_WARNING_LINE, L) BOOST_ATTRIBUTE_UNUSED; -#define BOOST_STATIC_WARNING(B) BOOST_SERIALIZATION_BSW(B, __LINE__) - -#endif // BOOST_SERIALIZATION_STATIC_WARNING_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/string.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/string.hpp deleted file mode 100644 index 76e695d4f3c..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/string.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef BOOST_SERIALIZATION_STRING_HPP -#define BOOST_SERIALIZATION_STRING_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization/string.hpp: -// serialization for stl string templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include - -BOOST_CLASS_IMPLEMENTATION(std::string, boost::serialization::primitive_type) -#ifndef BOOST_NO_STD_WSTRING -BOOST_CLASS_IMPLEMENTATION(std::wstring, boost::serialization::primitive_type) -#endif - -#endif // BOOST_SERIALIZATION_STRING_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/strong_typedef.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/strong_typedef.hpp deleted file mode 100644 index fdd1b24c9cb..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/strong_typedef.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef BOOST_SERIALIZATION_STRONG_TYPEDEF_HPP -#define BOOST_SERIALIZATION_STRONG_TYPEDEF_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// strong_typedef.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2016 Ashish Sadanandan -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org/libs/serialization for updates, documentation, and revision history. - -// macro used to implement a strong typedef. strong typedef -// guarentees that two types are distinguised even though the -// share the same underlying implementation. typedef does not create -// a new type. BOOST_STRONG_TYPEDEF(T, D) creates a new type named D -// that operates as a type T. - -#include -#include -#include -#include -#include - -#define BOOST_STRONG_TYPEDEF(T, D) \ -struct D \ - : boost::totally_ordered1< D \ - , boost::totally_ordered2< D, T \ - > > \ -{ \ - T t; \ - explicit D(const T& t_) BOOST_NOEXCEPT_IF(boost::has_nothrow_copy_constructor::value) : t(t_) {} \ - D() BOOST_NOEXCEPT_IF(boost::has_nothrow_default_constructor::value) : t() {} \ - D(const D & t_) BOOST_NOEXCEPT_IF(boost::has_nothrow_copy_constructor::value) : t(t_.t) {} \ - D& operator=(const D& rhs) BOOST_NOEXCEPT_IF(boost::has_nothrow_assign::value) {t = rhs.t; return *this;} \ - D& operator=(const T& rhs) BOOST_NOEXCEPT_IF(boost::has_nothrow_assign::value) {t = rhs; return *this;} \ - operator const T&() const {return t;} \ - operator T&() {return t;} \ - bool operator==(const D& rhs) const {return t == rhs.t;} \ - bool operator<(const D& rhs) const {return t < rhs.t;} \ -}; - -#endif // BOOST_SERIALIZATION_STRONG_TYPEDEF_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/throw_exception.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/throw_exception.hpp deleted file mode 100644 index b67618adc92..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/throw_exception.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef BOOST_SERIALIZATION_THROW_EXCEPTION_HPP_INCLUDED -#define BOOST_SERIALIZATION_THROW_EXCEPTION_HPP_INCLUDED - -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) -# pragma once -#endif - -// boost/throw_exception.hpp -// -// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include - -#ifndef BOOST_NO_EXCEPTIONS -#include -#endif - -namespace boost { -namespace serialization { - -#ifdef BOOST_NO_EXCEPTIONS - -inline void throw_exception(std::exception const & e) { - ::boost::throw_exception(e); -} - -#else - -template inline void throw_exception(E const & e){ - throw e; -} - -#endif - -} // namespace serialization -} // namespace boost - -#endif // #ifndef BOOST_SERIALIZATION_THROW_EXCEPTION_HPP_INCLUDED diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/tracking.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/tracking.hpp deleted file mode 100644 index d5c79b8409d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/tracking.hpp +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef BOOST_SERIALIZATION_TRACKING_HPP -#define BOOST_SERIALIZATION_TRACKING_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// tracking.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -struct basic_traits; - -// default tracking level -template -struct tracking_level_impl { - template - struct traits_class_tracking { - typedef typename U::tracking type; - }; - typedef mpl::integral_c_tag tag; - // note: at least one compiler complained w/o the full qualification - // on basic traits below - typedef - typename mpl::eval_if< - is_base_and_derived, - traits_class_tracking< T >, - //else - typename mpl::eval_if< - is_pointer< T >, - // pointers are not tracked by default - mpl::int_, - //else - typename mpl::eval_if< - // for primitives - typename mpl::equal_to< - implementation_level< T >, - mpl::int_ - >, - // is never - mpl::int_, - // otherwise its selective - mpl::int_ - > > >::type type; - BOOST_STATIC_CONSTANT(int, value = type::value); -}; - -template -struct tracking_level : - public tracking_level_impl -{ -}; - -template -inline bool operator>=(tracking_level< T > t, enum tracking_type l) -{ - return t.value >= (int)l; -} - -} // namespace serialization -} // namespace boost - - -// The STATIC_ASSERT is prevents one from setting tracking for a primitive type. -// This almost HAS to be an error. Doing this will effect serialization of all -// char's in your program which is almost certainly what you don't want to do. -// If you want to track all instances of a given primitive type, You'll have to -// wrap it in your own type so its not a primitive anymore. Then it will compile -// without problem. -#define BOOST_CLASS_TRACKING(T, E) \ -namespace boost { \ -namespace serialization { \ -template<> \ -struct tracking_level< T > \ -{ \ - typedef mpl::integral_c_tag tag; \ - typedef mpl::int_< E> type; \ - BOOST_STATIC_CONSTANT( \ - int, \ - value = tracking_level::type::value \ - ); \ - /* tracking for a class */ \ - BOOST_STATIC_ASSERT(( \ - mpl::greater< \ - /* that is a prmitive */ \ - implementation_level< T >, \ - mpl::int_ \ - >::value \ - )); \ -}; \ -}} - -#endif // BOOST_SERIALIZATION_TRACKING_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/tracking_enum.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/tracking_enum.hpp deleted file mode 100644 index 278051e1baf..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/tracking_enum.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef BOOST_SERIALIZATION_TRACKING_ENUM_HPP -#define BOOST_SERIALIZATION_TRACKING_ENUM_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// tracking_enum.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -namespace boost { -namespace serialization { - -// addresses of serialized objects may be tracked to avoid saving/loading -// redundant copies. This header defines a class trait that can be used -// to specify when objects should be tracked - -// names for each tracking level -enum tracking_type -{ - // never track this type - track_never = 0, - // track objects of this type if the object is serialized through a - // pointer. - track_selectively = 1, - // always track this type - track_always = 2 -}; - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_TRACKING_ENUM_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/traits.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/traits.hpp deleted file mode 100644 index 9e114fdd3df..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/traits.hpp +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef BOOST_SERIALIZATION_TRAITS_HPP -#define BOOST_SERIALIZATION_TRAITS_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// traits.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// This header is used to apply serialization traits to templates. The -// standard system can't be used for platforms which don't support -// Partial Templlate Specialization. - -// The motivation for this is the Name-Value Pair (NVP) template. -// it has to work the same on all platforms in order for archives -// to be portable accross platforms. - -#include -#include - -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -// common base class used to detect appended traits class -struct basic_traits {}; - -template -struct extended_type_info_impl; - -template< - class T, - int Level, - int Tracking, - unsigned int Version = 0, - class ETII = extended_type_info_impl< T >, - class Wrapper = mpl::false_ -> -struct traits : public basic_traits { - BOOST_STATIC_ASSERT(Version == 0 || Level >= object_class_info); - BOOST_STATIC_ASSERT(Tracking == track_never || Level >= object_serializable); - typedef typename mpl::int_ level; - typedef typename mpl::int_ tracking; - typedef typename mpl::int_ version; - typedef ETII type_info_implementation; - typedef Wrapper is_wrapper; -}; - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_TRAITS_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/type_info_implementation.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/type_info_implementation.hpp deleted file mode 100644 index 24637a8dbb3..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/type_info_implementation.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef BOOST_SERIALIZATION_TYPE_INFO_IMPLEMENTATION_HPP -#define BOOST_SERIALIZATION_TYPE_INFO_IMPLEMENTATION_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// type_info_implementation.hpp: interface for portable version of type_info - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - - -#include -#include - -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -// note that T and const T are folded into const T so that -// there is only one table entry per type -template -struct type_info_implementation { - template - struct traits_class_typeinfo_implementation { - typedef typename U::type_info_implementation::type type; - }; - // note: at least one compiler complained w/o the full qualification - // on basic traits below - typedef - typename mpl::eval_if< - is_base_and_derived, - traits_class_typeinfo_implementation< T >, - //else - mpl::identity< - typename extended_type_info_impl< T >::type - > - >::type type; -}; - -} // namespace serialization -} // namespace boost - -// define a macro to assign a particular derivation of extended_type_info -// to a specified a class. -#define BOOST_CLASS_TYPE_INFO(T, ETI) \ -namespace boost { \ -namespace serialization { \ -template<> \ -struct type_info_implementation< T > { \ - typedef ETI type; \ -}; \ -template<> \ -struct type_info_implementation< const T > { \ - typedef ETI type; \ -}; \ -} \ -} \ -/**/ - -#endif /// BOOST_SERIALIZATION_TYPE_INFO_IMPLEMENTATION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unique_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unique_ptr.hpp deleted file mode 100644 index 8d8703ef4f7..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/unique_ptr.hpp +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef BOOST_SERIALIZATION_UNIQUE_PTR_HPP -#define BOOST_SERIALIZATION_UNIQUE_PTR_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// unique_ptr.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. -#include -#include -#include - -namespace boost { -namespace serialization { - -///////////////////////////////////////////////////////////// -// implement serialization for unique_ptr< T > -// note: this must be added to the boost namespace in order to -// be called by the library -template -inline void save( - Archive & ar, - const std::unique_ptr< T > &t, - const unsigned int /*file_version*/ -){ - // only the raw pointer has to be saved - // the ref count is rebuilt automatically on load - const T * const tx = t.get(); - ar << BOOST_SERIALIZATION_NVP(tx); -} - -template -inline void load( - Archive & ar, - std::unique_ptr< T > &t, - const unsigned int /*file_version*/ -){ - T *tx; - ar >> BOOST_SERIALIZATION_NVP(tx); - // note that the reset automagically maintains the reference count - t.reset(tx); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::unique_ptr< T > &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - - -#endif // BOOST_SERIALIZATION_UNIQUE_PTR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_load_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_load_imp.hpp deleted file mode 100644 index d56a423d180..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_load_imp.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_LOAD_IMP_HPP -#define BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_LOAD_IMP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -# pragma warning (disable : 4786) // too long name, harmless warning -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// unordered_collections_load_imp.hpp: serialization for loading stl collections - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2014 Jim Bell -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// helper function templates for serialization of collections - -#include -#include // size_t -#include // msvc 6.0 needs this for warning suppression -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif -#include - -#include -#include -#include -#include -#include - -namespace boost{ -namespace serialization { -namespace stl { - -////////////////////////////////////////////////////////////////////// -// implementation of serialization for STL containers -// -template -inline void load_unordered_collection(Archive & ar, Container &s) -{ - collection_size_type count; - collection_size_type bucket_count; - boost::serialization::item_version_type item_version(0); - boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - ar >> BOOST_SERIALIZATION_NVP(count); - ar >> BOOST_SERIALIZATION_NVP(bucket_count); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - s.clear(); - s.rehash(bucket_count); - InputFunction ifunc; - while(count-- > 0){ - ifunc(ar, s, item_version); - } -} - -} // namespace stl -} // namespace serialization -} // namespace boost - -#endif //BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_LOAD_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_save_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_save_imp.hpp deleted file mode 100644 index 56746ebeaa3..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_save_imp.hpp +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_SAVE_IMP_HPP -#define BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_SAVE_IMP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// hash_collections_save_imp.hpp: serialization for stl collections - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2014 Jim Bell -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// helper function templates for serialization of collections - -#include -#include -#include -#include -#include -#include - -namespace boost{ -namespace serialization { -namespace stl { - -////////////////////////////////////////////////////////////////////// -// implementation of serialization for STL containers -// - -template -inline void save_unordered_collection(Archive & ar, const Container &s) -{ - collection_size_type count(s.size()); - const collection_size_type bucket_count(s.bucket_count()); - const item_version_type item_version( - version::value - ); - - #if 0 - /* should only be necessary to create archives of previous versions - * which is not currently supported. So for now comment this out - */ - boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - ar << BOOST_SERIALIZATION_NVP(count); - ar << BOOST_SERIALIZATION_NVP(bucket_count); - if(boost::archive::library_version_type(3) < library_version){ - // record number of elements - // make sure the target type is registered so we can retrieve - // the version when we load - ar << BOOST_SERIALIZATION_NVP(item_version); - } - #else - ar << BOOST_SERIALIZATION_NVP(count); - ar << BOOST_SERIALIZATION_NVP(bucket_count); - ar << BOOST_SERIALIZATION_NVP(item_version); - #endif - - typename Container::const_iterator it = s.begin(); - while(count-- > 0){ - // note borland emits a no-op without the explicit namespace - boost::serialization::save_construct_data_adl( - ar, - &(*it), - boost::serialization::version< - typename Container::value_type - >::value - ); - ar << boost::serialization::make_nvp("item", *it++); - } -} - -} // namespace stl -} // namespace serialization -} // namespace boost - -#endif //BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_SAVE_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_map.hpp deleted file mode 100644 index 4fdbddd7b65..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_map.hpp +++ /dev/null @@ -1,160 +0,0 @@ -#ifndef BOOST_SERIALIZATION_UNORDERED_MAP_HPP -#define BOOST_SERIALIZATION_UNORDERED_MAP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization/unordered_map.hpp: -// serialization for stl unordered_map templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2014 Jim Bell -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include - -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const std::unordered_map &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::save_unordered_collection< - Archive, - std::unordered_map - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - std::unordered_map &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::load_unordered_collection< - Archive, - std::unordered_map, - boost::serialization::stl::archive_input_unordered_map< - Archive, - std::unordered_map - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - std::unordered_map &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -// unordered_multimap -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const std::unordered_multimap< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::save_unordered_collection< - Archive, - std::unordered_multimap - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - std::unordered_multimap< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::load_unordered_collection< - Archive, - std::unordered_multimap< - Key, HashFcn, EqualKey, Allocator - >, - boost::serialization::stl::archive_input_unordered_multimap< - Archive, - std::unordered_multimap - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - std::unordered_multimap< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_UNORDERED_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_set.hpp deleted file mode 100644 index adfee609cbe..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_set.hpp +++ /dev/null @@ -1,162 +0,0 @@ -#ifndef BOOST_SERIALIZATION_UNORDERED_SET_HPP -#define BOOST_SERIALIZATION_UNORDERED_SET_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// unordered_set.hpp: serialization for stl unordered_set templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2014 Jim Bell -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include - -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const std::unordered_set< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::save_unordered_collection< - Archive, - std::unordered_set - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - std::unordered_set< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::load_unordered_collection< - Archive, - std::unordered_set, - stl::archive_input_unordered_set< - Archive, - std::unordered_set< - Key, HashFcn, EqualKey, Allocator - > - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - std::unordered_set< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - split_free(ar, t, file_version); -} - -// unordered_multiset -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const std::unordered_multiset< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int /*file_version*/ -){ - stl::save_unordered_collection< - Archive, - std::unordered_multiset - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - std::unordered_multiset< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::load_unordered_collection< - Archive, - std::unordered_multiset, - boost::serialization::stl::archive_input_unordered_multiset< - Archive, - std::unordered_multiset - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - std::unordered_multiset &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_UNORDERED_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/utility.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/utility.hpp deleted file mode 100644 index 4867a4a12d2..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/utility.hpp +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef BOOST_SERIALIZATION_UTILITY_HPP -#define BOOST_SERIALIZATION_UTILITY_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization/utility.hpp: -// serialization for stl utility templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -// pair -template -inline void serialize( - Archive & ar, - std::pair & p, - const unsigned int /* file_version */ -){ - // note: we remove any const-ness on the first argument. The reason is that - // for stl maps, the type saved is pair::type typef; - ar & boost::serialization::make_nvp("first", const_cast(p.first)); - ar & boost::serialization::make_nvp("second", p.second); -} - -/// specialization of is_bitwise_serializable for pairs -template -struct is_bitwise_serializable > - : public mpl::and_,is_bitwise_serializable > -{ -}; - -} // serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_UTILITY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/valarray.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/valarray.hpp deleted file mode 100644 index 9eece5c1737..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/valarray.hpp +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef BOOST_SERIALIZATION_VALARAY_HPP -#define BOOST_SERIALIZATION_VALARAY_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// valarray.hpp: serialization for stl vector templates - -// (C) Copyright 2005 Matthias Troyer . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -#include -#include -#include -#include -#include - -// function specializations must be defined in the appropriate -// namespace - boost::serialization -#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) -#define STD _STLP_STD -#else -#define STD std -#endif - -namespace boost { -namespace serialization { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// valarray< T > - -template -void save( Archive & ar, const STD::valarray &t, const unsigned int /*file_version*/ ) -{ - const collection_size_type count(t.size()); - ar << BOOST_SERIALIZATION_NVP(count); - if (t.size()){ - // explict template arguments to pass intel C++ compiler - ar << serialization::make_array( - static_cast(&t[0]), - count - ); - } -} - -template -void load( Archive & ar, STD::valarray &t, const unsigned int /*file_version*/ ) -{ - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - t.resize(count); - if (t.size()){ - // explict template arguments to pass intel C++ compiler - ar >> serialization::make_array( - static_cast(&t[0]), - count - ); - } -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( Archive & ar, STD::valarray & t, const unsigned int file_version) -{ - boost::serialization::split_free(ar, t, file_version); -} - -} } // end namespace boost::serialization - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::valarray) -#undef STD - -#endif // BOOST_SERIALIZATION_VALARAY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/variant.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/variant.hpp deleted file mode 100644 index dce6f3d49e7..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/variant.hpp +++ /dev/null @@ -1,158 +0,0 @@ -#ifndef BOOST_SERIALIZATION_VARIANT_HPP -#define BOOST_SERIALIZATION_VARIANT_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// variant.hpp - non-intrusive serialization of variant types -// -// copyright (c) 2005 -// troy d. straszheim -// http://www.resophonic.com -// -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org for updates, documentation, and revision history. -// -// thanks to Robert Ramey, Peter Dimov, and Richard Crossley. -// - -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include - -#include -#include -#include - -namespace boost { -namespace serialization { - -template -struct variant_save_visitor : - boost::static_visitor<> -{ - variant_save_visitor(Archive& ar) : - m_ar(ar) - {} - template - void operator()(T const & value) const - { - m_ar << BOOST_SERIALIZATION_NVP(value); - } -private: - Archive & m_ar; -}; - -template -void save( - Archive & ar, - boost::variant const & v, - unsigned int /*version*/ -){ - int which = v.which(); - ar << BOOST_SERIALIZATION_NVP(which); - variant_save_visitor visitor(ar); - v.apply_visitor(visitor); -} - -template -struct variant_impl { - - struct load_null { - template - static void invoke( - Archive & /*ar*/, - int /*which*/, - V & /*v*/, - const unsigned int /*version*/ - ){} - }; - - struct load_impl { - template - static void invoke( - Archive & ar, - int which, - V & v, - const unsigned int version - ){ - if(which == 0){ - // note: A non-intrusive implementation (such as this one) - // necessary has to copy the value. This wouldn't be necessary - // with an implementation that de-serialized to the address of the - // aligned storage included in the variant. - typedef typename mpl::front::type head_type; - head_type value; - ar >> BOOST_SERIALIZATION_NVP(value); - v = value; - ar.reset_object_address(& boost::get(v), & value); - return; - } - typedef typename mpl::pop_front::type type; - variant_impl::load(ar, which - 1, v, version); - } - }; - - template - static void load( - Archive & ar, - int which, - V & v, - const unsigned int version - ){ - typedef typename mpl::eval_if, - mpl::identity, - mpl::identity - >::type typex; - typex::invoke(ar, which, v, version); - } - -}; - -template -void load( - Archive & ar, - boost::variant& v, - const unsigned int version -){ - int which; - typedef typename boost::variant::types types; - ar >> BOOST_SERIALIZATION_NVP(which); - if(which >= mpl::size::value) - // this might happen if a type was removed from the list of variant types - boost::serialization::throw_exception( - boost::archive::archive_exception( - boost::archive::archive_exception::unsupported_version - ) - ); - variant_impl::load(ar, which, v, version); -} - -template -inline void serialize( - Archive & ar, - boost::variant & v, - const unsigned int file_version -){ - split_free(ar,v,file_version); -} - -} // namespace serialization -} // namespace boost - -#endif //BOOST_SERIALIZATION_VARIANT_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/vector.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/vector.hpp deleted file mode 100644 index 9a114c00e20..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/vector.hpp +++ /dev/null @@ -1,233 +0,0 @@ -#ifndef BOOST_SERIALIZATION_VECTOR_HPP -#define BOOST_SERIALIZATION_VECTOR_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// vector.hpp: serialization for stl vector templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// fast array serialization (C) Copyright 2005 Matthias Troyer -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -// default is being compatible with version 1.34.1 files, not 1.35 files -#ifndef BOOST_SERIALIZATION_VECTOR_VERSIONED -#define BOOST_SERIALIZATION_VECTOR_VERSIONED(V) (V==4 || V==5) -#endif - -// function specializations must be defined in the appropriate -// namespace - boost::serialization -#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) -#define STD _STLP_STD -#else -#define STD std -#endif - -namespace boost { -namespace serialization { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// vector< T > - -// the default versions - -template -inline void save( - Archive & ar, - const std::vector &t, - const unsigned int /* file_version */, - mpl::false_ -){ - boost::serialization::stl::save_collection >( - ar, t - ); -} - -template -inline void load( - Archive & ar, - std::vector &t, - const unsigned int /* file_version */, - mpl::false_ -){ - const boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - item_version_type item_version(0); - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - t.reserve(count); - stl::collection_load_impl(ar, t, count, item_version); -} - -// the optimized versions - -template -inline void save( - Archive & ar, - const std::vector &t, - const unsigned int /* file_version */, - mpl::true_ -){ - const collection_size_type count(t.size()); - ar << BOOST_SERIALIZATION_NVP(count); - if (!t.empty()) - // explict template arguments to pass intel C++ compiler - ar << serialization::make_array( - static_cast(&t[0]), - count - ); -} - -template -inline void load( - Archive & ar, - std::vector &t, - const unsigned int /* file_version */, - mpl::true_ -){ - collection_size_type count(t.size()); - ar >> BOOST_SERIALIZATION_NVP(count); - t.resize(count); - unsigned int item_version=0; - if(BOOST_SERIALIZATION_VECTOR_VERSIONED(ar.get_library_version())) { - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - if (!t.empty()) - // explict template arguments to pass intel C++ compiler - ar >> serialization::make_array( - static_cast(&t[0]), - count - ); - } - -// dispatch to either default or optimized versions - -template -inline void save( - Archive & ar, - const std::vector &t, - const unsigned int file_version -){ - typedef typename - boost::serialization::use_array_optimization::template apply< - typename remove_const::type - >::type use_optimized; - save(ar,t,file_version, use_optimized()); -} - -template -inline void load( - Archive & ar, - std::vector &t, - const unsigned int file_version -){ -#ifdef BOOST_SERIALIZATION_VECTOR_135_HPP - if (ar.get_library_version()==boost::archive::library_version_type(5)) - { - load(ar,t,file_version, boost::is_arithmetic()); - return; - } -#endif - typedef typename - boost::serialization::use_array_optimization::template apply< - typename remove_const::type - >::type use_optimized; - load(ar,t,file_version, use_optimized()); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::vector & t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// vector -template -inline void save( - Archive & ar, - const std::vector &t, - const unsigned int /* file_version */ -){ - // record number of elements - collection_size_type count (t.size()); - ar << BOOST_SERIALIZATION_NVP(count); - std::vector::const_iterator it = t.begin(); - while(count-- > 0){ - bool tb = *it++; - ar << boost::serialization::make_nvp("item", tb); - } -} - -template -inline void load( - Archive & ar, - std::vector &t, - const unsigned int /* file_version */ -){ - // retrieve number of elements - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - t.resize(count); - for(collection_size_type i = collection_size_type(0); i < count; ++i){ - bool b; - ar >> boost::serialization::make_nvp("item", b); - t[i] = b; - } -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::vector & t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(std::vector) -#undef STD - -#endif // BOOST_SERIALIZATION_VECTOR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/vector_135.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/vector_135.hpp deleted file mode 100644 index fd1a7393d1b..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/vector_135.hpp +++ /dev/null @@ -1,26 +0,0 @@ -////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// vector_135.hpp: serialization for stl vector templates for compatibility -// with release 1.35, which had a bug - -// (C) Copyright 2008 Matthias Troyer -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - - -#ifndef BOOST_SERIALIZATION_VECTOR_135_HPP -#define BOOST_SERIALIZATION_VECTOR_135_HPP - -#ifdef BOOST_SERIALIZATION_VECTOR_VERSIONED -#if BOOST_SERIALIZATION_VECTOR_VERSION != 4 -#error "Boost.Serialization cannot be compatible with both 1.35 and 1.36-1.40 files" -#endif -#else -#define BOOST_SERIALIZATION_VECTOR_VERSIONED(V) (V>4) -#endif - -#include - -#endif // BOOST_SERIALIZATION_VECTOR_135_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/version.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/version.hpp deleted file mode 100644 index 21a74d73daa..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/version.hpp +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef BOOST_SERIALIZATION_VERSION_HPP -#define BOOST_SERIALIZATION_VERSION_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// version.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace serialization { - -struct basic_traits; - -// default version number is 0. Override with higher version -// when class definition changes. -template -struct version -{ - template - struct traits_class_version { - typedef typename U::version type; - }; - - typedef mpl::integral_c_tag tag; - // note: at least one compiler complained w/o the full qualification - // on basic traits below - typedef - typename mpl::eval_if< - is_base_and_derived, - traits_class_version< T >, - mpl::int_<0> - >::type type; - BOOST_STATIC_CONSTANT(int, value = version::type::value); -}; - -#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION -template -const int version::value; -#endif - -} // namespace serialization -} // namespace boost - -/* note: at first it seemed that this would be a good place to trap - * as an error an attempt to set a version # for a class which doesn't - * save its class information (including version #) in the archive. - * However, this imposes a requirement that the version be set after - * the implemention level which would be pretty confusing. If this - * is to be done, do this check in the input or output operators when - * ALL the serialization traits are available. Included the implementation - * here with this comment as a reminder not to do this! - */ -//#include -//#include - -#include -#include - -// specify the current version number for the class -// version numbers limited to 8 bits !!! -#define BOOST_CLASS_VERSION(T, N) \ -namespace boost { \ -namespace serialization { \ -template<> \ -struct version \ -{ \ - typedef mpl::int_ type; \ - typedef mpl::integral_c_tag tag; \ - BOOST_STATIC_CONSTANT(int, value = version::type::value); \ - BOOST_MPL_ASSERT(( \ - boost::mpl::less< \ - boost::mpl::int_, \ - boost::mpl::int_<256> \ - > \ - )); \ - /* \ - BOOST_MPL_ASSERT(( \ - mpl::equal_to< \ - :implementation_level, \ - mpl::int_ \ - >::value \ - )); \ - */ \ -}; \ -} \ -} - -#endif // BOOST_SERIALIZATION_VERSION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/void_cast.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/void_cast.hpp deleted file mode 100644 index f1b38286115..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/void_cast.hpp +++ /dev/null @@ -1,298 +0,0 @@ -#ifndef BOOST_SERIALIZATION_VOID_CAST_HPP -#define BOOST_SERIALIZATION_VOID_CAST_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// void_cast.hpp: interface for run-time casting of void pointers. - -// (C) Copyright 2002-2009 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// gennadiy.rozental@tfn.com - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // for ptrdiff_t -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4251 4231 4660 4275) -#endif - -namespace boost { -namespace serialization { - -class extended_type_info; - -// Given a void *, assume that it really points to an instance of one type -// and alter it so that it would point to an instance of a related type. -// Return the altered pointer. If there exists no sequence of casts that -// can transform from_type to to_type, return a NULL. - -BOOST_SERIALIZATION_DECL void const * -void_upcast( - extended_type_info const & derived, - extended_type_info const & base, - void const * const t -); - -inline void * -void_upcast( - extended_type_info const & derived, - extended_type_info const & base, - void * const t -){ - return const_cast(void_upcast( - derived, - base, - const_cast(t) - )); -} - -BOOST_SERIALIZATION_DECL void const * -void_downcast( - extended_type_info const & derived, - extended_type_info const & base, - void const * const t -); - -inline void * -void_downcast( - extended_type_info const & derived, - extended_type_info const & base, - void * const t -){ - return const_cast(void_downcast( - derived, - base, - const_cast(t) - )); -} - -namespace void_cast_detail { - -class BOOST_SYMBOL_VISIBLE void_caster : - private boost::noncopyable -{ - friend - BOOST_SERIALIZATION_DECL void const * - boost::serialization::void_upcast( - extended_type_info const & derived, - extended_type_info const & base, - void const * const - ); - friend - BOOST_SERIALIZATION_DECL void const * - boost::serialization::void_downcast( - extended_type_info const & derived, - extended_type_info const & base, - void const * const - ); -protected: - BOOST_SERIALIZATION_DECL void recursive_register(bool includes_virtual_base = false) const; - BOOST_SERIALIZATION_DECL void recursive_unregister() const; - virtual bool has_virtual_base() const = 0; -public: - // Data members - const extended_type_info * m_derived; - const extended_type_info * m_base; - /*const*/ std::ptrdiff_t m_difference; - void_caster const * const m_parent; - - // note that void_casters are keyed on value of - // member extended type info records - NOT their - // addresses. This is necessary in order for the - // void cast operations to work across dll and exe - // module boundries. - bool operator<(const void_caster & rhs) const; - - const void_caster & operator*(){ - return *this; - } - // each derived class must re-implement these; - virtual void const * upcast(void const * const t) const = 0; - virtual void const * downcast(void const * const t) const = 0; - // Constructor - void_caster( - extended_type_info const * derived, - extended_type_info const * base, - std::ptrdiff_t difference = 0, - void_caster const * const parent = 0 - ) : - m_derived(derived), - m_base(base), - m_difference(difference), - m_parent(parent) - {} - virtual ~void_caster(){} -}; - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4251 4231 4660 4275 4511 4512) -#endif - -template -class BOOST_SYMBOL_VISIBLE void_caster_primitive : - public void_caster -{ - virtual void const * downcast(void const * const t) const { - const Derived * d = - boost::serialization::smart_cast( - static_cast(t) - ); - return d; - } - virtual void const * upcast(void const * const t) const { - const Base * b = - boost::serialization::smart_cast( - static_cast(t) - ); - return b; - } - virtual bool has_virtual_base() const { - return false; - } -public: - void_caster_primitive(); - virtual ~void_caster_primitive(); -}; - -template -void_caster_primitive::void_caster_primitive() : - void_caster( - & type_info_implementation::type::get_const_instance(), - & type_info_implementation::type::get_const_instance(), - // note:I wanted to displace from 0 here, but at least one compiler - // treated 0 by not shifting it at all. - reinterpret_cast( - static_cast( - reinterpret_cast(8) - ) - ) - 8 - ) -{ - recursive_register(); -} - -template -void_caster_primitive::~void_caster_primitive(){ - recursive_unregister(); -} - -template -class BOOST_SYMBOL_VISIBLE void_caster_virtual_base : - public void_caster -{ - virtual bool has_virtual_base() const { - return true; - } -public: - virtual void const * downcast(void const * const t) const { - const Derived * d = - dynamic_cast( - static_cast(t) - ); - return d; - } - virtual void const * upcast(void const * const t) const { - const Base * b = - dynamic_cast( - static_cast(t) - ); - return b; - } - void_caster_virtual_base(); - virtual ~void_caster_virtual_base(); -}; - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -template -void_caster_virtual_base::void_caster_virtual_base() : - void_caster( - & (type_info_implementation::type::get_const_instance()), - & (type_info_implementation::type::get_const_instance()) - ) -{ - recursive_register(true); -} - -template -void_caster_virtual_base::~void_caster_virtual_base(){ - recursive_unregister(); -} - -template -struct BOOST_SYMBOL_VISIBLE void_caster_base : - public void_caster -{ - typedef - typename mpl::eval_if, - mpl::identity< - void_cast_detail::void_caster_virtual_base - > - ,// else - mpl::identity< - void_cast_detail::void_caster_primitive - > - >::type type; -}; - -} // void_cast_detail - -template -BOOST_DLLEXPORT -inline const void_cast_detail::void_caster & void_cast_register( - Derived const * /* dnull = NULL */, - Base const * /* bnull = NULL */ -){ - typedef - typename mpl::eval_if, - mpl::identity< - void_cast_detail::void_caster_virtual_base - > - ,// else - mpl::identity< - void_cast_detail::void_caster_primitive - > - >::type typex; - return singleton::get_const_instance(); -} - -template -class BOOST_SYMBOL_VISIBLE void_caster : - public void_cast_detail::void_caster_base::type -{ -}; - -} // namespace serialization -} // namespace boost - -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_SERIALIZATION_VOID_CAST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/void_cast_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/void_cast_fwd.hpp deleted file mode 100644 index def61d52bb7..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/void_cast_fwd.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef BOOST_SERIALIZATION_VOID_CAST_FWD_HPP -#define BOOST_SERIALIZATION_VOID_CAST_FWD_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// void_cast_fwd.hpp: interface for run-time casting of void pointers. - -// (C) Copyright 2005 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// gennadiy.rozental@tfn.com - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // NULL -#include - -namespace boost { -namespace serialization { -namespace void_cast_detail{ -class void_caster; -} // namespace void_cast_detail -template -BOOST_DLLEXPORT -inline const void_cast_detail::void_caster & void_cast_register( - const Derived * dnull = NULL, - const Base * bnull = NULL -) BOOST_USED; -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_VOID_CAST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/weak_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/weak_ptr.hpp deleted file mode 100644 index 6952d24cb37..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/weak_ptr.hpp +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef BOOST_SERIALIZATION_WEAK_PTR_HPP -#define BOOST_SERIALIZATION_WEAK_PTR_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// weak_ptr.hpp: serialization for boost weak pointer - -// (C) Copyright 2004 Robert Ramey and Martin Ecker -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -namespace boost { -namespace serialization{ - -template -inline void save( - Archive & ar, - const boost::weak_ptr< T > &t, - const unsigned int /* file_version */ -){ - const boost::shared_ptr< T > sp = t.lock(); - ar << boost::serialization::make_nvp("weak_ptr", sp); -} - -template -inline void load( - Archive & ar, - boost::weak_ptr< T > &t, - const unsigned int /* file_version */ -){ - boost::shared_ptr< T > sp; - ar >> boost::serialization::make_nvp("weak_ptr", sp); - t = sp; -} - -template -inline void serialize( - Archive & ar, - boost::weak_ptr< T > &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#ifndef BOOST_NO_CXX11_SMART_PTR -#include - -namespace boost { -namespace serialization{ - -template -inline void save( - Archive & ar, - const std::weak_ptr< T > &t, - const unsigned int /* file_version */ -){ - const std::shared_ptr< T > sp = t.lock(); - ar << boost::serialization::make_nvp("weak_ptr", sp); -} - -template -inline void load( - Archive & ar, - std::weak_ptr< T > &t, - const unsigned int /* file_version */ -){ - std::shared_ptr< T > sp; - ar >> boost::serialization::make_nvp("weak_ptr", sp); - t = sp; -} - -template -inline void serialize( - Archive & ar, - std::weak_ptr< T > &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_NO_CXX11_SMART_PTR - -#endif // BOOST_SERIALIZATION_WEAK_PTR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/wrapper.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/wrapper.hpp deleted file mode 100644 index 60d7910b17a..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/wrapper.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef BOOST_SERIALIZATION_WRAPPER_HPP -#define BOOST_SERIALIZATION_WRAPPER_HPP - -// (C) Copyright 2005-2006 Matthias Troyer -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include - -namespace boost { namespace serialization { - -/// the base class for serialization wrappers -/// -/// wrappers need to be treated differently at various places in the serialization library, -/// e.g. saving of non-const wrappers has to be possible. Since partial specialization -// is not supported by all compilers, we derive all wrappers from wrapper_traits. - -template< - class T, - int Level = object_serializable, - int Tracking = track_never, - unsigned int Version = 0, - class ETII = extended_type_info_impl< T > -> -struct wrapper_traits : - public traits -{}; - -template -struct is_wrapper_impl : - boost::mpl::eval_if< - boost::is_base_and_derived, - boost::mpl::true_, - boost::mpl::false_ - >::type -{}; - -template -struct is_wrapper { - typedef typename is_wrapper_impl::type type; -}; - -} // serialization -} // boost - -// A macro to define that a class is a wrapper -#define BOOST_CLASS_IS_WRAPPER(T) \ -namespace boost { \ -namespace serialization { \ -template<> \ -struct is_wrapper_impl : boost::mpl::true_ {}; \ -} \ -} \ -/**/ - -#endif //BOOST_SERIALIZATION_WRAPPER_HPP diff --git a/contrib/poco b/contrib/poco new file mode 160000 index 00000000000..29439cf7fa3 --- /dev/null +++ b/contrib/poco @@ -0,0 +1 @@ +Subproject commit 29439cf7fa32c1a2d62d925bb6d6a3f14668a4a2 diff --git a/contrib/zlib-ng b/contrib/zlib-ng new file mode 160000 index 00000000000..9173b89d467 --- /dev/null +++ b/contrib/zlib-ng @@ -0,0 +1 @@ +Subproject commit 9173b89d46799582d20a30578e0aa9788bc7d6e1 diff --git a/dbms/src/Storages/MergeTree/MergeTreeData.cpp b/dbms/src/Storages/MergeTree/MergeTreeData.cpp index 08b4bb752e5..d9313ac8442 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeData.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeData.cpp @@ -2266,8 +2266,6 @@ MergeTreeData::DataPartPtr MergeTreeData::getActiveContainingPart( { auto committed_parts_range = getDataPartsStateRange(state); - auto committed_parts_range = getDataPartsStateRange(DataPartState::Committed); - /// The part can be covered only by the previous or the next one in data_parts. auto it = data_parts_by_state_and_info.lower_bound(DataPartStateAndInfo{state, part_info}); @@ -2600,7 +2598,6 @@ MergeTreeData::getDetachedParts() const part.prefix = dir_name.substr(0, first_separator); } - return res; } From 2930965938f595933fbd88080c8c7f4a593d1970 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Thu, 6 Jun 2019 21:10:56 -0400 Subject: [PATCH 0117/1165] * Renaming live_view_heartbeat_delay setting to live_view_heartbeat_interval and making the setting to be in seconds instead of usec * Updated LIVE VIEW table to keep version consistent as long as the server is up * Removed calculation of hash in writeIntoLiveView method as it is recalculated in the LiveViewBlockOutputStream * Changed to using values from the local context for live_view_heartbeat_interval and temporary_live_view_timeout instead of the global context * Updated LIVE VIEW tests to match the changes --- dbms/src/Core/Defines.h | 2 +- dbms/src/Core/Settings.h | 2 +- .../DataStreams/LiveViewBlockInputStream.h | 15 +++-- .../LiveViewEventsBlockInputStream.h | 13 ++-- dbms/src/Storages/StorageLiveView.cpp | 18 +++--- dbms/src/Storages/StorageLiveView.h | 62 +++++++++---------- .../00956_live_view_watch_events.reference | 4 +- .../00957_live_view_watch.reference | 4 +- ...00959_create_temporary_live_view.reference | 2 +- .../00959_create_temporary_live_view.sql | 5 +- .../00961_temporary_live_view_watch.reference | 4 +- ..._temporary_live_view_watch_live_timeout.py | 14 ++--- .../00964_live_view_watch_events_heartbeat.py | 4 +- .../00965_live_view_watch_heartbeat.py | 4 +- 14 files changed, 82 insertions(+), 71 deletions(-) diff --git a/dbms/src/Core/Defines.h b/dbms/src/Core/Defines.h index 82e882d29f2..49d9d1e3a74 100644 --- a/dbms/src/Core/Defines.h +++ b/dbms/src/Core/Defines.h @@ -36,7 +36,7 @@ #define DEFAULT_TEMPORARY_LIVE_CHANNEL_TIMEOUT_SEC 15 #define DEFAULT_ALTER_LIVE_CHANNEL_WAIT_MS 10000 #define SHOW_CHARS_ON_SYNTAX_ERROR ptrdiff_t(160) -#define DEFAULT_HEARTBEAT_DELAY 15000000 +#define DEFAULT_LIVE_VIEW_HEARTBEAT_INTERVAL_SEC 15 #define DBMS_DEFAULT_DISTRIBUTED_CONNECTIONS_POOL_SIZE 1024 #define DBMS_CONNECTION_POOL_WITH_FAILOVER_DEFAULT_MAX_TRIES 3 /// each period reduces the error counter by 2 times diff --git a/dbms/src/Core/Settings.h b/dbms/src/Core/Settings.h index ae7f891a17d..3d9a06e5984 100644 --- a/dbms/src/Core/Settings.h +++ b/dbms/src/Core/Settings.h @@ -326,7 +326,7 @@ struct Settings : public SettingsCollection M(SettingBool, allow_simdjson, 1, "Allow using simdjson library in 'JSON*' functions if AVX2 instructions are available. If disabled rapidjson will be used.") \ \ M(SettingUInt64, max_partitions_per_insert_block, 100, "Limit maximum number of partitions in single INSERTed block. Zero means unlimited. Throw exception if the block contains too many partitions. This setting is a safety threshold, because using large number of partitions is a common misconception.") \ - M(SettingUInt64, heartbeat_delay, DEFAULT_HEARTBEAT_DELAY, "The interval in microseconds to indicate live query is alive.") \ + M(SettingSeconds, live_view_heartbeat_interval, DEFAULT_LIVE_VIEW_HEARTBEAT_INTERVAL_SEC, "The heartbeat interval in seconds to indicate live query is alive.") \ M(SettingSeconds, temporary_live_view_timeout, DEFAULT_TEMPORARY_LIVE_VIEW_TIMEOUT_SEC, "Timeout after which temporary live view is deleted.") \ M(SettingSeconds, temporary_live_channel_timeout, DEFAULT_TEMPORARY_LIVE_CHANNEL_TIMEOUT_SEC, "Timeout after which temporary live channel is deleted.") \ M(SettingMilliseconds, alter_channel_wait_ms, DEFAULT_ALTER_LIVE_CHANNEL_WAIT_MS, "The wait time for alter channel request.") diff --git a/dbms/src/DataStreams/LiveViewBlockInputStream.h b/dbms/src/DataStreams/LiveViewBlockInputStream.h index a6c9c3533ee..93eae976177 100644 --- a/dbms/src/DataStreams/LiveViewBlockInputStream.h +++ b/dbms/src/DataStreams/LiveViewBlockInputStream.h @@ -37,15 +37,17 @@ public: /// Start storage no users thread /// if we are the last active user if (!storage.is_dropped && blocks_ptr.use_count() < 3) - storage.startNoUsersThread(); + storage.startNoUsersThread(temporary_live_view_timeout); } /// length default -2 because we want LIMIT to specify number of updates so that LIMIT 1 waits for 1 update /// and LIMIT 0 just returns data without waiting for any updates LiveViewBlockInputStream(StorageLiveView & storage_, std::shared_ptr blocks_ptr_, std::shared_ptr blocks_metadata_ptr_, std::shared_ptr active_ptr_, Poco::Condition & condition_, Poco::FastMutex & mutex_, - int64_t length_, const UInt64 & heartbeat_delay_) - : storage(storage_), blocks_ptr(blocks_ptr_), blocks_metadata_ptr(blocks_metadata_ptr_), active_ptr(active_ptr_), condition(condition_), mutex(mutex_), length(length_ + 1), heartbeat_delay(heartbeat_delay_), blocks_hash("") + int64_t length_, const UInt64 & heartbeat_interval_, + const UInt64 & temporary_live_view_timeout_) + : storage(storage_), blocks_ptr(blocks_ptr_), blocks_metadata_ptr(blocks_metadata_ptr_), active_ptr(active_ptr_), condition(condition_), mutex(mutex_), length(length_ + 1), heartbeat_interval(heartbeat_interval_), temporary_live_view_timeout(temporary_live_view_timeout_), + blocks_hash("") { /// grab active pointer active = active_ptr.lock(); @@ -158,7 +160,9 @@ protected: } while (true) { - bool signaled = condition.tryWait(mutex, std::max((UInt64)0, heartbeat_delay - ((UInt64)timestamp.epochMicroseconds() - last_event_timestamp)) / 1000); + bool signaled = condition.tryWait(mutex, + std::max((UInt64)0, (heartbeat_interval * 1000000) - + ((UInt64)timestamp.epochMicroseconds() - last_event_timestamp)) / 1000); if (isCancelled() || storage.is_dropped) { @@ -211,7 +215,8 @@ private: /// Length specifies number of updates to send, default -1 (no limit) int64_t length; bool end_of_blocks{0}; - UInt64 heartbeat_delay; + UInt64 heartbeat_interval; + UInt64 temporary_live_view_timeout; String blocks_hash; UInt64 last_event_timestamp{0}; Poco::Timestamp timestamp; diff --git a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h index 32290c3333b..d0f92806d74 100644 --- a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h +++ b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h @@ -41,13 +41,13 @@ public: /// Start storage no users thread /// if we are the last active user if (!storage.is_dropped && blocks_ptr.use_count() < 3) - storage.startNoUsersThread(); + storage.startNoUsersThread(temporary_live_view_timeout); } /// length default -2 because we want LIMIT to specify number of updates so that LIMIT 1 waits for 1 update /// and LIMIT 0 just returns data without waiting for any updates LiveViewEventsBlockInputStream(StorageLiveView & storage_, std::shared_ptr blocks_ptr_, std::shared_ptr blocks_metadata_ptr_, std::shared_ptr active_ptr_, Poco::Condition & condition_, Poco::FastMutex & mutex_, - int64_t length_, const UInt64 & heartbeat_delay_) - : storage(storage_), blocks_ptr(blocks_ptr_), blocks_metadata_ptr(blocks_metadata_ptr_), active_ptr(active_ptr_), condition(condition_), mutex(mutex_), length(length_ + 1), heartbeat_delay(heartbeat_delay_) + int64_t length_, const UInt64 & heartbeat_interval_, const UInt64 & temporary_live_view_timeout_) + : storage(storage_), blocks_ptr(blocks_ptr_), blocks_metadata_ptr(blocks_metadata_ptr_), active_ptr(active_ptr_), condition(condition_), mutex(mutex_), length(length_ + 1), heartbeat_interval(heartbeat_interval_), temporary_live_view_timeout(temporary_live_view_timeout_) { /// grab active pointer active = active_ptr.lock(); @@ -188,7 +188,9 @@ protected: } while (true) { - bool signaled = condition.tryWait(mutex, std::max((UInt64)0, heartbeat_delay - ((UInt64)timestamp.epochMicroseconds() - last_event_timestamp)) / 1000); + bool signaled = condition.tryWait(mutex, + std::max((UInt64)0, (heartbeat_interval * 1000000) - + ((UInt64)timestamp.epochMicroseconds() - last_event_timestamp)) / 1000); if (isCancelled() || storage.is_dropped) { @@ -241,7 +243,8 @@ private: /// Length specifies number of updates to send, default -1 (no limit) int64_t length; bool end_of_blocks{0}; - UInt64 heartbeat_delay; + UInt64 heartbeat_interval; + UInt64 temporary_live_view_timeout; UInt64 last_event_timestamp{0}; Poco::Timestamp timestamp; }; diff --git a/dbms/src/Storages/StorageLiveView.cpp b/dbms/src/Storages/StorageLiveView.cpp index 77578bc386d..108e146dc73 100644 --- a/dbms/src/Storages/StorageLiveView.cpp +++ b/dbms/src/Storages/StorageLiveView.cpp @@ -132,6 +132,7 @@ StorageLiveView::StorageLiveView( DatabaseAndTableName(database_name, table_name)); is_temporary = query.temporary; + temporary_live_view_timeout = local_context.getSettingsRef().temporary_live_view_timeout.totalSeconds(); blocks_ptr = std::make_shared(); blocks_metadata_ptr = std::make_shared(); @@ -235,7 +236,7 @@ void StorageLiveView::checkTableCanBeDropped() const } } -void StorageLiveView::noUsersThread() +void StorageLiveView::noUsersThread(const UInt64 & timeout) { if (shutdown_called) return; @@ -246,7 +247,8 @@ void StorageLiveView::noUsersThread() while (1) { Poco::FastMutex::ScopedLock lock(noUsersThreadMutex); - if (!noUsersThreadWakeUp && !noUsersThreadCondition.tryWait(noUsersThreadMutex, global_context.getSettingsRef().temporary_live_view_timeout.totalSeconds() * 1000)) + if (!noUsersThreadWakeUp && !noUsersThreadCondition.tryWait(noUsersThreadMutex, + timeout * 1000)) { noUsersThreadWakeUp = false; if (shutdown_called) @@ -283,7 +285,7 @@ void StorageLiveView::noUsersThread() } } -void StorageLiveView::startNoUsersThread() +void StorageLiveView::startNoUsersThread(const UInt64 & timeout) { bool expected = false; if (!startnousersthread_called.compare_exchange_strong(expected, true)) @@ -308,14 +310,14 @@ void StorageLiveView::startNoUsersThread() noUsersThreadWakeUp = false; } if (!is_dropped) - no_users_thread = std::thread(&StorageLiveView::noUsersThread, this); + no_users_thread = std::thread(&StorageLiveView::noUsersThread, this, timeout); } startnousersthread_called = false; } void StorageLiveView::startup() { - startNoUsersThread(); + startNoUsersThread(temporary_live_view_timeout); } void StorageLiveView::shutdown() @@ -400,7 +402,8 @@ BlockInputStreams StorageLiveView::watch( if (query.is_watch_events) { - auto reader = std::make_shared(*this, blocks_ptr, blocks_metadata_ptr, active_ptr, condition, mutex, length, context.getSettingsRef().heartbeat_delay); + auto reader = std::make_shared(*this, blocks_ptr, blocks_metadata_ptr, active_ptr, condition, mutex, length, context.getSettingsRef().live_view_heartbeat_interval.totalSeconds(), + context.getSettingsRef().temporary_live_view_timeout.totalSeconds()); if (no_users_thread.joinable()) { @@ -424,7 +427,8 @@ BlockInputStreams StorageLiveView::watch( } else { - auto reader = std::make_shared(*this, blocks_ptr, blocks_metadata_ptr, active_ptr, condition, mutex, length, context.getSettingsRef().heartbeat_delay); + auto reader = std::make_shared(*this, blocks_ptr, blocks_metadata_ptr, active_ptr, condition, mutex, length, context.getSettingsRef().live_view_heartbeat_interval.totalSeconds(), + context.getSettingsRef().temporary_live_view_timeout.totalSeconds()); if (no_users_thread.joinable()) { diff --git a/dbms/src/Storages/StorageLiveView.h b/dbms/src/Storages/StorageLiveView.h index bb4377fbed6..37faee4b266 100644 --- a/dbms/src/Storages/StorageLiveView.h +++ b/dbms/src/Storages/StorageLiveView.h @@ -84,7 +84,7 @@ public: } /// Background thread for temporary tables /// which drops this table if there are no users - void startNoUsersThread(); + void startNoUsersThread(const UInt64 & timeout); Poco::FastMutex noUsersThreadMutex; bool noUsersThreadWakeUp{false}; Poco::Condition noUsersThreadCondition; @@ -110,7 +110,8 @@ public: void reset() { (*blocks_ptr).reset(); - (*blocks_metadata_ptr).reset(); + if (*blocks_metadata_ptr) + (*blocks_metadata_ptr)->hash.clear(); mergeable_blocks.reset(); } @@ -163,8 +164,6 @@ public: } } - SipHash hash; - UInt128 key; BlockInputStreams from; BlocksPtr blocks = std::make_shared(); BlocksPtrs mergeable_blocks; @@ -234,22 +233,13 @@ public: while (Block this_block = data->read()) { - this_block.updateHash(hash); blocks->push_back(this_block); } - /// get hash key - hash.get128(key.low, key.high); - /// Update blocks only if hash keys do not match - /// NOTE: hash could be different for the same result - /// if blocks are not in the same order - if (live_view.getBlocksHashKey() != key.toHexString()) - { - auto sample_block = blocks->front().cloneEmpty(); - BlockInputStreamPtr new_data = std::make_shared(std::make_shared(blocks), sample_block); - { - copyData(*new_data, *output); - } - } + + auto sample_block = blocks->front().cloneEmpty(); + BlockInputStreamPtr new_data = std::make_shared(std::make_shared(blocks), sample_block); + + copyData(*new_data, *output); } private: @@ -272,10 +262,11 @@ private: BlocksMetadataPtr new_blocks_metadata; BlocksPtrs mergeable_blocks; - void noUsersThread(); + void noUsersThread(const UInt64 & timeout); std::thread no_users_thread; std::atomic shutdown_called{false}; std::atomic startnousersthread_called{false}; + UInt64 temporary_live_view_timeout; StorageLiveView( const String & table_name_, @@ -300,29 +291,36 @@ public: void writeSuffix() override { - Poco::FastMutex::ScopedLock lock(storage.mutex); UInt128 key; + String key_str; new_hash->get128(key.low, key.high); - new_blocks_metadata->hash = key.toHexString(); - new_blocks_metadata->version = storage.getBlocksVersion() + 1; + key_str = key.toHexString(); - for (auto & block : *new_blocks) + Poco::FastMutex::ScopedLock lock(storage.mutex); + + if (storage.getBlocksHashKey() != key_str) { - block.insert({DataTypeUInt64().createColumnConst( - block.rows(), new_blocks_metadata->version)->convertToFullColumnIfConst(), - std::make_shared(), - "_version"}); - } + new_blocks_metadata->hash = key_str; + new_blocks_metadata->version = storage.getBlocksVersion() + 1; - (*storage.blocks_ptr) = new_blocks; - (*storage.blocks_metadata_ptr) = new_blocks_metadata; + for (auto & block : *new_blocks) + { + block.insert({DataTypeUInt64().createColumnConst( + block.rows(), new_blocks_metadata->version)->convertToFullColumnIfConst(), + std::make_shared(), + "_version"}); + } + + (*storage.blocks_ptr) = new_blocks; + (*storage.blocks_metadata_ptr) = new_blocks_metadata; + + storage.condition.broadcast(); + } new_blocks.reset(); new_blocks_metadata.reset(); new_hash.reset(); - - storage.condition.broadcast(); } void write(const Block & block) override diff --git a/dbms/tests/queries/0_stateless/00956_live_view_watch_events.reference b/dbms/tests/queries/0_stateless/00956_live_view_watch_events.reference index 86a72083821..b67c49182e9 100644 --- a/dbms/tests/queries/0_stateless/00956_live_view_watch_events.reference +++ b/dbms/tests/queries/0_stateless/00956_live_view_watch_events.reference @@ -1,4 +1,4 @@ lv 1 c9d39b11cce79112219a73aaa319b475 -1 4cd0592103888d4682de9a32a23602e3 -1 2186dbea325ee4c56b67e9b792e993a3 +2 4cd0592103888d4682de9a32a23602e3 +3 2186dbea325ee4c56b67e9b792e993a3 diff --git a/dbms/tests/queries/0_stateless/00957_live_view_watch.reference b/dbms/tests/queries/0_stateless/00957_live_view_watch.reference index 69a461b3fc4..65500578a69 100644 --- a/dbms/tests/queries/0_stateless/00957_live_view_watch.reference +++ b/dbms/tests/queries/0_stateless/00957_live_view_watch.reference @@ -1,4 +1,4 @@ lv 0 1 -6 1 -21 1 +6 2 +21 3 diff --git a/dbms/tests/queries/0_stateless/00959_create_temporary_live_view.reference b/dbms/tests/queries/0_stateless/00959_create_temporary_live_view.reference index 4bd209d4424..49d86fc2fbf 100644 --- a/dbms/tests/queries/0_stateless/00959_create_temporary_live_view.reference +++ b/dbms/tests/queries/0_stateless/00959_create_temporary_live_view.reference @@ -1,4 +1,4 @@ temporary_live_view_timeout 5 +live_view_heartbeat_interval 15 lv 0 -0 diff --git a/dbms/tests/queries/0_stateless/00959_create_temporary_live_view.sql b/dbms/tests/queries/0_stateless/00959_create_temporary_live_view.sql index 4a4a7ae5eed..c0625324bb6 100644 --- a/dbms/tests/queries/0_stateless/00959_create_temporary_live_view.sql +++ b/dbms/tests/queries/0_stateless/00959_create_temporary_live_view.sql @@ -2,13 +2,14 @@ DROP TABLE IF EXISTS test.lv; DROP TABLE IF EXISTS test.mt; SELECT name, value from system.settings WHERE name = 'temporary_live_view_timeout'; +SELECT name, value from system.settings WHERE name = 'live_view_heartbeat_interval'; +SET temporary_live_view_timeout=1; CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple(); CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt; SHOW TABLES LIKE 'lv'; -SELECT sleep(3); -SELECT sleep(2); +SELECT sleep(1); SHOW TABLES LIKE 'lv'; DROP TABLE test.mt; diff --git a/dbms/tests/queries/0_stateless/00961_temporary_live_view_watch.reference b/dbms/tests/queries/0_stateless/00961_temporary_live_view_watch.reference index 69a461b3fc4..65500578a69 100644 --- a/dbms/tests/queries/0_stateless/00961_temporary_live_view_watch.reference +++ b/dbms/tests/queries/0_stateless/00961_temporary_live_view_watch.reference @@ -1,4 +1,4 @@ lv 0 1 -6 1 -21 1 +6 2 +21 3 diff --git a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py index 43bf748dc2b..29ec01c724a 100755 --- a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py +++ b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py @@ -26,30 +26,26 @@ client2.expect(prompt) client1.send('DROP TABLE IF EXISTS test.lv') client1.expect(prompt) -client1.send(' DROP TABLE IF EXISTS test.mt') +client1.send('DROP TABLE IF EXISTS test.mt') +client1.expect(prompt) +client1.send('SET temporary_live_view_timeout=1') client1.expect(prompt) client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') client1.expect(prompt) client1.send('CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') client1.expect(prompt) -client1.send('SELECT 4') -client1.expect(prompt, timeout=4) client1.send('WATCH test.lv') client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') client2.expect(prompt) client1.expect(r'6.*2' + end_of_block) -client2.send('SELECT sleep(3)') -client2.expect(prompt, timeout=4) client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') client2.expect(prompt) client1.expect(r'21.*3' + end_of_block) # send Ctrl-C os.kill(client1.process.pid,signal.SIGINT) client1.expect(prompt) -client1.send('SELECT sleep(3)') -client1.expect(prompt, timeout=4) -client1.send('SELECT sleep(3)') -client1.expect(prompt, timeout=4) +client1.send('SELECT sleep(1)') +client1.expect(prompt) client1.send('DROP TABLE test.lv') client1.expect('Table test.lv doesn\'t exist') client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py index 9d4f1d0716c..cbb659f1292 100755 --- a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py @@ -28,6 +28,8 @@ client1.send('DROP TABLE IF EXISTS test.lv') client1.expect(prompt) client1.send(' DROP TABLE IF EXISTS test.mt') client1.expect(prompt) +client1.send('SET live_view_heartbeat_interval=1') +client1.expect(prompt) client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') client1.expect(prompt) client1.send('CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') @@ -37,7 +39,7 @@ client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') client1.expect('2.*4cd0592103888d4682de9a32a23602e3' + end_of_block) client1.expect('Progress: 2.00 rows.*\)') # wait for heartbeat -client1.expect('Progress: 2.00 rows.*\)', timeout=15) +client1.expect('Progress: 2.00 rows.*\)') # send Ctrl-C os.kill(client1.process.pid,signal.SIGINT) client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py b/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py index cafbcd833b1..c596d169e1c 100755 --- a/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py @@ -28,6 +28,8 @@ client1.send('DROP TABLE IF EXISTS test.lv') client1.expect(prompt) client1.send(' DROP TABLE IF EXISTS test.mt') client1.expect(prompt) +client1.send('SET live_view_heartbeat_interval=1') +client1.expect(prompt) client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') client1.expect(prompt) client1.send('CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') @@ -37,7 +39,7 @@ client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') client1.expect(r'6.*2' + end_of_block) client1.expect('Progress: 2.00 rows.*\)') # wait for heartbeat -client1.expect('Progress: 2.00 rows.*\)', timeout=15) +client1.expect('Progress: 2.00 rows.*\)') # send Ctrl-C os.kill(client1.process.pid,signal.SIGINT) client1.expect(prompt) From aa3ef47aab0a3fa2546604da2dec6801b230d055 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Fri, 7 Jun 2019 09:05:14 -0400 Subject: [PATCH 0118/1165] * Adding JSONEachRowWithProgress format that can be used with WATCH queries when HTTP connection is used in this case progress events are used as a heartbeat * Adding new tests that use JSONEachRowWithProgress format * Adding tests for WATCH query heartbeats when HTTP connection is used * Small fixes to uexpect.py --- dbms/src/Formats/FormatFactory.cpp | 2 + dbms/src/Formats/JSONEachRowRowOutputStream.h | 2 +- ...JSONEachRowWithProgressRowOutputStream.cpp | 47 +++++++++++++++ .../JSONEachRowWithProgressRowOutputStream.h | 27 +++++++++ .../00959_create_temporary_live_view.sql | 2 +- ...t_format_jsoneachrowwithprogress.reference | 5 ++ ..._select_format_jsoneachrowwithprogress.sql | 14 +++++ ...h_format_jsoneachrowwithprogress.reference | 7 +++ ...w_watch_format_jsoneachrowwithprogress.sql | 20 +++++++ ...70_live_view_watch_events_http_hearbeat.py | 57 +++++++++++++++++++ ..._view_watch_events_http_hearbeat.reference | 0 .../00971_live_view_watch_http_hearbeat.py | 57 +++++++++++++++++++ ...71_live_view_watch_http_hearbeat.reference | 0 dbms/tests/queries/0_stateless/uexpect.py | 10 +++- 14 files changed, 245 insertions(+), 5 deletions(-) create mode 100644 dbms/src/Formats/JSONEachRowWithProgressRowOutputStream.cpp create mode 100644 dbms/src/Formats/JSONEachRowWithProgressRowOutputStream.h create mode 100644 dbms/tests/queries/0_stateless/00968_live_view_select_format_jsoneachrowwithprogress.reference create mode 100644 dbms/tests/queries/0_stateless/00968_live_view_select_format_jsoneachrowwithprogress.sql create mode 100644 dbms/tests/queries/0_stateless/00969_live_view_watch_format_jsoneachrowwithprogress.reference create mode 100644 dbms/tests/queries/0_stateless/00969_live_view_watch_format_jsoneachrowwithprogress.sql create mode 100755 dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_hearbeat.py create mode 100644 dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_hearbeat.reference create mode 100755 dbms/tests/queries/0_stateless/00971_live_view_watch_http_hearbeat.py create mode 100644 dbms/tests/queries/0_stateless/00971_live_view_watch_http_hearbeat.reference diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index d5718278554..4357b324ac7 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -113,6 +113,7 @@ void registerInputFormatTSKV(FormatFactory & factory); void registerOutputFormatTSKV(FormatFactory & factory); void registerInputFormatJSONEachRow(FormatFactory & factory); void registerOutputFormatJSONEachRow(FormatFactory & factory); +void registerOutputFormatJSONEachRowWithProgress(FormatFactory & factory); void registerInputFormatParquet(FormatFactory & factory); void registerOutputFormatParquet(FormatFactory & factory); void registerInputFormatProtobuf(FormatFactory & factory); @@ -153,6 +154,7 @@ FormatFactory::FormatFactory() registerOutputFormatTSKV(*this); registerInputFormatJSONEachRow(*this); registerOutputFormatJSONEachRow(*this); + registerOutputFormatJSONEachRowWithProgress(*this); registerInputFormatProtobuf(*this); registerOutputFormatProtobuf(*this); registerInputFormatCapnProto(*this); diff --git a/dbms/src/Formats/JSONEachRowRowOutputStream.h b/dbms/src/Formats/JSONEachRowRowOutputStream.h index 4f2dc690aed..7d0d410b219 100644 --- a/dbms/src/Formats/JSONEachRowRowOutputStream.h +++ b/dbms/src/Formats/JSONEachRowRowOutputStream.h @@ -27,7 +27,7 @@ public: ostr.next(); } -private: +protected: WriteBuffer & ostr; size_t field_number = 0; Names fields; diff --git a/dbms/src/Formats/JSONEachRowWithProgressRowOutputStream.cpp b/dbms/src/Formats/JSONEachRowWithProgressRowOutputStream.cpp new file mode 100644 index 00000000000..4f59e99ff6d --- /dev/null +++ b/dbms/src/Formats/JSONEachRowWithProgressRowOutputStream.cpp @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include + + +namespace DB +{ + + +void JSONEachRowWithProgressRowOutputStream::writeRowStartDelimiter() +{ + writeCString("{\"row\":{", ostr); +} + + +void JSONEachRowWithProgressRowOutputStream::writeRowEndDelimiter() +{ + writeCString("}}\n", ostr); + field_number = 0; +} + + +void JSONEachRowWithProgressRowOutputStream::onProgress(const Progress & value) +{ + progress.incrementPiecewiseAtomically(value); + writeCString("{\"progress\":", ostr); + progress.writeJSON(ostr); + writeCString("}\n", ostr); +} + + +void registerOutputFormatJSONEachRowWithProgress(FormatFactory & factory) +{ + factory.registerOutputFormat("JSONEachRowWithProgress", []( + WriteBuffer & buf, + const Block & sample, + const Context &, + const FormatSettings & format_settings) + { + return std::make_shared( + std::make_shared(buf, sample, format_settings), sample); + }); +} + +} diff --git a/dbms/src/Formats/JSONEachRowWithProgressRowOutputStream.h b/dbms/src/Formats/JSONEachRowWithProgressRowOutputStream.h new file mode 100644 index 00000000000..e8cef8e147b --- /dev/null +++ b/dbms/src/Formats/JSONEachRowWithProgressRowOutputStream.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + + +namespace DB +{ + +/** The stream for outputting data in JSON format, by object per line + * that includes progress rows. Does not validate UTF-8. + */ +class JSONEachRowWithProgressRowOutputStream : public JSONEachRowRowOutputStream +{ +public: + using JSONEachRowRowOutputStream::JSONEachRowRowOutputStream; + + void writeRowStartDelimiter() override; + void writeRowEndDelimiter() override; + void onProgress(const Progress & value) override; + +private: + Progress progress; +}; + +} + diff --git a/dbms/tests/queries/0_stateless/00959_create_temporary_live_view.sql b/dbms/tests/queries/0_stateless/00959_create_temporary_live_view.sql index c0625324bb6..8cd6ee06ace 100644 --- a/dbms/tests/queries/0_stateless/00959_create_temporary_live_view.sql +++ b/dbms/tests/queries/0_stateless/00959_create_temporary_live_view.sql @@ -9,7 +9,7 @@ CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple(); CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt; SHOW TABLES LIKE 'lv'; -SELECT sleep(1); +SELECT sleep(2); SHOW TABLES LIKE 'lv'; DROP TABLE test.mt; diff --git a/dbms/tests/queries/0_stateless/00968_live_view_select_format_jsoneachrowwithprogress.reference b/dbms/tests/queries/0_stateless/00968_live_view_select_format_jsoneachrowwithprogress.reference new file mode 100644 index 00000000000..0f6a0405cda --- /dev/null +++ b/dbms/tests/queries/0_stateless/00968_live_view_select_format_jsoneachrowwithprogress.reference @@ -0,0 +1,5 @@ +lv +{"row":{"a":1}} +{"row":{"a":2}} +{"row":{"a":3}} +{"progress":{"read_rows":"3","read_bytes":"36","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}} diff --git a/dbms/tests/queries/0_stateless/00968_live_view_select_format_jsoneachrowwithprogress.sql b/dbms/tests/queries/0_stateless/00968_live_view_select_format_jsoneachrowwithprogress.sql new file mode 100644 index 00000000000..748d901b3bf --- /dev/null +++ b/dbms/tests/queries/0_stateless/00968_live_view_select_format_jsoneachrowwithprogress.sql @@ -0,0 +1,14 @@ +DROP TABLE IF EXISTS test.lv; +DROP TABLE IF EXISTS test.mt; + +CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple(); +CREATE LIVE VIEW test.lv AS SELECT * FROM test.mt; + +SHOW TABLES LIKE 'lv'; + +INSERT INTO test.mt VALUES (1),(2),(3); + +SELECT * FROM test.lv FORMAT JSONEachRowWithProgress; + +DROP TABLE test.lv; +DROP TABLE test.mt; diff --git a/dbms/tests/queries/0_stateless/00969_live_view_watch_format_jsoneachrowwithprogress.reference b/dbms/tests/queries/0_stateless/00969_live_view_watch_format_jsoneachrowwithprogress.reference new file mode 100644 index 00000000000..8510bebad77 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00969_live_view_watch_format_jsoneachrowwithprogress.reference @@ -0,0 +1,7 @@ +lv +{"row":{"sum(a)":"0","_version":"1"}} +{"progress":{"read_rows":"1","read_bytes":"16","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}} +{"row":{"sum(a)":"6","_version":"2"}} +{"progress":{"read_rows":"1","read_bytes":"16","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}} +{"row":{"sum(a)":"21","_version":"3"}} +{"progress":{"read_rows":"1","read_bytes":"16","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}} diff --git a/dbms/tests/queries/0_stateless/00969_live_view_watch_format_jsoneachrowwithprogress.sql b/dbms/tests/queries/0_stateless/00969_live_view_watch_format_jsoneachrowwithprogress.sql new file mode 100644 index 00000000000..9f2e0384dd8 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00969_live_view_watch_format_jsoneachrowwithprogress.sql @@ -0,0 +1,20 @@ +DROP TABLE IF EXISTS test.lv; +DROP TABLE IF EXISTS test.mt; + +CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple(); +CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt; + +SHOW TABLES LIKE 'lv'; + +WATCH test.lv LIMIT 0 FORMAT JSONEachRowWithProgress; + +INSERT INTO test.mt VALUES (1),(2),(3); + +WATCH test.lv LIMIT 0 FORMAT JSONEachRowWithProgress; + +INSERT INTO test.mt VALUES (4),(5),(6); + +WATCH test.lv LIMIT 0 FORMAT JSONEachRowWithProgress; + +DROP TABLE test.lv; +DROP TABLE test.mt; diff --git a/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_hearbeat.py b/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_hearbeat.py new file mode 100755 index 00000000000..1021edd7769 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_hearbeat.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +import imp +import os +import sys +import signal + +CURDIR = os.path.dirname(os.path.realpath(__file__)) + +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'uexpect.py')) + +def client(name='', command=None): + if command is None: + client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) + else: + client = uexpect.spawn(command) + client.eol('\r') + # Note: uncomment this line for debugging + #client.logger(sys.stdout, prefix=name) + client.timeout(2) + return client + +prompt = ':\) ' +end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' +client1 = client('client1>') +client1.expect(prompt) + +client1.send('DROP TABLE IF EXISTS test.lv') +client1.expect(prompt) +client1.send(' DROP TABLE IF EXISTS test.mt') +client1.expect(prompt) +client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') +client1.expect(prompt) +client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') +client1.expect(prompt) + +client2 = client('client2>', ['bash', '--noediting']) +client2.expect('\$ ') +client2.send('wget -O- -q "http://localhost:8123/?live_view_heartbeat_interval=1&query=WATCH test.lv EVENTS FORMAT JSONEachRowWithProgress"') +client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}\r\n', escape=True) +client2.expect('{"row":{"version":"1","hash":"c9d39b11cce79112219a73aaa319b475"}}', escape=True) +client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}', escape=True) +# heartbeat is provided by progress message +client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}', escape=True) + +client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') +client1.expect(prompt) + +client2.expect('{"row":{"version":"2","hash":"4cd0592103888d4682de9a32a23602e3"}}\r\n', escape=True) + +client2.expect('.*2\t.*\r\n') +## send Ctrl-C +os.kill(client2.process.pid,signal.SIGINT) + +client1.send('DROP TABLE test.lv') +client1.expect(prompt) +client1.send('DROP TABLE test.mt') +client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_hearbeat.reference b/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_hearbeat.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dbms/tests/queries/0_stateless/00971_live_view_watch_http_hearbeat.py b/dbms/tests/queries/0_stateless/00971_live_view_watch_http_hearbeat.py new file mode 100755 index 00000000000..33c937de649 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00971_live_view_watch_http_hearbeat.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +import imp +import os +import sys +import signal + +CURDIR = os.path.dirname(os.path.realpath(__file__)) + +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'uexpect.py')) + +def client(name='', command=None): + if command is None: + client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) + else: + client = uexpect.spawn(command) + client.eol('\r') + # Note: uncomment this line for debugging + #client.logger(sys.stdout, prefix=name) + client.timeout(2) + return client + +prompt = ':\) ' +end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' +client1 = client('client1>') +client1.expect(prompt) + +client1.send('DROP TABLE IF EXISTS test.lv') +client1.expect(prompt) +client1.send(' DROP TABLE IF EXISTS test.mt') +client1.expect(prompt) +client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') +client1.expect(prompt) +client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') +client1.expect(prompt) + +client2 = client('client2>', ['bash', '--noediting']) +client2.expect('\$ ') +client2.send('wget -O- -q "http://localhost:8123/?live_view_heartbeat_interval=1&query=WATCH test.lv FORMAT JSONEachRowWithProgress"') +client2.expect('"progress".*',) +client2.expect('{"row":{"sum(a)":"0","_version":"1"}}\r\n', escape=True) +client2.expect('"progress".*\r\n') +# heartbeat is provided by progress message +client2.expect('"progress".*\r\n') + +client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') +client1.expect(prompt) + +client2.expect('"progress".*"read_rows":"2".*\r\n') +client2.expect('{"row":{"sum(a)":"6","_version":"2"}}\r\n', escape=True) + +## send Ctrl-C +os.kill(client2.process.pid,signal.SIGINT) + +client1.send('DROP TABLE test.lv') +client1.expect(prompt) +client1.send('DROP TABLE test.mt') +client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00971_live_view_watch_http_hearbeat.reference b/dbms/tests/queries/0_stateless/00971_live_view_watch_http_hearbeat.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dbms/tests/queries/0_stateless/uexpect.py b/dbms/tests/queries/0_stateless/uexpect.py index 412facb8389..f94a97addcc 100644 --- a/dbms/tests/queries/0_stateless/uexpect.py +++ b/dbms/tests/queries/0_stateless/uexpect.py @@ -132,7 +132,7 @@ class IO(object): self.buffer = self.buffer[self.match.end():] break if self._logger: - self._logger.write(self.before + self.after) + self._logger.write((self.before or '') + (self.after or '')) self._logger.flush() return self.match @@ -159,14 +159,18 @@ def spawn(command): os.close(slave) queue = Queue() - thread = Thread(target=reader, args=(master, queue)) + thread = Thread(target=reader, args=(process, master, queue)) thread.daemon = True thread.start() return IO(process, master, queue) -def reader(out, queue): +def reader(process, out, queue): while True: + if process.poll() is not None: + data = os.read(out) + queue.put(data) + break data = os.read(out, 65536) queue.put(data) From 4b68ffb15b0714372666bb46e86306227db3c436 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Fri, 7 Jun 2019 12:43:37 -0400 Subject: [PATCH 0119/1165] * Fixing typos in test names --- ...hearbeat.py => 00970_live_view_watch_events_http_heartbeat.py} | 0 ...ence => 00970_live_view_watch_events_http_heartbeat.reference} | 0 ...h_http_hearbeat.py => 00971_live_view_watch_http_heartbeat.py} | 0 ...t.reference => 00971_live_view_watch_http_heartbeat.reference} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename dbms/tests/queries/0_stateless/{00970_live_view_watch_events_http_hearbeat.py => 00970_live_view_watch_events_http_heartbeat.py} (100%) rename dbms/tests/queries/0_stateless/{00970_live_view_watch_events_http_hearbeat.reference => 00970_live_view_watch_events_http_heartbeat.reference} (100%) rename dbms/tests/queries/0_stateless/{00971_live_view_watch_http_hearbeat.py => 00971_live_view_watch_http_heartbeat.py} (100%) rename dbms/tests/queries/0_stateless/{00971_live_view_watch_http_hearbeat.reference => 00971_live_view_watch_http_heartbeat.reference} (100%) diff --git a/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_hearbeat.py b/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py similarity index 100% rename from dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_hearbeat.py rename to dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py diff --git a/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_hearbeat.reference b/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.reference similarity index 100% rename from dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_hearbeat.reference rename to dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.reference diff --git a/dbms/tests/queries/0_stateless/00971_live_view_watch_http_hearbeat.py b/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py similarity index 100% rename from dbms/tests/queries/0_stateless/00971_live_view_watch_http_hearbeat.py rename to dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py diff --git a/dbms/tests/queries/0_stateless/00971_live_view_watch_http_hearbeat.reference b/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.reference similarity index 100% rename from dbms/tests/queries/0_stateless/00971_live_view_watch_http_hearbeat.reference rename to dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.reference From 5079180595678bf5a92e35a16e292db99b80a285 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Sat, 8 Jun 2019 09:26:02 -0400 Subject: [PATCH 0120/1165] * Fixing a bug in LIVE VIEW tables. Before when a table is created with "AS SELECT 1" the SELECT and WATCH queries would fail * Adding and updating LIVE VIEW tests to increase coverage --- dbms/src/Storages/IStorage.h | 4 ++-- dbms/src/Storages/ProxyStorage.h | 2 ++ .../0_stateless/00953_live_view_select.reference | 7 ++++--- .../queries/0_stateless/00953_live_view_select.sql | 10 ++++++++-- .../0_stateless/00972_live_view_select_1.reference | 2 ++ .../queries/0_stateless/00972_live_view_select_1.sql | 5 +++++ 6 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00972_live_view_select_1.reference create mode 100644 dbms/tests/queries/0_stateless/00972_live_view_select_1.sql diff --git a/dbms/src/Storages/IStorage.h b/dbms/src/Storages/IStorage.h index 96b0dbd63ab..a617db6a8ad 100644 --- a/dbms/src/Storages/IStorage.h +++ b/dbms/src/Storages/IStorage.h @@ -82,8 +82,8 @@ public: public: /// thread-unsafe part. lockStructure must be acquired - const ColumnsDescription & getColumns() const; - void setColumns(ColumnsDescription columns_); + virtual const ColumnsDescription & getColumns() const; + virtual void setColumns(ColumnsDescription columns_); const IndicesDescription & getIndices() const; void setIndices(IndicesDescription indices_); diff --git a/dbms/src/Storages/ProxyStorage.h b/dbms/src/Storages/ProxyStorage.h index a4196b7d6f2..3e6926eb323 100644 --- a/dbms/src/Storages/ProxyStorage.h +++ b/dbms/src/Storages/ProxyStorage.h @@ -47,6 +47,8 @@ public: Names getColumnsRequiredForSampling() const override { return storage->getColumnsRequiredForSampling(); } Names getColumnsRequiredForFinal() const override { return storage->getColumnsRequiredForFinal(); } + const ColumnsDescription & getColumns() const override { return storage->getColumns(); } + void setColumns(ColumnsDescription columns_) override { return storage->setColumns(columns_); } NameAndTypePair getColumn(const String & column_name) const override { return storage->getColumn(column_name); } bool hasColumn(const String & column_name) const override { return storage->hasColumn(column_name); } static StoragePtr createProxyStorage(StoragePtr storage, BlockInputStreams streams, QueryProcessingStage::Enum to_stage) diff --git a/dbms/tests/queries/0_stateless/00953_live_view_select.reference b/dbms/tests/queries/0_stateless/00953_live_view_select.reference index 9c44fe02ff1..7beda18cd83 100644 --- a/dbms/tests/queries/0_stateless/00953_live_view_select.reference +++ b/dbms/tests/queries/0_stateless/00953_live_view_select.reference @@ -1,4 +1,5 @@ lv -1 -2 -3 +6 1 +6 1 +12 2 +12 2 diff --git a/dbms/tests/queries/0_stateless/00953_live_view_select.sql b/dbms/tests/queries/0_stateless/00953_live_view_select.sql index a51dfb112c1..492fa265b7d 100644 --- a/dbms/tests/queries/0_stateless/00953_live_view_select.sql +++ b/dbms/tests/queries/0_stateless/00953_live_view_select.sql @@ -2,13 +2,19 @@ DROP TABLE IF EXISTS test.lv; DROP TABLE IF EXISTS test.mt; CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple(); -CREATE LIVE VIEW test.lv AS SELECT * FROM test.mt; +CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt; SHOW TABLES LIKE 'lv'; INSERT INTO test.mt VALUES (1),(2),(3); -SELECT * FROM test.lv; +SELECT *,_version FROM test.lv; +SELECT *,_version FROM test.lv; + +INSERT INTO test.mt VALUES (1),(2),(3); + +SELECT *,_version FROM test.lv; +SELECT *,_version FROM test.lv; DROP TABLE test.lv; DROP TABLE test.mt; diff --git a/dbms/tests/queries/0_stateless/00972_live_view_select_1.reference b/dbms/tests/queries/0_stateless/00972_live_view_select_1.reference new file mode 100644 index 00000000000..f2f8c69d020 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00972_live_view_select_1.reference @@ -0,0 +1,2 @@ +lv +1 diff --git a/dbms/tests/queries/0_stateless/00972_live_view_select_1.sql b/dbms/tests/queries/0_stateless/00972_live_view_select_1.sql new file mode 100644 index 00000000000..01bfeb08fd5 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00972_live_view_select_1.sql @@ -0,0 +1,5 @@ +DROP TABLE IF EXISTS test.lv; +CREATE LIVE VIEW test.lv AS SELECT 1; +SHOW TABLES LIKE 'lv'; +SELECT * FROM test.lv; +DROP TABLE test.lv; From 137f5127ac3fc83b1322dfbe7fd71d0a6f8c0465 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Sat, 8 Jun 2019 09:54:48 -0400 Subject: [PATCH 0121/1165] * Renaming 00953_live_view_select test to avoid test number conflict --- ...ive_view_select.reference => 00973_live_view_select.reference} | 0 .../{00953_live_view_select.sql => 00973_live_view_select.sql} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename dbms/tests/queries/0_stateless/{00953_live_view_select.reference => 00973_live_view_select.reference} (100%) rename dbms/tests/queries/0_stateless/{00953_live_view_select.sql => 00973_live_view_select.sql} (100%) diff --git a/dbms/tests/queries/0_stateless/00953_live_view_select.reference b/dbms/tests/queries/0_stateless/00973_live_view_select.reference similarity index 100% rename from dbms/tests/queries/0_stateless/00953_live_view_select.reference rename to dbms/tests/queries/0_stateless/00973_live_view_select.reference diff --git a/dbms/tests/queries/0_stateless/00953_live_view_select.sql b/dbms/tests/queries/0_stateless/00973_live_view_select.sql similarity index 100% rename from dbms/tests/queries/0_stateless/00953_live_view_select.sql rename to dbms/tests/queries/0_stateless/00973_live_view_select.sql From 87b58e4150b086c100b6baee099664a19b726ca1 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Mon, 10 Jun 2019 07:18:33 -0400 Subject: [PATCH 0122/1165] * Fixing clang errors * Fixing LIVE VIEW tests --- .../PushingToViewsBlockOutputStream.cpp | 2 +- dbms/src/Storages/IStorage.h | 2 +- dbms/src/Storages/StorageLiveView.h | 8 +++--- .../00966_live_view_watch_events_http.py | 2 +- .../0_stateless/00967_live_view_watch_http.py | 2 +- ...0_live_view_watch_events_http_heartbeat.py | 3 +-- .../00971_live_view_watch_http_heartbeat.py | 2 +- dbms/tests/queries/0_stateless/uexpect.py | 25 +++++++++++++------ 8 files changed, 27 insertions(+), 19 deletions(-) diff --git a/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp b/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp index 06f9a1edacf..c023670d4e1 100644 --- a/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp +++ b/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp @@ -86,7 +86,7 @@ void PushingToViewsBlockOutputStream::write(const Block & block) if (auto * live_view = dynamic_cast(storage.get())) { - BlockOutputStreamPtr output = std::make_shared(*live_view); + output = std::make_shared(*live_view); StorageLiveView::writeIntoLiveView(*live_view, block, context, output); } else diff --git a/dbms/src/Storages/IStorage.h b/dbms/src/Storages/IStorage.h index a617db6a8ad..4a63c1ef34a 100644 --- a/dbms/src/Storages/IStorage.h +++ b/dbms/src/Storages/IStorage.h @@ -60,7 +60,7 @@ public: /// The name of the table. virtual std::string getTableName() const = 0; - virtual std::string getDatabaseName() const { return {}; } // FIXME: should be an abstract method! + virtual std::string getDatabaseName() const { return {}; } /// Returns true if the storage receives data from a remote server or servers. virtual bool isRemote() const { return false; } diff --git a/dbms/src/Storages/StorageLiveView.h b/dbms/src/Storages/StorageLiveView.h index 37faee4b266..56b48fe1154 100644 --- a/dbms/src/Storages/StorageLiveView.h +++ b/dbms/src/Storages/StorageLiveView.h @@ -47,7 +47,7 @@ public: ~StorageLiveView() override; String getName() const override { return "LiveView"; } String getTableName() const override { return table_name; } - String getDatabaseName() const { return database_name; } + String getDatabaseName() const override { return database_name; } String getSelectDatabaseName() const { return select_database_name; } String getSelectTableName() const { return select_table_name; } @@ -55,7 +55,7 @@ public: bool hasColumn(const String & column_name) const override; // const NamesAndTypesList & getColumnsListImpl() const override { return *columns; } - ASTPtr getInnerQuery() const { return inner_query->clone(); }; + ASTPtr getInnerQuery() const { return inner_query->clone(); } /// It is passed inside the query and solved at its level. bool supportsSampling() const override { return true; } @@ -218,10 +218,10 @@ public: mergeable_blocks->push_back(new_mergeable_blocks); /// Create from blocks streams - for (auto & blocks : *mergeable_blocks) + for (auto & blocks_ : *mergeable_blocks) { auto sample_block = mergeable_blocks->front()->front().cloneEmpty(); - BlockInputStreamPtr stream = std::make_shared(std::make_shared(blocks), sample_block); + BlockInputStreamPtr stream = std::make_shared(std::make_shared(blocks_), sample_block); from.push_back(std::move(stream)); } } diff --git a/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py b/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py index be1cd220679..904d5214d5b 100755 --- a/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py +++ b/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py @@ -34,7 +34,7 @@ client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') client1.expect(prompt) client2 = client('client2>', ['bash', '--noediting']) -client2.expect('\$ ') +client2.expect('[\$#] ') client2.send('wget -O- -q "http://localhost:8123/?query=WATCH test.lv EVENTS"') client2.expect('.*1\tc9d39b11cce79112219a73aaa319b475\r\n') diff --git a/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py b/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py index 0a844579f5d..4363b453852 100755 --- a/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py +++ b/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py @@ -34,7 +34,7 @@ client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') client1.expect(prompt) client2 = client('client2>', ['bash', '--noediting']) -client2.expect('\$ ') +client2.expect('[\$#] ') client2.send('wget -O- -q "http://localhost:8123/?query=WATCH test.lv"') client2.expect('.*0\t1\r\n') diff --git a/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py b/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py index 1021edd7769..f96cac1e1c7 100755 --- a/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py @@ -34,7 +34,7 @@ client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') client1.expect(prompt) client2 = client('client2>', ['bash', '--noediting']) -client2.expect('\$ ') +client2.expect('[\$#] ') client2.send('wget -O- -q "http://localhost:8123/?live_view_heartbeat_interval=1&query=WATCH test.lv EVENTS FORMAT JSONEachRowWithProgress"') client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}\r\n', escape=True) client2.expect('{"row":{"version":"1","hash":"c9d39b11cce79112219a73aaa319b475"}}', escape=True) @@ -47,7 +47,6 @@ client1.expect(prompt) client2.expect('{"row":{"version":"2","hash":"4cd0592103888d4682de9a32a23602e3"}}\r\n', escape=True) -client2.expect('.*2\t.*\r\n') ## send Ctrl-C os.kill(client2.process.pid,signal.SIGINT) diff --git a/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py b/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py index 33c937de649..cb8cf8f5582 100755 --- a/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py @@ -34,7 +34,7 @@ client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') client1.expect(prompt) client2 = client('client2>', ['bash', '--noediting']) -client2.expect('\$ ') +client2.expect('[\$#] ') client2.send('wget -O- -q "http://localhost:8123/?live_view_heartbeat_interval=1&query=WATCH test.lv FORMAT JSONEachRowWithProgress"') client2.expect('"progress".*',) client2.expect('{"row":{"sum(a)":"0","_version":"1"}}\r\n', escape=True) diff --git a/dbms/tests/queries/0_stateless/uexpect.py b/dbms/tests/queries/0_stateless/uexpect.py index f94a97addcc..dc77161d72f 100644 --- a/dbms/tests/queries/0_stateless/uexpect.py +++ b/dbms/tests/queries/0_stateless/uexpect.py @@ -37,8 +37,8 @@ class ExpectTimeoutError(Exception): def __str__(self): return ('Timeout %.3fs ' % float(self.timeout) + 'for %s ' % repr(self.pattern.pattern) + - 'buffer ends with %s ' % repr(self.buffer[-80:]) + - 'or \'%s\'' % ','.join(['%x' % ord(c) for c in self.buffer[-80:]])) + 'buffer %s ' % repr(self.buffer[:]) + + 'or \'%s\'' % ','.join(['%x' % ord(c) for c in self.buffer[:]])) class IO(object): class EOF(object): @@ -111,10 +111,11 @@ class IO(object): pattern = re.compile(pattern) if timeout is None: timeout = self._timeout - while timeout >= 0: + timeleft = timeout + while timeleft >= 0: start_time = time.time() try: - data = self.read(timeout=timeout, raise_exception=True) + data = self.read(timeout=timeleft, raise_exception=True) except TimeoutError: if self._logger: self._logger.write(self.buffer + '\n') @@ -122,7 +123,7 @@ class IO(object): exception = ExpectTimeoutError(pattern, timeout, self.buffer) self.buffer = None raise exception - timeout -= (time.time() - start_time) + timeleft -= (time.time() - start_time) if data: self.buffer = self.buffer + data if self.buffer else data self.match = pattern.search(self.buffer, 0) @@ -134,23 +135,31 @@ class IO(object): if self._logger: self._logger.write((self.before or '') + (self.after or '')) self._logger.flush() + if self.match is None: + exception = ExpectTimeoutError(pattern, timeout, self.buffer) + self.buffer = None + raise exception return self.match def read(self, timeout=0, raise_exception=False): data = '' + timeleft = timeout try: - while timeout >= 0 : + while timeleft >= 0 : start_time = time.time() - data += self.queue.get(timeout=timeout) + data += self.queue.get(timeout=timeleft) if data: break - timeout -= (time.time() - start_time) + timeleft -= (time.time() - start_time) except Empty: if data: return data if raise_exception: raise TimeoutError(timeout) pass + if not data and raise_exception: + raise TimeoutError(timeout) + return data def spawn(command): From a68980ab385d61dcb1e744a855e3053581b9fb90 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Mon, 10 Jun 2019 07:41:33 -0400 Subject: [PATCH 0123/1165] * Style check fixes --- .../DataStreams/LiveViewBlockInputStream.h | 7 +++---- .../LiveViewEventsBlockInputStream.h | 13 ++++++------ .../Interpreters/InterpreterAlterQuery.cpp | 20 +++++++++---------- dbms/src/Parsers/ParserAlterQuery.cpp | 4 +++- dbms/src/Storages/StorageLiveView.cpp | 4 ++-- dbms/src/Storages/StorageLiveView.h | 3 ++- 6 files changed, 27 insertions(+), 24 deletions(-) diff --git a/dbms/src/DataStreams/LiveViewBlockInputStream.h b/dbms/src/DataStreams/LiveViewBlockInputStream.h index 93eae976177..6129c836597 100644 --- a/dbms/src/DataStreams/LiveViewBlockInputStream.h +++ b/dbms/src/DataStreams/LiveViewBlockInputStream.h @@ -46,7 +46,7 @@ public: std::shared_ptr active_ptr_, Poco::Condition & condition_, Poco::FastMutex & mutex_, int64_t length_, const UInt64 & heartbeat_interval_, const UInt64 & temporary_live_view_timeout_) - : storage(storage_), blocks_ptr(blocks_ptr_), blocks_metadata_ptr(blocks_metadata_ptr_), active_ptr(active_ptr_), condition(condition_), mutex(mutex_), length(length_ + 1), heartbeat_interval(heartbeat_interval_), temporary_live_view_timeout(temporary_live_view_timeout_), + : storage(storage_), blocks_ptr(blocks_ptr_), blocks_metadata_ptr(blocks_metadata_ptr_), active_ptr(active_ptr_), condition(condition_), mutex(mutex_), length(length_ + 1), heartbeat_interval(heartbeat_interval_ * 1000000), temporary_live_view_timeout(temporary_live_view_timeout_), blocks_hash("") { /// grab active pointer @@ -160,9 +160,8 @@ protected: } while (true) { - bool signaled = condition.tryWait(mutex, - std::max((UInt64)0, (heartbeat_interval * 1000000) - - ((UInt64)timestamp.epochMicroseconds() - last_event_timestamp)) / 1000); + UInt64 timestamp_usec = (UInt64)timestamp.epochMicroseconds(); + bool signaled = condition.tryWait(mutex, std::max((UInt64)0, heartbeat_interval - (timestamp_usec - last_event_timestamp)) / 1000); if (isCancelled() || storage.is_dropped) { diff --git a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h index d0f92806d74..35d2545419b 100644 --- a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h +++ b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h @@ -47,7 +47,7 @@ public: /// and LIMIT 0 just returns data without waiting for any updates LiveViewEventsBlockInputStream(StorageLiveView & storage_, std::shared_ptr blocks_ptr_, std::shared_ptr blocks_metadata_ptr_, std::shared_ptr active_ptr_, Poco::Condition & condition_, Poco::FastMutex & mutex_, int64_t length_, const UInt64 & heartbeat_interval_, const UInt64 & temporary_live_view_timeout_) - : storage(storage_), blocks_ptr(blocks_ptr_), blocks_metadata_ptr(blocks_metadata_ptr_), active_ptr(active_ptr_), condition(condition_), mutex(mutex_), length(length_ + 1), heartbeat_interval(heartbeat_interval_), temporary_live_view_timeout(temporary_live_view_timeout_) + : storage(storage_), blocks_ptr(blocks_ptr_), blocks_metadata_ptr(blocks_metadata_ptr_), active_ptr(active_ptr_), condition(condition_), mutex(mutex_), length(length_ + 1), heartbeat_interval(heartbeat_interval_ * 1000000), temporary_live_view_timeout(temporary_live_view_timeout_) { /// grab active pointer active = active_ptr.lock(); @@ -64,7 +64,8 @@ public: condition.broadcast(); } - Block getHeader() const override { + Block getHeader() const override + { return { ColumnWithTypeAndName( ColumnUInt64::create(), @@ -92,7 +93,8 @@ public: { active = active_ptr.lock(); { - if (!blocks || blocks.get() != (*blocks_ptr).get()) { + if (!blocks || blocks.get() != (*blocks_ptr).get()) + { blocks = (*blocks_ptr); blocks_metadata = (*blocks_metadata_ptr); } @@ -188,9 +190,8 @@ protected: } while (true) { - bool signaled = condition.tryWait(mutex, - std::max((UInt64)0, (heartbeat_interval * 1000000) - - ((UInt64)timestamp.epochMicroseconds() - last_event_timestamp)) / 1000); + UInt64 timestamp_usec = (UInt64)timestamp.epochMicroseconds(); + bool signaled = condition.tryWait(mutex, std::max((UInt64)0, heartbeat_interval - (timestamp_usec - last_event_timestamp)) / 1000); if (isCancelled() || storage.is_dropped) { diff --git a/dbms/src/Interpreters/InterpreterAlterQuery.cpp b/dbms/src/Interpreters/InterpreterAlterQuery.cpp index 6d2fc61f080..e8f3e4f4553 100644 --- a/dbms/src/Interpreters/InterpreterAlterQuery.cpp +++ b/dbms/src/Interpreters/InterpreterAlterQuery.cpp @@ -79,17 +79,17 @@ BlockIO InterpreterAlterQuery::execute() if (!live_view_commands.empty()) { - live_view_commands.validate(*table); - for (const LiveViewCommand & command : live_view_commands) - { - auto live_view = std::dynamic_pointer_cast(table); - switch (command.type) - { - case LiveViewCommand::REFRESH: - live_view->refresh(context); - break; - } + live_view_commands.validate(*table); + for (const LiveViewCommand & command : live_view_commands) + { + auto live_view = std::dynamic_pointer_cast(table); + switch (command.type) + { + case LiveViewCommand::REFRESH: + live_view->refresh(context); + break; } + } } if (!alter_commands.empty()) diff --git a/dbms/src/Parsers/ParserAlterQuery.cpp b/dbms/src/Parsers/ParserAlterQuery.cpp index f8803cc3bc8..58a3b3a388b 100644 --- a/dbms/src/Parsers/ParserAlterQuery.cpp +++ b/dbms/src/Parsers/ParserAlterQuery.cpp @@ -446,10 +446,12 @@ bool ParserAlterQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) if (!s_alter_table.ignore(pos, expected)) { if (!s_alter_live_view.ignore(pos, expected)) - if (!s_alter_live_channel.ignore(pos, expected)) + { + if (!s_alter_live_channel.ignore(pos, expected)) return false; else is_live_channel = true; + } else is_live_view = true; } diff --git a/dbms/src/Storages/StorageLiveView.cpp b/dbms/src/Storages/StorageLiveView.cpp index 108e146dc73..dd6e0179410 100644 --- a/dbms/src/Storages/StorageLiveView.cpp +++ b/dbms/src/Storages/StorageLiveView.cpp @@ -141,7 +141,7 @@ StorageLiveView::StorageLiveView( NameAndTypePair StorageLiveView::getColumn(const String & column_name) const { - if ( column_name == "_version" ) + if (column_name == "_version") return NameAndTypePair("_version", std::make_shared()); return IStorage::getColumn(column_name); @@ -149,7 +149,7 @@ NameAndTypePair StorageLiveView::getColumn(const String & column_name) const bool StorageLiveView::hasColumn(const String & column_name) const { - if ( column_name == "_version" ) + if (column_name == "_version") return true; return IStorage::hasColumn(column_name); diff --git a/dbms/src/Storages/StorageLiveView.h b/dbms/src/Storages/StorageLiveView.h index 56b48fe1154..fb250aec859 100644 --- a/dbms/src/Storages/StorageLiveView.h +++ b/dbms/src/Storages/StorageLiveView.h @@ -30,7 +30,8 @@ namespace DB class IAST; using ASTPtr = std::shared_ptr; -struct BlocksMetadata { +struct BlocksMetadata +{ String hash; UInt64 version; }; From fc4ea55b98ebd1f4c9a2d6fb0f1fed5a00deade6 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Mon, 10 Jun 2019 08:11:43 -0400 Subject: [PATCH 0124/1165] * Fixing bug in dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp that was introduced when trying to fix a clang error. --- dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp b/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp index c023670d4e1..f361420de95 100644 --- a/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp +++ b/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp @@ -86,8 +86,8 @@ void PushingToViewsBlockOutputStream::write(const Block & block) if (auto * live_view = dynamic_cast(storage.get())) { - output = std::make_shared(*live_view); - StorageLiveView::writeIntoLiveView(*live_view, block, context, output); + BlockOutputStreamPtr output_ = std::make_shared(*live_view); + StorageLiveView::writeIntoLiveView(*live_view, block, context, output_); } else { From 1ebe3047ffc6719b4f817a25ea66a8d2f9ee47ac Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Mon, 10 Jun 2019 18:12:06 -0400 Subject: [PATCH 0125/1165] * Moving uexpect.py to dbms/tests/integration/helpers folder * Updating uexpect.py to support close() method and context manager for proper resource cleanup * Updating tests to use uexpect context manager --- .../helpers}/uexpect.py | 10 +++ .../0_stateless/00958_live_view_watch_live.py | 49 +++++++-------- .../00960_live_view_watch_events_live.py | 49 +++++++-------- .../00962_temporary_live_view_watch_live.py | 49 +++++++-------- ..._temporary_live_view_watch_live_timeout.py | 63 +++++++++---------- .../00964_live_view_watch_events_heartbeat.py | 55 ++++++++-------- .../00965_live_view_watch_heartbeat.py | 55 ++++++++-------- .../00966_live_view_watch_events_http.py | 48 +++++++------- .../0_stateless/00967_live_view_watch_http.py | 48 +++++++------- ...0_live_view_watch_events_http_heartbeat.py | 56 ++++++++--------- .../00971_live_view_watch_http_heartbeat.py | 58 ++++++++--------- 11 files changed, 272 insertions(+), 268 deletions(-) rename dbms/tests/{queries/0_stateless => integration/helpers}/uexpect.py (95%) diff --git a/dbms/tests/queries/0_stateless/uexpect.py b/dbms/tests/integration/helpers/uexpect.py similarity index 95% rename from dbms/tests/queries/0_stateless/uexpect.py rename to dbms/tests/integration/helpers/uexpect.py index dc77161d72f..58be8f60ff8 100644 --- a/dbms/tests/queries/0_stateless/uexpect.py +++ b/dbms/tests/integration/helpers/uexpect.py @@ -74,6 +74,12 @@ class IO(object): self._logger = None self._eol = '' + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + self.close() + def logger(self, logger=None, prefix=''): if logger: self._logger = self.Logger(logger, prefix=prefix) @@ -90,6 +96,8 @@ class IO(object): return self._eol def close(self): + self.process.terminate() + os.close(self.master) if self._logger: self._logger.write('\n') self._logger.flush() @@ -155,9 +163,11 @@ class IO(object): if data: return data if raise_exception: + print 'DEBUG...', timeleft, repr(data), raise TimeoutError(timeout) pass if not data and raise_exception: + print 'DEBUG.... here' raise TimeoutError(timeout) return data diff --git a/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py b/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py index 9fb58cb556c..b60e82299f7 100755 --- a/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py +++ b/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) def client(name=''): client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) @@ -18,29 +18,28 @@ def client(name=''): prompt = ':\) ' end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' -client1 = client('client1>') -client2 = client('client2>') -client1.expect(prompt) -client2.expect(prompt) +with client('client1>') as client1, client('client2>') as client2: + client1.expect(prompt) + client2.expect(prompt) -client1.send('DROP TABLE IF EXISTS test.lv') -client1.expect(prompt) -client1.send(' DROP TABLE IF EXISTS test.mt') -client1.expect(prompt) -client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') -client1.expect(prompt) -client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') -client1.expect(prompt) -client1.send('WATCH test.lv') -client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') -client1.expect(r'6.*2' + end_of_block) -client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') -client1.expect(r'21.*3' + end_of_block) -# send Ctrl-C -os.kill(client1.process.pid,signal.SIGINT) -client1.expect(prompt) -client1.send('DROP TABLE test.lv') -client1.expect(prompt) -client1.send('DROP TABLE test.mt') -client1.expect(prompt) + client1.send('DROP TABLE IF EXISTS test.lv') + client1.expect(prompt) + client1.send(' DROP TABLE IF EXISTS test.mt') + client1.expect(prompt) + client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') + client1.expect(prompt) + client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') + client1.expect(prompt) + client1.send('WATCH test.lv') + client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') + client1.expect(r'6.*2' + end_of_block) + client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') + client1.expect(r'21.*3' + end_of_block) + # send Ctrl-C + os.kill(client1.process.pid,signal.SIGINT) + client1.expect(prompt) + client1.send('DROP TABLE test.lv') + client1.expect(prompt) + client1.send('DROP TABLE test.mt') + client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py b/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py index fa96331e3fb..9fdabd499d0 100755 --- a/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py +++ b/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) def client(name=''): client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) @@ -18,29 +18,28 @@ def client(name=''): prompt = ':\) ' end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' -client1 = client('client1>') -client2 = client('client2>') -client1.expect(prompt) -client2.expect(prompt) +with client('client1>') as client1, client('client2>') as client2: + client1.expect(prompt) + client2.expect(prompt) -client1.send('DROP TABLE IF EXISTS test.lv') -client1.expect(prompt) -client1.send(' DROP TABLE IF EXISTS test.mt') -client1.expect(prompt) -client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') -client1.expect(prompt) -client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') -client1.expect(prompt) -client1.send('WATCH test.lv EVENTS') -client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') -client1.expect('2.*4cd0592103888d4682de9a32a23602e3' + end_of_block) -client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') -client1.expect('3.*2186dbea325ee4c56b67e9b792e993a3' + end_of_block) -# send Ctrl-C -os.kill(client1.process.pid,signal.SIGINT) -client1.expect(prompt) -client1.send('DROP TABLE test.lv') -client1.expect(prompt) -client1.send('DROP TABLE test.mt') -client1.expect(prompt) + client1.send('DROP TABLE IF EXISTS test.lv') + client1.expect(prompt) + client1.send(' DROP TABLE IF EXISTS test.mt') + client1.expect(prompt) + client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') + client1.expect(prompt) + client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') + client1.expect(prompt) + client1.send('WATCH test.lv EVENTS') + client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') + client1.expect('2.*4cd0592103888d4682de9a32a23602e3' + end_of_block) + client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') + client1.expect('3.*2186dbea325ee4c56b67e9b792e993a3' + end_of_block) + # send Ctrl-C + os.kill(client1.process.pid,signal.SIGINT) + client1.expect(prompt) + client1.send('DROP TABLE test.lv') + client1.expect(prompt) + client1.send('DROP TABLE test.mt') + client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py b/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py index 0b0260adeed..0e7c3c43254 100755 --- a/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py +++ b/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) def client(name=''): client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) @@ -18,29 +18,28 @@ def client(name=''): prompt = ':\) ' end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' -client1 = client('client1>') -client2 = client('client2>') -client1.expect(prompt) -client2.expect(prompt) +with client('client1>') as client1, client('client2>') as client2: + client1.expect(prompt) + client2.expect(prompt) -client1.send('DROP TABLE IF EXISTS test.lv') -client1.expect(prompt) -client1.send(' DROP TABLE IF EXISTS test.mt') -client1.expect(prompt) -client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') -client1.expect(prompt) -client1.send('CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') -client1.expect(prompt) -client1.send('WATCH test.lv') -client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') -client1.expect(r'6.*2' + end_of_block) -client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') -client1.expect(r'21.*3' + end_of_block) -# send Ctrl-C -os.kill(client1.process.pid,signal.SIGINT) -client1.expect(prompt) -client1.send('DROP TABLE test.lv') -client1.expect(prompt) -client1.send('DROP TABLE test.mt') -client1.expect(prompt) + client1.send('DROP TABLE IF EXISTS test.lv') + client1.expect(prompt) + client1.send(' DROP TABLE IF EXISTS test.mt') + client1.expect(prompt) + client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') + client1.expect(prompt) + client1.send('CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') + client1.expect(prompt) + client1.send('WATCH test.lv') + client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') + client1.expect(r'6.*2' + end_of_block) + client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') + client1.expect(r'21.*3' + end_of_block) + # send Ctrl-C + os.kill(client1.process.pid,signal.SIGINT) + client1.expect(prompt) + client1.send('DROP TABLE test.lv') + client1.expect(prompt) + client1.send('DROP TABLE test.mt') + client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py index 29ec01c724a..b3f6809ded0 100755 --- a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py +++ b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) def client(name=''): client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) @@ -18,36 +18,35 @@ def client(name=''): prompt = ':\) ' end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' -client1 = client('client1>') -client2 = client('client2>') -client1.expect(prompt) -client2.expect(prompt) +with client('client1>') as client1, client('client2>') as client2: + client1.expect(prompt) + client2.expect(prompt) -client1.send('DROP TABLE IF EXISTS test.lv') -client1.expect(prompt) -client1.send('DROP TABLE IF EXISTS test.mt') -client1.expect(prompt) -client1.send('SET temporary_live_view_timeout=1') -client1.expect(prompt) -client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') -client1.expect(prompt) -client1.send('CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') -client1.expect(prompt) -client1.send('WATCH test.lv') -client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') -client2.expect(prompt) -client1.expect(r'6.*2' + end_of_block) -client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') -client2.expect(prompt) -client1.expect(r'21.*3' + end_of_block) -# send Ctrl-C -os.kill(client1.process.pid,signal.SIGINT) -client1.expect(prompt) -client1.send('SELECT sleep(1)') -client1.expect(prompt) -client1.send('DROP TABLE test.lv') -client1.expect('Table test.lv doesn\'t exist') -client1.expect(prompt) -client1.send('DROP TABLE test.mt') -client1.expect(prompt) + client1.send('DROP TABLE IF EXISTS test.lv') + client1.expect(prompt) + client1.send('DROP TABLE IF EXISTS test.mt') + client1.expect(prompt) + client1.send('SET temporary_live_view_timeout=1') + client1.expect(prompt) + client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') + client1.expect(prompt) + client1.send('CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') + client1.expect(prompt) + client1.send('WATCH test.lv') + client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') + client2.expect(prompt) + client1.expect(r'6.*2' + end_of_block) + client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') + client2.expect(prompt) + client1.expect(r'21.*3' + end_of_block) + # send Ctrl-C + os.kill(client1.process.pid,signal.SIGINT) + client1.expect(prompt, timeout=5) + client1.send('SELECT sleep(1)') + client1.expect(prompt) + client1.send('DROP TABLE test.lv') + client1.expect('Table test.lv doesn\'t exist') + client1.expect(prompt) + client1.send('DROP TABLE test.mt') + client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py index cbb659f1292..1e66daef953 100755 --- a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) def client(name=''): client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) @@ -18,32 +18,31 @@ def client(name=''): prompt = ':\) ' end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' -client1 = client('client1>') -client2 = client('client2>') -client1.expect(prompt) -client2.expect(prompt) +with client('client1>') as client1, client('client2>') as client2: + client1.expect(prompt) + client2.expect(prompt) -client1.send('DROP TABLE IF EXISTS test.lv') -client1.expect(prompt) -client1.send(' DROP TABLE IF EXISTS test.mt') -client1.expect(prompt) -client1.send('SET live_view_heartbeat_interval=1') -client1.expect(prompt) -client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') -client1.expect(prompt) -client1.send('CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') -client1.expect(prompt) -client1.send('WATCH test.lv EVENTS') -client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') -client1.expect('2.*4cd0592103888d4682de9a32a23602e3' + end_of_block) -client1.expect('Progress: 2.00 rows.*\)') -# wait for heartbeat -client1.expect('Progress: 2.00 rows.*\)') -# send Ctrl-C -os.kill(client1.process.pid,signal.SIGINT) -client1.expect(prompt) -client1.send('DROP TABLE test.lv') -client1.expect(prompt) -client1.send('DROP TABLE test.mt') -client1.expect(prompt) + client1.send('DROP TABLE IF EXISTS test.lv') + client1.expect(prompt) + client1.send(' DROP TABLE IF EXISTS test.mt') + client1.expect(prompt) + client1.send('SET live_view_heartbeat_interval=1') + client1.expect(prompt) + client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') + client1.expect(prompt) + client1.send('CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') + client1.expect(prompt) + client1.send('WATCH test.lv EVENTS') + client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') + client1.expect('2.*4cd0592103888d4682de9a32a23602e3' + end_of_block) + client1.expect('Progress: 2.00 rows.*\)') + # wait for heartbeat + client1.expect('Progress: 2.00 rows.*\)') + # send Ctrl-C + os.kill(client1.process.pid,signal.SIGINT) + client1.expect(prompt) + client1.send('DROP TABLE test.lv') + client1.expect(prompt) + client1.send('DROP TABLE test.mt') + client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py b/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py index c596d169e1c..7f8ed6036ac 100755 --- a/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) def client(name=''): client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) @@ -18,32 +18,31 @@ def client(name=''): prompt = ':\) ' end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' -client1 = client('client1>') -client2 = client('client2>') -client1.expect(prompt) -client2.expect(prompt) +with client('client1>') as client1, client('client2>') as client2: + client1.expect(prompt) + client2.expect(prompt) -client1.send('DROP TABLE IF EXISTS test.lv') -client1.expect(prompt) -client1.send(' DROP TABLE IF EXISTS test.mt') -client1.expect(prompt) -client1.send('SET live_view_heartbeat_interval=1') -client1.expect(prompt) -client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') -client1.expect(prompt) -client1.send('CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') -client1.expect(prompt) -client1.send('WATCH test.lv') -client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') -client1.expect(r'6.*2' + end_of_block) -client1.expect('Progress: 2.00 rows.*\)') -# wait for heartbeat -client1.expect('Progress: 2.00 rows.*\)') -# send Ctrl-C -os.kill(client1.process.pid,signal.SIGINT) -client1.expect(prompt) -client1.send('DROP TABLE test.lv') -client1.expect(prompt) -client1.send('DROP TABLE test.mt') -client1.expect(prompt) + client1.send('DROP TABLE IF EXISTS test.lv') + client1.expect(prompt) + client1.send(' DROP TABLE IF EXISTS test.mt') + client1.expect(prompt) + client1.send('SET live_view_heartbeat_interval=1') + client1.expect(prompt) + client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') + client1.expect(prompt) + client1.send('CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') + client1.expect(prompt) + client1.send('WATCH test.lv') + client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') + client1.expect(r'6.*2' + end_of_block) + client1.expect('Progress: 2.00 rows.*\)') + # wait for heartbeat + client1.expect('Progress: 2.00 rows.*\)') + # send Ctrl-C + os.kill(client1.process.pid,signal.SIGINT) + client1.expect(prompt) + client1.send('DROP TABLE test.lv') + client1.expect(prompt) + client1.send('DROP TABLE test.mt') + client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py b/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py index 904d5214d5b..e7dc54ee4c0 100755 --- a/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py +++ b/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) def client(name='', command=None): if command is None: @@ -21,31 +21,31 @@ def client(name='', command=None): prompt = ':\) ' end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' -client1 = client('client1>') -client1.expect(prompt) -client1.send('DROP TABLE IF EXISTS test.lv') -client1.expect(prompt) -client1.send(' DROP TABLE IF EXISTS test.mt') -client1.expect(prompt) -client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') -client1.expect(prompt) -client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') -client1.expect(prompt) +with client('client1>') as client1, client('client2>', ['bash', '--noediting']) as client2: + client1.expect(prompt) -client2 = client('client2>', ['bash', '--noediting']) -client2.expect('[\$#] ') -client2.send('wget -O- -q "http://localhost:8123/?query=WATCH test.lv EVENTS"') -client2.expect('.*1\tc9d39b11cce79112219a73aaa319b475\r\n') + client1.send('DROP TABLE IF EXISTS test.lv') + client1.expect(prompt) + client1.send(' DROP TABLE IF EXISTS test.mt') + client1.expect(prompt) + client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') + client1.expect(prompt) + client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') + client1.expect(prompt) -client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') -client1.expect(prompt) + client2.expect('[\$#] ') + client2.send('wget -O- -q "http://localhost:8123/?query=WATCH test.lv EVENTS"') + client2.expect('.*1\tc9d39b11cce79112219a73aaa319b475\r\n') -client2.expect('.*2\t.*\r\n') -## send Ctrl-C -os.kill(client2.process.pid,signal.SIGINT) + client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') + client1.expect(prompt) -client1.send('DROP TABLE test.lv') -client1.expect(prompt) -client1.send('DROP TABLE test.mt') -client1.expect(prompt) + client2.expect('.*2\t.*\r\n') + ## send Ctrl-C + os.kill(client2.process.pid,signal.SIGINT) + + client1.send('DROP TABLE test.lv') + client1.expect(prompt) + client1.send('DROP TABLE test.mt') + client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py b/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py index 4363b453852..6874ae376a3 100755 --- a/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py +++ b/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) def client(name='', command=None): if command is None: @@ -21,31 +21,31 @@ def client(name='', command=None): prompt = ':\) ' end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' -client1 = client('client1>') -client1.expect(prompt) -client1.send('DROP TABLE IF EXISTS test.lv') -client1.expect(prompt) -client1.send(' DROP TABLE IF EXISTS test.mt') -client1.expect(prompt) -client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') -client1.expect(prompt) -client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') -client1.expect(prompt) +with client('client1>') as client1, client('client2>', ['bash', '--noediting']) as client2: + client1.expect(prompt) -client2 = client('client2>', ['bash', '--noediting']) -client2.expect('[\$#] ') -client2.send('wget -O- -q "http://localhost:8123/?query=WATCH test.lv"') -client2.expect('.*0\t1\r\n') + client1.send('DROP TABLE IF EXISTS test.lv') + client1.expect(prompt) + client1.send(' DROP TABLE IF EXISTS test.mt') + client1.expect(prompt) + client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') + client1.expect(prompt) + client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') + client1.expect(prompt) -client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') -client1.expect(prompt) + client2.expect('[\$#] ') + client2.send('wget -O- -q "http://localhost:8123/?query=WATCH test.lv"') + client2.expect('.*0\t1\r\n') -client2.expect('.*6\t2\r\n') -## send Ctrl-C -os.kill(client2.process.pid,signal.SIGINT) + client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') + client1.expect(prompt) -client1.send('DROP TABLE test.lv') -client1.expect(prompt) -client1.send('DROP TABLE test.mt') -client1.expect(prompt) + client2.expect('.*6\t2\r\n') + ## send Ctrl-C + os.kill(client2.process.pid,signal.SIGINT) + + client1.send('DROP TABLE test.lv') + client1.expect(prompt) + client1.send('DROP TABLE test.mt') + client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py b/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py index f96cac1e1c7..4730caf5f57 100755 --- a/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) def client(name='', command=None): if command is None: @@ -21,36 +21,36 @@ def client(name='', command=None): prompt = ':\) ' end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' -client1 = client('client1>') -client1.expect(prompt) -client1.send('DROP TABLE IF EXISTS test.lv') -client1.expect(prompt) -client1.send(' DROP TABLE IF EXISTS test.mt') -client1.expect(prompt) -client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') -client1.expect(prompt) -client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') -client1.expect(prompt) +with client('client1>') as client1, client('client2>', ['bash', '--noediting']) as client2: + client1.expect(prompt) -client2 = client('client2>', ['bash', '--noediting']) -client2.expect('[\$#] ') -client2.send('wget -O- -q "http://localhost:8123/?live_view_heartbeat_interval=1&query=WATCH test.lv EVENTS FORMAT JSONEachRowWithProgress"') -client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}\r\n', escape=True) -client2.expect('{"row":{"version":"1","hash":"c9d39b11cce79112219a73aaa319b475"}}', escape=True) -client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}', escape=True) -# heartbeat is provided by progress message -client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}', escape=True) + client1.send('DROP TABLE IF EXISTS test.lv') + client1.expect(prompt) + client1.send(' DROP TABLE IF EXISTS test.mt') + client1.expect(prompt) + client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') + client1.expect(prompt) + client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') + client1.expect(prompt) -client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') -client1.expect(prompt) + client2.expect('[\$#] ') + client2.send('wget -O- -q "http://localhost:8123/?live_view_heartbeat_interval=1&query=WATCH test.lv EVENTS FORMAT JSONEachRowWithProgress"') + client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}\r\n', escape=True) + client2.expect('{"row":{"version":"1","hash":"c9d39b11cce79112219a73aaa319b475"}}', escape=True) + client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}', escape=True) + # heartbeat is provided by progress message + client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}', escape=True) -client2.expect('{"row":{"version":"2","hash":"4cd0592103888d4682de9a32a23602e3"}}\r\n', escape=True) + client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') + client1.expect(prompt) -## send Ctrl-C -os.kill(client2.process.pid,signal.SIGINT) + client2.expect('{"row":{"version":"2","hash":"4cd0592103888d4682de9a32a23602e3"}}\r\n', escape=True) -client1.send('DROP TABLE test.lv') -client1.expect(prompt) -client1.send('DROP TABLE test.mt') -client1.expect(prompt) + ## send Ctrl-C + os.kill(client2.process.pid,signal.SIGINT) + + client1.send('DROP TABLE test.lv') + client1.expect(prompt) + client1.send('DROP TABLE test.mt') + client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py b/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py index cb8cf8f5582..5884bc1e2a5 100755 --- a/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) def client(name='', command=None): if command is None: @@ -21,37 +21,37 @@ def client(name='', command=None): prompt = ':\) ' end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' -client1 = client('client1>') -client1.expect(prompt) -client1.send('DROP TABLE IF EXISTS test.lv') -client1.expect(prompt) -client1.send(' DROP TABLE IF EXISTS test.mt') -client1.expect(prompt) -client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') -client1.expect(prompt) -client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') -client1.expect(prompt) +with client('client1>') as client1, client('client2>', ['bash', '--noediting']) as client2: + client1.expect(prompt) -client2 = client('client2>', ['bash', '--noediting']) -client2.expect('[\$#] ') -client2.send('wget -O- -q "http://localhost:8123/?live_view_heartbeat_interval=1&query=WATCH test.lv FORMAT JSONEachRowWithProgress"') -client2.expect('"progress".*',) -client2.expect('{"row":{"sum(a)":"0","_version":"1"}}\r\n', escape=True) -client2.expect('"progress".*\r\n') -# heartbeat is provided by progress message -client2.expect('"progress".*\r\n') + client1.send('DROP TABLE IF EXISTS test.lv') + client1.expect(prompt) + client1.send(' DROP TABLE IF EXISTS test.mt') + client1.expect(prompt) + client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') + client1.expect(prompt) + client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') + client1.expect(prompt) -client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') -client1.expect(prompt) + client2.expect('[\$#] ') + client2.send('wget -O- -q "http://localhost:8123/?live_view_heartbeat_interval=1&query=WATCH test.lv FORMAT JSONEachRowWithProgress"') + client2.expect('"progress".*',) + client2.expect('{"row":{"sum(a)":"0","_version":"1"}}\r\n', escape=True) + client2.expect('"progress".*\r\n') + # heartbeat is provided by progress message + client2.expect('"progress".*\r\n') -client2.expect('"progress".*"read_rows":"2".*\r\n') -client2.expect('{"row":{"sum(a)":"6","_version":"2"}}\r\n', escape=True) + client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') + client1.expect(prompt) -## send Ctrl-C -os.kill(client2.process.pid,signal.SIGINT) + client2.expect('"progress".*"read_rows":"2".*\r\n') + client2.expect('{"row":{"sum(a)":"6","_version":"2"}}\r\n', escape=True) -client1.send('DROP TABLE test.lv') -client1.expect(prompt) -client1.send('DROP TABLE test.mt') -client1.expect(prompt) + ## send Ctrl-C + os.kill(client2.process.pid,signal.SIGINT) + + client1.send('DROP TABLE test.lv') + client1.expect(prompt) + client1.send('DROP TABLE test.mt') + client1.expect(prompt) From 79989a766c54e6e316fa1cff39739d26f9021309 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Mon, 10 Jun 2019 19:56:12 -0400 Subject: [PATCH 0126/1165] * Fixing uexpect.py close() method and forcing to close the process by default * Updating tests to be more robust --- dbms/tests/integration/helpers/uexpect.py | 38 ++++++++++--------- .../0_stateless/00958_live_view_watch_live.py | 2 +- .../00960_live_view_watch_events_live.py | 2 +- .../00962_temporary_live_view_watch_live.py | 2 +- ..._temporary_live_view_watch_live_timeout.py | 2 +- .../00964_live_view_watch_events_heartbeat.py | 2 +- .../00965_live_view_watch_heartbeat.py | 2 +- .../00966_live_view_watch_events_http.py | 2 +- .../0_stateless/00967_live_view_watch_http.py | 2 +- ...0_live_view_watch_events_http_heartbeat.py | 2 +- .../00971_live_view_watch_http_heartbeat.py | 4 +- 11 files changed, 32 insertions(+), 28 deletions(-) diff --git a/dbms/tests/integration/helpers/uexpect.py b/dbms/tests/integration/helpers/uexpect.py index 58be8f60ff8..2a42b8a5de0 100644 --- a/dbms/tests/integration/helpers/uexpect.py +++ b/dbms/tests/integration/helpers/uexpect.py @@ -17,7 +17,7 @@ import time import sys import re -from threading import Thread +from threading import Thread, Event from subprocess import Popen from Queue import Queue, Empty @@ -61,7 +61,7 @@ class IO(object): def flush(self): self._logger.flush() - def __init__(self, process, master, queue): + def __init__(self, process, master, queue, reader): self.process = process self.master = master self.queue = queue @@ -70,6 +70,7 @@ class IO(object): self.after = None self.match = None self.pattern = None + self.reader = reader self._timeout = None self._logger = None self._eol = '' @@ -95,8 +96,12 @@ class IO(object): self._eol = eol return self._eol - def close(self): - self.process.terminate() + def close(self, force=True): + self.reader['kill_event'].set() + if force: + self.process.kill() + else: + self.process.terminate() os.close(self.master) if self._logger: self._logger.write('\n') @@ -133,9 +138,9 @@ class IO(object): raise exception timeleft -= (time.time() - start_time) if data: - self.buffer = self.buffer + data if self.buffer else data + self.buffer = (self.buffer + data) if self.buffer else data self.match = pattern.search(self.buffer, 0) - if self.match: + if self.match is not None: self.after = self.buffer[self.match.start():self.match.end()] self.before = self.buffer[:self.match.start()] self.buffer = self.buffer[self.match.end():] @@ -163,11 +168,9 @@ class IO(object): if data: return data if raise_exception: - print 'DEBUG...', timeleft, repr(data), raise TimeoutError(timeout) pass if not data and raise_exception: - print 'DEBUG.... here' raise TimeoutError(timeout) return data @@ -178,20 +181,21 @@ def spawn(command): os.close(slave) queue = Queue() - thread = Thread(target=reader, args=(process, master, queue)) - thread.daemon = True + reader_kill_event = Event() + thread = Thread(target=reader, args=(process, master, queue, reader_kill_event)) thread.start() - return IO(process, master, queue) + return IO(process, master, queue, reader={'thread':thread, 'kill_event':reader_kill_event}) -def reader(process, out, queue): +def reader(process, out, queue, kill_event): while True: - if process.poll() is not None: - data = os.read(out) + try: + data = os.read(out, 65536) queue.put(data) - break - data = os.read(out, 65536) - queue.put(data) + except OSError, e: + if e.errno == 5 and kill_event.is_set(): + break + raise if __name__ == '__main__': io = spawn(['/bin/bash','--noediting']) diff --git a/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py b/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py index b60e82299f7..51bdca1a9b6 100755 --- a/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py +++ b/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py @@ -17,7 +17,7 @@ def client(name=''): return client prompt = ':\) ' -end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' +end_of_block = r'.*\r\n.*\r\n' with client('client1>') as client1, client('client2>') as client2: client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py b/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py index 9fdabd499d0..0b441b72805 100755 --- a/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py +++ b/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py @@ -17,7 +17,7 @@ def client(name=''): return client prompt = ':\) ' -end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' +end_of_block = r'.*\r\n.*\r\n' with client('client1>') as client1, client('client2>') as client2: client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py b/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py index 0e7c3c43254..5dfa6ac841e 100755 --- a/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py +++ b/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py @@ -17,7 +17,7 @@ def client(name=''): return client prompt = ':\) ' -end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' +end_of_block = r'.*\r\n.*\r\n' with client('client1>') as client1, client('client2>') as client2: client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py index b3f6809ded0..09301aa6d59 100755 --- a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py +++ b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py @@ -17,7 +17,7 @@ def client(name=''): return client prompt = ':\) ' -end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' +end_of_block = r'.*\r\n.*\r\n' with client('client1>') as client1, client('client2>') as client2: client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py index 1e66daef953..f3e5b1ee435 100755 --- a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py @@ -17,7 +17,7 @@ def client(name=''): return client prompt = ':\) ' -end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' +end_of_block = r'.*\r\n.*\r\n' with client('client1>') as client1, client('client2>') as client2: client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py b/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py index 7f8ed6036ac..9f8a3c84af0 100755 --- a/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py @@ -17,7 +17,7 @@ def client(name=''): return client prompt = ':\) ' -end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' +end_of_block = r'.*\r\n.*\r\n' with client('client1>') as client1, client('client2>') as client2: client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py b/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py index e7dc54ee4c0..65999f4c55f 100755 --- a/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py +++ b/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py @@ -20,7 +20,7 @@ def client(name='', command=None): return client prompt = ':\) ' -end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' +end_of_block = r'.*\r\n.*\r\n' with client('client1>') as client1, client('client2>', ['bash', '--noediting']) as client2: client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py b/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py index 6874ae376a3..a79d6882aa9 100755 --- a/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py +++ b/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py @@ -20,7 +20,7 @@ def client(name='', command=None): return client prompt = ':\) ' -end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' +end_of_block = r'.*\r\n.*\r\n' with client('client1>') as client1, client('client2>', ['bash', '--noediting']) as client2: client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py b/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py index 4730caf5f57..95587ba9355 100755 --- a/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py @@ -20,7 +20,7 @@ def client(name='', command=None): return client prompt = ':\) ' -end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' +end_of_block = r'.*\r\n.*\r\n' with client('client1>') as client1, client('client2>', ['bash', '--noediting']) as client2: client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py b/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py index 5884bc1e2a5..8c40fc6d39d 100755 --- a/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py @@ -20,7 +20,7 @@ def client(name='', command=None): return client prompt = ':\) ' -end_of_block = r'.*\xe2\x94\x82\r\n.*\xe2\x94\x98\r\n' +end_of_block = r'.*\r\n.*\r\n' with client('client1>') as client1, client('client2>', ['bash', '--noediting']) as client2: client1.expect(prompt) @@ -49,7 +49,7 @@ with client('client1>') as client1, client('client2>', ['bash', '--noediting']) client2.expect('{"row":{"sum(a)":"6","_version":"2"}}\r\n', escape=True) ## send Ctrl-C - os.kill(client2.process.pid,signal.SIGINT) + os.kill(client2.process.pid, signal.SIGINT) client1.send('DROP TABLE test.lv') client1.expect(prompt) From a467e7c1054217d6b3751009cb03b850ae6e459c Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Mon, 10 Jun 2019 22:22:53 -0400 Subject: [PATCH 0127/1165] * Moving uexpect.py so that it can be found * Trying to fix failed style checks * Trying to fix clang build fail --- .../DataStreams/LiveViewEventsBlockInputStream.h | 15 +++++---------- dbms/src/Interpreters/InterpreterAlterQuery.cpp | 2 +- dbms/src/Parsers/ASTWatchQuery.h | 2 +- dbms/src/Storages/StorageLiveView.h | 2 +- .../0_stateless/00958_live_view_watch_live.py | 2 +- .../00960_live_view_watch_events_live.py | 2 +- .../00962_temporary_live_view_watch_live.py | 2 +- ...0963_temporary_live_view_watch_live_timeout.py | 2 +- .../00964_live_view_watch_events_heartbeat.py | 2 +- .../00965_live_view_watch_heartbeat.py | 2 +- .../00966_live_view_watch_events_http.py | 2 +- .../0_stateless/00967_live_view_watch_http.py | 2 +- ...00970_live_view_watch_events_http_heartbeat.py | 2 +- .../00971_live_view_watch_http_heartbeat.py | 2 +- .../0_stateless}/helpers/uexpect.py | 0 15 files changed, 18 insertions(+), 23 deletions(-) rename dbms/tests/{integration => queries/0_stateless}/helpers/uexpect.py (100%) diff --git a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h index 35d2545419b..be21c5c71f6 100644 --- a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h +++ b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h @@ -66,15 +66,10 @@ public: Block getHeader() const override { - return { - ColumnWithTypeAndName( - ColumnUInt64::create(), - std::make_shared(), - "version"), - ColumnWithTypeAndName( - ColumnString::create(), - std::make_shared(), - "hash") + return + { + ColumnWithTypeAndName(ColumnUInt64::create(), std::make_shared(), "version"), + ColumnWithTypeAndName(ColumnString::create(), std::make_shared(), "hash") }; } @@ -93,7 +88,7 @@ public: { active = active_ptr.lock(); { - if (!blocks || blocks.get() != (*blocks_ptr).get()) + if (!blocks || (blocks.get() != (*blocks_ptr).get())) { blocks = (*blocks_ptr); blocks_metadata = (*blocks_metadata_ptr); diff --git a/dbms/src/Interpreters/InterpreterAlterQuery.cpp b/dbms/src/Interpreters/InterpreterAlterQuery.cpp index e8f3e4f4553..507b7a873d2 100644 --- a/dbms/src/Interpreters/InterpreterAlterQuery.cpp +++ b/dbms/src/Interpreters/InterpreterAlterQuery.cpp @@ -80,7 +80,7 @@ BlockIO InterpreterAlterQuery::execute() if (!live_view_commands.empty()) { live_view_commands.validate(*table); - for (const LiveViewCommand & command : live_view_commands) + for (const LiveViewCommand & command : live_view_commands) { auto live_view = std::dynamic_pointer_cast(table); switch (command.type) diff --git a/dbms/src/Parsers/ASTWatchQuery.h b/dbms/src/Parsers/ASTWatchQuery.h index 7e75d62a629..06d1460f038 100644 --- a/dbms/src/Parsers/ASTWatchQuery.h +++ b/dbms/src/Parsers/ASTWatchQuery.h @@ -25,7 +25,7 @@ public: bool is_watch_events; ASTWatchQuery() = default; - String getID(char) const override { return "WatchQuery_" + database + "_" + table; }; + String getID(char) const override { return "WatchQuery_" + database + "_" + table; } ASTPtr clone() const override { diff --git a/dbms/src/Storages/StorageLiveView.h b/dbms/src/Storages/StorageLiveView.h index fb250aec859..1114da7049d 100644 --- a/dbms/src/Storages/StorageLiveView.h +++ b/dbms/src/Storages/StorageLiveView.h @@ -28,7 +28,6 @@ namespace DB { class IAST; -using ASTPtr = std::shared_ptr; struct BlocksMetadata { @@ -36,6 +35,7 @@ struct BlocksMetadata UInt64 version; }; +using ASTPtr = std::shared_ptr; using BlocksMetadataPtr = std::shared_ptr; using SipHashPtr = std::shared_ptr; diff --git a/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py b/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py index 51bdca1a9b6..96537d0d5c1 100755 --- a/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py +++ b/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) def client(name=''): client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) diff --git a/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py b/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py index 0b441b72805..a775854de9e 100755 --- a/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py +++ b/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) def client(name=''): client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) diff --git a/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py b/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py index 5dfa6ac841e..fb75134fc4c 100755 --- a/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py +++ b/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) def client(name=''): client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) diff --git a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py index 09301aa6d59..4e12cd2234b 100755 --- a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py +++ b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) def client(name=''): client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) diff --git a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py index f3e5b1ee435..c7b2b1a6906 100755 --- a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) def client(name=''): client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) diff --git a/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py b/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py index 9f8a3c84af0..b501c6e5889 100755 --- a/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) def client(name=''): client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) diff --git a/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py b/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py index 65999f4c55f..4424bac3e54 100755 --- a/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py +++ b/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) def client(name='', command=None): if command is None: diff --git a/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py b/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py index a79d6882aa9..3c7e8cdd489 100755 --- a/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py +++ b/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) def client(name='', command=None): if command is None: diff --git a/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py b/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py index 95587ba9355..b7ab164c67a 100755 --- a/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) def client(name='', command=None): if command is None: diff --git a/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py b/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py index 8c40fc6d39d..2102b890132 100755 --- a/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py @@ -6,7 +6,7 @@ import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, '..', '..', 'integration', 'helpers', 'uexpect.py')) +uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) def client(name='', command=None): if command is None: diff --git a/dbms/tests/integration/helpers/uexpect.py b/dbms/tests/queries/0_stateless/helpers/uexpect.py similarity index 100% rename from dbms/tests/integration/helpers/uexpect.py rename to dbms/tests/queries/0_stateless/helpers/uexpect.py From b6efd8599fee992e1f54337fe376918f123b3520 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Tue, 11 Jun 2019 06:30:57 -0400 Subject: [PATCH 0128/1165] * Trying again to fix style checks. Now running ./utils/check-style/check-style reports no errors. --- dbms/src/DataStreams/LiveViewEventsBlockInputStream.h | 11 ++++------- dbms/src/Storages/StorageLiveView.h | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h index be21c5c71f6..7841550b5cb 100644 --- a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h +++ b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h @@ -64,13 +64,10 @@ public: condition.broadcast(); } - Block getHeader() const override + Block getHeader() const override { - return - { - ColumnWithTypeAndName(ColumnUInt64::create(), std::make_shared(), "version"), - ColumnWithTypeAndName(ColumnString::create(), std::make_shared(), "hash") - }; + Block header(ColumnWithTypeAndName(ColumnUInt64::create(), std::make_shared(), "version"), ColumnWithTypeAndName(ColumnString::create(), std::make_shared(), "hash")); + return header; } void refresh() @@ -88,7 +85,7 @@ public: { active = active_ptr.lock(); { - if (!blocks || (blocks.get() != (*blocks_ptr).get())) + if (!blocks || blocks.get() != (*blocks_ptr).get()) { blocks = (*blocks_ptr); blocks_metadata = (*blocks_metadata_ptr); diff --git a/dbms/src/Storages/StorageLiveView.h b/dbms/src/Storages/StorageLiveView.h index 1114da7049d..6899067c9f9 100644 --- a/dbms/src/Storages/StorageLiveView.h +++ b/dbms/src/Storages/StorageLiveView.h @@ -29,7 +29,7 @@ namespace DB class IAST; -struct BlocksMetadata +struct BlocksMetadata { String hash; UInt64 version; From 12060d887973daea23821c8ab8bc8d76f48549b6 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Tue, 11 Jun 2019 08:27:47 -0400 Subject: [PATCH 0129/1165] * Fixing errors that prevented clang build. --- dbms/src/DataStreams/LiveViewBlockInputStream.h | 8 ++++---- dbms/src/DataStreams/LiveViewEventsBlockInputStream.h | 11 +++++------ dbms/src/Parsers/ParserCreateQuery.cpp | 1 - dbms/src/Storages/StorageLiveView.cpp | 3 +-- dbms/src/Storages/StorageLiveView.h | 2 -- 5 files changed, 10 insertions(+), 15 deletions(-) diff --git a/dbms/src/DataStreams/LiveViewBlockInputStream.h b/dbms/src/DataStreams/LiveViewBlockInputStream.h index 6129c836597..9de503fd6f7 100644 --- a/dbms/src/DataStreams/LiveViewBlockInputStream.h +++ b/dbms/src/DataStreams/LiveViewBlockInputStream.h @@ -160,8 +160,8 @@ protected: } while (true) { - UInt64 timestamp_usec = (UInt64)timestamp.epochMicroseconds(); - bool signaled = condition.tryWait(mutex, std::max((UInt64)0, heartbeat_interval - (timestamp_usec - last_event_timestamp)) / 1000); + UInt64 timestamp_usec = static_cast(timestamp.epochMicroseconds()); + bool signaled = condition.tryWait(mutex, std::max(static_cast(0), heartbeat_interval - (timestamp_usec - last_event_timestamp)) / 1000); if (isCancelled() || storage.is_dropped) { @@ -174,7 +174,7 @@ protected: else { // heartbeat - last_event_timestamp = (UInt64)timestamp.epochMicroseconds(); + last_event_timestamp = static_cast(timestamp.epochMicroseconds()); return { getHeader(), true }; } } @@ -194,7 +194,7 @@ protected: --length; } - last_event_timestamp = (UInt64)timestamp.epochMicroseconds(); + last_event_timestamp = static_cast(timestamp.epochMicroseconds()); return { res, true }; } diff --git a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h index 7841550b5cb..215d5a17380 100644 --- a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h +++ b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h @@ -66,8 +66,7 @@ public: Block getHeader() const override { - Block header(ColumnWithTypeAndName(ColumnUInt64::create(), std::make_shared(), "version"), ColumnWithTypeAndName(ColumnString::create(), std::make_shared(), "hash")); - return header; + return {ColumnWithTypeAndName(ColumnUInt64::create(), std::make_shared(), "version"), ColumnWithTypeAndName(ColumnString::create(), std::make_shared(), "hash")}; } void refresh() @@ -182,8 +181,8 @@ protected: } while (true) { - UInt64 timestamp_usec = (UInt64)timestamp.epochMicroseconds(); - bool signaled = condition.tryWait(mutex, std::max((UInt64)0, heartbeat_interval - (timestamp_usec - last_event_timestamp)) / 1000); + UInt64 timestamp_usec = static_cast(timestamp.epochMicroseconds()); + bool signaled = condition.tryWait(mutex, std::max(static_cast(0), heartbeat_interval - (timestamp_usec - last_event_timestamp)) / 1000); if (isCancelled() || storage.is_dropped) { @@ -196,7 +195,7 @@ protected: else { // repeat the event block as a heartbeat - last_event_timestamp = (UInt64)timestamp.epochMicroseconds(); + last_event_timestamp = static_cast(timestamp.epochMicroseconds()); return { getHeader(), true }; } } @@ -215,7 +214,7 @@ protected: --length; } - last_event_timestamp = (UInt64)timestamp.epochMicroseconds(); + last_event_timestamp = static_cast(timestamp.epochMicroseconds()); return { getEventBlock(), true }; } diff --git a/dbms/src/Parsers/ParserCreateQuery.cpp b/dbms/src/Parsers/ParserCreateQuery.cpp index 4064dde5213..c8341f81770 100644 --- a/dbms/src/Parsers/ParserCreateQuery.cpp +++ b/dbms/src/Parsers/ParserCreateQuery.cpp @@ -509,7 +509,6 @@ bool ParserCreateQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) if (!s_as.ignore(pos, expected)) return false; - ParserSelectWithUnionQuery select_p; if (!select_p.parse(pos, select, expected)) return false; } diff --git a/dbms/src/Storages/StorageLiveView.cpp b/dbms/src/Storages/StorageLiveView.cpp index dd6e0179410..28e6717611f 100644 --- a/dbms/src/Storages/StorageLiveView.cpp +++ b/dbms/src/Storages/StorageLiveView.cpp @@ -172,7 +172,6 @@ Block StorageLiveView::getHeader() const bool StorageLiveView::getNewBlocks() { - Block block; SipHash hash; UInt128 key; BlocksPtr new_blocks = std::make_shared(); @@ -398,7 +397,7 @@ BlockInputStreams StorageLiveView::watch( int64_t length = -2; if (query.limit_length) - length = (int64_t)safeGet(typeid_cast(*query.limit_length).value); + length = static_cast(safeGet(typeid_cast(*query.limit_length).value)); if (query.is_watch_events) { diff --git a/dbms/src/Storages/StorageLiveView.h b/dbms/src/Storages/StorageLiveView.h index 6899067c9f9..01dd82ff1fd 100644 --- a/dbms/src/Storages/StorageLiveView.h +++ b/dbms/src/Storages/StorageLiveView.h @@ -257,10 +257,8 @@ private: std::shared_ptr active_ptr; /// Current data blocks that store query result std::shared_ptr blocks_ptr; - BlocksPtr new_blocks; /// Current data blocks metadata std::shared_ptr blocks_metadata_ptr; - BlocksMetadataPtr new_blocks_metadata; BlocksPtrs mergeable_blocks; void noUsersThread(const UInt64 & timeout); From 536bdb588da53bc90f89933783dc94f04e1c307a Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Tue, 11 Jun 2019 21:28:20 -0400 Subject: [PATCH 0130/1165] * Fixing and reorganazing LIVE VIEW tests --- .../0_stateless/00958_live_view_watch_live.py | 20 ++--- .../00960_live_view_watch_events_live.py | 20 ++--- .../00962_temporary_live_view_watch_live.py | 20 ++--- ..._temporary_live_view_watch_live_timeout.py | 20 ++--- .../00964_live_view_watch_events_heartbeat.py | 19 ++--- .../00965_live_view_watch_heartbeat.py | 20 ++--- .../00966_live_view_watch_events_http.py | 38 +++------- .../0_stateless/00967_live_view_watch_http.py | 38 +++------- ...0_live_view_watch_events_http_heartbeat.py | 45 ++++-------- .../00971_live_view_watch_http_heartbeat.py | 48 +++++------- .../queries/0_stateless/helpers/client.py | 21 ++++++ .../queries/0_stateless/helpers/httpclient.py | 14 ++++ .../queries/0_stateless/helpers/httpexpect.py | 73 +++++++++++++++++++ .../queries/0_stateless/helpers/uexpect.py | 30 +++++--- 14 files changed, 224 insertions(+), 202 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/helpers/client.py create mode 100644 dbms/tests/queries/0_stateless/helpers/httpclient.py create mode 100644 dbms/tests/queries/0_stateless/helpers/httpexpect.py diff --git a/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py b/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py index 96537d0d5c1..cb6f1e95f7e 100755 --- a/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py +++ b/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py @@ -1,25 +1,18 @@ #!/usr/bin/env python -import imp import os import sys import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(CURDIR, 'helpers')) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) +from client import client, prompt, end_of_block -def client(name=''): - client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) - client.eol('\r') - # Note: uncomment this line for debugging - #client.logger(sys.stdout, prefix=name) - client.timeout(2) - return client +log = None +# uncomment the line below for debugging +#log=sys.stdout -prompt = ':\) ' -end_of_block = r'.*\r\n.*\r\n' - -with client('client1>') as client1, client('client2>') as client2: +with client(name='client1>', log=log) as client1, client(name='client2>', log=log) as client2: client1.expect(prompt) client2.expect(prompt) @@ -32,6 +25,7 @@ with client('client1>') as client1, client('client2>') as client2: client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') client1.expect(prompt) client1.send('WATCH test.lv') + client1.expect(r'0.*1' + end_of_block) client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') client1.expect(r'6.*2' + end_of_block) client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') diff --git a/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py b/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py index a775854de9e..414f9c1ad96 100755 --- a/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py +++ b/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py @@ -1,25 +1,18 @@ #!/usr/bin/env python -import imp import os import sys import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(CURDIR, 'helpers')) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) +from client import client, prompt, end_of_block -def client(name=''): - client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) - client.eol('\r') - # Note: uncomment this line for debugging - #client.logger(sys.stdout, prefix=name) - client.timeout(2) - return client +log = None +# uncomment the line below for debugging +#log=sys.stdout -prompt = ':\) ' -end_of_block = r'.*\r\n.*\r\n' - -with client('client1>') as client1, client('client2>') as client2: +with client(name='client1>', log=log) as client1, client(name='client2>', log=log) as client2: client1.expect(prompt) client2.expect(prompt) @@ -32,6 +25,7 @@ with client('client1>') as client1, client('client2>') as client2: client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') client1.expect(prompt) client1.send('WATCH test.lv EVENTS') + client1.expect('1.*' + end_of_block) client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') client1.expect('2.*4cd0592103888d4682de9a32a23602e3' + end_of_block) client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') diff --git a/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py b/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py index fb75134fc4c..48311d890c5 100755 --- a/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py +++ b/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py @@ -1,25 +1,18 @@ #!/usr/bin/env python -import imp import os import sys import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(CURDIR, 'helpers')) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) +from client import client, prompt, end_of_block -def client(name=''): - client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) - client.eol('\r') - # Note: uncomment this line for debugging - #client.logger(sys.stdout, prefix=name) - client.timeout(2) - return client +log = None +# uncomment the line below for debugging +#log=sys.stdout -prompt = ':\) ' -end_of_block = r'.*\r\n.*\r\n' - -with client('client1>') as client1, client('client2>') as client2: +with client(name='client1>', log=log) as client1, client(name='client2>', log=log) as client2: client1.expect(prompt) client2.expect(prompt) @@ -32,6 +25,7 @@ with client('client1>') as client1, client('client2>') as client2: client1.send('CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') client1.expect(prompt) client1.send('WATCH test.lv') + client1.expect(r'0.*1' + end_of_block) client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') client1.expect(r'6.*2' + end_of_block) client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') diff --git a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py index 4e12cd2234b..581363cd796 100755 --- a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py +++ b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py @@ -1,25 +1,18 @@ #!/usr/bin/env python -import imp import os import sys import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(CURDIR, 'helpers')) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) +from client import client, prompt, end_of_block -def client(name=''): - client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) - client.eol('\r') - # Note: uncomment this line for debugging - #client.logger(sys.stdout, prefix=name) - client.timeout(2) - return client +log = None +# uncomment the line below for debugging +#log=sys.stdout -prompt = ':\) ' -end_of_block = r'.*\r\n.*\r\n' - -with client('client1>') as client1, client('client2>') as client2: +with client(name='client1>', log=log) as client1, client(name='client2>', log=log) as client2: client1.expect(prompt) client2.expect(prompt) @@ -34,6 +27,7 @@ with client('client1>') as client1, client('client2>') as client2: client1.send('CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') client1.expect(prompt) client1.send('WATCH test.lv') + client1.expect(r'0.*1' + end_of_block) client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') client2.expect(prompt) client1.expect(r'6.*2' + end_of_block) diff --git a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py index c7b2b1a6906..b624e0b7080 100755 --- a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py @@ -1,25 +1,18 @@ #!/usr/bin/env python -import imp import os import sys import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(CURDIR, 'helpers')) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) +from client import client, prompt, end_of_block -def client(name=''): - client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) - client.eol('\r') - # Note: uncomment this line for debugging - #client.logger(sys.stdout, prefix=name) - client.timeout(2) - return client +log = None +# uncomment the line below for debugging +#log=sys.stdout -prompt = ':\) ' -end_of_block = r'.*\r\n.*\r\n' - -with client('client1>') as client1, client('client2>') as client2: +with client(name='client1>', log=log) as client1, client(name='client2>', log=log) as client2: client1.expect(prompt) client2.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py b/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py index b501c6e5889..dfb46273f7c 100755 --- a/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py @@ -1,25 +1,18 @@ #!/usr/bin/env python -import imp import os import sys import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(CURDIR, 'helpers')) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) +from client import client, prompt, end_of_block -def client(name=''): - client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) - client.eol('\r') - # Note: uncomment this line for debugging - #client.logger(sys.stdout, prefix=name) - client.timeout(2) - return client +log = None +# uncomment the line below for debugging +#log=sys.stdout -prompt = ':\) ' -end_of_block = r'.*\r\n.*\r\n' - -with client('client1>') as client1, client('client2>') as client2: +with client(name='client1>', log=log) as client1, client(name='client2>', log=log) as client2: client1.expect(prompt) client2.expect(prompt) @@ -34,6 +27,7 @@ with client('client1>') as client1, client('client2>') as client2: client1.send('CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') client1.expect(prompt) client1.send('WATCH test.lv') + client1.expect(r'0.*1' + end_of_block) client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') client1.expect(r'6.*2' + end_of_block) client1.expect('Progress: 2.00 rows.*\)') diff --git a/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py b/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py index 4424bac3e54..a1b6f2418ea 100755 --- a/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py +++ b/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py @@ -1,28 +1,18 @@ #!/usr/bin/env python -import imp import os import sys -import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(CURDIR, 'helpers')) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) +from client import client, prompt, end_of_block +from httpclient import client as http_client -def client(name='', command=None): - if command is None: - client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) - else: - client = uexpect.spawn(command) - client.eol('\r') - # Note: uncomment this line for debugging - #client.logger(sys.stdout, prefix=name) - client.timeout(2) - return client +log = None +# uncomment the line below for debugging +#log=sys.stdout -prompt = ':\) ' -end_of_block = r'.*\r\n.*\r\n' - -with client('client1>') as client1, client('client2>', ['bash', '--noediting']) as client2: +with client(name='client1>', log=log) as client1: client1.expect(prompt) client1.send('DROP TABLE IF EXISTS test.lv') @@ -34,16 +24,12 @@ with client('client1>') as client1, client('client2>', ['bash', '--noediting']) client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') client1.expect(prompt) - client2.expect('[\$#] ') - client2.send('wget -O- -q "http://localhost:8123/?query=WATCH test.lv EVENTS"') - client2.expect('.*1\tc9d39b11cce79112219a73aaa319b475\r\n') - client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') - client1.expect(prompt) - - client2.expect('.*2\t.*\r\n') - ## send Ctrl-C - os.kill(client2.process.pid,signal.SIGINT) + with http_client({'method':'GET', 'url': '/?query=WATCH%20test.lv%20EVENTS'}, name='client2>', log=log) as client2: + client2.expect('.*1\tc9d39b11cce79112219a73aaa319b475\n') + client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') + client1.expect(prompt) + client2.expect('.*2\t.*\n') client1.send('DROP TABLE test.lv') client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py b/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py index 3c7e8cdd489..d3439431eb3 100755 --- a/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py +++ b/dbms/tests/queries/0_stateless/00967_live_view_watch_http.py @@ -1,28 +1,18 @@ #!/usr/bin/env python -import imp import os import sys -import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(CURDIR, 'helpers')) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) +from client import client, prompt, end_of_block +from httpclient import client as http_client -def client(name='', command=None): - if command is None: - client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) - else: - client = uexpect.spawn(command) - client.eol('\r') - # Note: uncomment this line for debugging - #client.logger(sys.stdout, prefix=name) - client.timeout(2) - return client +log = None +# uncomment the line below for debugging +#log=sys.stdout -prompt = ':\) ' -end_of_block = r'.*\r\n.*\r\n' - -with client('client1>') as client1, client('client2>', ['bash', '--noediting']) as client2: +with client(name='client1>', log=log) as client1: client1.expect(prompt) client1.send('DROP TABLE IF EXISTS test.lv') @@ -34,16 +24,12 @@ with client('client1>') as client1, client('client2>', ['bash', '--noediting']) client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') client1.expect(prompt) - client2.expect('[\$#] ') - client2.send('wget -O- -q "http://localhost:8123/?query=WATCH test.lv"') - client2.expect('.*0\t1\r\n') - client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') - client1.expect(prompt) - - client2.expect('.*6\t2\r\n') - ## send Ctrl-C - os.kill(client2.process.pid,signal.SIGINT) + with http_client({'method':'GET', 'url':'/?query=WATCH%20test.lv'}, name='client2>', log=log) as client2: + client2.expect('.*0\t1\n') + client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') + client1.expect(prompt) + client2.expect('.*6\t2\n') client1.send('DROP TABLE test.lv') client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py b/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py index b7ab164c67a..29ea2142d5c 100755 --- a/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py @@ -1,28 +1,18 @@ #!/usr/bin/env python -import imp import os import sys -import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(CURDIR, 'helpers')) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) +from client import client, prompt, end_of_block +from httpclient import client as http_client -def client(name='', command=None): - if command is None: - client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) - else: - client = uexpect.spawn(command) - client.eol('\r') - # Note: uncomment this line for debugging - #client.logger(sys.stdout, prefix=name) - client.timeout(2) - return client +log = None +# uncomment the line below for debugging +#log=sys.stdout -prompt = ':\) ' -end_of_block = r'.*\r\n.*\r\n' - -with client('client1>') as client1, client('client2>', ['bash', '--noediting']) as client2: +with client(name='client1>', log=log) as client1: client1.expect(prompt) client1.send('DROP TABLE IF EXISTS test.lv') @@ -34,21 +24,18 @@ with client('client1>') as client1, client('client2>', ['bash', '--noediting']) client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') client1.expect(prompt) - client2.expect('[\$#] ') - client2.send('wget -O- -q "http://localhost:8123/?live_view_heartbeat_interval=1&query=WATCH test.lv EVENTS FORMAT JSONEachRowWithProgress"') - client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}\r\n', escape=True) - client2.expect('{"row":{"version":"1","hash":"c9d39b11cce79112219a73aaa319b475"}}', escape=True) - client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}', escape=True) - # heartbeat is provided by progress message - client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}', escape=True) - client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') - client1.expect(prompt) + with http_client({'method':'GET', 'url': '/?live_view_heartbeat_interval=1&query=WATCH%20test.lv%20EVENTS%20FORMAT%20JSONEachRowWithProgress'}, name='client2>', log=log) as client2: + client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}\n', escape=True) + client2.expect('{"row":{"version":"1","hash":"c9d39b11cce79112219a73aaa319b475"}}', escape=True) + client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}', escape=True) + # heartbeat is provided by progress message + client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}', escape=True) - client2.expect('{"row":{"version":"2","hash":"4cd0592103888d4682de9a32a23602e3"}}\r\n', escape=True) + client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') + client1.expect(prompt) - ## send Ctrl-C - os.kill(client2.process.pid,signal.SIGINT) + client2.expect('{"row":{"version":"2","hash":"4cd0592103888d4682de9a32a23602e3"}}\n', escape=True) client1.send('DROP TABLE test.lv') client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py b/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py index 2102b890132..7bdb47b7caa 100755 --- a/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00971_live_view_watch_http_heartbeat.py @@ -1,28 +1,18 @@ #!/usr/bin/env python -import imp import os import sys -import signal CURDIR = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(CURDIR, 'helpers')) -uexpect = imp.load_source('uexpect', os.path.join(CURDIR, 'helpers', 'uexpect.py')) +from client import client, prompt, end_of_block +from httpclient import client as http_client -def client(name='', command=None): - if command is None: - client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) - else: - client = uexpect.spawn(command) - client.eol('\r') - # Note: uncomment this line for debugging - #client.logger(sys.stdout, prefix=name) - client.timeout(2) - return client +log = None +# uncomment the line below for debugging +#log=sys.stdout -prompt = ':\) ' -end_of_block = r'.*\r\n.*\r\n' - -with client('client1>') as client1, client('client2>', ['bash', '--noediting']) as client2: +with client(name='client1>', log=log) as client1: client1.expect(prompt) client1.send('DROP TABLE IF EXISTS test.lv') @@ -34,22 +24,18 @@ with client('client1>') as client1, client('client2>', ['bash', '--noediting']) client1.send('CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') client1.expect(prompt) - client2.expect('[\$#] ') - client2.send('wget -O- -q "http://localhost:8123/?live_view_heartbeat_interval=1&query=WATCH test.lv FORMAT JSONEachRowWithProgress"') - client2.expect('"progress".*',) - client2.expect('{"row":{"sum(a)":"0","_version":"1"}}\r\n', escape=True) - client2.expect('"progress".*\r\n') - # heartbeat is provided by progress message - client2.expect('"progress".*\r\n') + with http_client({'method':'GET', 'url':'/?live_view_heartbeat_interval=1&query=WATCH%20test.lv%20FORMAT%20JSONEachRowWithProgress'}, name='client2>', log=log) as client2: + client2.expect('"progress".*',) + client2.expect('{"row":{"sum(a)":"0","_version":"1"}}\n', escape=True) + client2.expect('"progress".*\n') + # heartbeat is provided by progress message + client2.expect('"progress".*\n') - client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') - client1.expect(prompt) + client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') + client1.expect(prompt) - client2.expect('"progress".*"read_rows":"2".*\r\n') - client2.expect('{"row":{"sum(a)":"6","_version":"2"}}\r\n', escape=True) - - ## send Ctrl-C - os.kill(client2.process.pid, signal.SIGINT) + client2.expect('"progress".*"read_rows":"2".*\n') + client2.expect('{"row":{"sum(a)":"6","_version":"2"}}\n', escape=True) client1.send('DROP TABLE test.lv') client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/helpers/client.py b/dbms/tests/queries/0_stateless/helpers/client.py new file mode 100644 index 00000000000..b509a321cee --- /dev/null +++ b/dbms/tests/queries/0_stateless/helpers/client.py @@ -0,0 +1,21 @@ +import os +import sys + +CURDIR = os.path.dirname(os.path.realpath(__file__)) + +sys.path.insert(0, os.path.join(CURDIR)) + +import uexpect + +prompt = ':\) ' +end_of_block = r'.*\r\n.*\r\n' + +def client(command=None, name='', log=None): + if command is None: + client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) + else: + client = uexpect.spawn(command) + client.eol('\r') + client.logger(log, prefix=name) + client.timeout(2) + return client diff --git a/dbms/tests/queries/0_stateless/helpers/httpclient.py b/dbms/tests/queries/0_stateless/helpers/httpclient.py new file mode 100644 index 00000000000..111841ba708 --- /dev/null +++ b/dbms/tests/queries/0_stateless/helpers/httpclient.py @@ -0,0 +1,14 @@ +import os +import sys + +CURDIR = os.path.dirname(os.path.realpath(__file__)) + +sys.path.insert(0, os.path.join(CURDIR)) + +import httpexpect + +def client(request, name='', log=None): + client = httpexpect.spawn({'host':'localhost','port':8123}, request) + client.logger(log, prefix=name) + client.timeout(2) + return client diff --git a/dbms/tests/queries/0_stateless/helpers/httpexpect.py b/dbms/tests/queries/0_stateless/helpers/httpexpect.py new file mode 100644 index 00000000000..e440dafce4e --- /dev/null +++ b/dbms/tests/queries/0_stateless/helpers/httpexpect.py @@ -0,0 +1,73 @@ +# Copyright (c) 2019 Vitaliy Zakaznikov +# +# Licensed 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. +import os +import sys +import httplib + +CURDIR = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, CURDIR) + +import uexpect + +from threading import Thread, Event +from Queue import Queue, Empty + +class IO(uexpect.IO): + def __init__(self, connection, response, queue, reader): + self.connection = connection + self.response = response + super(IO, self).__init__(None, None, queue, reader) + + def write(self, data): + raise NotImplementedError + + def close(self, force=True): + self.reader['kill_event'].set() + self.connection.close() + if self._logger: + self._logger.write('\n') + self._logger.flush() + + +def reader(response, queue, kill_event): + while True: + try: + if kill_event.is_set(): + break + data = response.read(1) + queue.put(data) + except Exception, e: + if kill_event.is_set(): + break + raise + +def spawn(connection, request): + connection = httplib.HTTPConnection(**connection) + connection.request(**request) + response = connection.getresponse() + + queue = Queue() + reader_kill_event = Event() + thread = Thread(target=reader, args=(response, queue, reader_kill_event)) + thread.daemon = True + thread.start() + + return IO(connection, response, queue, reader={'thread':thread, 'kill_event':reader_kill_event}) + +if __name__ == '__main__': + with http({'host':'localhost','port':8123},{'method':'GET', 'url':'?query=SELECT%201'}) as client: + client.logger(sys.stdout) + client.timeout(2) + print client.response.status, client.response.reason + client.expect('1\n') diff --git a/dbms/tests/queries/0_stateless/helpers/uexpect.py b/dbms/tests/queries/0_stateless/helpers/uexpect.py index 2a42b8a5de0..2f323cf6ca6 100644 --- a/dbms/tests/queries/0_stateless/helpers/uexpect.py +++ b/dbms/tests/queries/0_stateless/helpers/uexpect.py @@ -35,10 +35,13 @@ class ExpectTimeoutError(Exception): self.buffer = buffer def __str__(self): - return ('Timeout %.3fs ' % float(self.timeout) + - 'for %s ' % repr(self.pattern.pattern) + - 'buffer %s ' % repr(self.buffer[:]) + - 'or \'%s\'' % ','.join(['%x' % ord(c) for c in self.buffer[:]])) + s = 'Timeout %.3fs ' % float(self.timeout) + if self.pattern: + s += 'for %s ' % repr(self.pattern.pattern) + if self.buffer: + s += 'buffer %s ' % repr(self.buffer[:]) + s += 'or \'%s\'' % ','.join(['%x' % ord(c) for c in self.buffer[:]]) + return s class IO(object): class EOF(object): @@ -125,13 +128,22 @@ class IO(object): if timeout is None: timeout = self._timeout timeleft = timeout - while timeleft >= 0: + while True: start_time = time.time() + if self.buffer is not None: + self.match = pattern.search(self.buffer, 0) + if self.match is not None: + self.after = self.buffer[self.match.start():self.match.end()] + self.before = self.buffer[:self.match.start()] + self.buffer = self.buffer[self.match.end():] + break + if timeleft < 0: + break try: data = self.read(timeout=timeleft, raise_exception=True) except TimeoutError: if self._logger: - self._logger.write(self.buffer + '\n') + self._logger.write((self.buffer or '') + '\n') self._logger.flush() exception = ExpectTimeoutError(pattern, timeout, self.buffer) self.buffer = None @@ -139,12 +151,6 @@ class IO(object): timeleft -= (time.time() - start_time) if data: self.buffer = (self.buffer + data) if self.buffer else data - self.match = pattern.search(self.buffer, 0) - if self.match is not None: - self.after = self.buffer[self.match.start():self.match.end()] - self.before = self.buffer[:self.match.start()] - self.buffer = self.buffer[self.match.end():] - break if self._logger: self._logger.write((self.before or '') + (self.after or '')) self._logger.flush() From 5983273694c45c76da6619b0b732d52e02db8bd7 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Wed, 12 Jun 2019 09:11:44 -0400 Subject: [PATCH 0131/1165] Fixing bugs reported by sanitizers * data race condition on storage is_dropped access * invalid reference to storage after it is deleted * invalid reference to mutex after storage is deleted --- .../DataStreams/LiveViewBlockInputStream.h | 33 +++++++++---------- .../LiveViewEventsBlockInputStream.h | 28 ++++++++-------- dbms/src/Storages/IStorage.h | 2 +- dbms/src/Storages/StorageLiveView.cpp | 4 +-- 4 files changed, 32 insertions(+), 35 deletions(-) diff --git a/dbms/src/DataStreams/LiveViewBlockInputStream.h b/dbms/src/DataStreams/LiveViewBlockInputStream.h index 9de503fd6f7..e9bb599a1d6 100644 --- a/dbms/src/DataStreams/LiveViewBlockInputStream.h +++ b/dbms/src/DataStreams/LiveViewBlockInputStream.h @@ -36,17 +36,18 @@ public: { /// Start storage no users thread /// if we are the last active user - if (!storage.is_dropped && blocks_ptr.use_count() < 3) - storage.startNoUsersThread(temporary_live_view_timeout); + if (!storage->is_dropped && blocks_ptr.use_count() < 3) + storage->startNoUsersThread(temporary_live_view_timeout); } /// length default -2 because we want LIMIT to specify number of updates so that LIMIT 1 waits for 1 update /// and LIMIT 0 just returns data without waiting for any updates - LiveViewBlockInputStream(StorageLiveView & storage_, std::shared_ptr blocks_ptr_, + LiveViewBlockInputStream(std::shared_ptr storage_, + std::shared_ptr blocks_ptr_, std::shared_ptr blocks_metadata_ptr_, - std::shared_ptr active_ptr_, Poco::Condition & condition_, Poco::FastMutex & mutex_, + std::shared_ptr active_ptr_, int64_t length_, const UInt64 & heartbeat_interval_, const UInt64 & temporary_live_view_timeout_) - : storage(storage_), blocks_ptr(blocks_ptr_), blocks_metadata_ptr(blocks_metadata_ptr_), active_ptr(active_ptr_), condition(condition_), mutex(mutex_), length(length_ + 1), heartbeat_interval(heartbeat_interval_ * 1000000), temporary_live_view_timeout(temporary_live_view_timeout_), + : storage(storage_), blocks_ptr(blocks_ptr_), blocks_metadata_ptr(blocks_metadata_ptr_), active_ptr(active_ptr_), length(length_ + 1), heartbeat_interval(heartbeat_interval_ * 1000000), temporary_live_view_timeout(temporary_live_view_timeout_), blocks_hash("") { /// grab active pointer @@ -57,14 +58,14 @@ public: void cancel(bool kill) override { - if (isCancelled() || storage.is_dropped) + if (isCancelled() || storage->is_dropped) return; IBlockInputStream::cancel(kill); - Poco::FastMutex::ScopedLock lock(mutex); - condition.broadcast(); + Poco::FastMutex::ScopedLock lock(storage->mutex); + storage->condition.broadcast(); } - Block getHeader() const override { return storage.getHeader(); } + Block getHeader() const override { return storage->getHeader(); } void refresh() { @@ -117,7 +118,7 @@ protected: /// If blocks were never assigned get blocks if (!blocks) { - Poco::FastMutex::ScopedLock lock(mutex); + Poco::FastMutex::ScopedLock lock(storage->mutex); if (!active) return { Block(), false }; blocks = (*blocks_ptr); @@ -126,7 +127,7 @@ protected: end = blocks->end(); } - if (isCancelled() || storage.is_dropped) + if (isCancelled() || storage->is_dropped) { return { Block(), true }; } @@ -134,7 +135,7 @@ protected: if (it == end) { { - Poco::FastMutex::ScopedLock lock(mutex); + Poco::FastMutex::ScopedLock lock(storage->mutex); if (!active) return { Block(), false }; /// If we are done iterating over our blocks @@ -161,9 +162,9 @@ protected: while (true) { UInt64 timestamp_usec = static_cast(timestamp.epochMicroseconds()); - bool signaled = condition.tryWait(mutex, std::max(static_cast(0), heartbeat_interval - (timestamp_usec - last_event_timestamp)) / 1000); + bool signaled = storage->condition.tryWait(storage->mutex, std::max(static_cast(0), heartbeat_interval - (timestamp_usec - last_event_timestamp)) / 1000); - if (isCancelled() || storage.is_dropped) + if (isCancelled() || storage->is_dropped) { return { Block(), true }; } @@ -199,7 +200,7 @@ protected: } private: - StorageLiveView & storage; + std::shared_ptr storage; std::shared_ptr blocks_ptr; std::shared_ptr blocks_metadata_ptr; std::weak_ptr active_ptr; @@ -209,8 +210,6 @@ private: Blocks::iterator it; Blocks::iterator end; Blocks::iterator begin; - Poco::Condition & condition; - Poco::FastMutex & mutex; /// Length specifies number of updates to send, default -1 (no limit) int64_t length; bool end_of_blocks{0}; diff --git a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h index 215d5a17380..c7911074176 100644 --- a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h +++ b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h @@ -40,14 +40,14 @@ public: { /// Start storage no users thread /// if we are the last active user - if (!storage.is_dropped && blocks_ptr.use_count() < 3) - storage.startNoUsersThread(temporary_live_view_timeout); + if (!storage->is_dropped && blocks_ptr.use_count() < 3) + storage->startNoUsersThread(temporary_live_view_timeout); } /// length default -2 because we want LIMIT to specify number of updates so that LIMIT 1 waits for 1 update /// and LIMIT 0 just returns data without waiting for any updates - LiveViewEventsBlockInputStream(StorageLiveView & storage_, std::shared_ptr blocks_ptr_, std::shared_ptr blocks_metadata_ptr_, std::shared_ptr active_ptr_, Poco::Condition & condition_, Poco::FastMutex & mutex_, + LiveViewEventsBlockInputStream(std::shared_ptr storage_, std::shared_ptr blocks_ptr_, std::shared_ptr blocks_metadata_ptr_, std::shared_ptr active_ptr_, int64_t length_, const UInt64 & heartbeat_interval_, const UInt64 & temporary_live_view_timeout_) - : storage(storage_), blocks_ptr(blocks_ptr_), blocks_metadata_ptr(blocks_metadata_ptr_), active_ptr(active_ptr_), condition(condition_), mutex(mutex_), length(length_ + 1), heartbeat_interval(heartbeat_interval_ * 1000000), temporary_live_view_timeout(temporary_live_view_timeout_) + : storage(storage_), blocks_ptr(blocks_ptr_), blocks_metadata_ptr(blocks_metadata_ptr_), active_ptr(active_ptr_), length(length_ + 1), heartbeat_interval(heartbeat_interval_ * 1000000), temporary_live_view_timeout(temporary_live_view_timeout_) { /// grab active pointer active = active_ptr.lock(); @@ -57,11 +57,11 @@ public: void cancel(bool kill) override { - if (isCancelled() || storage.is_dropped) + if (isCancelled() || storage->is_dropped) return; IBlockInputStream::cancel(kill); - Poco::FastMutex::ScopedLock lock(mutex); - condition.broadcast(); + Poco::FastMutex::ScopedLock lock(storage->mutex); + storage->condition.broadcast(); } Block getHeader() const override @@ -136,7 +136,7 @@ protected: /// If blocks were never assigned get blocks if (!blocks) { - Poco::FastMutex::ScopedLock lock(mutex); + Poco::FastMutex::ScopedLock lock(storage->mutex); if (!active) return { Block(), false }; blocks = (*blocks_ptr); @@ -146,7 +146,7 @@ protected: end = blocks->end(); } - if (isCancelled() || storage.is_dropped) + if (isCancelled() || storage->is_dropped) { return { Block(), true }; } @@ -154,7 +154,7 @@ protected: if (it == end) { { - Poco::FastMutex::ScopedLock lock(mutex); + Poco::FastMutex::ScopedLock lock(storage->mutex); if (!active) return { Block(), false }; /// If we are done iterating over our blocks @@ -182,9 +182,9 @@ protected: while (true) { UInt64 timestamp_usec = static_cast(timestamp.epochMicroseconds()); - bool signaled = condition.tryWait(mutex, std::max(static_cast(0), heartbeat_interval - (timestamp_usec - last_event_timestamp)) / 1000); + bool signaled = storage->condition.tryWait(storage->mutex, std::max(static_cast(0), heartbeat_interval - (timestamp_usec - last_event_timestamp)) / 1000); - if (isCancelled() || storage.is_dropped) + if (isCancelled() || storage->is_dropped) { return { Block(), true }; } @@ -220,7 +220,7 @@ protected: } private: - StorageLiveView & storage; + std::shared_ptr storage; std::shared_ptr blocks_ptr; std::shared_ptr blocks_metadata_ptr; std::weak_ptr active_ptr; @@ -230,8 +230,6 @@ private: Blocks::iterator it; Blocks::iterator end; Blocks::iterator begin; - Poco::Condition & condition; - Poco::FastMutex & mutex; /// Length specifies number of updates to send, default -1 (no limit) int64_t length; bool end_of_blocks{0}; diff --git a/dbms/src/Storages/IStorage.h b/dbms/src/Storages/IStorage.h index 4a63c1ef34a..9fcd8e5ddcf 100644 --- a/dbms/src/Storages/IStorage.h +++ b/dbms/src/Storages/IStorage.h @@ -298,7 +298,7 @@ public: return {}; } - bool is_dropped{false}; + std::atomic is_dropped{false}; /// Does table support index for IN sections virtual bool supportsIndexForIn() const { return false; } diff --git a/dbms/src/Storages/StorageLiveView.cpp b/dbms/src/Storages/StorageLiveView.cpp index 28e6717611f..9a129141a1b 100644 --- a/dbms/src/Storages/StorageLiveView.cpp +++ b/dbms/src/Storages/StorageLiveView.cpp @@ -401,7 +401,7 @@ BlockInputStreams StorageLiveView::watch( if (query.is_watch_events) { - auto reader = std::make_shared(*this, blocks_ptr, blocks_metadata_ptr, active_ptr, condition, mutex, length, context.getSettingsRef().live_view_heartbeat_interval.totalSeconds(), + auto reader = std::make_shared(std::static_pointer_cast(shared_from_this()), blocks_ptr, blocks_metadata_ptr, active_ptr, length, context.getSettingsRef().live_view_heartbeat_interval.totalSeconds(), context.getSettingsRef().temporary_live_view_timeout.totalSeconds()); if (no_users_thread.joinable()) @@ -426,7 +426,7 @@ BlockInputStreams StorageLiveView::watch( } else { - auto reader = std::make_shared(*this, blocks_ptr, blocks_metadata_ptr, active_ptr, condition, mutex, length, context.getSettingsRef().live_view_heartbeat_interval.totalSeconds(), + auto reader = std::make_shared(std::static_pointer_cast( shared_from_this()), blocks_ptr, blocks_metadata_ptr, active_ptr, length, context.getSettingsRef().live_view_heartbeat_interval.totalSeconds(), context.getSettingsRef().temporary_live_view_timeout.totalSeconds()); if (no_users_thread.joinable()) From 576393272bc5d67983ca55bdd7f169598a7db654 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Wed, 12 Jun 2019 20:45:41 -0400 Subject: [PATCH 0132/1165] * Fixing styling check error --- dbms/src/Storages/StorageLiveView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Storages/StorageLiveView.cpp b/dbms/src/Storages/StorageLiveView.cpp index 9a129141a1b..77e95ac2e48 100644 --- a/dbms/src/Storages/StorageLiveView.cpp +++ b/dbms/src/Storages/StorageLiveView.cpp @@ -426,7 +426,7 @@ BlockInputStreams StorageLiveView::watch( } else { - auto reader = std::make_shared(std::static_pointer_cast( shared_from_this()), blocks_ptr, blocks_metadata_ptr, active_ptr, length, context.getSettingsRef().live_view_heartbeat_interval.totalSeconds(), + auto reader = std::make_shared(std::static_pointer_cast(shared_from_this()), blocks_ptr, blocks_metadata_ptr, active_ptr, length, context.getSettingsRef().live_view_heartbeat_interval.totalSeconds(), context.getSettingsRef().temporary_live_view_timeout.totalSeconds()); if (no_users_thread.joinable()) From 825c21f29a38e33debe9c931e6435cef84dba2c3 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Thu, 13 Jun 2019 06:36:59 -0400 Subject: [PATCH 0133/1165] * Increasing timeout from 2 to 20 sec. * Style fix --- .../queries/0_stateless/00962_temporary_live_view_watch_live.py | 2 +- dbms/tests/queries/0_stateless/helpers/client.py | 2 +- dbms/tests/queries/0_stateless/helpers/httpclient.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py b/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py index 48311d890c5..1967284c38b 100755 --- a/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py +++ b/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py @@ -18,7 +18,7 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client1.send('DROP TABLE IF EXISTS test.lv') client1.expect(prompt) - client1.send(' DROP TABLE IF EXISTS test.mt') + client1.send('DROP TABLE IF EXISTS test.mt') client1.expect(prompt) client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/helpers/client.py b/dbms/tests/queries/0_stateless/helpers/client.py index b509a321cee..59ea3d898ea 100644 --- a/dbms/tests/queries/0_stateless/helpers/client.py +++ b/dbms/tests/queries/0_stateless/helpers/client.py @@ -17,5 +17,5 @@ def client(command=None, name='', log=None): client = uexpect.spawn(command) client.eol('\r') client.logger(log, prefix=name) - client.timeout(2) + client.timeout(20) return client diff --git a/dbms/tests/queries/0_stateless/helpers/httpclient.py b/dbms/tests/queries/0_stateless/helpers/httpclient.py index 111841ba708..a42fad2cbc3 100644 --- a/dbms/tests/queries/0_stateless/helpers/httpclient.py +++ b/dbms/tests/queries/0_stateless/helpers/httpclient.py @@ -10,5 +10,5 @@ import httpexpect def client(request, name='', log=None): client = httpexpect.spawn({'host':'localhost','port':8123}, request) client.logger(log, prefix=name) - client.timeout(2) + client.timeout(20) return client From b82bb4a954391398fab7e60b86e536a5d215c350 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Thu, 13 Jun 2019 12:37:29 -0400 Subject: [PATCH 0134/1165] * Updates to sync with yandex/master --- contrib/googletest | 1 + .../boost/archive/archive_exception.hpp | 100 - .../boost/archive/basic_archive.hpp | 304 --- .../boost/archive/basic_binary_iarchive.hpp | 204 -- .../boost/archive/basic_binary_iprimitive.hpp | 198 -- .../boost/archive/basic_binary_oarchive.hpp | 185 -- .../boost/archive/basic_binary_oprimitive.hpp | 188 -- .../archive/basic_streambuf_locale_saver.hpp | 108 -- .../boost/archive/basic_text_iarchive.hpp | 96 - .../boost/archive/basic_text_iprimitive.hpp | 142 -- .../boost/archive/basic_text_oarchive.hpp | 119 -- .../boost/archive/basic_text_oprimitive.hpp | 209 -- .../boost/archive/basic_xml_archive.hpp | 67 - .../boost/archive/basic_xml_iarchive.hpp | 119 -- .../boost/archive/basic_xml_oarchive.hpp | 138 -- .../boost/archive/binary_iarchive.hpp | 64 - .../boost/archive/binary_iarchive_impl.hpp | 105 - .../boost/archive/binary_oarchive.hpp | 64 - .../boost/archive/binary_oarchive_impl.hpp | 106 - .../boost/archive/binary_wiarchive.hpp | 56 - .../boost/archive/binary_woarchive.hpp | 59 - .../boost/archive/codecvt_null.hpp | 109 -- .../boost/archive/detail/abi_prefix.hpp | 16 - .../boost/archive/detail/abi_suffix.hpp | 15 - .../archive/detail/archive_serializer_map.hpp | 54 - .../archive/detail/auto_link_archive.hpp | 48 - .../archive/detail/auto_link_warchive.hpp | 47 - .../boost/archive/detail/basic_iarchive.hpp | 105 - .../archive/detail/basic_iserializer.hpp | 91 - .../boost/archive/detail/basic_oarchive.hpp | 94 - .../archive/detail/basic_oserializer.hpp | 89 - .../detail/basic_pointer_iserializer.hpp | 70 - .../detail/basic_pointer_oserializer.hpp | 68 - .../boost/archive/detail/basic_serializer.hpp | 77 - .../archive/detail/basic_serializer_map.hpp | 69 - .../boost/archive/detail/check.hpp | 169 -- .../boost/archive/detail/common_iarchive.hpp | 88 - .../boost/archive/detail/common_oarchive.hpp | 88 - .../boost/archive/detail/decl.hpp | 57 - .../archive/detail/helper_collection.hpp | 99 - .../archive/detail/interface_iarchive.hpp | 85 - .../archive/detail/interface_oarchive.hpp | 87 - .../boost/archive/detail/iserializer.hpp | 631 ------ .../boost/archive/detail/oserializer.hpp | 540 ------ .../detail/polymorphic_iarchive_route.hpp | 218 --- .../detail/polymorphic_oarchive_route.hpp | 209 -- .../boost/archive/detail/register_archive.hpp | 91 - .../archive/detail/utf8_codecvt_facet.hpp | 39 - .../boost_1_65_0/boost/archive/dinkumware.hpp | 224 --- .../archive/impl/archive_serializer_map.ipp | 75 - .../archive/impl/basic_binary_iarchive.ipp | 134 -- .../archive/impl/basic_binary_iprimitive.ipp | 171 -- .../archive/impl/basic_binary_oarchive.ipp | 42 - .../archive/impl/basic_binary_oprimitive.ipp | 126 -- .../archive/impl/basic_text_iarchive.ipp | 76 - .../archive/impl/basic_text_iprimitive.ipp | 137 -- .../archive/impl/basic_text_oarchive.ipp | 62 - .../archive/impl/basic_text_oprimitive.ipp | 115 -- .../boost/archive/impl/basic_xml_grammar.hpp | 173 -- .../boost/archive/impl/basic_xml_iarchive.ipp | 115 -- .../boost/archive/impl/basic_xml_oarchive.ipp | 272 --- .../boost/archive/impl/text_iarchive_impl.ipp | 128 -- .../boost/archive/impl/text_oarchive_impl.ipp | 122 -- .../archive/impl/text_wiarchive_impl.ipp | 118 -- .../archive/impl/text_woarchive_impl.ipp | 85 - .../boost/archive/impl/xml_iarchive_impl.ipp | 199 -- .../boost/archive/impl/xml_oarchive_impl.ipp | 142 -- .../boost/archive/impl/xml_wiarchive_impl.ipp | 189 -- .../boost/archive/impl/xml_woarchive_impl.ipp | 171 -- .../archive/iterators/base64_exception.hpp | 68 - .../archive/iterators/base64_from_binary.hpp | 109 -- .../archive/iterators/binary_from_base64.hpp | 118 -- .../boost/archive/iterators/dataflow.hpp | 102 - .../archive/iterators/dataflow_exception.hpp | 80 - .../boost/archive/iterators/escape.hpp | 115 -- .../archive/iterators/insert_linebreaks.hpp | 99 - .../archive/iterators/istream_iterator.hpp | 92 - .../boost/archive/iterators/mb_from_wchar.hpp | 139 -- .../archive/iterators/ostream_iterator.hpp | 83 - .../archive/iterators/remove_whitespace.hpp | 167 -- .../archive/iterators/transform_width.hpp | 177 -- .../boost/archive/iterators/unescape.hpp | 89 - .../boost/archive/iterators/wchar_from_mb.hpp | 194 -- .../boost/archive/iterators/xml_escape.hpp | 121 -- .../boost/archive/iterators/xml_unescape.hpp | 125 -- .../iterators/xml_unescape_exception.hpp | 49 - .../archive/polymorphic_binary_iarchive.hpp | 54 - .../archive/polymorphic_binary_oarchive.hpp | 43 - .../boost/archive/polymorphic_iarchive.hpp | 168 -- .../boost/archive/polymorphic_oarchive.hpp | 154 -- .../archive/polymorphic_text_iarchive.hpp | 54 - .../archive/polymorphic_text_oarchive.hpp | 39 - .../archive/polymorphic_text_wiarchive.hpp | 59 - .../archive/polymorphic_text_woarchive.hpp | 44 - .../archive/polymorphic_xml_iarchive.hpp | 54 - .../archive/polymorphic_xml_oarchive.hpp | 39 - .../archive/polymorphic_xml_wiarchive.hpp | 50 - .../archive/polymorphic_xml_woarchive.hpp | 44 - .../boost/archive/text_iarchive.hpp | 132 -- .../boost/archive/text_oarchive.hpp | 121 -- .../boost/archive/text_wiarchive.hpp | 137 -- .../boost/archive/text_woarchive.hpp | 155 -- .../boost_1_65_0/boost/archive/tmpdir.hpp | 50 - .../boost_1_65_0/boost/archive/wcslen.hpp | 58 - .../boost/archive/xml_archive_exception.hpp | 57 - .../boost/archive/xml_iarchive.hpp | 142 -- .../boost/archive/xml_oarchive.hpp | 137 -- .../boost/archive/xml_wiarchive.hpp | 149 -- .../boost/archive/xml_woarchive.hpp | 134 -- .../boost_1_65_0/boost/foreach_fwd.hpp | 51 - .../boost/multi_index/composite_key.hpp | 1513 --------------- .../multi_index/detail/access_specifier.hpp | 54 - .../boost/multi_index/detail/adl_swap.hpp | 44 - .../detail/archive_constructed.hpp | 83 - .../boost/multi_index/detail/auto_space.hpp | 91 - .../boost/multi_index/detail/base_type.hpp | 74 - .../detail/bidir_node_iterator.hpp | 114 -- .../boost/multi_index/detail/bucket_array.hpp | 243 --- .../multi_index/detail/cons_stdtuple.hpp | 93 - .../boost/multi_index/detail/converter.hpp | 52 - .../boost/multi_index/detail/copy_map.hpp | 142 -- .../detail/do_not_copy_elements_tag.hpp | 34 - .../detail/duplicates_iterator.hpp | 120 -- .../boost/multi_index/detail/has_tag.hpp | 42 - .../multi_index/detail/hash_index_args.hpp | 105 - .../detail/hash_index_iterator.hpp | 166 -- .../multi_index/detail/hash_index_node.hpp | 778 -------- .../multi_index/detail/header_holder.hpp | 50 - .../detail/ignore_wstrict_aliasing.hpp | 18 - .../boost/multi_index/detail/index_base.hpp | 293 --- .../boost/multi_index/detail/index_loader.hpp | 139 -- .../multi_index/detail/index_matcher.hpp | 249 --- .../multi_index/detail/index_node_base.hpp | 135 -- .../boost/multi_index/detail/index_saver.hpp | 135 -- .../multi_index/detail/invariant_assert.hpp | 21 - .../multi_index/detail/is_index_list.hpp | 40 - .../multi_index/detail/is_transparent.hpp | 135 -- .../boost/multi_index/detail/iter_adaptor.hpp | 321 --- .../multi_index/detail/modify_key_adaptor.hpp | 49 - .../multi_index/detail/no_duplicate_tags.hpp | 97 - .../boost/multi_index/detail/node_type.hpp | 66 - .../multi_index/detail/ord_index_args.hpp | 83 - .../multi_index/detail/ord_index_impl.hpp | 1567 --------------- .../multi_index/detail/ord_index_impl_fwd.hpp | 128 -- .../multi_index/detail/ord_index_node.hpp | 658 ------- .../multi_index/detail/ord_index_ops.hpp | 266 --- .../boost/multi_index/detail/promotes_arg.hpp | 83 - .../boost/multi_index/detail/raw_ptr.hpp | 52 - .../detail/restore_wstrict_aliasing.hpp | 11 - .../multi_index/detail/rnd_index_loader.hpp | 173 -- .../multi_index/detail/rnd_index_node.hpp | 273 --- .../multi_index/detail/rnd_index_ops.hpp | 203 -- .../detail/rnd_index_ptr_array.hpp | 144 -- .../multi_index/detail/rnd_node_iterator.hpp | 140 -- .../multi_index/detail/rnk_index_ops.hpp | 300 --- .../boost/multi_index/detail/safe_mode.hpp | 588 ------ .../boost/multi_index/detail/scope_guard.hpp | 453 ----- .../multi_index/detail/seq_index_node.hpp | 217 --- .../multi_index/detail/seq_index_ops.hpp | 203 -- .../detail/serialization_version.hpp | 73 - .../boost/multi_index/detail/uintptr_type.hpp | 76 - .../boost/multi_index/detail/unbounded.hpp | 66 - .../multi_index/detail/value_compare.hpp | 56 - .../multi_index/detail/vartempl_support.hpp | 247 --- .../boost/multi_index/global_fun.hpp | 185 -- .../boost/multi_index/hashed_index.hpp | 1725 ----------------- .../boost/multi_index/hashed_index_fwd.hpp | 74 - .../boost/multi_index/identity.hpp | 145 -- .../boost/multi_index/identity_fwd.hpp | 26 - .../boost/multi_index/indexed_by.hpp | 68 - .../boost/multi_index/key_extractors.hpp | 22 - .../boost/multi_index/mem_fun.hpp | 205 -- .../boost_1_65_0/boost/multi_index/member.hpp | 262 --- .../boost/multi_index/ordered_index.hpp | 114 -- .../boost/multi_index/ordered_index_fwd.hpp | 35 - .../boost/multi_index/random_access_index.hpp | 1167 ----------- .../multi_index/random_access_index_fwd.hpp | 91 - .../boost/multi_index/ranked_index.hpp | 382 ---- .../boost/multi_index/ranked_index_fwd.hpp | 35 - .../boost/multi_index/safe_mode_errors.hpp | 48 - .../boost/multi_index/sequenced_index.hpp | 1062 ---------- .../boost/multi_index/sequenced_index_fwd.hpp | 91 - .../boost_1_65_0/boost/multi_index/tag.hpp | 88 - .../boost/multi_index_container.hpp | 1362 ------------- .../boost/multi_index_container_fwd.hpp | 121 -- .../boost/serialization/access.hpp | 145 -- .../archive_input_unordered_map.hpp | 85 - .../archive_input_unordered_set.hpp | 72 - .../boost/serialization/array.hpp | 48 - .../serialization/array_optimization.hpp | 37 - .../boost/serialization/array_wrapper.hpp | 121 -- .../boost/serialization/assume_abstract.hpp | 60 - .../boost/serialization/base_object.hpp | 100 - .../boost/serialization/binary_object.hpp | 79 - .../boost/serialization/bitset.hpp | 75 - .../boost/serialization/boost_array.hpp | 33 - .../serialization/boost_unordered_map.hpp | 154 -- .../serialization/boost_unordered_set.hpp | 150 -- .../serialization/collection_size_type.hpp | 62 - .../boost/serialization/collection_traits.hpp | 79 - .../serialization/collections_load_imp.hpp | 106 - .../serialization/collections_save_imp.hpp | 82 - .../boost/serialization/complex.hpp | 81 - .../boost/serialization/config.hpp | 74 - .../boost/serialization/deque.hpp | 80 - .../detail/is_default_constructible.hpp | 54 - .../serialization/detail/shared_count_132.hpp | 551 ------ .../serialization/detail/shared_ptr_132.hpp | 443 ----- .../detail/shared_ptr_nmt_132.hpp | 182 -- .../detail/stack_constructor.hpp | 66 - .../boost/serialization/ephemeral.hpp | 72 - .../boost/serialization/export.hpp | 225 --- .../serialization/extended_type_info.hpp | 116 -- .../extended_type_info_no_rtti.hpp | 182 -- .../extended_type_info_typeid.hpp | 167 -- .../boost/serialization/factory.hpp | 102 - .../boost/serialization/force_include.hpp | 55 - .../boost/serialization/forward_list.hpp | 124 -- .../hash_collections_load_imp.hpp | 77 - .../hash_collections_save_imp.hpp | 97 - .../boost/serialization/hash_map.hpp | 232 --- .../boost/serialization/hash_set.hpp | 222 --- .../serialization/is_bitwise_serializable.hpp | 46 - .../boost/serialization/item_version_type.hpp | 68 - .../boost/serialization/level.hpp | 116 -- .../boost/serialization/level_enum.hpp | 55 - .../boost_1_65_0/boost/serialization/list.hpp | 85 - .../boost_1_65_0/boost/serialization/map.hpp | 139 -- .../boost_1_65_0/boost/serialization/nvp.hpp | 123 -- .../boost/serialization/optional.hpp | 107 - .../boost/serialization/priority_queue.hpp | 76 - .../boost/serialization/queue.hpp | 76 - .../boost/serialization/scoped_ptr.hpp | 58 - .../boost/serialization/serialization.hpp | 154 -- .../boost_1_65_0/boost/serialization/set.hpp | 137 -- .../boost/serialization/shared_ptr.hpp | 281 --- .../boost/serialization/shared_ptr_132.hpp | 222 --- .../boost/serialization/shared_ptr_helper.hpp | 209 -- .../boost/serialization/singleton.hpp | 166 -- .../boost/serialization/slist.hpp | 145 -- .../boost/serialization/smart_cast.hpp | 275 --- .../boost/serialization/split_free.hpp | 93 - .../boost/serialization/split_member.hpp | 86 - .../boost/serialization/stack.hpp | 76 - .../boost/serialization/state_saver.hpp | 96 - .../boost/serialization/static_warning.hpp | 103 - .../boost/serialization/string.hpp | 30 - .../boost/serialization/strong_typedef.hpp | 50 - .../boost/serialization/throw_exception.hpp | 44 - .../boost/serialization/tracking.hpp | 118 -- .../boost/serialization/tracking_enum.hpp | 41 - .../boost/serialization/traits.hpp | 65 - .../type_info_implementation.hpp | 73 - .../boost/serialization/unique_ptr.hpp | 68 - .../unordered_collections_load_imp.hpp | 73 - .../unordered_collections_save_imp.hpp | 86 - .../boost/serialization/unordered_map.hpp | 160 -- .../boost/serialization/unordered_set.hpp | 162 -- .../boost/serialization/utility.hpp | 56 - .../boost/serialization/valarray.hpp | 86 - .../boost/serialization/variant.hpp | 158 -- .../boost/serialization/vector.hpp | 233 --- .../boost/serialization/vector_135.hpp | 26 - .../boost/serialization/version.hpp | 107 - .../boost/serialization/void_cast.hpp | 298 --- .../boost/serialization/void_cast_fwd.hpp | 37 - .../boost/serialization/weak_ptr.hpp | 99 - .../boost/serialization/wrapper.hpp | 60 - contrib/poco | 1 + contrib/zlib-ng | 1 + dbms/src/Storages/MergeTree/MergeTreeData.cpp | 3 - 271 files changed, 3 insertions(+), 41591 deletions(-) create mode 160000 contrib/googletest delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/archive_exception.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_archive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iprimitive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oprimitive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_streambuf_locale_saver.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_text_iarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_text_iprimitive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_text_oarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_text_oprimitive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_xml_archive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_xml_iarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/basic_xml_oarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive_impl.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive_impl.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/binary_wiarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/binary_woarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/codecvt_null.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/abi_prefix.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/abi_suffix.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/archive_serializer_map.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_archive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_warchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iserializer.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oserializer.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_iserializer.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_oserializer.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer_map.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/check.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/common_iarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/common_oarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/decl.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/helper_collection.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/interface_iarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/interface_oarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/iserializer.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/oserializer.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_iarchive_route.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_oarchive_route.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/register_archive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/detail/utf8_codecvt_facet.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/dinkumware.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/archive_serializer_map.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iarchive.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iprimitive.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oarchive.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oprimitive.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iarchive.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iprimitive.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oarchive.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oprimitive.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_grammar.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_iarchive.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_oarchive.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/text_iarchive_impl.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/text_oarchive_impl.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/text_wiarchive_impl.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/text_woarchive_impl.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/xml_iarchive_impl.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/xml_oarchive_impl.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/xml_wiarchive_impl.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/impl/xml_woarchive_impl.ipp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_exception.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_from_binary.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/binary_from_base64.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow_exception.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/escape.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/insert_linebreaks.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/istream_iterator.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/mb_from_wchar.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/ostream_iterator.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/remove_whitespace.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/transform_width.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/unescape.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/wchar_from_mb.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_escape.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape_exception.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_iarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_oarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_iarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_oarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_iarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_oarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_wiarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_woarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_iarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_oarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_wiarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_woarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/text_iarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/text_oarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/text_wiarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/text_woarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/tmpdir.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/wcslen.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/xml_archive_exception.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/xml_iarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/xml_oarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/xml_wiarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/archive/xml_woarchive.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/foreach_fwd.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/composite_key.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/access_specifier.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/adl_swap.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/archive_constructed.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/auto_space.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/base_type.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/bidir_node_iterator.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/bucket_array.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/cons_stdtuple.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/converter.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/copy_map.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/do_not_copy_elements_tag.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/duplicates_iterator.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/has_tag.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_args.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_iterator.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_node.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/header_holder.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/ignore_wstrict_aliasing.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_base.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_loader.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_matcher.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_node_base.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_saver.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/invariant_assert.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_index_list.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_transparent.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/iter_adaptor.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/modify_key_adaptor.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/no_duplicate_tags.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/node_type.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_args.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl_fwd.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_node.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_ops.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/promotes_arg.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/raw_ptr.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/restore_wstrict_aliasing.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_loader.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_node.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ops.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ptr_array.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_node_iterator.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnk_index_ops.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/safe_mode.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/scope_guard.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_node.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_ops.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/serialization_version.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/uintptr_type.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/unbounded.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/value_compare.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/detail/vartempl_support.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/global_fun.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index_fwd.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/identity.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/identity_fwd.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/indexed_by.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/key_extractors.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/mem_fun.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/member.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index_fwd.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index_fwd.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index_fwd.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/safe_mode_errors.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index_fwd.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index/tag.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index_container.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/multi_index_container_fwd.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/access.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_map.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_set.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/array.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/array_optimization.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/array_wrapper.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/assume_abstract.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/base_object.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/binary_object.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/bitset.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/boost_array.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_map.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_set.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/collection_size_type.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/collection_traits.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/collections_load_imp.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/collections_save_imp.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/complex.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/config.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/deque.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/detail/is_default_constructible.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_count_132.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_132.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_nmt_132.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/detail/stack_constructor.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/ephemeral.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/export.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_no_rtti.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_typeid.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/factory.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/force_include.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/forward_list.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_load_imp.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_save_imp.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/hash_map.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/hash_set.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/is_bitwise_serializable.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/item_version_type.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/level.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/level_enum.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/list.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/map.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/nvp.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/optional.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/priority_queue.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/queue.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/scoped_ptr.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/serialization.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/set.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_132.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_helper.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/singleton.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/slist.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/smart_cast.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/split_free.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/split_member.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/stack.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/state_saver.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/static_warning.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/string.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/strong_typedef.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/throw_exception.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/tracking.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/tracking_enum.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/traits.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/type_info_implementation.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/unique_ptr.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_load_imp.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_save_imp.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/unordered_map.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/unordered_set.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/utility.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/valarray.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/variant.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/vector.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/vector_135.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/version.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/void_cast.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/void_cast_fwd.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/weak_ptr.hpp delete mode 100644 contrib/libboost/boost_1_65_0/boost/serialization/wrapper.hpp create mode 160000 contrib/poco create mode 160000 contrib/zlib-ng diff --git a/contrib/googletest b/contrib/googletest new file mode 160000 index 00000000000..d175c8bf823 --- /dev/null +++ b/contrib/googletest @@ -0,0 +1 @@ +Subproject commit d175c8bf823e709d570772b038757fadf63bc632 diff --git a/contrib/libboost/boost_1_65_0/boost/archive/archive_exception.hpp b/contrib/libboost/boost_1_65_0/boost/archive/archive_exception.hpp deleted file mode 100644 index fabcdb5fa71..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/archive_exception.hpp +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP -#define BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// archive/archive_exception.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include - -#include -#include - -// note: the only reason this is in here is that windows header -// includes #define exception_code _exception_code (arrrgghhhh!). -// the most expedient way to address this is be sure that this -// header is always included whenever this header file is included. -#if defined(BOOST_WINDOWS) -#include -#endif - -#include // must be the last header - -namespace boost { -namespace archive { - -////////////////////////////////////////////////////////////////////// -// exceptions thrown by archives -// -class BOOST_SYMBOL_VISIBLE archive_exception : - public virtual std::exception -{ -private: - char m_buffer[128]; -protected: - BOOST_ARCHIVE_DECL unsigned int - append(unsigned int l, const char * a); - BOOST_ARCHIVE_DECL - archive_exception() BOOST_NOEXCEPT; -public: - typedef enum { - no_exception, // initialized without code - other_exception, // any excepton not listed below - unregistered_class, // attempt to serialize a pointer of - // an unregistered class - invalid_signature, // first line of archive does not contain - // expected string - unsupported_version,// archive created with library version - // subsequent to this one - pointer_conflict, // an attempt has been made to directly - // serialize an object which has - // already been serialized through a pointer. - // Were this permitted, the archive load would result - // in the creation of an extra copy of the obect. - incompatible_native_format, // attempt to read native binary format - // on incompatible platform - array_size_too_short,// array being loaded doesn't fit in array allocated - input_stream_error, // error on input stream - invalid_class_name, // class name greater than the maximum permitted. - // most likely a corrupted archive or an attempt - // to insert virus via buffer overrun method. - unregistered_cast, // base - derived relationship not registered with - // void_cast_register - unsupported_class_version, // type saved with a version # greater than the - // one used by the program. This indicates that the program - // needs to be rebuilt. - multiple_code_instantiation, // code for implementing serialization for some - // type has been instantiated in more than one module. - output_stream_error // error on input stream - } exception_code; - exception_code code; - - BOOST_ARCHIVE_DECL archive_exception( - exception_code c, - const char * e1 = NULL, - const char * e2 = NULL - ) BOOST_NOEXCEPT; - BOOST_ARCHIVE_DECL archive_exception(archive_exception const &) BOOST_NOEXCEPT ; - virtual BOOST_ARCHIVE_DECL ~archive_exception() BOOST_NOEXCEPT_OR_NOTHROW ; - virtual BOOST_ARCHIVE_DECL const char * what() const BOOST_NOEXCEPT_OR_NOTHROW ; -}; - -}// namespace archive -}// namespace boost - -#include // pops abi_suffix.hpp pragmas - -#endif //BOOST_ARCHIVE_ARCHIVE_EXCEPTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_archive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_archive.hpp deleted file mode 100644 index ce7ac99a6dd..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/basic_archive.hpp +++ /dev/null @@ -1,304 +0,0 @@ -#ifndef BOOST_ARCHIVE_BASIC_ARCHIVE_HPP -#define BOOST_ARCHIVE_BASIC_ARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_archive.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. -#include // count -#include -#include -#include // size_t -#include -#include - -#include -#include // must be the last header - -namespace boost { -namespace archive { - -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4244 4267 ) -#endif - -/* NOTE : Warning : Warning : Warning : Warning : Warning - * Don't ever changes this. If you do, they previously created - * binary archives won't be readable !!! - */ -class library_version_type { -private: - typedef uint_least16_t base_type; - base_type t; -public: - library_version_type(): t(0) {}; - explicit library_version_type(const unsigned int & t_) : t(t_){ - BOOST_ASSERT(t_ <= boost::integer_traits::const_max); - } - library_version_type(const library_version_type & t_) : - t(t_.t) - {} - library_version_type & operator=(const library_version_type & rhs){ - t = rhs.t; - return *this; - } - // used for text output - operator base_type () const { - return t; - } - // used for text input - operator base_type & (){ - return t; - } - bool operator==(const library_version_type & rhs) const { - return t == rhs.t; - } - bool operator<(const library_version_type & rhs) const { - return t < rhs.t; - } -}; - -BOOST_ARCHIVE_DECL library_version_type -BOOST_ARCHIVE_VERSION(); - -class version_type { -private: - typedef uint_least32_t base_type; - base_type t; -public: - // should be private - but MPI fails if it's not!!! - version_type(): t(0) {}; - explicit version_type(const unsigned int & t_) : t(t_){ - BOOST_ASSERT(t_ <= boost::integer_traits::const_max); - } - version_type(const version_type & t_) : - t(t_.t) - {} - version_type & operator=(const version_type & rhs){ - t = rhs.t; - return *this; - } - // used for text output - operator base_type () const { - return t; - } - // used for text intput - operator base_type & (){ - return t; - } - bool operator==(const version_type & rhs) const { - return t == rhs.t; - } - bool operator<(const version_type & rhs) const { - return t < rhs.t; - } -}; - -class class_id_type { -private: - typedef int_least16_t base_type; - base_type t; -public: - // should be private - but then can't use BOOST_STRONG_TYPE below - class_id_type() : t(0) {}; - explicit class_id_type(const int t_) : t(t_){ - BOOST_ASSERT(t_ <= boost::integer_traits::const_max); - } - explicit class_id_type(const std::size_t t_) : t(t_){ - // BOOST_ASSERT(t_ <= boost::integer_traits::const_max); - } - class_id_type(const class_id_type & t_) : - t(t_.t) - {} - class_id_type & operator=(const class_id_type & rhs){ - t = rhs.t; - return *this; - } - - // used for text output - operator int () const { - return t; - } - // used for text input - operator int_least16_t &() { - return t; - } - bool operator==(const class_id_type & rhs) const { - return t == rhs.t; - } - bool operator<(const class_id_type & rhs) const { - return t < rhs.t; - } -}; - -#define NULL_POINTER_TAG boost::archive::class_id_type(-1) - -class object_id_type { -private: - typedef uint_least32_t base_type; - base_type t; -public: - object_id_type(): t(0) {}; - // note: presumes that size_t >= unsigned int. - explicit object_id_type(const std::size_t & t_) : t(t_){ - BOOST_ASSERT(t_ <= boost::integer_traits::const_max); - } - object_id_type(const object_id_type & t_) : - t(t_.t) - {} - object_id_type & operator=(const object_id_type & rhs){ - t = rhs.t; - return *this; - } - // used for text output - operator uint_least32_t () const { - return t; - } - // used for text input - operator uint_least32_t & () { - return t; - } - bool operator==(const object_id_type & rhs) const { - return t == rhs.t; - } - bool operator<(const object_id_type & rhs) const { - return t < rhs.t; - } -}; - -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - -struct tracking_type { - bool t; - explicit tracking_type(const bool t_ = false) - : t(t_) - {}; - tracking_type(const tracking_type & t_) - : t(t_.t) - {} - operator bool () const { - return t; - }; - operator bool & () { - return t; - }; - tracking_type & operator=(const bool t_){ - t = t_; - return *this; - } - bool operator==(const tracking_type & rhs) const { - return t == rhs.t; - } - bool operator==(const bool & rhs) const { - return t == rhs; - } - tracking_type & operator=(const tracking_type & rhs){ - t = rhs.t; - return *this; - } -}; - -struct class_name_type : - private boost::noncopyable -{ - char *t; - operator const char * & () const { - return const_cast(t); - } - operator char * () { - return t; - } - std::size_t size() const { - return std::strlen(t); - } - explicit class_name_type(const char *key_) - : t(const_cast(key_)){} - explicit class_name_type(char *key_) - : t(key_){} - class_name_type & operator=(const class_name_type & rhs){ - t = rhs.t; - return *this; - } -}; - -enum archive_flags { - no_header = 1, // suppress archive header info - no_codecvt = 2, // suppress alteration of codecvt facet - no_xml_tag_checking = 4, // suppress checking of xml tags - no_tracking = 8, // suppress ALL tracking - flags_last = 8 -}; - -BOOST_ARCHIVE_DECL const char * -BOOST_ARCHIVE_SIGNATURE(); - -/* NOTE : Warning : Warning : Warning : Warning : Warning - * If any of these are changed to different sized types, - * binary_iarchive won't be able to read older archives - * unless you rev the library version and include conditional - * code based on the library version. There is nothing - * inherently wrong in doing this - but you have to be super - * careful because it's easy to get wrong and start breaking - * old archives !!! - */ - -#define BOOST_ARCHIVE_STRONG_TYPEDEF(T, D) \ - class D : public T { \ - public: \ - explicit D(const T tt) : T(tt){} \ - }; \ -/**/ - -BOOST_ARCHIVE_STRONG_TYPEDEF(class_id_type, class_id_reference_type) -BOOST_ARCHIVE_STRONG_TYPEDEF(class_id_type, class_id_optional_type) -BOOST_ARCHIVE_STRONG_TYPEDEF(object_id_type, object_reference_type) - -}// namespace archive -}// namespace boost - -#include // pops abi_suffix.hpp pragmas - -#include - -// set implementation level to primitive for all types -// used internally by the serialization library - -BOOST_CLASS_IMPLEMENTATION(boost::archive::library_version_type, primitive_type) -BOOST_CLASS_IMPLEMENTATION(boost::archive::version_type, primitive_type) -BOOST_CLASS_IMPLEMENTATION(boost::archive::class_id_type, primitive_type) -BOOST_CLASS_IMPLEMENTATION(boost::archive::class_id_reference_type, primitive_type) -BOOST_CLASS_IMPLEMENTATION(boost::archive::class_id_optional_type, primitive_type) -BOOST_CLASS_IMPLEMENTATION(boost::archive::class_name_type, primitive_type) -BOOST_CLASS_IMPLEMENTATION(boost::archive::object_id_type, primitive_type) -BOOST_CLASS_IMPLEMENTATION(boost::archive::object_reference_type, primitive_type) -BOOST_CLASS_IMPLEMENTATION(boost::archive::tracking_type, primitive_type) - -#include - -// set types used internally by the serialization library -// to be bitwise serializable - -BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::library_version_type) -BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::version_type) -BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::class_id_type) -BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::class_id_reference_type) -BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::class_id_optional_type) -BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::class_name_type) -BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::object_id_type) -BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::object_reference_type) -BOOST_IS_BITWISE_SERIALIZABLE(boost::archive::tracking_type) - -#endif //BOOST_ARCHIVE_BASIC_ARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iarchive.hpp deleted file mode 100644 index c0cc655c997..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iarchive.hpp +++ /dev/null @@ -1,204 +0,0 @@ -#ifndef BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP -#define BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_binary_iarchive.hpp -// -// archives stored as native binary - this should be the fastest way -// to archive the state of a group of obects. It makes no attempt to -// convert to any canonical form. - -// IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE -// ON PLATFORM APART FROM THE ONE THEY ARE CREATED ON - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -#include -#include -#include -#include -#include -#include - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -#include // must be the last header - -namespace boost { -namespace archive { - -namespace detail { - template class interface_iarchive; -} // namespace detail - -///////////////////////////////////////////////////////////////////////// -// class basic_binary_iarchive - read serialized objects from a input binary stream -template -class BOOST_SYMBOL_VISIBLE basic_binary_iarchive : - public detail::common_iarchive -{ -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else -protected: - #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) - // for some inexplicable reason insertion of "class" generates compile erro - // on msvc 7.1 - friend detail::interface_iarchive; - #else - friend class detail::interface_iarchive; - #endif -#endif - // intermediate level to support override of operators - // fot templates in the absence of partial function - // template ordering. If we get here pass to base class - // note extra nonsense to sneak it pass the borland compiers - typedef detail::common_iarchive detail_common_iarchive; - template - void load_override(T & t){ - this->detail_common_iarchive::load_override(t); - } - - // include these to trap a change in binary format which - // isn't specifically handled - // upto 32K classes - BOOST_STATIC_ASSERT(sizeof(class_id_type) == sizeof(int_least16_t)); - BOOST_STATIC_ASSERT(sizeof(class_id_reference_type) == sizeof(int_least16_t)); - // upto 2G objects - BOOST_STATIC_ASSERT(sizeof(object_id_type) == sizeof(uint_least32_t)); - BOOST_STATIC_ASSERT(sizeof(object_reference_type) == sizeof(uint_least32_t)); - - // binary files don't include the optional information - void load_override(class_id_optional_type & /* t */){} - - void load_override(tracking_type & t, int /*version*/){ - library_version_type lvt = this->get_library_version(); - if(boost::archive::library_version_type(6) < lvt){ - int_least8_t x=0; - * this->This() >> x; - t = boost::archive::tracking_type(x); - } - else{ - bool x=0; - * this->This() >> x; - t = boost::archive::tracking_type(x); - } - } - void load_override(class_id_type & t){ - library_version_type lvt = this->get_library_version(); - if(boost::archive::library_version_type(7) < lvt){ - this->detail_common_iarchive::load_override(t); - } - else - if(boost::archive::library_version_type(6) < lvt){ - int_least16_t x=0; - * this->This() >> x; - t = boost::archive::class_id_type(x); - } - else{ - int x=0; - * this->This() >> x; - t = boost::archive::class_id_type(x); - } - } - void load_override(class_id_reference_type & t){ - load_override(static_cast(t)); - } - - void load_override(version_type & t){ - library_version_type lvt = this->get_library_version(); - if(boost::archive::library_version_type(7) < lvt){ - this->detail_common_iarchive::load_override(t); - } - else - if(boost::archive::library_version_type(6) < lvt){ - uint_least8_t x=0; - * this->This() >> x; - t = boost::archive::version_type(x); - } - else - if(boost::archive::library_version_type(5) < lvt){ - uint_least16_t x=0; - * this->This() >> x; - t = boost::archive::version_type(x); - } - else - if(boost::archive::library_version_type(2) < lvt){ - // upto 255 versions - unsigned char x=0; - * this->This() >> x; - t = version_type(x); - } - else{ - unsigned int x=0; - * this->This() >> x; - t = boost::archive::version_type(x); - } - } - - void load_override(boost::serialization::item_version_type & t){ - library_version_type lvt = this->get_library_version(); -// if(boost::archive::library_version_type(7) < lvt){ - if(boost::archive::library_version_type(6) < lvt){ - this->detail_common_iarchive::load_override(t); - } - else - if(boost::archive::library_version_type(6) < lvt){ - uint_least16_t x=0; - * this->This() >> x; - t = boost::serialization::item_version_type(x); - } - else{ - unsigned int x=0; - * this->This() >> x; - t = boost::serialization::item_version_type(x); - } - } - - void load_override(serialization::collection_size_type & t){ - if(boost::archive::library_version_type(5) < this->get_library_version()){ - this->detail_common_iarchive::load_override(t); - } - else{ - unsigned int x=0; - * this->This() >> x; - t = serialization::collection_size_type(x); - } - } - - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - load_override(class_name_type & t); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - init(); - - basic_binary_iarchive(unsigned int flags) : - detail::common_iarchive(flags) - {} -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_ARCHIVE_BASIC_BINARY_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iprimitive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iprimitive.hpp deleted file mode 100644 index 665d3e81e1f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_iprimitive.hpp +++ /dev/null @@ -1,198 +0,0 @@ -#ifndef BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP -#define BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -#if defined(_MSC_VER) -#pragma warning( disable : 4800 ) -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_binary_iprimitive.hpp -// -// archives stored as native binary - this should be the fastest way -// to archive the state of a group of obects. It makes no attempt to -// convert to any canonical form. - -// IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE -// ON PLATFORM APART FROM THE ONE THEY ARE CREATED ON - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include // std::memcpy -#include // std::size_t -#include // basic_streambuf -#include - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::memcpy; - using ::size_t; -} // namespace std -#endif - -#include -#include -#include -#include - -//#include -#include -#include - -#include -#include -#include -#include -#include // must be the last header - -namespace boost { -namespace archive { - -///////////////////////////////////////////////////////////////////////////// -// class binary_iarchive - read serialized objects from a input binary stream -template -class BOOST_SYMBOL_VISIBLE basic_binary_iprimitive { -#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS - friend class load_access; -protected: -#else -public: -#endif - std::basic_streambuf & m_sb; - // return a pointer to the most derived class - Archive * This(){ - return static_cast(this); - } - - #ifndef BOOST_NO_STD_LOCALE - // note order! - if you change this, libstd++ will fail! - // a) create new locale with new codecvt facet - // b) save current locale - // c) change locale to new one - // d) use stream buffer - // e) change locale back to original - // f) destroy new codecvt facet - boost::archive::codecvt_null codecvt_null_facet; - basic_streambuf_locale_saver locale_saver; - std::locale archive_locale; - #endif - - // main template for serilization of primitive types - template - void load(T & t){ - load_binary(& t, sizeof(T)); - } - - ///////////////////////////////////////////////////////// - // fundamental types that need special treatment - - // trap usage of invalid uninitialized boolean - void load(bool & t){ - load_binary(& t, sizeof(t)); - int i = t; - BOOST_ASSERT(0 == i || 1 == i); - (void)i; // warning suppression for release builds. - } - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - load(std::string &s); - #ifndef BOOST_NO_STD_WSTRING - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - load(std::wstring &ws); - #endif - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - load(char * t); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - load(wchar_t * t); - - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - init(); - BOOST_ARCHIVE_OR_WARCHIVE_DECL - basic_binary_iprimitive( - std::basic_streambuf & sb, - bool no_codecvt - ); - BOOST_ARCHIVE_OR_WARCHIVE_DECL - ~basic_binary_iprimitive(); -public: - // we provide an optimized load for all fundamental types - // typedef serialization::is_bitwise_serializable - // use_array_optimization; - struct use_array_optimization { - template - #if defined(BOOST_NO_DEPENDENT_NESTED_DERIVATIONS) - struct apply { - typedef typename boost::serialization::is_bitwise_serializable< T >::type type; - }; - #else - struct apply : public boost::serialization::is_bitwise_serializable< T > {}; - #endif - }; - - // the optimized load_array dispatches to load_binary - template - void load_array(serialization::array_wrapper& a, unsigned int) - { - load_binary(a.address(),a.count()*sizeof(ValueType)); - } - - void - load_binary(void *address, std::size_t count); -}; - -template -inline void -basic_binary_iprimitive::load_binary( - void *address, - std::size_t count -){ - // note: an optimizer should eliminate the following for char files - BOOST_ASSERT( - static_cast(count / sizeof(Elem)) - <= boost::integer_traits::const_max - ); - std::streamsize s = static_cast(count / sizeof(Elem)); - std::streamsize scount = m_sb.sgetn( - static_cast(address), - s - ); - if(scount != s) - boost::serialization::throw_exception( - archive_exception(archive_exception::input_stream_error) - ); - // note: an optimizer should eliminate the following for char files - BOOST_ASSERT(count % sizeof(Elem) <= boost::integer_traits::const_max); - s = static_cast(count % sizeof(Elem)); - if(0 < s){ -// if(is.fail()) -// boost::serialization::throw_exception( -// archive_exception(archive_exception::stream_error) -// ); - Elem t; - scount = m_sb.sgetn(& t, 1); - if(scount != 1) - boost::serialization::throw_exception( - archive_exception(archive_exception::input_stream_error) - ); - std::memcpy(static_cast(address) + (count - s), &t, static_cast(s)); - } -} - -} // namespace archive -} // namespace boost - -#include // pop pragmas - -#endif // BOOST_ARCHIVE_BINARY_IPRIMITIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oarchive.hpp deleted file mode 100644 index f05f2f86d55..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oarchive.hpp +++ /dev/null @@ -1,185 +0,0 @@ -#ifndef BOOST_ARCHIVE_BASIC_BINARY_OARCHIVE_HPP -#define BOOST_ARCHIVE_BASIC_BINARY_OARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_binary_oarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// archives stored as native binary - this should be the fastest way -// to archive the state of a group of obects. It makes no attempt to -// convert to any canonical form. - -// IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE -// ON PLATFORM APART FROM THE ONE THEY ARE CREATE ON - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -namespace detail { - template class interface_oarchive; -} // namespace detail - -////////////////////////////////////////////////////////////////////// -// class basic_binary_oarchive - write serialized objects to a binary output stream -// note: this archive has no pretensions to portability. Archive format -// may vary across machine architectures and compilers. About the only -// guarentee is that an archive created with this code will be readable -// by a program built with the same tools for the same machne. This class -// does have the virtue of buiding the smalles archive in the minimum amount -// of time. So under some circumstances it may be he right choice. -template -class BOOST_SYMBOL_VISIBLE basic_binary_oarchive : - public detail::common_oarchive -{ -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else -protected: - #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) - // for some inexplicable reason insertion of "class" generates compile erro - // on msvc 7.1 - friend detail::interface_oarchive; - #else - friend class detail::interface_oarchive; - #endif -#endif - // any datatype not specifed below will be handled by base class - typedef detail::common_oarchive detail_common_oarchive; - template - void save_override(const T & t){ - this->detail_common_oarchive::save_override(t); - } - - // include these to trap a change in binary format which - // isn't specifically handled - BOOST_STATIC_ASSERT(sizeof(tracking_type) == sizeof(bool)); - // upto 32K classes - BOOST_STATIC_ASSERT(sizeof(class_id_type) == sizeof(int_least16_t)); - BOOST_STATIC_ASSERT(sizeof(class_id_reference_type) == sizeof(int_least16_t)); - // upto 2G objects - BOOST_STATIC_ASSERT(sizeof(object_id_type) == sizeof(uint_least32_t)); - BOOST_STATIC_ASSERT(sizeof(object_reference_type) == sizeof(uint_least32_t)); - - // binary files don't include the optional information - void save_override(const class_id_optional_type & /* t */){} - - // enable this if we decide to support generation of previous versions - #if 0 - void save_override(const boost::archive::version_type & t){ - library_version_type lvt = this->get_library_version(); - if(boost::archive::library_version_type(7) < lvt){ - this->detail_common_oarchive::save_override(t); - } - else - if(boost::archive::library_version_type(6) < lvt){ - const boost::uint_least16_t x = t; - * this->This() << x; - } - else{ - const unsigned int x = t; - * this->This() << x; - } - } - void save_override(const boost::serialization::item_version_type & t){ - library_version_type lvt = this->get_library_version(); - if(boost::archive::library_version_type(7) < lvt){ - this->detail_common_oarchive::save_override(t); - } - else - if(boost::archive::library_version_type(6) < lvt){ - const boost::uint_least16_t x = t; - * this->This() << x; - } - else{ - const unsigned int x = t; - * this->This() << x; - } - } - - void save_override(class_id_type & t){ - library_version_type lvt = this->get_library_version(); - if(boost::archive::library_version_type(7) < lvt){ - this->detail_common_oarchive::save_override(t); - } - else - if(boost::archive::library_version_type(6) < lvt){ - const boost::int_least16_t x = t; - * this->This() << x; - } - else{ - const int x = t; - * this->This() << x; - } - } - void save_override(class_id_reference_type & t){ - save_override(static_cast(t)); - } - - #endif - - // explicitly convert to char * to avoid compile ambiguities - void save_override(const class_name_type & t){ - const std::string s(t); - * this->This() << s; - } - - #if 0 - void save_override(const serialization::collection_size_type & t){ - if (get_library_version() < boost::archive::library_version_type(6)){ - unsigned int x=0; - * this->This() >> x; - t = serialization::collection_size_type(x); - } - else{ - * this->This() >> t; - } - } - #endif - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - init(); - - basic_binary_oarchive(unsigned int flags) : - detail::common_oarchive(flags) - {} -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_ARCHIVE_BASIC_BINARY_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oprimitive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oprimitive.hpp deleted file mode 100644 index 6dc770c60e8..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/basic_binary_oprimitive.hpp +++ /dev/null @@ -1,188 +0,0 @@ -#ifndef BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP -#define BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_binary_oprimitive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// archives stored as native binary - this should be the fastest way -// to archive the state of a group of obects. It makes no attempt to -// convert to any canonical form. - -// IN GENERAL, ARCHIVES CREATED WITH THIS CLASS WILL NOT BE READABLE -// ON PLATFORM APART FROM THE ONE THEY ARE CREATE ON - -#include -#include -#include -#include // basic_streambuf -#include -#include // size_t - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include -#include -#include -#include -#include - -//#include -#include -#include - -#include -#include -#include -#include -#include // must be the last header - -namespace boost { -namespace archive { - -///////////////////////////////////////////////////////////////////////// -// class basic_binary_oprimitive - binary output of prmitives - -template -class BOOST_SYMBOL_VISIBLE basic_binary_oprimitive { -#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS - friend class save_access; -protected: -#else -public: -#endif - std::basic_streambuf & m_sb; - // return a pointer to the most derived class - Archive * This(){ - return static_cast(this); - } - #ifndef BOOST_NO_STD_LOCALE - // note order! - if you change this, libstd++ will fail! - // a) create new locale with new codecvt facet - // b) save current locale - // c) change locale to new one - // d) use stream buffer - // e) change locale back to original - // f) destroy new codecvt facet - boost::archive::codecvt_null codecvt_null_facet; - basic_streambuf_locale_saver locale_saver; - std::locale archive_locale; - #endif - // default saving of primitives. - template - void save(const T & t) - { - save_binary(& t, sizeof(T)); - } - - ///////////////////////////////////////////////////////// - // fundamental types that need special treatment - - // trap usage of invalid uninitialized boolean which would - // otherwise crash on load. - void save(const bool t){ - BOOST_ASSERT(0 == static_cast(t) || 1 == static_cast(t)); - save_binary(& t, sizeof(t)); - } - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - save(const std::string &s); - #ifndef BOOST_NO_STD_WSTRING - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - save(const std::wstring &ws); - #endif - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - save(const char * t); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - save(const wchar_t * t); - - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - init(); - - BOOST_ARCHIVE_OR_WARCHIVE_DECL - basic_binary_oprimitive( - std::basic_streambuf & sb, - bool no_codecvt - ); - BOOST_ARCHIVE_OR_WARCHIVE_DECL - ~basic_binary_oprimitive(); -public: - - // we provide an optimized save for all fundamental types - // typedef serialization::is_bitwise_serializable - // use_array_optimization; - // workaround without using mpl lambdas - struct use_array_optimization { - template - #if defined(BOOST_NO_DEPENDENT_NESTED_DERIVATIONS) - struct apply { - typedef typename boost::serialization::is_bitwise_serializable< T >::type type; - }; - #else - struct apply : public boost::serialization::is_bitwise_serializable< T > {}; - #endif - }; - - // the optimized save_array dispatches to save_binary - template - void save_array(boost::serialization::array_wrapper const& a, unsigned int) - { - save_binary(a.address(),a.count()*sizeof(ValueType)); - } - - void save_binary(const void *address, std::size_t count); -}; - -template -inline void -basic_binary_oprimitive::save_binary( - const void *address, - std::size_t count -){ - // BOOST_ASSERT(count <= std::size_t(boost::integer_traits::const_max)); - // note: if the following assertions fail - // a likely cause is that the output stream is set to "text" - // mode where by cr characters recieve special treatment. - // be sure that the output stream is opened with ios::binary - //if(os.fail()) - // boost::serialization::throw_exception( - // archive_exception(archive_exception::output_stream_error) - // ); - // figure number of elements to output - round up - count = ( count + sizeof(Elem) - 1) / sizeof(Elem); - std::streamsize scount = m_sb.sputn( - static_cast(address), - static_cast(count) - ); - if(count != static_cast(scount)) - boost::serialization::throw_exception( - archive_exception(archive_exception::output_stream_error) - ); - //os.write( - // static_cast(address), - // count - //); - //BOOST_ASSERT(os.good()); -} - -} //namespace boost -} //namespace archive - -#include // pop pragmas - -#endif // BOOST_ARCHIVE_BASIC_BINARY_OPRIMITIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_streambuf_locale_saver.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_streambuf_locale_saver.hpp deleted file mode 100644 index 5cd4b36f081..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/basic_streambuf_locale_saver.hpp +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_HPP -#define BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_streambuf_locale_saver.hpp - -// (C) Copyright 2005 Robert Ramey - http://www.rrsd.com - -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// note derived from boost/io/ios_state.hpp -// Copyright 2002, 2005 Daryle Walker. Use, modification, and distribution -// are subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or a copy at .) - -// See for the library's home page. - -#ifndef BOOST_NO_STD_LOCALE - -#include // for std::locale -#include -#include // for std::basic_streambuf - -#include -#include - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost{ -namespace archive{ - -template < typename Ch, class Tr > -class basic_streambuf_locale_saver : - private boost::noncopyable -{ -public: - explicit basic_streambuf_locale_saver(std::basic_streambuf &s) : - m_streambuf(s), - m_locale(s.getloc()) - {} - ~basic_streambuf_locale_saver(){ - m_streambuf.pubsync(); - m_streambuf.pubimbue(m_locale); - } -private: - std::basic_streambuf & m_streambuf; - std::locale const m_locale; -}; - -template < typename Ch, class Tr > -class basic_istream_locale_saver : - private boost::noncopyable -{ -public: - explicit basic_istream_locale_saver(std::basic_istream &s) : - m_istream(s), - m_locale(s.getloc()) - {} - ~basic_istream_locale_saver(){ - // libstdc++ crashes without this - m_istream.sync(); - m_istream.imbue(m_locale); - } -private: - std::basic_istream & m_istream; - std::locale const m_locale; -}; - -template < typename Ch, class Tr > -class basic_ostream_locale_saver : - private boost::noncopyable -{ -public: - explicit basic_ostream_locale_saver(std::basic_ostream &s) : - m_ostream(s), - m_locale(s.getloc()) - {} - ~basic_ostream_locale_saver(){ - m_ostream.flush(); - m_ostream.imbue(m_locale); - } -private: - std::basic_ostream & m_ostream; - std::locale const m_locale; -}; - - -} // archive -} // boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_NO_STD_LOCALE -#endif // BOOST_ARCHIVE_BASIC_STREAMBUF_LOCALE_SAVER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iarchive.hpp deleted file mode 100644 index 48a646cc1f7..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iarchive.hpp +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef BOOST_ARCHIVE_BASIC_TEXT_IARCHIVE_HPP -#define BOOST_ARCHIVE_BASIC_TEXT_IARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_text_iarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// archives stored as text - note these ar templated on the basic -// stream templates to accommodate wide (and other?) kind of characters -// -// note the fact that on libraries without wide characters, ostream is -// is not a specialization of basic_ostream which in fact is not defined -// in such cases. So we can't use basic_istream but rather -// use two template parameters - -#include -#include - -#include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -namespace detail { - template class interface_iarchive; -} // namespace detail - -///////////////////////////////////////////////////////////////////////// -// class basic_text_iarchive - read serialized objects from a input text stream -template -class BOOST_SYMBOL_VISIBLE basic_text_iarchive : - public detail::common_iarchive -{ -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else -protected: - #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) - // for some inexplicable reason insertion of "class" generates compile erro - // on msvc 7.1 - friend detail::interface_iarchive; - #else - friend class detail::interface_iarchive; - #endif -#endif - // intermediate level to support override of operators - // fot templates in the absence of partial function - // template ordering - typedef detail::common_iarchive detail_common_iarchive; - template - void load_override(T & t){ - this->detail_common_iarchive::load_override(t); - } - // text file don't include the optional information - void load_override(class_id_optional_type & /*t*/){} - - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - load_override(class_name_type & t); - - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - init(void); - - basic_text_iarchive(unsigned int flags) : - detail::common_iarchive(flags) - {} - ~basic_text_iarchive(){} -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_ARCHIVE_BASIC_TEXT_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iprimitive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iprimitive.hpp deleted file mode 100644 index bf936b55546..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/basic_text_iprimitive.hpp +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef BOOST_ARCHIVE_BASIC_TEXT_IPRIMITIVE_HPP -#define BOOST_ARCHIVE_BASIC_TEXT_IPRIMITIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_text_iprimitive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// archives stored as text - note these are templated on the basic -// stream templates to accommodate wide (and other?) kind of characters -// -// Note the fact that on libraries without wide characters, ostream is -// not a specialization of basic_ostream which in fact is not defined -// in such cases. So we can't use basic_ostream but rather -// use two template parameters - -#include -#include // size_t - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; - #if ! defined(BOOST_DINKUMWARE_STDLIB) && ! defined(__SGI_STL_PORT) - using ::locale; - #endif -} // namespace std -#endif - -#include -#include - -#include -#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) -#include -#endif -#include -#include -#include -#include -#include // must be the last header - -namespace boost { -namespace archive { - -///////////////////////////////////////////////////////////////////////// -// class basic_text_iarchive - load serialized objects from a input text stream -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4244 4267 ) -#endif - -template -class BOOST_SYMBOL_VISIBLE basic_text_iprimitive { -protected: - IStream &is; - io::ios_flags_saver flags_saver; - io::ios_precision_saver precision_saver; - - #ifndef BOOST_NO_STD_LOCALE - // note order! - if you change this, libstd++ will fail! - // a) create new locale with new codecvt facet - // b) save current locale - // c) change locale to new one - // d) use stream buffer - // e) change locale back to original - // f) destroy new codecvt facet - boost::archive::codecvt_null codecvt_null_facet; - std::locale archive_locale; - basic_istream_locale_saver< - typename IStream::char_type, - typename IStream::traits_type - > locale_saver; - #endif - - template - void load(T & t) - { - if(is >> t) - return; - boost::serialization::throw_exception( - archive_exception(archive_exception::input_stream_error) - ); - } - - void load(char & t) - { - short int i; - load(i); - t = i; - } - void load(signed char & t) - { - short int i; - load(i); - t = i; - } - void load(unsigned char & t) - { - unsigned short int i; - load(i); - t = i; - } - - #ifndef BOOST_NO_INTRINSIC_WCHAR_T - void load(wchar_t & t) - { - BOOST_STATIC_ASSERT(sizeof(wchar_t) <= sizeof(int)); - int i; - load(i); - t = i; - } - #endif - BOOST_ARCHIVE_OR_WARCHIVE_DECL - basic_text_iprimitive(IStream &is, bool no_codecvt); - BOOST_ARCHIVE_OR_WARCHIVE_DECL - ~basic_text_iprimitive(); -public: - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - load_binary(void *address, std::size_t count); -}; - -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - -} // namespace archive -} // namespace boost - -#include // pop pragmas - -#endif // BOOST_ARCHIVE_BASIC_TEXT_IPRIMITIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oarchive.hpp deleted file mode 100644 index 6f7f8fb167d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oarchive.hpp +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef BOOST_ARCHIVE_BASIC_TEXT_OARCHIVE_HPP -#define BOOST_ARCHIVE_BASIC_TEXT_OARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_text_oarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// archives stored as text - note these ar templated on the basic -// stream templates to accommodate wide (and other?) kind of characters -// -// note the fact that on libraries without wide characters, ostream is -// is not a specialization of basic_ostream which in fact is not defined -// in such cases. So we can't use basic_ostream but rather -// use two template parameters - -#include -#include -#include -#include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -namespace detail { - template class interface_oarchive; -} // namespace detail - -///////////////////////////////////////////////////////////////////////// -// class basic_text_oarchive -template -class BOOST_SYMBOL_VISIBLE basic_text_oarchive : - public detail::common_oarchive -{ -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else -protected: - #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) - // for some inexplicable reason insertion of "class" generates compile erro - // on msvc 7.1 - friend detail::interface_oarchive; - #else - friend class detail::interface_oarchive; - #endif -#endif - - enum { - none, - eol, - space - } delimiter; - - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - newtoken(); - - void newline(){ - delimiter = eol; - } - - // default processing - kick back to base class. Note the - // extra stuff to get it passed borland compilers - typedef detail::common_oarchive detail_common_oarchive; - template - void save_override(T & t){ - this->detail_common_oarchive::save_override(t); - } - - // start new objects on a new line - void save_override(const object_id_type & t){ - this->This()->newline(); - this->detail_common_oarchive::save_override(t); - } - - // text file don't include the optional information - void save_override(const class_id_optional_type & /* t */){} - - void save_override(const class_name_type & t){ - const std::string s(t); - * this->This() << s; - } - - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - init(); - - basic_text_oarchive(unsigned int flags) : - detail::common_oarchive(flags), - delimiter(none) - {} - ~basic_text_oarchive(){} -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_ARCHIVE_BASIC_TEXT_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oprimitive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oprimitive.hpp deleted file mode 100644 index 45f09358ece..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/basic_text_oprimitive.hpp +++ /dev/null @@ -1,209 +0,0 @@ -#ifndef BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP -#define BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_text_oprimitive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// archives stored as text - note these ar templated on the basic -// stream templates to accommodate wide (and other?) kind of characters -// -// note the fact that on libraries without wide characters, ostream is -// is not a specialization of basic_ostream which in fact is not defined -// in such cases. So we can't use basic_ostream but rather -// use two template parameters - -#include -#include -#include // size_t - -#include -#include -#include - -#include -#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) -#include -#endif - -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; - #if ! defined(BOOST_DINKUMWARE_STDLIB) && ! defined(__SGI_STL_PORT) - using ::locale; - #endif -} // namespace std -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include // must be the last header - -namespace boost { -namespace archive { - -///////////////////////////////////////////////////////////////////////// -// class basic_text_oprimitive - output of prmitives to stream -template -class BOOST_SYMBOL_VISIBLE basic_text_oprimitive -{ -protected: - OStream &os; - io::ios_flags_saver flags_saver; - io::ios_precision_saver precision_saver; - - #ifndef BOOST_NO_STD_LOCALE - // note order! - if you change this, libstd++ will fail! - // a) create new locale with new codecvt facet - // b) save current locale - // c) change locale to new one - // d) use stream buffer - // e) change locale back to original - // f) destroy new codecvt facet - boost::archive::codecvt_null codecvt_null_facet; - std::locale archive_locale; - basic_ostream_locale_saver< - typename OStream::char_type, - typename OStream::traits_type - > locale_saver; - #endif - - ///////////////////////////////////////////////////////// - // fundamental types that need special treatment - void save(const bool t){ - // trap usage of invalid uninitialized boolean which would - // otherwise crash on load. - BOOST_ASSERT(0 == static_cast(t) || 1 == static_cast(t)); - if(os.fail()) - boost::serialization::throw_exception( - archive_exception(archive_exception::output_stream_error) - ); - os << t; - } - void save(const signed char t) - { - save(static_cast(t)); - } - void save(const unsigned char t) - { - save(static_cast(t)); - } - void save(const char t) - { - save(static_cast(t)); - } - #ifndef BOOST_NO_INTRINSIC_WCHAR_T - void save(const wchar_t t) - { - BOOST_STATIC_ASSERT(sizeof(wchar_t) <= sizeof(int)); - save(static_cast(t)); - } - #endif - - ///////////////////////////////////////////////////////// - // saving of any types not listed above - - template - void save_impl(const T &t, boost::mpl::bool_ &){ - if(os.fail()) - boost::serialization::throw_exception( - archive_exception(archive_exception::output_stream_error) - ); - os << t; - } - - ///////////////////////////////////////////////////////// - // floating point types need even more special treatment - // the following determines whether the type T is some sort - // of floating point type. Note that we then assume that - // the stream << operator is defined on that type - if not - // we'll get a compile time error. This is meant to automatically - // support synthesized types which support floating point - // operations. Also it should handle compiler dependent types - // such long double. Due to John Maddock. - - template - struct is_float { - typedef typename mpl::bool_< - boost::is_floating_point::value - || (std::numeric_limits::is_specialized - && !std::numeric_limits::is_integer - && !std::numeric_limits::is_exact - && std::numeric_limits::max_exponent) - >::type type; - }; - - template - void save_impl(const T &t, boost::mpl::bool_ &){ - // must be a user mistake - can't serialize un-initialized data - if(os.fail()) - boost::serialization::throw_exception( - archive_exception(archive_exception::output_stream_error) - ); - // The formulae for the number of decimla digits required is given in - // http://www2.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1822.pdf - // which is derived from Kahan's paper: - // www.eecs.berkeley.edu/~wkahan/ieee754status/ieee754.ps - // const unsigned int digits = (std::numeric_limits::digits * 3010) / 10000; - // note: I've commented out the above because I didn't get good results. e.g. - // in one case I got a difference of 19 units. - #ifndef BOOST_NO_CXX11_NUMERIC_LIMITS - const unsigned int digits = std::numeric_limits::max_digits10; - #else - const unsigned int digits = std::numeric_limits::digits10 + 2; - #endif - os << std::setprecision(digits) << std::scientific << t; - } - - template - void save(const T & t){ - typename is_float::type tf; - save_impl(t, tf); - } - - BOOST_ARCHIVE_OR_WARCHIVE_DECL - basic_text_oprimitive(OStream & os, bool no_codecvt); - BOOST_ARCHIVE_OR_WARCHIVE_DECL - ~basic_text_oprimitive(); -public: - // unformatted append of one character - void put(typename OStream::char_type c){ - if(os.fail()) - boost::serialization::throw_exception( - archive_exception(archive_exception::output_stream_error) - ); - os.put(c); - } - // unformatted append of null terminated string - void put(const char * s){ - while('\0' != *s) - os.put(*s++); - } - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - save_binary(const void *address, std::size_t count); -}; - -} //namespace boost -} //namespace archive - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_ARCHIVE_BASIC_TEXT_OPRIMITIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_archive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_archive.hpp deleted file mode 100644 index bef368b973b..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_archive.hpp +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef BOOST_ARCHIVE_BASIC_XML_TEXT_ARCHIVE_HPP -#define BOOST_ARCHIVE_BASIC_XML_TEXT_ARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_xml_archive.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include // must be the last header - -namespace boost { -namespace archive { - -// constant strings used in xml i/o - -extern -BOOST_ARCHIVE_DECL const char * -BOOST_ARCHIVE_XML_OBJECT_ID(); - -extern -BOOST_ARCHIVE_DECL const char * -BOOST_ARCHIVE_XML_OBJECT_REFERENCE(); - -extern -BOOST_ARCHIVE_DECL const char * -BOOST_ARCHIVE_XML_CLASS_ID(); - -extern -BOOST_ARCHIVE_DECL const char * -BOOST_ARCHIVE_XML_CLASS_ID_REFERENCE(); - -extern -BOOST_ARCHIVE_DECL const char * -BOOST_ARCHIVE_XML_CLASS_NAME(); - -extern -BOOST_ARCHIVE_DECL const char * -BOOST_ARCHIVE_XML_TRACKING(); - -extern -BOOST_ARCHIVE_DECL const char * -BOOST_ARCHIVE_XML_VERSION(); - -extern -BOOST_ARCHIVE_DECL const char * -BOOST_ARCHIVE_XML_SIGNATURE(); - -}// namespace archive -}// namespace boost - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_ARCHIVE_BASIC_XML_TEXT_ARCHIVE_HPP - diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_iarchive.hpp deleted file mode 100644 index e9f7482f744..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_iarchive.hpp +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef BOOST_ARCHIVE_BASIC_XML_IARCHIVE_HPP -#define BOOST_ARCHIVE_BASIC_XML_IARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_xml_iarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -#include -#include -#include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -namespace detail { - template class interface_iarchive; -} // namespace detail - -///////////////////////////////////////////////////////////////////////// -// class basic_xml_iarchive - read serialized objects from a input text stream -template -class BOOST_SYMBOL_VISIBLE basic_xml_iarchive : - public detail::common_iarchive -{ - unsigned int depth; -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else -protected: - friend class detail::interface_iarchive; -#endif - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - load_start(const char *name); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - load_end(const char *name); - - // Anything not an attribute and not a name-value pair is an - // should be trapped here. - template - void load_override(T & t) - { - // If your program fails to compile here, its most likely due to - // not specifying an nvp wrapper around the variable to - // be serialized. - BOOST_MPL_ASSERT((serialization::is_wrapper< T >)); - this->detail_common_iarchive::load_override(t); - } - - // Anything not an attribute - see below - should be a name value - // pair and be processed here - typedef detail::common_iarchive detail_common_iarchive; - template - void load_override( - const boost::serialization::nvp< T > & t - ){ - this->This()->load_start(t.name()); - this->detail_common_iarchive::load_override(t.value()); - this->This()->load_end(t.name()); - } - - // specific overrides for attributes - handle as - // primitives. These are not name-value pairs - // so they have to be intercepted here and passed on to load. - // although the class_id is included in the xml text file in order - // to make the file self describing, it isn't used when loading - // an xml archive. So we can skip it here. Note: we MUST override - // it otherwise it will be loaded as a normal primitive w/o tag and - // leaving the archive in an undetermined state - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - load_override(class_id_type & t); - void load_override(class_id_optional_type & /* t */){} - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - load_override(object_id_type & t); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - load_override(version_type & t); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - load_override(tracking_type & t); - // class_name_type can't be handled here as it depends upon the - // char type used by the stream. So require the derived implementation - // handle this. - // void load_override(class_name_type & t); - - BOOST_ARCHIVE_OR_WARCHIVE_DECL - basic_xml_iarchive(unsigned int flags); - BOOST_ARCHIVE_OR_WARCHIVE_DECL - ~basic_xml_iarchive(); -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_ARCHIVE_BASIC_XML_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_oarchive.hpp deleted file mode 100644 index 107fca4ec65..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/basic_xml_oarchive.hpp +++ /dev/null @@ -1,138 +0,0 @@ -#ifndef BOOST_ARCHIVE_BASIC_XML_OARCHIVE_HPP -#define BOOST_ARCHIVE_BASIC_XML_OARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_xml_oarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -#include -#include -#include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -namespace detail { - template class interface_oarchive; -} // namespace detail - -////////////////////////////////////////////////////////////////////// -// class basic_xml_oarchive - write serialized objects to a xml output stream -template -class BOOST_SYMBOL_VISIBLE basic_xml_oarchive : - public detail::common_oarchive -{ - // special stuff for xml output - unsigned int depth; - bool pending_preamble; -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else -protected: - friend class detail::interface_oarchive; -#endif - bool indent_next; - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - indent(); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - init(); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - windup(); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - write_attribute( - const char *attribute_name, - int t, - const char *conjunction = "=\"" - ); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - write_attribute( - const char *attribute_name, - const char *key - ); - // helpers used below - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - save_start(const char *name); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - save_end(const char *name); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - end_preamble(); - - // Anything not an attribute and not a name-value pair is an - // error and should be trapped here. - template - void save_override(T & t) - { - // If your program fails to compile here, its most likely due to - // not specifying an nvp wrapper around the variable to - // be serialized. - BOOST_MPL_ASSERT((serialization::is_wrapper< T >)); - this->detail_common_oarchive::save_override(t); - } - - // special treatment for name-value pairs. - typedef detail::common_oarchive detail_common_oarchive; - template - void save_override( - const ::boost::serialization::nvp< T > & t - ){ - this->This()->save_start(t.name()); - this->detail_common_oarchive::save_override(t.const_value()); - this->This()->save_end(t.name()); - } - - // specific overrides for attributes - not name value pairs so we - // want to trap them before the above "fall through" - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - save_override(const class_id_type & t); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - save_override(const class_id_optional_type & t); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - save_override(const class_id_reference_type & t); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - save_override(const object_id_type & t); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - save_override(const object_reference_type & t); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - save_override(const version_type & t); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - save_override(const class_name_type & t); - BOOST_ARCHIVE_OR_WARCHIVE_DECL void - save_override(const tracking_type & t); - - BOOST_ARCHIVE_OR_WARCHIVE_DECL - basic_xml_oarchive(unsigned int flags); - BOOST_ARCHIVE_OR_WARCHIVE_DECL - ~basic_xml_oarchive(); -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_ARCHIVE_BASIC_XML_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive.hpp deleted file mode 100644 index 785ce7610b1..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef BOOST_ARCHIVE_BINARY_IARCHIVE_HPP -#define BOOST_ARCHIVE_BINARY_IARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// binary_iarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -// do not derive from this class. If you want to extend this functionality -// via inhertance, derived from binary_iarchive_impl instead. This will -// preserve correct static polymorphism. -class BOOST_SYMBOL_VISIBLE binary_iarchive : - public binary_iarchive_impl< - boost::archive::binary_iarchive, - std::istream::char_type, - std::istream::traits_type - >{ -public: - binary_iarchive(std::istream & is, unsigned int flags = 0) : - binary_iarchive_impl< - binary_iarchive, std::istream::char_type, std::istream::traits_type - >(is, flags) - {} - binary_iarchive(std::streambuf & bsb, unsigned int flags = 0) : - binary_iarchive_impl< - binary_iarchive, std::istream::char_type, std::istream::traits_type - >(bsb, flags) - {} -}; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_iarchive) -BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::archive::binary_iarchive) - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_ARCHIVE_BINARY_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive_impl.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive_impl.hpp deleted file mode 100644 index b4747c98ece..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/binary_iarchive_impl.hpp +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_HPP -#define BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// binary_iarchive_impl.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -namespace detail { - template class interface_iarchive; -} // namespace detail - -template -class BOOST_SYMBOL_VISIBLE binary_iarchive_impl : - public basic_binary_iprimitive, - public basic_binary_iarchive -{ -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else -protected: - #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) - // for some inexplicable reason insertion of "class" generates compile erro - // on msvc 7.1 - friend detail::interface_iarchive; - friend basic_binary_iarchive; - friend load_access; - #else - friend class detail::interface_iarchive; - friend class basic_binary_iarchive; - friend class load_access; - #endif -#endif - template - void load_override(T & t){ - this->basic_binary_iarchive::load_override(t); - } - void init(unsigned int flags){ - if(0 != (flags & no_header)){ - return; - } - #if ! defined(__MWERKS__) - this->basic_binary_iarchive::init(); - this->basic_binary_iprimitive::init(); - #else - basic_binary_iarchive::init(); - basic_binary_iprimitive::init(); - #endif - } - binary_iarchive_impl( - std::basic_streambuf & bsb, - unsigned int flags - ) : - basic_binary_iprimitive( - bsb, - 0 != (flags & no_codecvt) - ), - basic_binary_iarchive(flags) - { - init(flags); - } - binary_iarchive_impl( - std::basic_istream & is, - unsigned int flags - ) : - basic_binary_iprimitive( - * is.rdbuf(), - 0 != (flags & no_codecvt) - ), - basic_binary_iarchive(flags) - { - init(flags); - } -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_ARCHIVE_BINARY_IARCHIVE_IMPL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive.hpp deleted file mode 100644 index e8313fd7c95..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef BOOST_ARCHIVE_BINARY_OARCHIVE_HPP -#define BOOST_ARCHIVE_BINARY_OARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// binary_oarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -// do not derive from this class. If you want to extend this functionality -// via inhertance, derived from binary_oarchive_impl instead. This will -// preserve correct static polymorphism. -class BOOST_SYMBOL_VISIBLE binary_oarchive : - public binary_oarchive_impl< - binary_oarchive, std::ostream::char_type, std::ostream::traits_type - > -{ -public: - binary_oarchive(std::ostream & os, unsigned int flags = 0) : - binary_oarchive_impl< - binary_oarchive, std::ostream::char_type, std::ostream::traits_type - >(os, flags) - {} - binary_oarchive(std::streambuf & bsb, unsigned int flags = 0) : - binary_oarchive_impl< - binary_oarchive, std::ostream::char_type, std::ostream::traits_type - >(bsb, flags) - {} -}; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_oarchive) -BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(boost::archive::binary_oarchive) - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_ARCHIVE_BINARY_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive_impl.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive_impl.hpp deleted file mode 100644 index 6b4d018a564..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/binary_oarchive_impl.hpp +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef BOOST_ARCHIVE_BINARY_OARCHIVE_IMPL_HPP -#define BOOST_ARCHIVE_BINARY_OARCHIVE_IMPL_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// binary_oarchive_impl.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -namespace detail { - template class interface_oarchive; -} // namespace detail - -template -class BOOST_SYMBOL_VISIBLE binary_oarchive_impl : - public basic_binary_oprimitive, - public basic_binary_oarchive -{ -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else -protected: - #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) - // for some inexplicable reason insertion of "class" generates compile erro - // on msvc 7.1 - friend detail::interface_oarchive; - friend basic_binary_oarchive; - friend save_access; - #else - friend class detail::interface_oarchive; - friend class basic_binary_oarchive; - friend class save_access; - #endif -#endif - template - void save_override(T & t){ - this->basic_binary_oarchive::save_override(t); - } - void init(unsigned int flags) { - if(0 != (flags & no_header)){ - return; - } - #if ! defined(__MWERKS__) - this->basic_binary_oarchive::init(); - this->basic_binary_oprimitive::init(); - #else - basic_binary_oarchive::init(); - basic_binary_oprimitive::init(); - #endif - } - binary_oarchive_impl( - std::basic_streambuf & bsb, - unsigned int flags - ) : - basic_binary_oprimitive( - bsb, - 0 != (flags & no_codecvt) - ), - basic_binary_oarchive(flags) - { - init(flags); - } - binary_oarchive_impl( - std::basic_ostream & os, - unsigned int flags - ) : - basic_binary_oprimitive( - * os.rdbuf(), - 0 != (flags & no_codecvt) - ), - basic_binary_oarchive(flags) - { - init(flags); - } -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_ARCHIVE_BINARY_OARCHIVE_IMPL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_wiarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_wiarchive.hpp deleted file mode 100644 index 775d8f82726..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/binary_wiarchive.hpp +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef BOOST_ARCHIVE_BINARY_WIARCHIVE_HPP -#define BOOST_ARCHIVE_BINARY_WIARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// binary_wiarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifdef BOOST_NO_STD_WSTREAMBUF -#error "wide char i/o not supported on this platform" -#else - -#include // wistream -#include -#include - -namespace boost { -namespace archive { - -class binary_wiarchive : - public binary_iarchive_impl< - binary_wiarchive, std::wistream::char_type, std::wistream::traits_type - > -{ -public: - binary_wiarchive(std::wistream & is, unsigned int flags = 0) : - binary_iarchive_impl< - binary_wiarchive, std::wistream::char_type, std::wistream::traits_type - >(is, flags) - {} - binary_wiarchive(std::wstreambuf & bsb, unsigned int flags = 0) : - binary_iarchive_impl< - binary_wiarchive, std::wistream::char_type, std::wistream::traits_type - >(bsb, flags) - {} -}; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_wiarchive) - -#endif // BOOST_NO_STD_WSTREAMBUF -#endif // BOOST_ARCHIVE_BINARY_WIARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/binary_woarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/binary_woarchive.hpp deleted file mode 100644 index a8817d6f8b4..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/binary_woarchive.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef BOOST_ARCHIVE_BINARY_WOARCHIVE_HPP -#define BOOST_ARCHIVE_BINARY_WOARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// binary_woarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifdef BOOST_NO_STD_WSTREAMBUF -#error "wide char i/o not supported on this platform" -#else - -#include -#include -#include - -namespace boost { -namespace archive { - -// do not derive from this class. If you want to extend this functionality -// via inhertance, derived from binary_oarchive_impl instead. This will -// preserve correct static polymorphism. -class binary_woarchive : - public binary_oarchive_impl< - binary_woarchive, std::wostream::char_type, std::wostream::traits_type - > -{ -public: - binary_woarchive(std::wostream & os, unsigned int flags = 0) : - binary_oarchive_impl< - binary_woarchive, std::wostream::char_type, std::wostream::traits_type - >(os, flags) - {} - binary_woarchive(std::wstreambuf & bsb, unsigned int flags = 0) : - binary_oarchive_impl< - binary_woarchive, std::wostream::char_type, std::wostream::traits_type - >(bsb, flags) - {} -}; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::binary_woarchive) - -#endif // BOOST_NO_STD_WSTREAMBUF -#endif // BOOST_ARCHIVE_BINARY_WOARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/codecvt_null.hpp b/contrib/libboost/boost_1_65_0/boost/archive/codecvt_null.hpp deleted file mode 100644 index 7bce2b9b329..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/codecvt_null.hpp +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef BOOST_ARCHIVE_CODECVT_NULL_HPP -#define BOOST_ARCHIVE_CODECVT_NULL_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// codecvt_null.hpp: - -// (C) Copyright 2004 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include // NULL, size_t -#ifndef BOOST_NO_CWCHAR -#include // for mbstate_t -#endif -#include -#include -#include -#include // must be the last header - -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std { -// For STLport on WinCE, BOOST_NO_STDC_NAMESPACE can get defined if STLport is putting symbols in its own namespace. -// In the case of codecvt, however, this does not mean that codecvt is in the global namespace (it will be in STLport's namespace) -# if !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION) - using ::codecvt; -# endif - using ::mbstate_t; - using ::size_t; -} // namespace -#endif - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -template -class codecvt_null; - -template<> -class codecvt_null : public std::codecvt -{ - virtual bool do_always_noconv() const throw() { - return true; - } -public: - explicit codecvt_null(std::size_t no_locale_manage = 0) : - std::codecvt(no_locale_manage) - {} - virtual ~codecvt_null(){}; -}; - -template<> -class BOOST_SYMBOL_VISIBLE codecvt_null : public std::codecvt -{ - virtual BOOST_WARCHIVE_DECL BOOST_DLLEXPORT std::codecvt_base::result - do_out( - std::mbstate_t & state, - const wchar_t * first1, - const wchar_t * last1, - const wchar_t * & next1, - char * first2, - char * last2, - char * & next2 - ) const BOOST_USED; - virtual BOOST_WARCHIVE_DECL BOOST_DLLEXPORT std::codecvt_base::result - do_in( - std::mbstate_t & state, - const char * first1, - const char * last1, - const char * & next1, - wchar_t * first2, - wchar_t * last2, - wchar_t * & next2 - ) const BOOST_USED; - virtual int do_encoding( ) const throw( ){ - return sizeof(wchar_t) / sizeof(char); - } - virtual int do_max_length( ) const throw( ){ - return do_encoding(); - } -public: - BOOST_DLLEXPORT explicit codecvt_null(std::size_t no_locale_manage = 0) : - std::codecvt(no_locale_manage) - {} - virtual ~codecvt_null(){}; -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif -#include // pop pragmas - -#endif //BOOST_ARCHIVE_CODECVT_NULL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_prefix.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_prefix.hpp deleted file mode 100644 index debf79e9f0b..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_prefix.hpp +++ /dev/null @@ -1,16 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// abi_prefix.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // must be the last header -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4251 4231 4660 4275) -#endif - diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_suffix.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_suffix.hpp deleted file mode 100644 index 4e054d66214..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/abi_suffix.hpp +++ /dev/null @@ -1,15 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// abi_suffix.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif -#include // pops abi_suffix.hpp pragmas - diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/archive_serializer_map.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/archive_serializer_map.hpp deleted file mode 100644 index 5432bfc73e7..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/archive_serializer_map.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef BOOST_ARCHIVE_SERIALIZER_MAP_HPP -#define BOOST_ARCHIVE_SERIALIZER_MAP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// archive_serializer_map.hpp: extenstion of type_info required for -// serialization. - -// (C) Copyright 2009 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// note: this is nothing more than the thinest of wrappers around -// basic_serializer_map so we can have a one map / archive type. - -#include -#include -#include // must be the last header - -namespace boost { - -namespace serialization { - class extended_type_info; -} // namespace serialization - -namespace archive { -namespace detail { - -class basic_serializer; - -template -class BOOST_SYMBOL_VISIBLE archive_serializer_map { -public: - static BOOST_ARCHIVE_OR_WARCHIVE_DECL bool insert(const basic_serializer * bs); - static BOOST_ARCHIVE_OR_WARCHIVE_DECL void erase(const basic_serializer * bs); - static BOOST_ARCHIVE_OR_WARCHIVE_DECL const basic_serializer * find( - const boost::serialization::extended_type_info & type_ - ); -}; - -} // namespace detail -} // namespace archive -} // namespace boost - -#include // must be the last header - -#endif //BOOST_ARCHIVE_SERIALIZER_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_archive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_archive.hpp deleted file mode 100644 index 79b0e490d65..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_archive.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef BOOST_ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP -#define BOOST_ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// auto_link_archive.hpp -// -// (c) Copyright Robert Ramey 2004 -// Use, modification, and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See library home page at http://www.boost.org/libs/serialization - -//----------------------------------------------------------------------------// - -// This header implements separate compilation features as described in -// http://www.boost.org/more/separate_compilation.html - -// enable automatic library variant selection ------------------------------// - -#include - -#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) \ -&& !defined(BOOST_ARCHIVE_SOURCE) && !defined(BOOST_WARCHIVE_SOURCE) \ -&& !defined(BOOST_SERIALIZATION_SOURCE) - - // Set the name of our library, this will get undef'ed by auto_link.hpp - // once it's done with it: - // - #define BOOST_LIB_NAME boost_serialization - // - // If we're importing code from a dll, then tell auto_link.hpp about it: - // - #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) - # define BOOST_DYN_LINK - #endif - // - // And include the header that does the work: - // - #include -#endif // auto-linking disabled - -#endif // BOOST_ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_warchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_warchive.hpp deleted file mode 100644 index 683d191c20d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/auto_link_warchive.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef BOOST_ARCHIVE_DETAIL_AUTO_LINK_WARCHIVE_HPP -#define BOOST_ARCHIVE_DETAIL_AUTO_LINK_WARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// auto_link_warchive.hpp -// -// (c) Copyright Robert Ramey 2004 -// Use, modification, and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See library home page at http://www.boost.org/libs/serialization - -//----------------------------------------------------------------------------// - -// This header implements separate compilation features as described in -// http://www.boost.org/more/separate_compilation.html - -// enable automatic library variant selection ------------------------------// - -#include - -#if !defined(BOOST_WARCHIVE_SOURCE) \ -&& !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) - -// Set the name of our library, this will get undef'ed by auto_link.hpp -// once it's done with it: -// -#define BOOST_LIB_NAME boost_wserialization -// -// If we're importing code from a dll, then tell auto_link.hpp about it: -// -#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) -# define BOOST_DYN_LINK -#endif -// -// And include the header that does the work: -// -#include -#endif // auto-linking disabled - -#endif // ARCHIVE_DETAIL_AUTO_LINK_ARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iarchive.hpp deleted file mode 100644 index 1f5a8bf63bf..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iarchive.hpp +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef BOOST_ARCHIVE_DETAIL_BASIC_IARCHIVE_HPP -#define BOOST_ARCHIVE_DETAIL_BASIC_IARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_iarchive.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// can't use this - much as I'd like to as borland doesn't support it - -#include -#include -#include - -#include -#include -#include -#include -#include // must be the last header - -namespace boost { -namespace serialization { - class extended_type_info; -} // namespace serialization - -namespace archive { -namespace detail { - -class basic_iarchive_impl; -class basic_iserializer; -class basic_pointer_iserializer; - -////////////////////////////////////////////////////////////////////// -// class basic_iarchive - read serialized objects from a input stream -class BOOST_SYMBOL_VISIBLE basic_iarchive : - private boost::noncopyable, - public boost::archive::detail::helper_collection -{ - friend class basic_iarchive_impl; - // hide implementation of this class to minimize header conclusion - boost::scoped_ptr pimpl; - - virtual void vload(version_type &t) = 0; - virtual void vload(object_id_type &t) = 0; - virtual void vload(class_id_type &t) = 0; - virtual void vload(class_id_optional_type &t) = 0; - virtual void vload(class_name_type &t) = 0; - virtual void vload(tracking_type &t) = 0; -protected: - BOOST_ARCHIVE_DECL basic_iarchive(unsigned int flags); - boost::archive::detail::helper_collection & - get_helper_collection(){ - return *this; - } -public: - // some msvc versions require that the following function be public - // otherwise it should really protected. - virtual BOOST_ARCHIVE_DECL ~basic_iarchive(); - // note: NOT part of the public API. - BOOST_ARCHIVE_DECL void next_object_pointer(void *t); - BOOST_ARCHIVE_DECL void register_basic_serializer( - const basic_iserializer & bis - ); - BOOST_ARCHIVE_DECL void load_object( - void *t, - const basic_iserializer & bis - ); - BOOST_ARCHIVE_DECL const basic_pointer_iserializer * - load_pointer( - void * & t, - const basic_pointer_iserializer * bpis_ptr, - const basic_pointer_iserializer * (*finder)( - const boost::serialization::extended_type_info & eti - ) - ); - // real public API starts here - BOOST_ARCHIVE_DECL void - set_library_version(library_version_type archive_library_version); - BOOST_ARCHIVE_DECL library_version_type - get_library_version() const; - BOOST_ARCHIVE_DECL unsigned int - get_flags() const; - BOOST_ARCHIVE_DECL void - reset_object_address(const void * new_address, const void * old_address); - BOOST_ARCHIVE_DECL void - delete_created_pointers(); -}; - -} // namespace detail -} // namespace archive -} // namespace boost - -#include // pops abi_suffix.hpp pragmas - -#endif //BOOST_ARCHIVE_DETAIL_BASIC_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iserializer.hpp deleted file mode 100644 index 0d66674c349..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_iserializer.hpp +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef BOOST_ARCHIVE_DETAIL_BASIC_ISERIALIZER_HPP -#define BOOST_ARCHIVE_DETAIL_BASIC_ISERIALIZER_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_iserializer.hpp: extenstion of type_info required for serialization. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // NULL -#include - -#include -#include -#include -#include -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace serialization { - class extended_type_info; -} // namespace serialization - -// forward declarations -namespace archive { -namespace detail { - -class basic_iarchive; -class basic_pointer_iserializer; - -class BOOST_SYMBOL_VISIBLE basic_iserializer : - public basic_serializer -{ -private: - basic_pointer_iserializer *m_bpis; -protected: - explicit BOOST_ARCHIVE_DECL basic_iserializer( - const boost::serialization::extended_type_info & type - ); - virtual BOOST_ARCHIVE_DECL ~basic_iserializer(); -public: - bool serialized_as_pointer() const { - return m_bpis != NULL; - } - void set_bpis(basic_pointer_iserializer *bpis){ - m_bpis = bpis; - } - const basic_pointer_iserializer * get_bpis_ptr() const { - return m_bpis; - } - virtual void load_object_data( - basic_iarchive & ar, - void *x, - const unsigned int file_version - ) const = 0; - // returns true if class_info should be saved - virtual bool class_info() const = 0 ; - // returns true if objects should be tracked - virtual bool tracking(const unsigned int) const = 0 ; - // returns class version - virtual version_type version() const = 0 ; - // returns true if this class is polymorphic - virtual bool is_polymorphic() const = 0; - virtual void destroy(/*const*/ void *address) const = 0 ; -}; - -} // namespae detail -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_ARCHIVE_DETAIL_BASIC_ISERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oarchive.hpp deleted file mode 100644 index c379108d584..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oarchive.hpp +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef BOOST_ARCHIVE_BASIC_OARCHIVE_HPP -#define BOOST_ARCHIVE_BASIC_OARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_oarchive.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // NULL -#include -#include -#include - -#include -#include -#include -#include // must be the last header - -namespace boost { -namespace serialization { - class extended_type_info; -} // namespace serialization - -namespace archive { -namespace detail { - -class basic_oarchive_impl; -class basic_oserializer; -class basic_pointer_oserializer; - -////////////////////////////////////////////////////////////////////// -// class basic_oarchive - write serialized objects to an output stream -class BOOST_SYMBOL_VISIBLE basic_oarchive : - private boost::noncopyable, - public boost::archive::detail::helper_collection -{ - friend class basic_oarchive_impl; - // hide implementation of this class to minimize header conclusion - boost::scoped_ptr pimpl; - - // overload these to bracket object attributes. Used to implement - // xml archives - virtual void vsave(const version_type t) = 0; - virtual void vsave(const object_id_type t) = 0; - virtual void vsave(const object_reference_type t) = 0; - virtual void vsave(const class_id_type t) = 0; - virtual void vsave(const class_id_optional_type t) = 0; - virtual void vsave(const class_id_reference_type t) = 0; - virtual void vsave(const class_name_type & t) = 0; - virtual void vsave(const tracking_type t) = 0; -protected: - BOOST_ARCHIVE_DECL basic_oarchive(unsigned int flags = 0); - BOOST_ARCHIVE_DECL boost::archive::detail::helper_collection & - get_helper_collection(); - virtual BOOST_ARCHIVE_DECL ~basic_oarchive(); -public: - // note: NOT part of the public interface - BOOST_ARCHIVE_DECL void register_basic_serializer( - const basic_oserializer & bos - ); - BOOST_ARCHIVE_DECL void save_object( - const void *x, - const basic_oserializer & bos - ); - BOOST_ARCHIVE_DECL void save_pointer( - const void * t, - const basic_pointer_oserializer * bpos_ptr - ); - void save_null_pointer(){ - vsave(NULL_POINTER_TAG); - } - // real public interface starts here - BOOST_ARCHIVE_DECL void end_preamble(); // default implementation does nothing - BOOST_ARCHIVE_DECL library_version_type get_library_version() const; - BOOST_ARCHIVE_DECL unsigned int get_flags() const; -}; - -} // namespace detail -} // namespace archive -} // namespace boost - -#include // pops abi_suffix.hpp pragmas - -#endif //BOOST_ARCHIVE_BASIC_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oserializer.hpp deleted file mode 100644 index 94247e90056..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_oserializer.hpp +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef BOOST_SERIALIZATION_BASIC_OSERIALIZER_HPP -#define BOOST_SERIALIZATION_BASIC_OSERIALIZER_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_oserializer.hpp: extenstion of type_info required for serialization. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // NULL -#include -#include - -#include -#include -#include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace serialization { - class extended_type_info; -} // namespace serialization - -// forward declarations -namespace archive { -namespace detail { - -class basic_oarchive; -class basic_pointer_oserializer; - -class BOOST_SYMBOL_VISIBLE basic_oserializer : - public basic_serializer -{ -private: - basic_pointer_oserializer *m_bpos; -protected: - explicit BOOST_ARCHIVE_DECL basic_oserializer( - const boost::serialization::extended_type_info & type_ - ); - virtual BOOST_ARCHIVE_DECL ~basic_oserializer(); -public: - bool serialized_as_pointer() const { - return m_bpos != NULL; - } - void set_bpos(basic_pointer_oserializer *bpos){ - m_bpos = bpos; - } - const basic_pointer_oserializer * get_bpos() const { - return m_bpos; - } - virtual void save_object_data( - basic_oarchive & ar, const void * x - ) const = 0; - // returns true if class_info should be saved - virtual bool class_info() const = 0; - // returns true if objects should be tracked - virtual bool tracking(const unsigned int flags) const = 0; - // returns class version - virtual version_type version() const = 0; - // returns true if this class is polymorphic - virtual bool is_polymorphic() const = 0; -}; - -} // namespace detail -} // namespace serialization -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_SERIALIZATION_BASIC_OSERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_iserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_iserializer.hpp deleted file mode 100644 index 1fc4b14d6e9..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_iserializer.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP -#define BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_pointer_oserializer.hpp: extenstion of type_info required for -// serialization. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. -#include -#include -#include -#include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace serialization { - class extended_type_info; -} // namespace serialization - -// forward declarations -namespace archive { -namespace detail { - -class basic_iarchive; -class basic_iserializer; - -class BOOST_SYMBOL_VISIBLE basic_pointer_iserializer - : public basic_serializer { -protected: - explicit BOOST_ARCHIVE_DECL basic_pointer_iserializer( - const boost::serialization::extended_type_info & type_ - ); - virtual BOOST_ARCHIVE_DECL ~basic_pointer_iserializer(); -public: - virtual void * heap_allocation() const = 0; - virtual const basic_iserializer & get_basic_serializer() const = 0; - virtual void load_object_ptr( - basic_iarchive & ar, - void * x, - const unsigned int file_version - ) const = 0; -}; - -} // namespace detail -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_ARCHIVE_BASIC_POINTER_ISERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_oserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_oserializer.hpp deleted file mode 100644 index 1a5d9549eab..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_pointer_oserializer.hpp +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef BOOST_ARCHIVE_BASIC_POINTER_OSERIALIZER_HPP -#define BOOST_ARCHIVE_BASIC_POINTER_OSERIALIZER_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_pointer_oserializer.hpp: extenstion of type_info required for -// serialization. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. -#include -#include -#include -#include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace serialization { - class extended_type_info; -} // namespace serialization - -namespace archive { -namespace detail { - -class basic_oarchive; -class basic_oserializer; - -class BOOST_SYMBOL_VISIBLE basic_pointer_oserializer : - public basic_serializer -{ -protected: - explicit BOOST_ARCHIVE_DECL basic_pointer_oserializer( - const boost::serialization::extended_type_info & type_ - ); -public: - virtual BOOST_ARCHIVE_DECL ~basic_pointer_oserializer(); - virtual const basic_oserializer & get_basic_serializer() const = 0; - virtual void save_object_ptr( - basic_oarchive & ar, - const void * x - ) const = 0; -}; - -} // namespace detail -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_ARCHIVE_BASIC_POINTER_OSERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer.hpp deleted file mode 100644 index f9c4203f862..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef BOOST_ARCHIVE_BASIC_SERIALIZER_HPP -#define BOOST_ARCHIVE_BASIC_SERIALIZER_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_serializer.hpp: extenstion of type_info required for serialization. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include // NULL - -#include -#include -#include - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { -namespace detail { - -class basic_serializer : - private boost::noncopyable -{ - const boost::serialization::extended_type_info * m_eti; -protected: - explicit basic_serializer( - const boost::serialization::extended_type_info & eti - ) : - m_eti(& eti) - {} -public: - inline bool - operator<(const basic_serializer & rhs) const { - // can't compare address since there can be multiple eti records - // for the same type in different execution modules (that is, DLLS) - // leave this here as a reminder not to do this! - // return & lhs.get_eti() < & rhs.get_eti(); - return get_eti() < rhs.get_eti(); - } - const char * get_debug_info() const { - return m_eti->get_debug_info(); - } - const boost::serialization::extended_type_info & get_eti() const { - return * m_eti; - } -}; - -class basic_serializer_arg : public basic_serializer { -public: - basic_serializer_arg(const serialization::extended_type_info & eti) : - basic_serializer(eti) - {} -}; - -} // namespace detail -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_ARCHIVE_BASIC_SERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer_map.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer_map.hpp deleted file mode 100644 index 79341803367..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/basic_serializer_map.hpp +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef BOOST_SERIALIZER_MAP_HPP -#define BOOST_SERIALIZER_MAP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_serializer_map.hpp: extenstion of type_info required for serialization. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include -#include - -#include // must be the last header - -namespace boost { -namespace serialization { - class extended_type_info; -} - -namespace archive { -namespace detail { - -class basic_serializer; - -class BOOST_SYMBOL_VISIBLE -basic_serializer_map : public - boost::noncopyable -{ - struct type_info_pointer_compare - { - bool operator()( - const basic_serializer * lhs, const basic_serializer * rhs - ) const ; - }; - typedef std::set< - const basic_serializer *, - type_info_pointer_compare - > map_type; - map_type m_map; -public: - BOOST_ARCHIVE_DECL bool insert(const basic_serializer * bs); - BOOST_ARCHIVE_DECL void erase(const basic_serializer * bs); - BOOST_ARCHIVE_DECL const basic_serializer * find( - const boost::serialization::extended_type_info & type_ - ) const; -private: - // cw 8.3 requires this - basic_serializer_map& operator=(basic_serializer_map const&); -}; - -} // namespace detail -} // namespace archive -} // namespace boost - -#include // must be the last header - -#endif // BOOST_SERIALIZER_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/check.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/check.hpp deleted file mode 100644 index 10034e7d101..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/check.hpp +++ /dev/null @@ -1,169 +0,0 @@ -#ifndef BOOST_ARCHIVE_DETAIL_CHECK_HPP -#define BOOST_ARCHIVE_DETAIL_CHECK_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#pragma inline_depth(511) -#pragma inline_recursion(on) -#endif - -#if defined(__MWERKS__) -#pragma inline_depth(511) -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// check.hpp: interface for serialization system. - -// (C) Copyright 2009 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace boost { -namespace archive { -namespace detail { - -// checks for objects - -template -inline void check_object_level(){ - typedef - typename mpl::greater_equal< - serialization::implementation_level< T >, - mpl::int_ - >::type typex; - - // trap attempts to serialize objects marked - // not_serializable - BOOST_STATIC_ASSERT(typex::value); -} - -template -inline void check_object_versioning(){ - typedef - typename mpl::or_< - typename mpl::greater< - serialization::implementation_level< T >, - mpl::int_ - >, - typename mpl::equal_to< - serialization::version< T >, - mpl::int_<0> - > - > typex; - // trap attempts to serialize with objects that don't - // save class information in the archive with versioning. - BOOST_STATIC_ASSERT(typex::value); -} - -template -inline void check_object_tracking(){ - // presume it has already been determined that - // T is not a const - BOOST_STATIC_ASSERT(! boost::is_const< T >::value); - typedef typename mpl::equal_to< - serialization::tracking_level< T >, - mpl::int_ - >::type typex; - // saving an non-const object of a type not marked "track_never) - - // may be an indicator of an error usage of the - // serialization library and should be double checked. - // See documentation on object tracking. Also, see the - // "rationale" section of the documenation - // for motivation for this checking. - - BOOST_STATIC_WARNING(typex::value); -} - -// checks for pointers - -template -inline void check_pointer_level(){ - // we should only invoke this once we KNOW that T - // has been used as a pointer!! - typedef - typename mpl::or_< - typename mpl::greater< - serialization::implementation_level< T >, - mpl::int_ - >, - typename mpl::not_< - typename mpl::equal_to< - serialization::tracking_level< T >, - mpl::int_ - > - > - > typex; - // Address the following when serializing to a pointer: - - // a) This type doesn't save class information in the - // archive. That is, the serialization trait implementation - // level <= object_serializable. - // b) Tracking for this type is set to "track selectively" - - // in this case, indication that an object is tracked is - // not stored in the archive itself - see level == object_serializable - // but rather the existence of the operation ar >> T * is used to - // infer that an object of this type should be tracked. So, if - // you save via a pointer but don't load via a pointer the operation - // will fail on load without given any valid reason for the failure. - - // So if your program traps here, consider changing the - // tracking or implementation level traits - or not - // serializing via a pointer. - BOOST_STATIC_WARNING(typex::value); -} - -template -void inline check_pointer_tracking(){ - typedef typename mpl::greater< - serialization::tracking_level< T >, - mpl::int_ - >::type typex; - // serializing an object of a type marked "track_never" through a pointer - // could result in creating more objects than were saved! - BOOST_STATIC_WARNING(typex::value); -} - -template -inline void check_const_loading(){ - typedef - typename mpl::or_< - typename boost::serialization::is_wrapper< T >, - typename mpl::not_< - typename boost::is_const< T > - > - >::type typex; - // cannot load data into a "const" object unless it's a - // wrapper around some other non-const object. - BOOST_STATIC_ASSERT(typex::value); -} - -} // detail -} // archive -} // boost - -#endif // BOOST_ARCHIVE_DETAIL_CHECK_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/common_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/common_iarchive.hpp deleted file mode 100644 index 82304f1e5ac..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/common_iarchive.hpp +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef BOOST_ARCHIVE_DETAIL_COMMON_IARCHIVE_HPP -#define BOOST_ARCHIVE_DETAIL_COMMON_IARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// common_iarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include -#include - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { -namespace detail { - -class extended_type_info; - -// note: referred to as Curiously Recurring Template Patter (CRTP) -template -class BOOST_SYMBOL_VISIBLE common_iarchive : - public basic_iarchive, - public interface_iarchive -{ - friend class interface_iarchive; -private: - virtual void vload(version_type & t){ - * this->This() >> t; - } - virtual void vload(object_id_type & t){ - * this->This() >> t; - } - virtual void vload(class_id_type & t){ - * this->This() >> t; - } - virtual void vload(class_id_optional_type & t){ - * this->This() >> t; - } - virtual void vload(tracking_type & t){ - * this->This() >> t; - } - virtual void vload(class_name_type &s){ - * this->This() >> s; - } -protected: - // default processing - invoke serialization library - template - void load_override(T & t){ - archive::load(* this->This(), t); - } - // default implementations of functions which emit start/end tags for - // archive types that require them. - void load_start(const char * /*name*/){} - void load_end(const char * /*name*/){} - // default archive initialization - common_iarchive(unsigned int flags = 0) : - basic_iarchive(flags), - interface_iarchive() - {} -}; - -} // namespace detail -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_ARCHIVE_DETAIL_COMMON_IARCHIVE_HPP - diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/common_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/common_oarchive.hpp deleted file mode 100644 index ee42bbe5976..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/common_oarchive.hpp +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef BOOST_ARCHIVE_DETAIL_COMMON_OARCHIVE_HPP -#define BOOST_ARCHIVE_DETAIL_COMMON_OARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// common_oarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { -namespace detail { - -// note: referred to as Curiously Recurring Template Patter (CRTP) -template - -class BOOST_SYMBOL_VISIBLE common_oarchive : - public basic_oarchive, - public interface_oarchive -{ - friend class interface_oarchive; -private: - virtual void vsave(const version_type t){ - * this->This() << t; - } - virtual void vsave(const object_id_type t){ - * this->This() << t; - } - virtual void vsave(const object_reference_type t){ - * this->This() << t; - } - virtual void vsave(const class_id_type t){ - * this->This() << t; - } - virtual void vsave(const class_id_reference_type t){ - * this->This() << t; - } - virtual void vsave(const class_id_optional_type t){ - * this->This() << t; - } - virtual void vsave(const class_name_type & t){ - * this->This() << t; - } - virtual void vsave(const tracking_type t){ - * this->This() << t; - } -protected: - // default processing - invoke serialization library - template - void save_override(T & t){ - archive::save(* this->This(), t); - } - void save_start(const char * /*name*/){} - void save_end(const char * /*name*/){} - common_oarchive(unsigned int flags = 0) : - basic_oarchive(flags), - interface_oarchive() - {} -}; - -} // namespace detail -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_ARCHIVE_DETAIL_COMMON_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/decl.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/decl.hpp deleted file mode 100644 index 4f731cded37..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/decl.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef BOOST_ARCHIVE_DETAIL_DECL_HPP -#define BOOST_ARCHIVE_DETAIL_DECL_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2///////// 3/////////4/////////5/////////6/////////7/////////8 -// decl.hpp -// -// (c) Copyright Robert Ramey 2004 -// Use, modification, and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See library home page at http://www.boost.org/libs/serialization - -//----------------------------------------------------------------------------// - -// This header implements separate compilation features as described in -// http://www.boost.org/more/separate_compilation.html - -#include - -#if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK)) - #if defined(BOOST_ARCHIVE_SOURCE) - #define BOOST_ARCHIVE_DECL BOOST_SYMBOL_EXPORT - #else - #define BOOST_ARCHIVE_DECL BOOST_SYMBOL_IMPORT - #endif - - #if defined(BOOST_WARCHIVE_SOURCE) - #define BOOST_WARCHIVE_DECL BOOST_SYMBOL_EXPORT - #else - #define BOOST_WARCHIVE_DECL BOOST_SYMBOL_IMPORT - #endif - - #if defined(BOOST_WARCHIVE_SOURCE) || defined(BOOST_ARCHIVE_SOURCE) - #define BOOST_ARCHIVE_OR_WARCHIVE_DECL BOOST_SYMBOL_EXPORT - #else - #define BOOST_ARCHIVE_OR_WARCHIVE_DECL BOOST_SYMBOL_IMPORT - #endif - -#endif - -#if ! defined(BOOST_ARCHIVE_DECL) - #define BOOST_ARCHIVE_DECL -#endif -#if ! defined(BOOST_WARCHIVE_DECL) - #define BOOST_WARCHIVE_DECL -#endif -#if ! defined(BOOST_ARCHIVE_OR_WARCHIVE_DECL) - #define BOOST_ARCHIVE_OR_WARCHIVE_DECL -#endif - -#endif // BOOST_ARCHIVE_DETAIL_DECL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/helper_collection.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/helper_collection.hpp deleted file mode 100644 index edb4125e308..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/helper_collection.hpp +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef BOOST_ARCHIVE_DETAIL_HELPER_COLLECTION_HPP -#define BOOST_ARCHIVE_DETAIL_HELPER_COLLECTION_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// helper_collection.hpp: archive support for run-time helpers - -// (C) Copyright 2002-2008 Robert Ramey and Joaquin M Lopez Munoz -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // NULL -#include -#include -#include -#include - -#include - -#include -#include - -namespace boost { - -namespace archive { -namespace detail { - -class helper_collection -{ - helper_collection(const helper_collection&); // non-copyable - helper_collection& operator = (const helper_collection&); // non-copyable - - // note: we dont' actually "share" the function object pointer - // we only use shared_ptr to make sure that it get's deleted - - typedef std::pair< - const void *, - boost::shared_ptr - > helper_value_type; - template - boost::shared_ptr make_helper_ptr(){ - // use boost::shared_ptr rather than std::shared_ptr to maintain - // c++03 compatibility - return boost::make_shared(); - } - - typedef std::vector collection; - collection m_collection; - - struct predicate { - BOOST_DELETED_FUNCTION(predicate & operator=(const predicate & rhs)) - public: - const void * const m_ti; - bool operator()(helper_value_type const &rhs) const { - return m_ti == rhs.first; - } - predicate(const void * ti) : - m_ti(ti) - {} - }; -protected: - helper_collection(){} - ~helper_collection(){} -public: - template - Helper& find_helper(void * const id = 0) { - collection::const_iterator it = - std::find_if( - m_collection.begin(), - m_collection.end(), - predicate(id) - ); - - void * rval = 0; - if(it == m_collection.end()){ - m_collection.push_back( - std::make_pair(id, make_helper_ptr()) - ); - rval = m_collection.back().second.get(); - } - else{ - rval = it->second.get(); - } - return *static_cast(rval); - } -}; - -} // namespace detail -} // namespace serialization -} // namespace boost - -#endif // BOOST_ARCHIVE_DETAIL_HELPER_COLLECTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_iarchive.hpp deleted file mode 100644 index 4a99e28b59f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_iarchive.hpp +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP -#define BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// interface_iarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. -#include // NULL -#include -#include -#include -#include -#include -#include -#include // must be the last header - -namespace boost { -namespace archive { -namespace detail { - -class basic_pointer_iserializer; - -template -class interface_iarchive -{ -protected: - interface_iarchive(){}; -public: - ///////////////////////////////////////////////////////// - // archive public interface - typedef mpl::bool_ is_loading; - typedef mpl::bool_ is_saving; - - // return a pointer to the most derived class - Archive * This(){ - return static_cast(this); - } - - template - const basic_pointer_iserializer * - register_type(T * = NULL){ - const basic_pointer_iserializer & bpis = - boost::serialization::singleton< - pointer_iserializer - >::get_const_instance(); - this->This()->register_basic_serializer(bpis.get_basic_serializer()); - return & bpis; - } - template - Helper & - get_helper(void * const id = 0){ - helper_collection & hc = this->This()->get_helper_collection(); - return hc.template find_helper(id); - } - - template - Archive & operator>>(T & t){ - this->This()->load_override(t); - return * this->This(); - } - - // the & operator - template - Archive & operator&(T & t){ - return *(this->This()) >> t; - } -}; - -} // namespace detail -} // namespace archive -} // namespace boost - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_oarchive.hpp deleted file mode 100644 index 359463ed9d8..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/interface_oarchive.hpp +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef BOOST_ARCHIVE_DETAIL_INTERFACE_OARCHIVE_HPP -#define BOOST_ARCHIVE_DETAIL_INTERFACE_OARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// interface_oarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. -#include // NULL -#include -#include - -#include -#include -#include // must be the last header - -#include - -namespace boost { -namespace archive { -namespace detail { - -class basic_pointer_oserializer; - -template -class interface_oarchive -{ -protected: - interface_oarchive(){}; -public: - ///////////////////////////////////////////////////////// - // archive public interface - typedef mpl::bool_ is_loading; - typedef mpl::bool_ is_saving; - - // return a pointer to the most derived class - Archive * This(){ - return static_cast(this); - } - - template - const basic_pointer_oserializer * - register_type(const T * = NULL){ - const basic_pointer_oserializer & bpos = - boost::serialization::singleton< - pointer_oserializer - >::get_const_instance(); - this->This()->register_basic_serializer(bpos.get_basic_serializer()); - return & bpos; - } - - template - Helper & - get_helper(void * const id = 0){ - helper_collection & hc = this->This()->get_helper_collection(); - return hc.template find_helper(id); - } - - template - Archive & operator<<(const T & t){ - this->This()->save_override(t); - return * this->This(); - } - - // the & operator - template - Archive & operator&(const T & t){ - return * this ->This() << t; - } -}; - -} // namespace detail -} // namespace archive -} // namespace boost - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_ARCHIVE_DETAIL_INTERFACE_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/iserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/iserializer.hpp deleted file mode 100644 index 193e98a82e4..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/iserializer.hpp +++ /dev/null @@ -1,631 +0,0 @@ -#ifndef BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP -#define BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#pragma inline_depth(511) -#pragma inline_recursion(on) -#endif - -#if defined(__MWERKS__) -#pragma inline_depth(511) -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// iserializer.hpp: interface for serialization system. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // for placement new -#include // size_t, NULL - -#include -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include - -#include -#include -#include -#include -#include - -#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO - #include -#endif -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#ifndef BOOST_MSVC - #define DONT_USE_HAS_NEW_OPERATOR ( \ - BOOST_WORKAROUND(__IBMCPP__, < 1210) \ - || defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x590) \ - ) -#else - #define DONT_USE_HAS_NEW_OPERATOR 0 -#endif - -#if ! DONT_USE_HAS_NEW_OPERATOR -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// the following is need only for dynamic cast of polymorphic pointers -#include -#include -#include -#include -#include -#include - -namespace boost { - -namespace serialization { - class extended_type_info; -} // namespace serialization - -namespace archive { - -// an accessor to permit friend access to archives. Needed because -// some compilers don't handle friend templates completely -class load_access { -public: - template - static void load_primitive(Archive &ar, T &t){ - ar.load(t); - } -}; - -namespace detail { - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -template -class iserializer : public basic_iserializer -{ -private: - virtual void destroy(/*const*/ void *address) const { - boost::serialization::access::destroy(static_cast(address)); - } -protected: - // protected constructor since it's always created by singleton - explicit iserializer() : - basic_iserializer( - boost::serialization::singleton< - typename - boost::serialization::type_info_implementation< T >::type - >::get_const_instance() - ) - {} -public: - virtual BOOST_DLLEXPORT void load_object_data( - basic_iarchive & ar, - void *x, - const unsigned int file_version - ) const BOOST_USED; - virtual bool class_info() const { - return boost::serialization::implementation_level< T >::value - >= boost::serialization::object_class_info; - } - virtual bool tracking(const unsigned int /* flags */) const { - return boost::serialization::tracking_level< T >::value - == boost::serialization::track_always - || ( boost::serialization::tracking_level< T >::value - == boost::serialization::track_selectively - && serialized_as_pointer()); - } - virtual version_type version() const { - return version_type(::boost::serialization::version< T >::value); - } - virtual bool is_polymorphic() const { - return boost::is_polymorphic< T >::value; - } - virtual ~iserializer(){}; -}; - -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif - -template -BOOST_DLLEXPORT void iserializer::load_object_data( - basic_iarchive & ar, - void *x, - const unsigned int file_version -) const { - // note: we now comment this out. Before we permited archive - // version # to be very large. Now we don't. To permit - // readers of these old archives, we have to suppress this - // code. Perhaps in the future we might re-enable it but - // permit its suppression with a runtime switch. - #if 0 - // trap case where the program cannot handle the current version - if(file_version > static_cast(version())) - boost::serialization::throw_exception( - archive::archive_exception( - boost::archive::archive_exception::unsupported_class_version, - get_debug_info() - ) - ); - #endif - // make sure call is routed through the higest interface that might - // be specialized by the user. - boost::serialization::serialize_adl( - boost::serialization::smart_cast_reference(ar), - * static_cast(x), - file_version - ); -} - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -// the purpose of this code is to allocate memory for an object -// without requiring the constructor to be called. Presumably -// the allocated object will be subsequently initialized with -// "placement new". -// note: we have the boost type trait has_new_operator but we -// have no corresponding has_delete_operator. So we presume -// that the former being true would imply that the a delete -// operator is also defined for the class T. - -template -struct heap_allocation { - // boost::has_new_operator< T > doesn't work on these compilers - #if DONT_USE_HAS_NEW_OPERATOR - // This doesn't handle operator new overload for class T - static T * invoke_new(){ - return static_cast(operator new(sizeof(T))); - } - static void invoke_delete(T *t){ - (operator delete(t)); - } - #else - // note: we presume that a true value for has_new_operator - // implies the existence of a class specific delete operator as well - // as a class specific new operator. - struct has_new_operator { - static T * invoke_new() { - return static_cast((T::operator new)(sizeof(T))); - } - static void invoke_delete(T * t) { - // if compilation fails here, the likely cause that the class - // T has a class specific new operator but no class specific - // delete operator which matches the following signature. - // note that this solution addresses the issue that two - // possible signatures. But it doesn't address the possibility - // that the class might have class specific new with NO - // class specific delete at all. Patches (compatible with - // C++03) welcome! - delete t; - } - }; - struct doesnt_have_new_operator { - static T* invoke_new() { - return static_cast(operator new(sizeof(T))); - } - static void invoke_delete(T * t) { - // Note: I'm reliance upon automatic conversion from T * to void * here - delete t; - } - }; - static T * invoke_new() { - typedef typename - mpl::eval_if< - boost::has_new_operator< T >, - mpl::identity, - mpl::identity - >::type typex; - return typex::invoke_new(); - } - static void invoke_delete(T *t) { - typedef typename - mpl::eval_if< - boost::has_new_operator< T >, - mpl::identity, - mpl::identity - >::type typex; - typex::invoke_delete(t); - } - #endif - explicit heap_allocation(){ - m_p = invoke_new(); - } - ~heap_allocation(){ - if (0 != m_p) - invoke_delete(m_p); - } - T* get() const { - return m_p; - } - - T* release() { - T* p = m_p; - m_p = 0; - return p; - } -private: - T* m_p; -}; - -template -class pointer_iserializer : - public basic_pointer_iserializer -{ -private: - virtual void * heap_allocation() const { - detail::heap_allocation h; - T * t = h.get(); - h.release(); - return t; - } - virtual const basic_iserializer & get_basic_serializer() const { - return boost::serialization::singleton< - iserializer - >::get_const_instance(); - } - BOOST_DLLEXPORT virtual void load_object_ptr( - basic_iarchive & ar, - void * x, - const unsigned int file_version - ) const BOOST_USED; -protected: - // this should alway be a singleton so make the constructor protected - pointer_iserializer(); - ~pointer_iserializer(); -}; - -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif - -// note: BOOST_DLLEXPORT is so that code for polymorphic class -// serialized only through base class won't get optimized out -template -BOOST_DLLEXPORT void pointer_iserializer::load_object_ptr( - basic_iarchive & ar, - void * t, - const unsigned int file_version -) const -{ - Archive & ar_impl = - boost::serialization::smart_cast_reference(ar); - - // note that the above will throw std::bad_alloc if the allocation - // fails so we don't have to address this contingency here. - - // catch exception during load_construct_data so that we don't - // automatically delete the t which is most likely not fully - // constructed - BOOST_TRY { - // this addresses an obscure situation that occurs when - // load_constructor de-serializes something through a pointer. - ar.next_object_pointer(t); - boost::serialization::load_construct_data_adl( - ar_impl, - static_cast(t), - file_version - ); - } - BOOST_CATCH(...){ - // if we get here the load_construct failed. The heap_allocation - // will be automatically deleted so we don't have to do anything - // special here. - BOOST_RETHROW; - } - BOOST_CATCH_END - - ar_impl >> boost::serialization::make_nvp(NULL, * static_cast(t)); -} - -template -pointer_iserializer::pointer_iserializer() : - basic_pointer_iserializer( - boost::serialization::singleton< - typename - boost::serialization::type_info_implementation< T >::type - >::get_const_instance() - ) -{ - boost::serialization::singleton< - iserializer - >::get_mutable_instance().set_bpis(this); - archive_serializer_map::insert(this); -} - -template -pointer_iserializer::~pointer_iserializer(){ - archive_serializer_map::erase(this); -} - -template -struct load_non_pointer_type { - // note this bounces the call right back to the archive - // with no runtime overhead - struct load_primitive { - template - static void invoke(Archive & ar, T & t){ - load_access::load_primitive(ar, t); - } - }; - // note this bounces the call right back to the archive - // with no runtime overhead - struct load_only { - template - static void invoke(Archive & ar, const T & t){ - // short cut to user's serializer - // make sure call is routed through the higest interface that might - // be specialized by the user. - boost::serialization::serialize_adl( - ar, - const_cast(t), - boost::serialization::version< T >::value - ); - } - }; - - // note this save class information including version - // and serialization level to the archive - struct load_standard { - template - static void invoke(Archive &ar, const T & t){ - void * x = & const_cast(t); - ar.load_object( - x, - boost::serialization::singleton< - iserializer - >::get_const_instance() - ); - } - }; - - struct load_conditional { - template - static void invoke(Archive &ar, T &t){ - //if(0 == (ar.get_flags() & no_tracking)) - load_standard::invoke(ar, t); - //else - // load_only::invoke(ar, t); - } - }; - - template - static void invoke(Archive & ar, T &t){ - typedef typename mpl::eval_if< - // if its primitive - mpl::equal_to< - boost::serialization::implementation_level< T >, - mpl::int_ - >, - mpl::identity, - // else - typename mpl::eval_if< - // class info / version - mpl::greater_equal< - boost::serialization::implementation_level< T >, - mpl::int_ - >, - // do standard load - mpl::identity, - // else - typename mpl::eval_if< - // no tracking - mpl::equal_to< - boost::serialization::tracking_level< T >, - mpl::int_ - >, - // do a fast load - mpl::identity, - // else - // do a fast load only tracking is turned off - mpl::identity - > > >::type typex; - check_object_versioning< T >(); - check_object_level< T >(); - typex::invoke(ar, t); - } -}; - -template -struct load_pointer_type { - struct abstract - { - template - static const basic_pointer_iserializer * register_type(Archive & /* ar */){ - // it has? to be polymorphic - BOOST_STATIC_ASSERT(boost::is_polymorphic< T >::value); - return static_cast(NULL); - } - }; - - struct non_abstract - { - template - static const basic_pointer_iserializer * register_type(Archive & ar){ - return ar.register_type(static_cast(NULL)); - } - }; - - template - static const basic_pointer_iserializer * register_type(Archive &ar, const T & /*t*/){ - // there should never be any need to load an abstract polymorphic - // class pointer. Inhibiting code generation for this - // permits abstract base classes to be used - note: exception - // virtual serialize functions used for plug-ins - typedef typename - mpl::eval_if< - boost::serialization::is_abstract, - boost::mpl::identity, - boost::mpl::identity - >::type typex; - return typex::template register_type< T >(ar); - } - - template - static T * pointer_tweak( - const boost::serialization::extended_type_info & eti, - void const * const t, - const T & - ) { - // tweak the pointer back to the base class - void * upcast = const_cast( - boost::serialization::void_upcast( - eti, - boost::serialization::singleton< - typename - boost::serialization::type_info_implementation< T >::type - >::get_const_instance(), - t - ) - ); - if(NULL == upcast) - boost::serialization::throw_exception( - archive_exception(archive_exception::unregistered_class) - ); - return static_cast(upcast); - } - - template - static void check_load(T & /* t */){ - check_pointer_level< T >(); - check_pointer_tracking< T >(); - } - - static const basic_pointer_iserializer * - find(const boost::serialization::extended_type_info & type){ - return static_cast( - archive_serializer_map::find(type) - ); - } - - template - static void invoke(Archive & ar, Tptr & t){ - check_load(*t); - const basic_pointer_iserializer * bpis_ptr = register_type(ar, *t); - const basic_pointer_iserializer * newbpis_ptr = ar.load_pointer( - // note major hack here !!! - // I tried every way to convert Tptr &t (where Tptr might - // include const) to void * &. This is the only way - // I could make it work. RR - (void * & )t, - bpis_ptr, - find - ); - // if the pointer isn't that of the base class - if(newbpis_ptr != bpis_ptr){ - t = pointer_tweak(newbpis_ptr->get_eti(), t, *t); - } - } -}; - -template -struct load_enum_type { - template - static void invoke(Archive &ar, T &t){ - // convert integers to correct enum to load - int i; - ar >> boost::serialization::make_nvp(NULL, i); - t = static_cast< T >(i); - } -}; - -template -struct load_array_type { - template - static void invoke(Archive &ar, T &t){ - typedef typename remove_extent< T >::type value_type; - - // convert integers to correct enum to load - // determine number of elements in the array. Consider the - // fact that some machines will align elements on boundries - // other than characters. - std::size_t current_count = sizeof(t) / ( - static_cast(static_cast(&t[1])) - - static_cast(static_cast(&t[0])) - ); - boost::serialization::collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - if(static_cast(count) > current_count) - boost::serialization::throw_exception( - archive::archive_exception( - boost::archive::archive_exception::array_size_too_short - ) - ); - // explict template arguments to pass intel C++ compiler - ar >> serialization::make_array< - value_type, - boost::serialization::collection_size_type - >( - static_cast(&t[0]), - count - ); - } -}; - -} // detail - -template -inline void load(Archive & ar, T &t){ - // if this assertion trips. It means we're trying to load a - // const object with a compiler that doesn't have correct - // function template ordering. On other compilers, this is - // handled below. - detail::check_const_loading< T >(); - typedef - typename mpl::eval_if, - mpl::identity > - ,//else - typename mpl::eval_if, - mpl::identity > - ,//else - typename mpl::eval_if, - mpl::identity > - ,//else - mpl::identity > - > - > - >::type typex; - typex::invoke(ar, t); -} - -} // namespace archive -} // namespace boost - -#endif // BOOST_ARCHIVE_DETAIL_ISERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/oserializer.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/oserializer.hpp deleted file mode 100644 index c120ec55073..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/oserializer.hpp +++ /dev/null @@ -1,540 +0,0 @@ -#ifndef BOOST_ARCHIVE_OSERIALIZER_HPP -#define BOOST_ARCHIVE_OSERIALIZER_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#pragma inline_depth(511) -#pragma inline_recursion(on) -#endif - -#if defined(__MWERKS__) -#pragma inline_depth(511) -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// oserializer.hpp: interface for serialization system. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include // NULL - -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO - #include -#endif -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -namespace boost { - -namespace serialization { - class extended_type_info; -} // namespace serialization - -namespace archive { - -// an accessor to permit friend access to archives. Needed because -// some compilers don't handle friend templates completely -class save_access { -public: - template - static void end_preamble(Archive & ar){ - ar.end_preamble(); - } - template - static void save_primitive(Archive & ar, const T & t){ - ar.end_preamble(); - ar.save(t); - } -}; - -namespace detail { - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -template -class oserializer : public basic_oserializer -{ -private: - // private constructor to inhibit any existence other than the - // static one -public: - explicit BOOST_DLLEXPORT oserializer() : - basic_oserializer( - boost::serialization::singleton< - typename - boost::serialization::type_info_implementation< T >::type - >::get_const_instance() - ) - {} - virtual BOOST_DLLEXPORT void save_object_data( - basic_oarchive & ar, - const void *x - ) const BOOST_USED; - virtual bool class_info() const { - return boost::serialization::implementation_level< T >::value - >= boost::serialization::object_class_info; - } - virtual bool tracking(const unsigned int /* flags */) const { - return boost::serialization::tracking_level< T >::value == boost::serialization::track_always - || (boost::serialization::tracking_level< T >::value == boost::serialization::track_selectively - && serialized_as_pointer()); - } - virtual version_type version() const { - return version_type(::boost::serialization::version< T >::value); - } - virtual bool is_polymorphic() const { - return boost::is_polymorphic< T >::value; - } - virtual ~oserializer(){} -}; - -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif - -template -BOOST_DLLEXPORT void oserializer::save_object_data( - basic_oarchive & ar, - const void *x -) const { - // make sure call is routed through the highest interface that might - // be specialized by the user. - BOOST_STATIC_ASSERT(boost::is_const< T >::value == false); - boost::serialization::serialize_adl( - boost::serialization::smart_cast_reference(ar), - * static_cast(const_cast(x)), - version() - ); -} - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -template -class pointer_oserializer : - public basic_pointer_oserializer -{ -private: - const basic_oserializer & - get_basic_serializer() const { - return boost::serialization::singleton< - oserializer - >::get_const_instance(); - } - virtual BOOST_DLLEXPORT void save_object_ptr( - basic_oarchive & ar, - const void * x - ) const BOOST_USED; -public: - pointer_oserializer(); - ~pointer_oserializer(); -}; - -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif - -template -BOOST_DLLEXPORT void pointer_oserializer::save_object_ptr( - basic_oarchive & ar, - const void * x -) const { - BOOST_ASSERT(NULL != x); - // make sure call is routed through the highest interface that might - // be specialized by the user. - T * t = static_cast(const_cast(x)); - const unsigned int file_version = boost::serialization::version< T >::value; - Archive & ar_impl - = boost::serialization::smart_cast_reference(ar); - boost::serialization::save_construct_data_adl( - ar_impl, - t, - file_version - ); - ar_impl << boost::serialization::make_nvp(NULL, * t); -} - -template -pointer_oserializer::pointer_oserializer() : - basic_pointer_oserializer( - boost::serialization::singleton< - typename - boost::serialization::type_info_implementation< T >::type - >::get_const_instance() - ) -{ - // make sure appropriate member function is instantiated - boost::serialization::singleton< - oserializer - >::get_mutable_instance().set_bpos(this); - archive_serializer_map::insert(this); -} - -template -pointer_oserializer::~pointer_oserializer(){ - archive_serializer_map::erase(this); -} - -template -struct save_non_pointer_type { - // note this bounces the call right back to the archive - // with no runtime overhead - struct save_primitive { - template - static void invoke(Archive & ar, const T & t){ - save_access::save_primitive(ar, t); - } - }; - // same as above but passes through serialization - struct save_only { - template - static void invoke(Archive & ar, const T & t){ - // make sure call is routed through the highest interface that might - // be specialized by the user. - boost::serialization::serialize_adl( - ar, - const_cast(t), - ::boost::serialization::version< T >::value - ); - } - }; - // adds class information to the archive. This includes - // serialization level and class version - struct save_standard { - template - static void invoke(Archive &ar, const T & t){ - ar.save_object( - & t, - boost::serialization::singleton< - oserializer - >::get_const_instance() - ); - } - }; - - // adds class information to the archive. This includes - // serialization level and class version - struct save_conditional { - template - static void invoke(Archive &ar, const T &t){ - //if(0 == (ar.get_flags() & no_tracking)) - save_standard::invoke(ar, t); - //else - // save_only::invoke(ar, t); - } - }; - - - template - static void invoke(Archive & ar, const T & t){ - typedef - typename mpl::eval_if< - // if its primitive - mpl::equal_to< - boost::serialization::implementation_level< T >, - mpl::int_ - >, - mpl::identity, - // else - typename mpl::eval_if< - // class info / version - mpl::greater_equal< - boost::serialization::implementation_level< T >, - mpl::int_ - >, - // do standard save - mpl::identity, - // else - typename mpl::eval_if< - // no tracking - mpl::equal_to< - boost::serialization::tracking_level< T >, - mpl::int_ - >, - // do a fast save - mpl::identity, - // else - // do a fast save only tracking is turned off - mpl::identity - > > >::type typex; - check_object_versioning< T >(); - typex::invoke(ar, t); - } - template - static void invoke(Archive & ar, T & t){ - check_object_level< T >(); - check_object_tracking< T >(); - invoke(ar, const_cast(t)); - } -}; - -template -struct save_pointer_type { - struct abstract - { - template - static const basic_pointer_oserializer * register_type(Archive & /* ar */){ - // it has? to be polymorphic - BOOST_STATIC_ASSERT(boost::is_polymorphic< T >::value); - return NULL; - } - }; - - struct non_abstract - { - template - static const basic_pointer_oserializer * register_type(Archive & ar){ - return ar.register_type(static_cast(NULL)); - } - }; - - template - static const basic_pointer_oserializer * register_type(Archive &ar, T & /*t*/){ - // there should never be any need to save an abstract polymorphic - // class pointer. Inhibiting code generation for this - // permits abstract base classes to be used - note: exception - // virtual serialize functions used for plug-ins - typedef - typename mpl::eval_if< - boost::serialization::is_abstract< T >, - mpl::identity, - mpl::identity - >::type typex; - return typex::template register_type< T >(ar); - } - - struct non_polymorphic - { - template - static void save( - Archive &ar, - T & t - ){ - const basic_pointer_oserializer & bpos = - boost::serialization::singleton< - pointer_oserializer - >::get_const_instance(); - // save the requested pointer type - ar.save_pointer(& t, & bpos); - } - }; - - struct polymorphic - { - template - static void save( - Archive &ar, - T & t - ){ - typename - boost::serialization::type_info_implementation< T >::type const - & i = boost::serialization::singleton< - typename - boost::serialization::type_info_implementation< T >::type - >::get_const_instance(); - - boost::serialization::extended_type_info const * const this_type = & i; - - // retrieve the true type of the object pointed to - // if this assertion fails its an error in this library - BOOST_ASSERT(NULL != this_type); - - const boost::serialization::extended_type_info * true_type = - i.get_derived_extended_type_info(t); - - // note:if this exception is thrown, be sure that derived pointer - // is either registered or exported. - if(NULL == true_type){ - boost::serialization::throw_exception( - archive_exception( - archive_exception::unregistered_class, - "derived class not registered or exported" - ) - ); - } - - // if its not a pointer to a more derived type - const void *vp = static_cast(&t); - if(*this_type == *true_type){ - const basic_pointer_oserializer * bpos = register_type(ar, t); - ar.save_pointer(vp, bpos); - return; - } - // convert pointer to more derived type. if this is thrown - // it means that the base/derived relationship hasn't be registered - vp = serialization::void_downcast( - *true_type, - *this_type, - static_cast(&t) - ); - if(NULL == vp){ - boost::serialization::throw_exception( - archive_exception( - archive_exception::unregistered_cast, - true_type->get_debug_info(), - this_type->get_debug_info() - ) - ); - } - - // since true_type is valid, and this only gets made if the - // pointer oserializer object has been created, this should never - // fail - const basic_pointer_oserializer * bpos - = static_cast( - boost::serialization::singleton< - archive_serializer_map - >::get_const_instance().find(*true_type) - ); - BOOST_ASSERT(NULL != bpos); - if(NULL == bpos) - boost::serialization::throw_exception( - archive_exception( - archive_exception::unregistered_class, - "derived class not registered or exported" - ) - ); - ar.save_pointer(vp, bpos); - } - }; - - template - static void save( - Archive & ar, - const T & t - ){ - check_pointer_level< T >(); - check_pointer_tracking< T >(); - typedef typename mpl::eval_if< - is_polymorphic< T >, - mpl::identity, - mpl::identity - >::type type; - type::save(ar, const_cast(t)); - } - - template - static void invoke(Archive &ar, const TPtr t){ - register_type(ar, * t); - if(NULL == t){ - basic_oarchive & boa - = boost::serialization::smart_cast_reference(ar); - boa.save_null_pointer(); - save_access::end_preamble(ar); - return; - } - save(ar, * t); - } -}; - -template -struct save_enum_type -{ - template - static void invoke(Archive &ar, const T &t){ - // convert enum to integers on save - const int i = static_cast(t); - ar << boost::serialization::make_nvp(NULL, i); - } -}; - -template -struct save_array_type -{ - template - static void invoke(Archive &ar, const T &t){ - typedef typename boost::remove_extent< T >::type value_type; - - save_access::end_preamble(ar); - // consider alignment - std::size_t c = sizeof(t) / ( - static_cast(static_cast(&t[1])) - - static_cast(static_cast(&t[0])) - ); - boost::serialization::collection_size_type count(c); - ar << BOOST_SERIALIZATION_NVP(count); - // explict template arguments to pass intel C++ compiler - ar << serialization::make_array< - const value_type, - boost::serialization::collection_size_type - >( - static_cast(&t[0]), - count - ); - } -}; - -} // detail - -template -inline void save(Archive & ar, /*const*/ T &t){ - typedef - typename mpl::eval_if, - mpl::identity >, - //else - typename mpl::eval_if, - mpl::identity >, - //else - typename mpl::eval_if, - mpl::identity >, - //else - mpl::identity > - > - > - >::type typex; - typex::invoke(ar, t); -} - -} // namespace archive -} // namespace boost - -#endif // BOOST_ARCHIVE_OSERIALIZER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_iarchive_route.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_iarchive_route.hpp deleted file mode 100644 index 105685ebbd8..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_iarchive_route.hpp +++ /dev/null @@ -1,218 +0,0 @@ -#ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_ROUTE_HPP -#define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_ROUTE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// polymorphic_iarchive_route.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include -#include -#include -#include // must be the last header - -namespace boost { -namespace serialization { - class extended_type_info; -} // namespace serialization -namespace archive { -namespace detail{ - -class basic_iserializer; -class basic_pointer_iserializer; - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -template -class polymorphic_iarchive_route : - public polymorphic_iarchive, - // note: gcc dynamic cross cast fails if the the derivation below is - // not public. I think this is a mistake. - public /*protected*/ ArchiveImplementation -{ -private: - // these are used by the serialization library. - virtual void load_object( - void *t, - const basic_iserializer & bis - ){ - ArchiveImplementation::load_object(t, bis); - } - virtual const basic_pointer_iserializer * load_pointer( - void * & t, - const basic_pointer_iserializer * bpis_ptr, - const basic_pointer_iserializer * (*finder)( - const boost::serialization::extended_type_info & type - ) - ){ - return ArchiveImplementation::load_pointer(t, bpis_ptr, finder); - } - virtual void set_library_version(library_version_type archive_library_version){ - ArchiveImplementation::set_library_version(archive_library_version); - } - virtual library_version_type get_library_version() const{ - return ArchiveImplementation::get_library_version(); - } - virtual unsigned int get_flags() const { - return ArchiveImplementation::get_flags(); - } - virtual void delete_created_pointers(){ - ArchiveImplementation::delete_created_pointers(); - } - virtual void reset_object_address( - const void * new_address, - const void * old_address - ){ - ArchiveImplementation::reset_object_address(new_address, old_address); - } - virtual void load_binary(void * t, std::size_t size){ - ArchiveImplementation::load_binary(t, size); - } - // primitive types the only ones permitted by polymorphic archives - virtual void load(bool & t){ - ArchiveImplementation::load(t); - } - virtual void load(char & t){ - ArchiveImplementation::load(t); - } - virtual void load(signed char & t){ - ArchiveImplementation::load(t); - } - virtual void load(unsigned char & t){ - ArchiveImplementation::load(t); - } - #ifndef BOOST_NO_CWCHAR - #ifndef BOOST_NO_INTRINSIC_WCHAR_T - virtual void load(wchar_t & t){ - ArchiveImplementation::load(t); - } - #endif - #endif - virtual void load(short & t){ - ArchiveImplementation::load(t); - } - virtual void load(unsigned short & t){ - ArchiveImplementation::load(t); - } - virtual void load(int & t){ - ArchiveImplementation::load(t); - } - virtual void load(unsigned int & t){ - ArchiveImplementation::load(t); - } - virtual void load(long & t){ - ArchiveImplementation::load(t); - } - virtual void load(unsigned long & t){ - ArchiveImplementation::load(t); - } - #if defined(BOOST_HAS_LONG_LONG) - virtual void load(boost::long_long_type & t){ - ArchiveImplementation::load(t); - } - virtual void load(boost::ulong_long_type & t){ - ArchiveImplementation::load(t); - } - #elif defined(BOOST_HAS_MS_INT64) - virtual void load(__int64 & t){ - ArchiveImplementation::load(t); - } - virtual void load(unsigned __int64 & t){ - ArchiveImplementation::load(t); - } - #endif - virtual void load(float & t){ - ArchiveImplementation::load(t); - } - virtual void load(double & t){ - ArchiveImplementation::load(t); - } - virtual void load(std::string & t){ - ArchiveImplementation::load(t); - } - #ifndef BOOST_NO_STD_WSTRING - virtual void load(std::wstring & t){ - ArchiveImplementation::load(t); - } - #endif - // used for xml and other tagged formats default does nothing - virtual void load_start(const char * name){ - ArchiveImplementation::load_start(name); - } - virtual void load_end(const char * name){ - ArchiveImplementation::load_end(name); - } - virtual void register_basic_serializer(const basic_iserializer & bis){ - ArchiveImplementation::register_basic_serializer(bis); - } - virtual helper_collection & - get_helper_collection(){ - return ArchiveImplementation::get_helper_collection(); - } -public: - // this can't be inheriteded because they appear in mulitple - // parents - typedef mpl::bool_ is_loading; - typedef mpl::bool_ is_saving; - // the >> operator - template - polymorphic_iarchive & operator>>(T & t){ - return polymorphic_iarchive::operator>>(t); - } - // the & operator - template - polymorphic_iarchive & operator&(T & t){ - return polymorphic_iarchive::operator&(t); - } - // register type function - template - const basic_pointer_iserializer * - register_type(T * t = NULL){ - return ArchiveImplementation::register_type(t); - } - // all current archives take a stream as constructor argument - template - polymorphic_iarchive_route( - std::basic_istream<_Elem, _Tr> & is, - unsigned int flags = 0 - ) : - ArchiveImplementation(is, flags) - {} - virtual ~polymorphic_iarchive_route(){}; -}; - -} // namespace detail -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_ARCHIVE_DETAIL_POLYMORPHIC_IARCHIVE_DISPATCH_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_oarchive_route.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_oarchive_route.hpp deleted file mode 100644 index b23fd6bf39d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/polymorphic_oarchive_route.hpp +++ /dev/null @@ -1,209 +0,0 @@ -#ifndef BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_ROUTE_HPP -#define BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_ROUTE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// polymorphic_oarchive_route.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include // size_t - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include -#include -#include -#include // must be the last header - -namespace boost { -namespace serialization { - class extended_type_info; -} // namespace serialization -namespace archive { -namespace detail{ - -class basic_oserializer; -class basic_pointer_oserializer; - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -template -class polymorphic_oarchive_route : - public polymorphic_oarchive, - // note: gcc dynamic cross cast fails if the the derivation below is - // not public. I think this is a mistake. - public /*protected*/ ArchiveImplementation -{ -private: - // these are used by the serialization library. - virtual void save_object( - const void *x, - const detail::basic_oserializer & bos - ){ - ArchiveImplementation::save_object(x, bos); - } - virtual void save_pointer( - const void * t, - const detail::basic_pointer_oserializer * bpos_ptr - ){ - ArchiveImplementation::save_pointer(t, bpos_ptr); - } - virtual void save_null_pointer(){ - ArchiveImplementation::save_null_pointer(); - } - // primitive types the only ones permitted by polymorphic archives - virtual void save(const bool t){ - ArchiveImplementation::save(t); - } - virtual void save(const char t){ - ArchiveImplementation::save(t); - } - virtual void save(const signed char t){ - ArchiveImplementation::save(t); - } - virtual void save(const unsigned char t){ - ArchiveImplementation::save(t); - } - #ifndef BOOST_NO_CWCHAR - #ifndef BOOST_NO_INTRINSIC_WCHAR_T - virtual void save(const wchar_t t){ - ArchiveImplementation::save(t); - } - #endif - #endif - virtual void save(const short t){ - ArchiveImplementation::save(t); - } - virtual void save(const unsigned short t){ - ArchiveImplementation::save(t); - } - virtual void save(const int t){ - ArchiveImplementation::save(t); - } - virtual void save(const unsigned int t){ - ArchiveImplementation::save(t); - } - virtual void save(const long t){ - ArchiveImplementation::save(t); - } - virtual void save(const unsigned long t){ - ArchiveImplementation::save(t); - } - #if defined(BOOST_HAS_LONG_LONG) - virtual void save(const boost::long_long_type t){ - ArchiveImplementation::save(t); - } - virtual void save(const boost::ulong_long_type t){ - ArchiveImplementation::save(t); - } - #elif defined(BOOST_HAS_MS_INT64) - virtual void save(const boost::int64_t t){ - ArchiveImplementation::save(t); - } - virtual void save(const boost::uint64_t t){ - ArchiveImplementation::save(t); - } - #endif - virtual void save(const float t){ - ArchiveImplementation::save(t); - } - virtual void save(const double t){ - ArchiveImplementation::save(t); - } - virtual void save(const std::string & t){ - ArchiveImplementation::save(t); - } - #ifndef BOOST_NO_STD_WSTRING - virtual void save(const std::wstring & t){ - ArchiveImplementation::save(t); - } - #endif - virtual library_version_type get_library_version() const{ - return ArchiveImplementation::get_library_version(); - } - virtual unsigned int get_flags() const { - return ArchiveImplementation::get_flags(); - } - virtual void save_binary(const void * t, std::size_t size){ - ArchiveImplementation::save_binary(t, size); - } - // used for xml and other tagged formats default does nothing - virtual void save_start(const char * name){ - ArchiveImplementation::save_start(name); - } - virtual void save_end(const char * name){ - ArchiveImplementation::save_end(name); - } - virtual void end_preamble(){ - ArchiveImplementation::end_preamble(); - } - virtual void register_basic_serializer(const detail::basic_oserializer & bos){ - ArchiveImplementation::register_basic_serializer(bos); - } - virtual helper_collection & - get_helper_collection(){ - return ArchiveImplementation::get_helper_collection(); - } -public: - // this can't be inheriteded because they appear in mulitple - // parents - typedef mpl::bool_ is_loading; - typedef mpl::bool_ is_saving; - // the << operator - template - polymorphic_oarchive & operator<<(T & t){ - return polymorphic_oarchive::operator<<(t); - } - // the & operator - template - polymorphic_oarchive & operator&(T & t){ - return polymorphic_oarchive::operator&(t); - } - // register type function - template - const basic_pointer_oserializer * - register_type(T * t = NULL){ - return ArchiveImplementation::register_type(t); - } - // all current archives take a stream as constructor argument - template - polymorphic_oarchive_route( - std::basic_ostream<_Elem, _Tr> & os, - unsigned int flags = 0 - ) : - ArchiveImplementation(os, flags) - {} - virtual ~polymorphic_oarchive_route(){}; -}; - -} // namespace detail -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_ARCHIVE_DETAIL_POLYMORPHIC_OARCHIVE_DISPATCH_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/register_archive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/register_archive.hpp deleted file mode 100644 index 5ffecc702ce..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/register_archive.hpp +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright David Abrahams 2006. Distributed under the Boost -// Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_ARCHIVE_DETAIL_REGISTER_ARCHIVE_DWA2006521_HPP -# define BOOST_ARCHIVE_DETAIL_REGISTER_ARCHIVE_DWA2006521_HPP - -namespace boost { namespace archive { namespace detail { - -// No instantiate_ptr_serialization overloads generated by -// BOOST_SERIALIZATION_REGISTER_ARCHIVE that lexically follow the call -// will be seen *unless* they are in an associated namespace of one of -// the arguments, so we pass one of these along to make sure this -// namespace is considered. See temp.dep.candidate (14.6.4.2) in the -// standard. -struct adl_tag {}; - -template -struct ptr_serialization_support; - -// We could've just used ptr_serialization_support, above, but using -// it with only a forward declaration causes vc6/7 to complain about a -// missing instantiate member, even if it has one. This is just a -// friendly layer of indirection. -template -struct _ptr_serialization_support - : ptr_serialization_support -{ - typedef int type; -}; - -#if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5130) - -template -struct counter : counter {}; -template<> -struct counter<0> {}; - -template -void instantiate_ptr_serialization(Serializable* s, int, adl_tag) { - instantiate_ptr_serialization(s, counter<20>()); -} - -template -struct get_counter { - static const int value = sizeof(adjust_counter(counter<20>())); - typedef counter type; - typedef counter prior; - typedef char (&next)[value+1]; -}; - -char adjust_counter(counter<0>); -template -void instantiate_ptr_serialization(Serializable*, counter<0>) {} - -#define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive) \ -namespace boost { namespace archive { namespace detail { \ - get_counter::next adjust_counter(get_counter::type);\ - template \ - void instantiate_ptr_serialization(Serializable* s, \ - get_counter::type) { \ - ptr_serialization_support x; \ - instantiate_ptr_serialization(s, get_counter::prior()); \ - }\ -}}} - - -#else - -// This function gets called, but its only purpose is to participate -// in overload resolution with the functions declared by -// BOOST_SERIALIZATION_REGISTER_ARCHIVE, below. -template -void instantiate_ptr_serialization(Serializable*, int, adl_tag ) {} - -// The function declaration generated by this macro never actually -// gets called, but its return type gets instantiated, and that's -// enough to cause registration of serialization functions between -// Archive and any exported Serializable type. See also: -// boost/serialization/export.hpp -# define BOOST_SERIALIZATION_REGISTER_ARCHIVE(Archive) \ -namespace boost { namespace archive { namespace detail { \ - \ -template \ -typename _ptr_serialization_support::type \ -instantiate_ptr_serialization( Serializable*, Archive*, adl_tag ); \ - \ -}}} -#endif -}}} // namespace boost::archive::detail - -#endif // BOOST_ARCHIVE_DETAIL_INSTANTIATE_SERIALIZE_DWA2006521_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/detail/utf8_codecvt_facet.hpp b/contrib/libboost/boost_1_65_0/boost/archive/detail/utf8_codecvt_facet.hpp deleted file mode 100644 index a40104abea6..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/detail/utf8_codecvt_facet.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu) -// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu). -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP -#define BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP - -#include - -#ifdef BOOST_NO_STD_WSTREAMBUF -#error "wide char i/o not supported on this platform" -#endif - -// std::codecvt_utf8 doesn't seem to work for any versions of msvc - -#if defined(_MSC_VER) || defined(BOOST_NO_CXX11_HDR_CODECVT) - // use boost's utf8 codecvt facet - #include - #define BOOST_UTF8_BEGIN_NAMESPACE \ - namespace boost { namespace archive { namespace detail { - #define BOOST_UTF8_DECL BOOST_ARCHIVE_DECL - #define BOOST_UTF8_END_NAMESPACE }}} - - #include - - #undef BOOST_UTF8_END_NAMESPACE - #undef BOOST_UTF8_DECL - #undef BOOST_UTF8_BEGIN_NAMESPACE -#else - // use the standard vendor supplied facet - #include - namespace boost { namespace archive { namespace detail { - typedef std::codecvt_utf8 utf8_codecvt_facet; - } } } -#endif - -#endif // BOOST_ARCHIVE_DETAIL_UTF8_CODECVT_FACET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/dinkumware.hpp b/contrib/libboost/boost_1_65_0/boost/archive/dinkumware.hpp deleted file mode 100644 index 90ba6271cdd..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/dinkumware.hpp +++ /dev/null @@ -1,224 +0,0 @@ -#ifndef BOOST_ARCHIVE_DINKUMWARE_HPP -#define BOOST_ARCHIVE_DINKUMWARE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// dinkumware.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// this file adds a couple of things that are missing from the dinkumware -// implementation of the standard library. - -#include -#include - -#include -#include - -namespace std { - -// define i/o operators for 64 bit integers -template -basic_ostream & -operator<<(basic_ostream & os, boost::uint64_t t){ - // octal rendering of 64 bit number would be 22 octets + eos - CharType d[23]; - unsigned int radix; - - if(os.flags() & (int)std::ios_base::hex) - radix = 16; - else - if(os.flags() & (int)std::ios_base::oct) - radix = 8; - else - //if(s.flags() & (int)std::ios_base::dec) - radix = 10; - unsigned int i = 0; - do{ - unsigned int j = t % radix; - d[i++] = j + ((j < 10) ? '0' : ('a' - 10)); - t /= radix; - } - while(t > 0); - d[i--] = '\0'; - - // reverse digits - unsigned int j = 0; - while(j < i){ - CharType k = d[i]; - d[i] = d[j]; - d[j] = k; - --i;++j; - } - os << d; - return os; - -} - -template -basic_ostream & -operator<<(basic_ostream &os, boost::int64_t t){ - if(0 <= t){ - os << static_cast(t); - } - else{ - os.put('-'); - os << -t; - } - return os; -} - -template -basic_istream & -operator>>(basic_istream &is, boost::int64_t & t){ - CharType d; - do{ - d = is.get(); - } - while(::isspace(d)); - bool negative = (d == '-'); - if(negative) - d = is.get(); - unsigned int radix; - if(is.flags() & (int)std::ios_base::hex) - radix = 16; - else - if(is.flags() & (int)std::ios_base::oct) - radix = 8; - else - //if(s.flags() & (int)std::ios_base::dec) - radix = 10; - t = 0; - do{ - if('0' <= d && d <= '9') - t = t * radix + (d - '0'); - else - if('a' <= d && d <= 'f') - t = t * radix + (d - 'a' + 10); - else - break; - d = is.get(); - } - while(!is.fail()); - // restore the delimiter - is.putback(d); - is.clear(); - if(negative) - t = -t; - return is; -} - -template -basic_istream & -operator>>(basic_istream &is, boost::uint64_t & t){ - boost::int64_t it; - is >> it; - t = it; - return is; -} - -//#endif - -template<> -class back_insert_iterator > : public - iterator -{ -public: - typedef basic_string container_type; - typedef container_type::reference reference; - - explicit back_insert_iterator(container_type & s) - : container(& s) - {} // construct with container - - back_insert_iterator & operator=( - container_type::const_reference Val_ - ){ // push value into container - //container->push_back(Val_); - *container += Val_; - return (*this); - } - - back_insert_iterator & operator*(){ - return (*this); - } - - back_insert_iterator & operator++(){ - // pretend to preincrement - return (*this); - } - - back_insert_iterator operator++(int){ - // pretend to postincrement - return (*this); - } - -protected: - container_type *container; // pointer to container -}; - -template -inline back_insert_iterator > back_inserter( - basic_string & s -){ - return (std::back_insert_iterator >(s)); -} - -template<> -class back_insert_iterator > : public - iterator -{ -public: - typedef basic_string container_type; - typedef container_type::reference reference; - - explicit back_insert_iterator(container_type & s) - : container(& s) - {} // construct with container - - back_insert_iterator & operator=( - container_type::const_reference Val_ - ){ // push value into container - //container->push_back(Val_); - *container += Val_; - return (*this); - } - - back_insert_iterator & operator*(){ - return (*this); - } - - back_insert_iterator & operator++(){ - // pretend to preincrement - return (*this); - } - - back_insert_iterator operator++(int){ - // pretend to postincrement - return (*this); - } - -protected: - container_type *container; // pointer to container -}; - -template -inline back_insert_iterator > back_inserter( - basic_string & s -){ - return (std::back_insert_iterator >(s)); -} - -} // namespace std - -#endif //BOOST_ARCHIVE_DINKUMWARE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/archive_serializer_map.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/archive_serializer_map.ipp deleted file mode 100644 index 7f163ec4076..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/archive_serializer_map.ipp +++ /dev/null @@ -1,75 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// archive_serializer_map.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -////////////////////////////////////////////////////////////////////// -// implementation of basic_text_iprimitive overrides for the combination -// of template parameters used to implement a text_iprimitive - -#include -#include -#include -#include - -namespace boost { -namespace archive { -namespace detail { - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace extra_detail { // anon - template - class map : public basic_serializer_map - {}; -} - -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL bool -archive_serializer_map::insert(const basic_serializer * bs){ - return boost::serialization::singleton< - extra_detail::map - >::get_mutable_instance().insert(bs); -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -archive_serializer_map::erase(const basic_serializer * bs){ - BOOST_ASSERT(! boost::serialization::singleton< - extra_detail::map - >::is_destroyed() - ); - if(boost::serialization::singleton< - extra_detail::map - >::is_destroyed()) - return; - boost::serialization::singleton< - extra_detail::map - >::get_mutable_instance().erase(bs); -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL const basic_serializer * -archive_serializer_map::find( - const boost::serialization::extended_type_info & eti -) { - return boost::serialization::singleton< - extra_detail::map - >::get_const_instance().find(eti); -} - -} // namespace detail -} // namespace archive -} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iarchive.ipp deleted file mode 100644 index d5619ab6cf3..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iarchive.ipp +++ /dev/null @@ -1,134 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_binary_iarchive.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. -#include -#include -#include -#include - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::memcpy; - using ::strlen; - using ::size_t; -} -#endif - -#include -#include - -#include - -namespace boost { -namespace archive { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// implementation of binary_binary_archive -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_binary_iarchive::load_override(class_name_type & t){ - std::string cn; - cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE); - load_override(cn); - if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)) - boost::serialization::throw_exception( - archive_exception(archive_exception::invalid_class_name) - ); - std::memcpy(t, cn.data(), cn.size()); - // borland tweak - t.t[cn.size()] = '\0'; -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_binary_iarchive::init(void){ - // read signature in an archive version independent manner - std::string file_signature; - - #if 0 // commented out since it interfers with derivation - BOOST_TRY { - std::size_t l; - this->This()->load(l); - if(l == std::strlen(BOOST_ARCHIVE_SIGNATURE())) { - // borland de-allocator fixup - #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) - if(NULL != file_signature.data()) - #endif - file_signature.resize(l); - // note breaking a rule here - could be a problem on some platform - if(0 < l) - this->This()->load_binary(&(*file_signature.begin()), l); - } - } - BOOST_CATCH(archive_exception const &) { // catch stream_error archive exceptions - // will cause invalid_signature archive exception to be thrown below - file_signature = ""; - } - BOOST_CATCH_END - #else - // https://svn.boost.org/trac/boost/ticket/7301 - * this->This() >> file_signature; - #endif - - if(file_signature != BOOST_ARCHIVE_SIGNATURE()) - boost::serialization::throw_exception( - archive_exception(archive_exception::invalid_signature) - ); - - // make sure the version of the reading archive library can - // support the format of the archive being read - library_version_type input_library_version; - //* this->This() >> input_library_version; - { - int v = 0; - v = this->This()->m_sb.sbumpc(); - #if defined(BOOST_LITTLE_ENDIAN) - if(v < 6){ - ; - } - else - if(v < 7){ - // version 6 - next byte should be zero - this->This()->m_sb.sbumpc(); - } - else - if(v < 8){ - int x1; - // version 7 = might be followed by zero or some other byte - x1 = this->This()->m_sb.sgetc(); - // it's =a zero, push it back - if(0 == x1) - this->This()->m_sb.sbumpc(); - } - else{ - // version 8+ followed by a zero - this->This()->m_sb.sbumpc(); - } - #elif defined(BOOST_BIG_ENDIAN) - if(v == 0) - v = this->This()->m_sb.sbumpc(); - #endif - input_library_version = static_cast(v); - } - - #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) - this->set_library_version(input_library_version); - #else - detail::basic_iarchive::set_library_version(input_library_version); - #endif - - if(BOOST_ARCHIVE_VERSION() < input_library_version) - boost::serialization::throw_exception( - archive_exception(archive_exception::unsupported_version) - ); -} - -} // namespace archive -} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iprimitive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iprimitive.ipp deleted file mode 100644 index bbe933ccf63..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_iprimitive.ipp +++ /dev/null @@ -1,171 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_binary_iprimitive.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include // size_t, NULL -#include // memcpy - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; - using ::memcpy; -} // namespace std -#endif - -#include -#include -#include -#include - -namespace boost { -namespace archive { - -////////////////////////////////////////////////////////////////////// -// implementation of basic_binary_iprimitive - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_binary_iprimitive::init() -{ - // Detect attempts to pass native binary archives across - // incompatible platforms. This is not fool proof but its - // better than nothing. - unsigned char size; - this->This()->load(size); - if(sizeof(int) != size) - boost::serialization::throw_exception( - archive_exception( - archive_exception::incompatible_native_format, - "size of int" - ) - ); - this->This()->load(size); - if(sizeof(long) != size) - boost::serialization::throw_exception( - archive_exception( - archive_exception::incompatible_native_format, - "size of long" - ) - ); - this->This()->load(size); - if(sizeof(float) != size) - boost::serialization::throw_exception( - archive_exception( - archive_exception::incompatible_native_format, - "size of float" - ) - ); - this->This()->load(size); - if(sizeof(double) != size) - boost::serialization::throw_exception( - archive_exception( - archive_exception::incompatible_native_format, - "size of double" - ) - ); - - // for checking endian - int i; - this->This()->load(i); - if(1 != i) - boost::serialization::throw_exception( - archive_exception( - archive_exception::incompatible_native_format, - "endian setting" - ) - ); -} - -#ifndef BOOST_NO_CWCHAR -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_binary_iprimitive::load(wchar_t * ws) -{ - std::size_t l; // number of wchar_t !!! - this->This()->load(l); - load_binary(ws, l * sizeof(wchar_t) / sizeof(char)); - ws[l] = L'\0'; -} -#endif - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_binary_iprimitive::load(std::string & s) -{ - std::size_t l; - this->This()->load(l); - // borland de-allocator fixup - #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) - if(NULL != s.data()) - #endif - s.resize(l); - // note breaking a rule here - could be a problem on some platform - if(0 < l) - load_binary(&(*s.begin()), l); -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_binary_iprimitive::load(char * s) -{ - std::size_t l; - this->This()->load(l); - load_binary(s, l); - s[l] = '\0'; -} - -#ifndef BOOST_NO_STD_WSTRING -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_binary_iprimitive::load(std::wstring & ws) -{ - std::size_t l; - this->This()->load(l); - // borland de-allocator fixup - #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) - if(NULL != ws.data()) - #endif - ws.resize(l); - // note breaking a rule here - is could be a problem on some platform - load_binary(const_cast(ws.data()), l * sizeof(wchar_t) / sizeof(char)); -} -#endif - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL -basic_binary_iprimitive::basic_binary_iprimitive( - std::basic_streambuf & sb, - bool no_codecvt -) : -#ifndef BOOST_NO_STD_LOCALE - m_sb(sb), - codecvt_null_facet(1), - locale_saver(m_sb), - archive_locale(sb.getloc(), & codecvt_null_facet) -{ - if(! no_codecvt){ - m_sb.pubsync(); - m_sb.pubimbue(archive_locale); - } -} -#else - m_sb(sb) -{} -#endif - -// scoped_ptr requires that g be a complete type at time of -// destruction so define destructor here rather than in the header -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL -basic_binary_iprimitive::~basic_binary_iprimitive(){} - -} // namespace archive -} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oarchive.ipp deleted file mode 100644 index d5a019d32bc..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oarchive.ipp +++ /dev/null @@ -1,42 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_binary_oarchive.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. -#include -#include -#include -#include - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::memcpy; -} -#endif - -#include - -namespace boost { -namespace archive { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// implementation of binary_binary_oarchive - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_binary_oarchive::init(){ - // write signature in an archive version independent manner - const std::string file_signature(BOOST_ARCHIVE_SIGNATURE()); - * this->This() << file_signature; - // write library version - const library_version_type v(BOOST_ARCHIVE_VERSION()); - * this->This() << v; -} - -} // namespace archive -} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oprimitive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oprimitive.ipp deleted file mode 100644 index 7b042173a48..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_binary_oprimitive.ipp +++ /dev/null @@ -1,126 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_binary_oprimitive.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include // NULL -#include - -#include - -#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__) -namespace std{ - using ::strlen; -} // namespace std -#endif - -#ifndef BOOST_NO_CWCHAR -#include -#ifdef BOOST_NO_STDC_NAMESPACE -namespace std{ using ::wcslen; } -#endif -#endif - -#include -#include - -namespace boost { -namespace archive { - -////////////////////////////////////////////////////////////////////// -// implementation of basic_binary_oprimitive - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_binary_oprimitive::init() -{ - // record native sizes of fundamental types - // this is to permit detection of attempts to pass - // native binary archives accross incompatible machines. - // This is not foolproof but its better than nothing. - this->This()->save(static_cast(sizeof(int))); - this->This()->save(static_cast(sizeof(long))); - this->This()->save(static_cast(sizeof(float))); - this->This()->save(static_cast(sizeof(double))); - // for checking endianness - this->This()->save(int(1)); -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_binary_oprimitive::save(const char * s) -{ - std::size_t l = std::strlen(s); - this->This()->save(l); - save_binary(s, l); -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_binary_oprimitive::save(const std::string &s) -{ - std::size_t l = static_cast(s.size()); - this->This()->save(l); - save_binary(s.data(), l); -} - -#ifndef BOOST_NO_CWCHAR -#ifndef BOOST_NO_INTRINSIC_WCHAR_T -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_binary_oprimitive::save(const wchar_t * ws) -{ - std::size_t l = std::wcslen(ws); - this->This()->save(l); - save_binary(ws, l * sizeof(wchar_t) / sizeof(char)); -} -#endif - -#ifndef BOOST_NO_STD_WSTRING -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_binary_oprimitive::save(const std::wstring &ws) -{ - std::size_t l = ws.size(); - this->This()->save(l); - save_binary(ws.data(), l * sizeof(wchar_t) / sizeof(char)); -} -#endif -#endif // BOOST_NO_CWCHAR - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL -basic_binary_oprimitive::basic_binary_oprimitive( - std::basic_streambuf & sb, - bool no_codecvt -) : -#ifndef BOOST_NO_STD_LOCALE - m_sb(sb), - codecvt_null_facet(1), - locale_saver(m_sb), - archive_locale(sb.getloc(), & codecvt_null_facet) -{ - if(! no_codecvt){ - m_sb.pubsync(); - m_sb.pubimbue(archive_locale); - } -} -#else - m_sb(sb) -{} -#endif - -// scoped_ptr requires that g be a complete type at time of -// destruction so define destructor here rather than in the header -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL -basic_binary_oprimitive::~basic_binary_oprimitive(){} - -} // namespace archive -} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iarchive.ipp deleted file mode 100644 index 9ec8c6588c8..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iarchive.ipp +++ /dev/null @@ -1,76 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_text_iarchive.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. -#include -#include -#include - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::memcpy; -} -#endif - -#include -#include -#include - -namespace boost { -namespace archive { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// implementation of text_text_archive - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_text_iarchive::load_override(class_name_type & t){ - std::string cn; - cn.reserve(BOOST_SERIALIZATION_MAX_KEY_SIZE); - load_override(cn); - if(cn.size() > (BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)) - boost::serialization::throw_exception( - archive_exception(archive_exception::invalid_class_name) - ); - std::memcpy(t, cn.data(), cn.size()); - // borland tweak - t.t[cn.size()] = '\0'; -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_text_iarchive::init(void){ - // read signature in an archive version independent manner - std::string file_signature; - * this->This() >> file_signature; - if(file_signature != BOOST_ARCHIVE_SIGNATURE()) - boost::serialization::throw_exception( - archive_exception(archive_exception::invalid_signature) - ); - - // make sure the version of the reading archive library can - // support the format of the archive being read - library_version_type input_library_version; - * this->This() >> input_library_version; - - #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) - this->set_library_version(input_library_version); - #else - detail::basic_iarchive::set_library_version(input_library_version); - #endif - - // extra little .t is to get around borland quirk - if(BOOST_ARCHIVE_VERSION() < input_library_version) - boost::serialization::throw_exception( - archive_exception(archive_exception::unsupported_version) - ); -} - -} // namespace archive -} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iprimitive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iprimitive.ipp deleted file mode 100644 index 4e44728068d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_iprimitive.ipp +++ /dev/null @@ -1,137 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_text_iprimitive.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // size_t, NULL -#include // NULL - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include - -#include - -#include -#include -#include -#include - -namespace boost { -namespace archive { - -namespace detail { - template - static inline bool is_whitespace(CharType c); - - template<> - inline bool is_whitespace(char t){ - return 0 != std::isspace(t); - } - - #ifndef BOOST_NO_CWCHAR - template<> - inline bool is_whitespace(wchar_t t){ - return 0 != std::iswspace(t); - } - #endif -} // detail - -// translate base64 text into binary and copy into buffer -// until buffer is full. -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_text_iprimitive::load_binary( - void *address, - std::size_t count -){ - typedef typename IStream::char_type CharType; - - if(0 == count) - return; - - BOOST_ASSERT( - static_cast((std::numeric_limits::max)()) - > (count + sizeof(CharType) - 1)/sizeof(CharType) - ); - - if(is.fail()) - boost::serialization::throw_exception( - archive_exception(archive_exception::input_stream_error) - ); - // convert from base64 to binary - typedef typename - iterators::transform_width< - iterators::binary_from_base64< - iterators::remove_whitespace< - iterators::istream_iterator - > - ,typename IStream::int_type - > - ,8 - ,6 - ,CharType - > - binary; - - binary i = binary(iterators::istream_iterator(is)); - - char * caddr = static_cast(address); - - // take care that we don't increment anymore than necessary - while(count-- > 0){ - *caddr++ = static_cast(*i++); - } - - // skip over any excess input - for(;;){ - typename IStream::int_type r; - r = is.get(); - if(is.eof()) - break; - if(detail::is_whitespace(static_cast(r))) - break; - } -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL -basic_text_iprimitive::basic_text_iprimitive( - IStream &is_, - bool no_codecvt -) : - is(is_), - flags_saver(is_), - precision_saver(is_), -#ifndef BOOST_NO_STD_LOCALE - codecvt_null_facet(1), - archive_locale(is.getloc(), & codecvt_null_facet), - locale_saver(is) -{ - if(! no_codecvt){ - is_.sync(); - is_.imbue(archive_locale); - } - is_ >> std::noboolalpha; -} -#else -{} -#endif - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL -basic_text_iprimitive::~basic_text_iprimitive(){ -} - -} // namespace archive -} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oarchive.ipp deleted file mode 100644 index 44bc1401fd6..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oarchive.ipp +++ /dev/null @@ -1,62 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_text_oarchive.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. -#include -#include -#include - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::memcpy; -} -#endif - -#include - -namespace boost { -namespace archive { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// implementation of basic_text_oarchive - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_text_oarchive::newtoken() -{ - switch(delimiter){ - default: - BOOST_ASSERT(false); - break; - case eol: - this->This()->put('\n'); - delimiter = space; - break; - case space: - this->This()->put(' '); - break; - case none: - delimiter = space; - break; - } -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_text_oarchive::init(){ - // write signature in an archive version independent manner - const std::string file_signature(BOOST_ARCHIVE_SIGNATURE()); - * this->This() << file_signature; - // write library version - const library_version_type v(BOOST_ARCHIVE_VERSION()); - * this->This() << v; -} - -} // namespace archive -} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oprimitive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oprimitive.ipp deleted file mode 100644 index 6030fd44c57..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_text_oprimitive.ipp +++ /dev/null @@ -1,115 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_text_oprimitive.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // NULL -#include // std::copy -#include // std::uncaught_exception -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include - -#include -#include -#include -#include - -namespace boost { -namespace archive { - -// translate to base64 and copy in to buffer. -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_text_oprimitive::save_binary( - const void *address, - std::size_t count -){ - typedef typename OStream::char_type CharType; - - if(0 == count) - return; - - if(os.fail()) - boost::serialization::throw_exception( - archive_exception(archive_exception::output_stream_error) - ); - - os.put('\n'); - - typedef - boost::archive::iterators::insert_linebreaks< - boost::archive::iterators::base64_from_binary< - boost::archive::iterators::transform_width< - const char *, - 6, - 8 - > - > - ,76 - ,const char // cwpro8 needs this - > - base64_text; - - boost::archive::iterators::ostream_iterator oi(os); - std::copy( - base64_text(static_cast(address)), - base64_text( - static_cast(address) + count - ), - oi - ); - - std::size_t tail = count % 3; - if(tail > 0){ - *oi++ = '='; - if(tail < 2) - *oi = '='; - } -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL -basic_text_oprimitive::basic_text_oprimitive( - OStream & os_, - bool no_codecvt -) : - os(os_), - flags_saver(os_), - precision_saver(os_), -#ifndef BOOST_NO_STD_LOCALE - codecvt_null_facet(1), - archive_locale(os.getloc(), & codecvt_null_facet), - locale_saver(os) -{ - if(! no_codecvt){ - os_.flush(); - os_.imbue(archive_locale); - } - os_ << std::noboolalpha; -} -#else -{} -#endif - - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL -basic_text_oprimitive::~basic_text_oprimitive(){ - if(std::uncaught_exception()) - return; - os << std::endl; -} - -} //namespace boost -} //namespace archive diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_grammar.hpp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_grammar.hpp deleted file mode 100644 index 6d4e4683f6a..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_grammar.hpp +++ /dev/null @@ -1,173 +0,0 @@ -#ifndef BOOST_ARCHIVE_BASIC_XML_GRAMMAR_HPP -#define BOOST_ARCHIVE_BASIC_XML_GRAMMAR_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_xml_grammar.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// this module is derived from simplexml.cpp - an example shipped as part of -// the spirit parser. This example contains the following notice: -/*============================================================================= - simplexml.cpp - - Spirit V1.3 - URL: http://spirit.sourceforge.net/ - - Copyright (c) 2001, Daniel C. Nuffer - - This software is provided 'as-is', without any express or implied - warranty. In no event will the copyright holder be held liable for - any damages arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute - it freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product documentation - would be appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -=============================================================================*/ -#include - -#include -#include - -#include -#include - -#include -#include -#include - -namespace boost { -namespace archive { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// XML grammar parsing - -template -class basic_xml_grammar { -public: - // The following is not necessary according to DR45, but at least - // one compiler (Compaq C++ 6.5 in strict_ansi mode) chokes otherwise. - struct return_values; - friend struct return_values; - -private: - typedef typename std::basic_istream IStream; - typedef typename std::basic_string StringType; - typedef typename boost::spirit::classic::chset chset_t; - typedef typename boost::spirit::classic::chlit chlit_t; - typedef typename boost::spirit::classic::scanner< - typename std::basic_string::iterator - > scanner_t; - typedef typename boost::spirit::classic::rule rule_t; - // Start grammar definition - rule_t - Reference, - Eq, - STag, - ETag, - LetterOrUnderscoreOrColon, - AttValue, - CharRef1, - CharRef2, - CharRef, - AmpRef, - LTRef, - GTRef, - AposRef, - QuoteRef, - CharData, - CharDataChars, - content, - AmpName, - LTName, - GTName, - ClassNameChar, - ClassName, - Name, - XMLDecl, - XMLDeclChars, - DocTypeDecl, - DocTypeDeclChars, - ClassIDAttribute, - ObjectIDAttribute, - ClassNameAttribute, - TrackingAttribute, - VersionAttribute, - UnusedAttribute, - Attribute, - SignatureAttribute, - SerializationWrapper, - NameHead, - NameTail, - AttributeList, - S; - - // XML Character classes - chset_t - BaseChar, - Ideographic, - Char, - Letter, - Digit, - CombiningChar, - Extender, - Sch, - NameChar; - - void init_chset(); - - bool my_parse( - IStream & is, - const rule_t &rule_, - const CharType delimiter = L'>' - ) const ; -public: - struct return_values { - StringType object_name; - StringType contents; - //class_id_type class_id; - int_least16_t class_id; - //object_id_type object_id; - uint_least32_t object_id; - //version_type version; - unsigned int version; - tracking_type tracking_level; - StringType class_name; - return_values() : - version(0), - tracking_level(false) - {} - } rv; - bool parse_start_tag(IStream & is) /*const*/; - bool parse_end_tag(IStream & is) const; - bool parse_string(IStream & is, StringType & s) /*const*/; - void init(IStream & is); - bool windup(IStream & is); - basic_xml_grammar(); -}; - -} // namespace archive -} // namespace boost - -#endif // BOOST_ARCHIVE_BASIC_XML_GRAMMAR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_iarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_iarchive.ipp deleted file mode 100644 index 625458b9eb5..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_iarchive.ipp +++ /dev/null @@ -1,115 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_xml_iarchive.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include // NULL -#include - -#include -#include -#include -#include - -namespace boost { -namespace archive { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// implementation of xml_text_archive - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_iarchive::load_start(const char *name){ - // if there's no name - if(NULL == name) - return; - bool result = this->This()->gimpl->parse_start_tag(this->This()->get_is()); - if(true != result){ - boost::serialization::throw_exception( - archive_exception(archive_exception::input_stream_error) - ); - } - // don't check start tag at highest level - ++depth; - return; -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_iarchive::load_end(const char *name){ - // if there's no name - if(NULL == name) - return; - bool result = this->This()->gimpl->parse_end_tag(this->This()->get_is()); - if(true != result){ - boost::serialization::throw_exception( - archive_exception(archive_exception::input_stream_error) - ); - } - - // don't check start tag at highest level - if(0 == --depth) - return; - - if(0 == (this->get_flags() & no_xml_tag_checking)){ - // double check that the tag matches what is expected - useful for debug - if(0 != name[this->This()->gimpl->rv.object_name.size()] - || ! std::equal( - this->This()->gimpl->rv.object_name.begin(), - this->This()->gimpl->rv.object_name.end(), - name - ) - ){ - boost::serialization::throw_exception( - xml_archive_exception( - xml_archive_exception::xml_archive_tag_mismatch, - name - ) - ); - } - } -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_iarchive::load_override(object_id_type & t){ - t = object_id_type(this->This()->gimpl->rv.object_id); -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_iarchive::load_override(version_type & t){ - t = version_type(this->This()->gimpl->rv.version); -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_iarchive::load_override(class_id_type & t){ - t = class_id_type(this->This()->gimpl->rv.class_id); -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_iarchive::load_override(tracking_type & t){ - t = this->This()->gimpl->rv.tracking_level; -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL -basic_xml_iarchive::basic_xml_iarchive(unsigned int flags) : - detail::common_iarchive(flags), - depth(0) -{} -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL -basic_xml_iarchive::~basic_xml_iarchive(){ -} - -} // namespace archive -} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_oarchive.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_oarchive.ipp deleted file mode 100644 index 3184413f382..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/basic_xml_oarchive.ipp +++ /dev/null @@ -1,272 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// basic_xml_oarchive.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include // NULL -#include -#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__) -namespace std{ - using ::strlen; -} // namespace std -#endif - -#include -#include -#include -#include - -namespace boost { -namespace archive { - -namespace detail { -template -struct XML_name { - void operator()(CharType t) const{ - const unsigned char lookup_table[] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0, // -. - 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 0-9 - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // A- - 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, // -Z _ - 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // a- - 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, // -z - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - }; - if((unsigned)t > 127) - return; - if(0 == lookup_table[(unsigned)t]) - boost::serialization::throw_exception( - xml_archive_exception( - xml_archive_exception::xml_archive_tag_name_error - ) - ); - } -}; - -} // namespace detail - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// implemenations of functions common to both types of xml output - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::write_attribute( - const char *attribute_name, - int t, - const char *conjunction -){ - this->This()->put(' '); - this->This()->put(attribute_name); - this->This()->put(conjunction); - this->This()->save(t); - this->This()->put('"'); -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::write_attribute( - const char *attribute_name, - const char *key -){ - this->This()->put(' '); - this->This()->put(attribute_name); - this->This()->put("=\""); - this->This()->save(key); - this->This()->put('"'); -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::indent(){ - int i; - for(i = depth; i-- > 0;) - this->This()->put('\t'); -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::save_start(const char *name) -{ - if(NULL == name) - return; - - // be sure name has no invalid characters - std::for_each(name, name + std::strlen(name), detail::XML_name()); - - end_preamble(); - if(depth > 0){ - this->This()->put('\n'); - indent(); - } - ++depth; - this->This()->put('<'); - this->This()->save(name); - pending_preamble = true; - indent_next = false; -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::save_end(const char *name) -{ - if(NULL == name) - return; - - // be sure name has no invalid characters - std::for_each(name, name + std::strlen(name), detail::XML_name()); - - end_preamble(); - --depth; - if(indent_next){ - this->This()->put('\n'); - indent(); - } - indent_next = true; - this->This()->put("This()->save(name); - this->This()->put('>'); - if(0 == depth) - this->This()->put('\n'); -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::end_preamble(){ - if(pending_preamble){ - this->This()->put('>'); - pending_preamble = false; - } -} -#if 0 -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::save_override(const object_id_type & t) -{ - int i = t.t; // extra .t is for borland - write_attribute(BOOST_ARCHIVE_XML_OBJECT_ID(), i, "=\"_"); -} -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::save_override( - const object_reference_type & t, - int -){ - int i = t.t; // extra .t is for borland - write_attribute(BOOST_ARCHIVE_XML_OBJECT_REFERENCE(), i, "=\"_"); -} -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::save_override(const version_type & t) -{ - int i = t.t; // extra .t is for borland - write_attribute(BOOST_ARCHIVE_XML_VERSION(), i); -} -#endif - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::save_override(const object_id_type & t) -{ - // borland doesn't do conversion of STRONG_TYPEDEFs very well - const unsigned int i = t; - write_attribute(BOOST_ARCHIVE_XML_OBJECT_ID(), i, "=\"_"); -} -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::save_override( - const object_reference_type & t -){ - const unsigned int i = t; - write_attribute(BOOST_ARCHIVE_XML_OBJECT_REFERENCE(), i, "=\"_"); -} -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::save_override(const version_type & t) -{ - const unsigned int i = t; - write_attribute(BOOST_ARCHIVE_XML_VERSION(), i); -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::save_override(const class_id_type & t) -{ - write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t); -} -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::save_override( - const class_id_reference_type & t -){ - write_attribute(BOOST_ARCHIVE_XML_CLASS_ID_REFERENCE(), t); -} -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::save_override( - const class_id_optional_type & t -){ - write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t); -} -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::save_override(const class_name_type & t) -{ - const char * key = t; - if(NULL == key) - return; - write_attribute(BOOST_ARCHIVE_XML_CLASS_NAME(), key); -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::save_override(const tracking_type & t) -{ - write_attribute(BOOST_ARCHIVE_XML_TRACKING(), t.t); -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::init(){ - // xml header - this->This()->put("\n"); - this->This()->put("\n"); - // xml document wrapper - outer root - this->This()->put("This()->put(">\n"); -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL void -basic_xml_oarchive::windup(){ - // xml_trailer - this->This()->put("\n"); -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL -basic_xml_oarchive::basic_xml_oarchive(unsigned int flags) : - detail::common_oarchive(flags), - depth(0), - pending_preamble(false), - indent_next(false) -{ -} - -template -BOOST_ARCHIVE_OR_WARCHIVE_DECL -basic_xml_oarchive::~basic_xml_oarchive(){ -} - -} // namespace archive -} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/text_iarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_iarchive_impl.ipp deleted file mode 100644 index ae4e2750ce8..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/text_iarchive_impl.ipp +++ /dev/null @@ -1,128 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// text_iarchive_impl.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -////////////////////////////////////////////////////////////////////// -// implementation of basic_text_iprimitive overrides for the combination -// of template parameters used to implement a text_iprimitive - -#include // size_t, NULL -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include // RogueWave - -#include - -namespace boost { -namespace archive { - -template -BOOST_ARCHIVE_DECL void -text_iarchive_impl::load(char *s) -{ - std::size_t size; - * this->This() >> size; - // skip separating space - is.get(); - // Works on all tested platforms - is.read(s, size); - s[size] = '\0'; -} - -template -BOOST_ARCHIVE_DECL void -text_iarchive_impl::load(std::string &s) -{ - std::size_t size; - * this->This() >> size; - // skip separating space - is.get(); - // borland de-allocator fixup - #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) - if(NULL != s.data()) - #endif - s.resize(size); - if(0 < size) - is.read(&(*s.begin()), size); -} - -#ifndef BOOST_NO_CWCHAR -#ifndef BOOST_NO_INTRINSIC_WCHAR_T -template -BOOST_ARCHIVE_DECL void -text_iarchive_impl::load(wchar_t *ws) -{ - std::size_t size; - * this->This() >> size; - // skip separating space - is.get(); - is.read((char *)ws, size * sizeof(wchar_t)/sizeof(char)); - ws[size] = L'\0'; -} -#endif // BOOST_NO_INTRINSIC_WCHAR_T - -#ifndef BOOST_NO_STD_WSTRING -template -BOOST_ARCHIVE_DECL void -text_iarchive_impl::load(std::wstring &ws) -{ - std::size_t size; - * this->This() >> size; - // borland de-allocator fixup - #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) - if(NULL != ws.data()) - #endif - ws.resize(size); - // skip separating space - is.get(); - is.read((char *)ws.data(), size * sizeof(wchar_t)/sizeof(char)); -} - -#endif // BOOST_NO_STD_WSTRING -#endif // BOOST_NO_CWCHAR - -template -BOOST_ARCHIVE_DECL void -text_iarchive_impl::load_override(class_name_type & t){ - basic_text_iarchive::load_override(t); -} - -template -BOOST_ARCHIVE_DECL void -text_iarchive_impl::init(){ - basic_text_iarchive::init(); -} - -template -BOOST_ARCHIVE_DECL -text_iarchive_impl::text_iarchive_impl( - std::istream & is, - unsigned int flags -) : - basic_text_iprimitive( - is, - 0 != (flags & no_codecvt) - ), - basic_text_iarchive(flags) -{ - if(0 == (flags & no_header)) - #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) - this->init(); - #else - this->basic_text_iarchive::init(); - #endif -} - -} // namespace archive -} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/text_oarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_oarchive_impl.ipp deleted file mode 100644 index 37d8664a98c..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/text_oarchive_impl.ipp +++ /dev/null @@ -1,122 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// text_oarchive_impl.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include // size_t - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#ifndef BOOST_NO_CWCHAR -#include -#ifdef BOOST_NO_STDC_NAMESPACE -namespace std{ using ::wcslen; } -#endif -#endif - -#include - -namespace boost { -namespace archive { - -////////////////////////////////////////////////////////////////////// -// implementation of basic_text_oprimitive overrides for the combination -// of template parameters used to create a text_oprimitive - -template -BOOST_ARCHIVE_DECL void -text_oarchive_impl::save(const char * s) -{ - const std::size_t len = std::ostream::traits_type::length(s); - *this->This() << len; - this->This()->newtoken(); - os << s; -} - -template -BOOST_ARCHIVE_DECL void -text_oarchive_impl::save(const std::string &s) -{ - const std::size_t size = s.size(); - *this->This() << size; - this->This()->newtoken(); - os << s; -} - -#ifndef BOOST_NO_CWCHAR -#ifndef BOOST_NO_INTRINSIC_WCHAR_T -template -BOOST_ARCHIVE_DECL void -text_oarchive_impl::save(const wchar_t * ws) -{ - const std::size_t l = std::wcslen(ws); - * this->This() << l; - this->This()->newtoken(); - os.write((const char *)ws, l * sizeof(wchar_t)/sizeof(char)); -} -#endif - -#ifndef BOOST_NO_STD_WSTRING -template -BOOST_ARCHIVE_DECL void -text_oarchive_impl::save(const std::wstring &ws) -{ - const std::size_t l = ws.size(); - * this->This() << l; - this->This()->newtoken(); - os.write((const char *)(ws.data()), l * sizeof(wchar_t)/sizeof(char)); -} -#endif -#endif // BOOST_NO_CWCHAR - -template -BOOST_ARCHIVE_DECL -text_oarchive_impl::text_oarchive_impl( - std::ostream & os, - unsigned int flags -) : - basic_text_oprimitive( - os, - 0 != (flags & no_codecvt) - ), - basic_text_oarchive(flags) -{ - if(0 == (flags & no_header)) - #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) - this->init(); - #else - this->basic_text_oarchive::init(); - #endif -} - -template -BOOST_ARCHIVE_DECL void -text_oarchive_impl::save_binary(const void *address, std::size_t count){ - put('\n'); - this->end_preamble(); - #if ! defined(__MWERKS__) - this->basic_text_oprimitive::save_binary( - #else - this->basic_text_oprimitive::save_binary( - #endif - address, - count - ); - this->delimiter = this->eol; -} - -} // namespace archive -} // namespace boost - diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/text_wiarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_wiarchive_impl.ipp deleted file mode 100644 index e85625ac326..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/text_wiarchive_impl.ipp +++ /dev/null @@ -1,118 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// text_text_wiarchive_impl.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // size_t, NULL - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include // fixup for RogueWave - -#ifndef BOOST_NO_STD_WSTREAMBUF -#include - -namespace boost { -namespace archive { - -////////////////////////////////////////////////////////////////////// -// implementation of wiprimtives functions -// -template -BOOST_WARCHIVE_DECL void -text_wiarchive_impl::load(char *s) -{ - std::size_t size; - * this->This() >> size; - // skip separating space - is.get(); - while(size-- > 0){ - *s++ = is.narrow(is.get(), '\0'); - } - *s = '\0'; -} - -template -BOOST_WARCHIVE_DECL void -text_wiarchive_impl::load(std::string &s) -{ - std::size_t size; - * this->This() >> size; - // skip separating space - is.get(); - #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) - if(NULL != s.data()) - #endif - s.resize(0); - s.reserve(size); - while(size-- > 0){ - char x = is.narrow(is.get(), '\0'); - s += x; - } -} - -#ifndef BOOST_NO_INTRINSIC_WCHAR_T -template -BOOST_WARCHIVE_DECL void -text_wiarchive_impl::load(wchar_t *s) -{ - std::size_t size; - * this->This() >> size; - // skip separating space - is.get(); - // Works on all tested platforms - is.read(s, size); - s[size] = L'\0'; -} -#endif - -#ifndef BOOST_NO_STD_WSTRING -template -BOOST_WARCHIVE_DECL void -text_wiarchive_impl::load(std::wstring &ws) -{ - std::size_t size; - * this->This() >> size; - // skip separating space - is.get(); - // borland complains about resize - // borland de-allocator fixup - #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) - if(NULL != ws.data()) - #endif - ws.resize(size); - // note breaking a rule here - is this a problem on some platform - is.read(const_cast(ws.data()), size); -} -#endif - -template -BOOST_WARCHIVE_DECL -text_wiarchive_impl::text_wiarchive_impl( - std::wistream & is, - unsigned int flags -) : - basic_text_iprimitive( - is, - 0 != (flags & no_codecvt) - ), - basic_text_iarchive(flags) -{ - if(0 == (flags & no_header)) - basic_text_iarchive::init(); -} - -} // archive -} // boost - -#endif // BOOST_NO_STD_WSTREAMBUF diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/text_woarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/text_woarchive_impl.ipp deleted file mode 100644 index 2b6d427cd3a..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/text_woarchive_impl.ipp +++ /dev/null @@ -1,85 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// text_woarchive_impl.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifndef BOOST_NO_STD_WSTREAMBUF - -#include -#include // size_t -#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__) -namespace std{ - using ::strlen; - using ::size_t; -} // namespace std -#endif - -#include - -#include - -namespace boost { -namespace archive { - -////////////////////////////////////////////////////////////////////// -// implementation of woarchive functions -// -template -BOOST_WARCHIVE_DECL void -text_woarchive_impl::save(const char *s) -{ - // note: superfluous local variable fixes borland warning - const std::size_t size = std::strlen(s); - * this->This() << size; - this->This()->newtoken(); - while(*s != '\0') - os.put(os.widen(*s++)); -} - -template -BOOST_WARCHIVE_DECL void -text_woarchive_impl::save(const std::string &s) -{ - const std::size_t size = s.size(); - * this->This() << size; - this->This()->newtoken(); - const char * cptr = s.data(); - for(std::size_t i = size; i-- > 0;) - os.put(os.widen(*cptr++)); -} - -#ifndef BOOST_NO_INTRINSIC_WCHAR_T -template -BOOST_WARCHIVE_DECL void -text_woarchive_impl::save(const wchar_t *ws) -{ - const std::size_t size = std::wostream::traits_type::length(ws); - * this->This() << size; - this->This()->newtoken(); - os.write(ws, size); -} -#endif - -#ifndef BOOST_NO_STD_WSTRING -template -BOOST_WARCHIVE_DECL void -text_woarchive_impl::save(const std::wstring &ws) -{ - const std::size_t size = ws.length(); - * this->This() << size; - this->This()->newtoken(); - os.write(ws.data(), size); -} -#endif - -} // namespace archive -} // namespace boost - -#endif - diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_iarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_iarchive_impl.ipp deleted file mode 100644 index efc32e01632..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_iarchive_impl.ipp +++ /dev/null @@ -1,199 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// xml_iarchive_impl.cpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include // memcpy -#include // NULL -#include - -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::memcpy; -} // namespace std -#endif - -#ifndef BOOST_NO_CWCHAR -#include // mbstate_t and mbrtowc -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::mbstate_t; - using ::mbrtowc; - } // namespace std -#endif -#endif // BOOST_NO_CWCHAR - -#include // RogueWave and Dinkumware -#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) -#include -#endif - -#include - -#include -#include -#include -#include - -#include "basic_xml_grammar.hpp" - -namespace boost { -namespace archive { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// implemenations of functions specific to char archives - -// wide char stuff used by char archives - -#ifndef BOOST_NO_CWCHAR -#ifndef BOOST_NO_STD_WSTRING -template -BOOST_ARCHIVE_DECL void -xml_iarchive_impl::load(std::wstring &ws){ - std::string s; - bool result = gimpl->parse_string(is, s); - if(! result) - boost::serialization::throw_exception( - xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) - ); - - #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) - if(NULL != ws.data()) - #endif - ws.resize(0); - std::mbstate_t mbs = std::mbstate_t(); - const char * start = s.data(); - const char * end = start + s.size(); - while(start < end){ - wchar_t wc; - std::size_t count = std::mbrtowc(&wc, start, end - start, &mbs); - if(count == static_cast(-1)) - boost::serialization::throw_exception( - iterators::dataflow_exception( - iterators::dataflow_exception::invalid_conversion - ) - ); - if(count == static_cast(-2)) - continue; - start += count; - ws += wc; - } -} -#endif // BOOST_NO_STD_WSTRING - -#ifndef BOOST_NO_INTRINSIC_WCHAR_T -template -BOOST_ARCHIVE_DECL void -xml_iarchive_impl::load(wchar_t * ws){ - std::string s; - bool result = gimpl->parse_string(is, s); - if(! result) - boost::serialization::throw_exception( - xml_archive_exception( - xml_archive_exception::xml_archive_parsing_error - ) - ); - - std::mbstate_t mbs = std::mbstate_t(); - const char * start = s.data(); - const char * end = start + s.size(); - while(start < end){ - wchar_t wc; - std::size_t length = std::mbrtowc(&wc, start, end - start, &mbs); - if(static_cast(-1) == length) - boost::serialization::throw_exception( - iterators::dataflow_exception( - iterators::dataflow_exception::invalid_conversion - ) - ); - if(static_cast(-2) == length) - continue; - - start += length; - *ws++ = wc; - } - *ws = L'\0'; -} -#endif // BOOST_NO_INTRINSIC_WCHAR_T - -#endif // BOOST_NO_CWCHAR - -template -BOOST_ARCHIVE_DECL void -xml_iarchive_impl::load(std::string &s){ - bool result = gimpl->parse_string(is, s); - if(! result) - boost::serialization::throw_exception( - xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) - ); -} - -template -BOOST_ARCHIVE_DECL void -xml_iarchive_impl::load(char * s){ - std::string tstring; - bool result = gimpl->parse_string(is, tstring); - if(! result) - boost::serialization::throw_exception( - xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) - ); - std::memcpy(s, tstring.data(), tstring.size()); - s[tstring.size()] = 0; -} - -template -BOOST_ARCHIVE_DECL void -xml_iarchive_impl::load_override(class_name_type & t){ - const std::string & s = gimpl->rv.class_name; - if(s.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1) - boost::serialization::throw_exception( - archive_exception(archive_exception::invalid_class_name) - ); - char * tptr = t; - std::memcpy(tptr, s.data(), s.size()); - tptr[s.size()] = '\0'; -} - -template -BOOST_ARCHIVE_DECL void -xml_iarchive_impl::init(){ - gimpl->init(is); - this->set_library_version( - library_version_type(gimpl->rv.version) - ); -} - -template -BOOST_ARCHIVE_DECL -xml_iarchive_impl::xml_iarchive_impl( - std::istream &is_, - unsigned int flags -) : - basic_text_iprimitive( - is_, - 0 != (flags & no_codecvt) - ), - basic_xml_iarchive(flags), - gimpl(new xml_grammar()) -{ - if(0 == (flags & no_header)) - init(); -} - -template -BOOST_ARCHIVE_DECL -xml_iarchive_impl::~xml_iarchive_impl(){ - if(std::uncaught_exception()) - return; - if(0 == (this->get_flags() & no_header)){ - gimpl->windup(is); - } -} -} // namespace archive -} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_oarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_oarchive_impl.ipp deleted file mode 100644 index 5ebd454e722..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_oarchive_impl.ipp +++ /dev/null @@ -1,142 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// xml_oarchive_impl.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include // std::copy -#include -#include - -#include // strlen -#include // msvc 6.0 needs this to suppress warnings -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::strlen; -} // namespace std -#endif - -#include -#include - -#ifndef BOOST_NO_CWCHAR -#include -#include -#endif - -namespace boost { -namespace archive { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// implemenations of functions specific to char archives - -// wide char stuff used by char archives -#ifndef BOOST_NO_CWCHAR -// copy chars to output escaping to xml and translating wide chars to mb chars -template -void save_iterator(std::ostream &os, InputIterator begin, InputIterator end){ - typedef boost::archive::iterators::mb_from_wchar< - boost::archive::iterators::xml_escape - > translator; - std::copy( - translator(begin), - translator(end), - boost::archive::iterators::ostream_iterator(os) - ); -} - -#ifndef BOOST_NO_STD_WSTRING -template -BOOST_ARCHIVE_DECL void -xml_oarchive_impl::save(const std::wstring & ws){ -// at least one library doesn't typedef value_type for strings -// so rather than using string directly make a pointer iterator out of it -// save_iterator(os, ws.data(), ws.data() + std::wcslen(ws.data())); - save_iterator(os, ws.data(), ws.data() + ws.size()); -} -#endif - -#ifndef BOOST_NO_INTRINSIC_WCHAR_T -template -BOOST_ARCHIVE_DECL void -xml_oarchive_impl::save(const wchar_t * ws){ - save_iterator(os, ws, ws + std::wcslen(ws)); -} -#endif - -#endif // BOOST_NO_CWCHAR - -template -BOOST_ARCHIVE_DECL void -xml_oarchive_impl::save(const std::string & s){ -// at least one library doesn't typedef value_type for strings -// so rather than using string directly make a pointer iterator out of it - typedef boost::archive::iterators::xml_escape< - const char * - > xml_escape_translator; - std::copy( - xml_escape_translator(s.data()), - xml_escape_translator(s.data()+ s.size()), - boost::archive::iterators::ostream_iterator(os) - ); -} - -template -BOOST_ARCHIVE_DECL void -xml_oarchive_impl::save(const char * s){ - typedef boost::archive::iterators::xml_escape< - const char * - > xml_escape_translator; - std::copy( - xml_escape_translator(s), - xml_escape_translator(s + std::strlen(s)), - boost::archive::iterators::ostream_iterator(os) - ); -} - -template -BOOST_ARCHIVE_DECL -xml_oarchive_impl::xml_oarchive_impl( - std::ostream & os_, - unsigned int flags -) : - basic_text_oprimitive( - os_, - 0 != (flags & no_codecvt) - ), - basic_xml_oarchive(flags) -{ - if(0 == (flags & no_header)) - this->init(); -} - -template -BOOST_ARCHIVE_DECL void -xml_oarchive_impl::save_binary(const void *address, std::size_t count){ - this->end_preamble(); - #if ! defined(__MWERKS__) - this->basic_text_oprimitive::save_binary( - #else - this->basic_text_oprimitive::save_binary( - #endif - address, - count - ); - this->indent_next = true; -} - -template -BOOST_ARCHIVE_DECL -xml_oarchive_impl::~xml_oarchive_impl(){ - if(std::uncaught_exception()) - return; - if(0 == (this->get_flags() & no_header)) - this->windup(); -} - -} // namespace archive -} // namespace boost diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_wiarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_wiarchive_impl.ipp deleted file mode 100644 index ee66c1263e6..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_wiarchive_impl.ipp +++ /dev/null @@ -1,189 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// xml_wiarchive_impl.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::memcpy; -} //std -#endif - -#include // msvc 6.0 needs this to suppress warnings -#ifndef BOOST_NO_STD_WSTREAMBUF - -#include -#include // std::copy -#include // uncaught exception -#include // Dinkumware and RogueWave -#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) -#include -#endif - -#include -#include -#include - -#include -#include - -#include -#include - -#include - -#include "basic_xml_grammar.hpp" - -namespace boost { -namespace archive { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// implemenations of functions specific to wide char archives - -namespace { // anonymous - -void copy_to_ptr(char * s, const std::wstring & ws){ - std::copy( - iterators::mb_from_wchar( - ws.begin() - ), - iterators::mb_from_wchar( - ws.end() - ), - s - ); - s[ws.size()] = 0; -} - -} // anonymous - -template -BOOST_WARCHIVE_DECL void -xml_wiarchive_impl::load(std::string & s){ - std::wstring ws; - bool result = gimpl->parse_string(is, ws); - if(! result) - boost::serialization::throw_exception( - xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) - ); - #if BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(20101)) - if(NULL != s.data()) - #endif - s.resize(0); - s.reserve(ws.size()); - std::copy( - iterators::mb_from_wchar( - ws.begin() - ), - iterators::mb_from_wchar( - ws.end() - ), - std::back_inserter(s) - ); -} - -#ifndef BOOST_NO_STD_WSTRING -template -BOOST_WARCHIVE_DECL void -xml_wiarchive_impl::load(std::wstring & ws){ - bool result = gimpl->parse_string(is, ws); - if(! result) - boost::serialization::throw_exception( - xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) - ); -} -#endif - -template -BOOST_WARCHIVE_DECL void -xml_wiarchive_impl::load(char * s){ - std::wstring ws; - bool result = gimpl->parse_string(is, ws); - if(! result) - boost::serialization::throw_exception( - xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) - ); - copy_to_ptr(s, ws); -} - -#ifndef BOOST_NO_INTRINSIC_WCHAR_T -template -BOOST_WARCHIVE_DECL void -xml_wiarchive_impl::load(wchar_t * ws){ - std::wstring twstring; - bool result = gimpl->parse_string(is, twstring); - if(! result) - boost::serialization::throw_exception( - xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) - ); - std::memcpy(ws, twstring.c_str(), twstring.size()); - ws[twstring.size()] = L'\0'; -} -#endif - -template -BOOST_WARCHIVE_DECL void -xml_wiarchive_impl::load_override(class_name_type & t){ - const std::wstring & ws = gimpl->rv.class_name; - if(ws.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1) - boost::serialization::throw_exception( - archive_exception(archive_exception::invalid_class_name) - ); - copy_to_ptr(t, ws); -} - -template -BOOST_WARCHIVE_DECL void -xml_wiarchive_impl::init(){ - gimpl->init(is); - this->set_library_version( - library_version_type(gimpl->rv.version) - ); -} - -template -BOOST_WARCHIVE_DECL -xml_wiarchive_impl::xml_wiarchive_impl( - std::wistream &is_, - unsigned int flags -) : - basic_text_iprimitive( - is_, - true // don't change the codecvt - use the one below - ), - basic_xml_iarchive(flags), - gimpl(new xml_wgrammar()) -{ - if(0 == (flags & no_codecvt)){ - std::locale l = std::locale( - is_.getloc(), - new boost::archive::detail::utf8_codecvt_facet - ); - // libstdc++ crashes without this - is_.sync(); - is_.imbue(l); - } - if(0 == (flags & no_header)) - init(); -} - -template -BOOST_WARCHIVE_DECL -xml_wiarchive_impl::~xml_wiarchive_impl(){ - if(std::uncaught_exception()) - return; - if(0 == (this->get_flags() & no_header)){ - gimpl->windup(is); - } -} - -} // namespace archive -} // namespace boost - -#endif // BOOST_NO_STD_WSTREAMBUF diff --git a/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_woarchive_impl.ipp b/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_woarchive_impl.ipp deleted file mode 100644 index 01b1a052d51..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/impl/xml_woarchive_impl.ipp +++ /dev/null @@ -1,171 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// xml_woarchive_impl.ipp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#ifndef BOOST_NO_STD_WSTREAMBUF - -#include -#include -#include // std::copy -#include -#include - -#include // strlen -#include // mbtowc -#ifndef BOOST_NO_CWCHAR -#include // wcslen -#endif - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::strlen; - #if ! defined(BOOST_NO_INTRINSIC_WCHAR_T) - using ::mbtowc; - using ::wcslen; - #endif -} // namespace std -#endif - -#include -#include - -#include - -#include -#include -#include -#include - -namespace boost { -namespace archive { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// implemenations of functions specific to wide char archives - -// copy chars to output escaping to xml and widening characters as we go -template -void save_iterator(std::wostream &os, InputIterator begin, InputIterator end){ - typedef iterators::wchar_from_mb< - iterators::xml_escape - > xmbtows; - std::copy( - xmbtows(begin), - xmbtows(end), - boost::archive::iterators::ostream_iterator(os) - ); -} - -template -BOOST_WARCHIVE_DECL void -xml_woarchive_impl::save(const std::string & s){ - // note: we don't use s.begin() and s.end() because dinkumware - // doesn't have string::value_type defined. So use a wrapper - // around these values to implement the definitions. - const char * begin = s.data(); - const char * end = begin + s.size(); - save_iterator(os, begin, end); -} - -#ifndef BOOST_NO_STD_WSTRING -template -BOOST_WARCHIVE_DECL void -xml_woarchive_impl::save(const std::wstring & ws){ -#if 0 - typedef iterators::xml_escape xmbtows; - std::copy( - xmbtows(ws.begin()), - xmbtows(ws.end()), - boost::archive::iterators::ostream_iterator(os) - ); -#endif - typedef iterators::xml_escape xmbtows; - std::copy( - xmbtows(ws.data()), - xmbtows(ws.data() + ws.size()), - boost::archive::iterators::ostream_iterator(os) - ); -} -#endif //BOOST_NO_STD_WSTRING - -template -BOOST_WARCHIVE_DECL void -xml_woarchive_impl::save(const char * s){ - save_iterator(os, s, s + std::strlen(s)); -} - -#ifndef BOOST_NO_INTRINSIC_WCHAR_T -template -BOOST_WARCHIVE_DECL void -xml_woarchive_impl::save(const wchar_t * ws){ - os << ws; - typedef iterators::xml_escape xmbtows; - std::copy( - xmbtows(ws), - xmbtows(ws + std::wcslen(ws)), - boost::archive::iterators::ostream_iterator(os) - ); -} -#endif - -template -BOOST_WARCHIVE_DECL -xml_woarchive_impl::xml_woarchive_impl( - std::wostream & os_, - unsigned int flags -) : - basic_text_oprimitive( - os_, - true // don't change the codecvt - use the one below - ), - basic_xml_oarchive(flags) -{ - if(0 == (flags & no_codecvt)){ - std::locale l = std::locale( - os_.getloc(), - new boost::archive::detail::utf8_codecvt_facet - ); - os_.flush(); - os_.imbue(l); - } - if(0 == (flags & no_header)) - this->init(); -} - -template -BOOST_WARCHIVE_DECL -xml_woarchive_impl::~xml_woarchive_impl(){ - if(std::uncaught_exception()) - return; - if(0 == (this->get_flags() & no_header)){ - save(L"\n"); - } -} - -template -BOOST_WARCHIVE_DECL void -xml_woarchive_impl::save_binary( - const void *address, - std::size_t count -){ - this->end_preamble(); - #if ! defined(__MWERKS__) - this->basic_text_oprimitive::save_binary( - #else - this->basic_text_oprimitive::save_binary( - #endif - address, - count - ); - this->indent_next = true; -} - -} // namespace archive -} // namespace boost - -#endif //BOOST_NO_STD_WSTREAMBUF diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_exception.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_exception.hpp deleted file mode 100644 index 8f9208b60ea..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_exception.hpp +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef BOOST_ARCHIVE_ITERATORS_BASE64_EXCEPTION_HPP -#define BOOST_ARCHIVE_ITERATORS_BASE64_EXCEPTION_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// base64_exception.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifndef BOOST_NO_EXCEPTIONS -#include - -#include - -namespace boost { -namespace archive { -namespace iterators { - -////////////////////////////////////////////////////////////////////// -// exceptions thrown by base64s -// -class base64_exception : public std::exception -{ -public: - typedef enum { - invalid_code, // attempt to encode a value > 6 bits - invalid_character, // decode a value not in base64 char set - other_exception - } exception_code; - exception_code code; - - base64_exception(exception_code c = other_exception) : code(c) - {} - - virtual const char *what( ) const throw( ) - { - const char *msg = "unknown exception code"; - switch(code){ - case invalid_code: - msg = "attempt to encode a value > 6 bits"; - break; - case invalid_character: - msg = "attempt to decode a value not in base64 char set"; - break; - default: - BOOST_ASSERT(false); - break; - } - return msg; - } -}; - -} // namespace iterators -} // namespace archive -} // namespace boost - -#endif //BOOST_NO_EXCEPTIONS -#endif //BOOST_ARCHIVE_ITERATORS_ARCHIVE_EXCEPTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_from_binary.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_from_binary.hpp deleted file mode 100644 index ee849944397..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/iterators/base64_from_binary.hpp +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef BOOST_ARCHIVE_ITERATORS_BASE64_FROM_BINARY_HPP -#define BOOST_ARCHIVE_ITERATORS_BASE64_FROM_BINARY_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// base64_from_binary.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include // size_t -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include -#include - -namespace boost { -namespace archive { -namespace iterators { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// convert binary integers to base64 characters - -namespace detail { - -template -struct from_6_bit { - typedef CharType result_type; - CharType operator()(CharType t) const{ - static const char * lookup_table = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789" - "+/"; - BOOST_ASSERT(t < 64); - return lookup_table[static_cast(t)]; - } -}; - -} // namespace detail - -// note: what we would like to do is -// template -// typedef transform_iterator< -// from_6_bit, -// transform_width -// > base64_from_binary; -// but C++ won't accept this. Rather than using a "type generator" and -// using a different syntax, make a derivation which should be equivalent. -// -// Another issue addressed here is that the transform_iterator doesn't have -// a templated constructor. This makes it incompatible with the dataflow -// ideal. This is also addressed here. - -//template -template< - class Base, - class CharType = typename boost::iterator_value::type -> -class base64_from_binary : - public transform_iterator< - detail::from_6_bit, - Base - > -{ - friend class boost::iterator_core_access; - typedef transform_iterator< - typename detail::from_6_bit, - Base - > super_t; - -public: - // make composible buy using templated constructor - template - base64_from_binary(T start) : - super_t( - Base(static_cast< T >(start)), - detail::from_6_bit() - ) - {} - // intel 7.1 doesn't like default copy constructor - base64_from_binary(const base64_from_binary & rhs) : - super_t( - Base(rhs.base_reference()), - detail::from_6_bit() - ) - {} -// base64_from_binary(){}; -}; - -} // namespace iterators -} // namespace archive -} // namespace boost - -#endif // BOOST_ARCHIVE_ITERATORS_BASE64_FROM_BINARY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/binary_from_base64.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/binary_from_base64.hpp deleted file mode 100644 index 89b8f889da3..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/iterators/binary_from_base64.hpp +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP -#define BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// binary_from_base64.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include - -#include -#include - -namespace boost { -namespace archive { -namespace iterators { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// convert base64 characters to binary data - -namespace detail { - -template -struct to_6_bit { - typedef CharType result_type; - CharType operator()(CharType t) const{ - static const signed char lookup_table[] = { - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, - 52,53,54,55,56,57,58,59,60,61,-1,-1,-1, 0,-1,-1, // render '=' as 0 - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, - 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, - -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, - 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1 - }; - // metrowerks trips this assertion - how come? - #if ! defined(__MWERKS__) - BOOST_STATIC_ASSERT(128 == sizeof(lookup_table)); - #endif - signed char value = -1; - if((unsigned)t <= 127) - value = lookup_table[(unsigned)t]; - if(-1 == value) - boost::serialization::throw_exception( - dataflow_exception(dataflow_exception::invalid_base64_character) - ); - return value; - } -}; - -} // namespace detail - -// note: what we would like to do is -// template -// typedef transform_iterator< -// from_6_bit, -// transform_width -// > base64_from_binary; -// but C++ won't accept this. Rather than using a "type generator" and -// using a different syntax, make a derivation which should be equivalent. -// -// Another issue addressed here is that the transform_iterator doesn't have -// a templated constructor. This makes it incompatible with the dataflow -// ideal. This is also addressed here. - -template< - class Base, - class CharType = typename boost::iterator_value::type -> -class binary_from_base64 : public - transform_iterator< - detail::to_6_bit, - Base - > -{ - friend class boost::iterator_core_access; - typedef transform_iterator< - detail::to_6_bit, - Base - > super_t; -public: - // make composible buy using templated constructor - template - binary_from_base64(T start) : - super_t( - Base(static_cast< T >(start)), - detail::to_6_bit() - ) - {} - // intel 7.1 doesn't like default copy constructor - binary_from_base64(const binary_from_base64 & rhs) : - super_t( - Base(rhs.base_reference()), - detail::to_6_bit() - ) - {} -// binary_from_base64(){}; -}; - -} // namespace iterators -} // namespace archive -} // namespace boost - -#endif // BOOST_ARCHIVE_ITERATORS_BINARY_FROM_BASE64_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow.hpp deleted file mode 100644 index 07733d5fd62..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow.hpp +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef BOOST_ARCHIVE_ITERATORS_DATAFLOW_HPP -#define BOOST_ARCHIVE_ITERATORS_DATAFLOW_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// dataflow.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace archive { -namespace iterators { - -// poor man's tri-state -struct tri_state { - enum state_enum { - is_false = false, - is_true = true, - is_indeterminant - } m_state; - // convert to bool - operator bool (){ - BOOST_ASSERT(is_indeterminant != m_state); - return is_true == m_state ? true : false; - } - // assign from bool - tri_state & operator=(bool rhs) { - m_state = rhs ? is_true : is_false; - return *this; - } - tri_state(bool rhs) : - m_state(rhs ? is_true : is_false) - {} - tri_state(state_enum state) : - m_state(state) - {} - bool operator==(const tri_state & rhs) const { - return m_state == rhs.m_state; - } - bool operator!=(const tri_state & rhs) const { - return m_state != rhs.m_state; - } -}; - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// implement functions common to dataflow iterators -template -class dataflow { - bool m_eoi; -protected: - // test for iterator equality - tri_state equal(const Derived & rhs) const { - if(m_eoi && rhs.m_eoi) - return true; - if(m_eoi || rhs.m_eoi) - return false; - return tri_state(tri_state::is_indeterminant); - } - void eoi(bool tf){ - m_eoi = tf; - } - bool eoi() const { - return m_eoi; - } -public: - dataflow(bool tf) : - m_eoi(tf) - {} - dataflow() : // used for iterator end - m_eoi(true) - {} -}; - -} // namespace iterators -} // namespace archive -} // namespace boost - -#endif // BOOST_ARCHIVE_ITERATORS_DATAFLOW_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow_exception.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow_exception.hpp deleted file mode 100644 index e3e18605b38..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/iterators/dataflow_exception.hpp +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef BOOST_ARCHIVE_ITERATORS_DATAFLOW_EXCEPTION_HPP -#define BOOST_ARCHIVE_ITERATORS_DATAFLOW_EXCEPTION_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// dataflow_exception.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifndef BOOST_NO_EXCEPTIONS -#include -#endif //BOOST_NO_EXCEPTIONS - -#include - -namespace boost { -namespace archive { -namespace iterators { - -////////////////////////////////////////////////////////////////////// -// exceptions thrown by dataflows -// -class dataflow_exception : public std::exception -{ -public: - typedef enum { - invalid_6_bitcode, - invalid_base64_character, - invalid_xml_escape_sequence, - comparison_not_permitted, - invalid_conversion, - other_exception - } exception_code; - exception_code code; - - dataflow_exception(exception_code c = other_exception) : code(c) - {} - - virtual const char *what( ) const throw( ) - { - const char *msg = "unknown exception code"; - switch(code){ - case invalid_6_bitcode: - msg = "attempt to encode a value > 6 bits"; - break; - case invalid_base64_character: - msg = "attempt to decode a value not in base64 char set"; - break; - case invalid_xml_escape_sequence: - msg = "invalid xml escape_sequence"; - break; - case comparison_not_permitted: - msg = "cannot invoke iterator comparison now"; - break; - case invalid_conversion: - msg = "invalid multbyte/wide char conversion"; - break; - default: - BOOST_ASSERT(false); - break; - } - return msg; - } -}; - -} // namespace iterators -} // namespace archive -} // namespace boost - -#endif //BOOST_ARCHIVE_ITERATORS_DATAFLOW_EXCEPTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/escape.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/escape.hpp deleted file mode 100644 index 103b31e0fef..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/iterators/escape.hpp +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef BOOST_ARCHIVE_ITERATORS_ESCAPE_HPP -#define BOOST_ARCHIVE_ITERATORS_ESCAPE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// escape.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include // NULL - -#include -#include - -namespace boost { -namespace archive { -namespace iterators { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// insert escapes into text - -template -class escape : - public boost::iterator_adaptor< - Derived, - Base, - typename boost::iterator_value::type, - single_pass_traversal_tag, - typename boost::iterator_value::type - > -{ - typedef typename boost::iterator_value::type base_value_type; - typedef typename boost::iterator_reference::type reference_type; - friend class boost::iterator_core_access; - - typedef typename boost::iterator_adaptor< - Derived, - Base, - base_value_type, - single_pass_traversal_tag, - base_value_type - > super_t; - - typedef escape this_t; - - void dereference_impl() { - m_current_value = static_cast(this)->fill(m_bnext, m_bend); - m_full = true; - } - - //Access the value referred to - reference_type dereference() const { - if(!m_full) - const_cast(this)->dereference_impl(); - return m_current_value; - } - - bool equal(const this_t & rhs) const { - if(m_full){ - if(! rhs.m_full) - const_cast(& rhs)->dereference_impl(); - } - else{ - if(rhs.m_full) - const_cast(this)->dereference_impl(); - } - if(m_bnext != rhs.m_bnext) - return false; - if(this->base_reference() != rhs.base_reference()) - return false; - return true; - } - - void increment(){ - if(++m_bnext < m_bend){ - m_current_value = *m_bnext; - return; - } - ++(this->base_reference()); - m_bnext = NULL; - m_bend = NULL; - m_full = false; - } - - // buffer to handle pending characters - const base_value_type *m_bnext; - const base_value_type *m_bend; - bool m_full; - base_value_type m_current_value; -public: - escape(Base base) : - super_t(base), - m_bnext(NULL), - m_bend(NULL), - m_full(false), - m_current_value(0) - { - } -}; - -} // namespace iterators -} // namespace archive -} // namespace boost - -#endif // BOOST_ARCHIVE_ITERATORS_ESCAPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/insert_linebreaks.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/insert_linebreaks.hpp deleted file mode 100644 index 2504b030db1..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/iterators/insert_linebreaks.hpp +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef BOOST_ARCHIVE_ITERATORS_INSERT_LINEBREAKS_HPP -#define BOOST_ARCHIVE_ITERATORS_INSERT_LINEBREAKS_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// insert_linebreaks.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ using ::memcpy; } -#endif - -#include -#include - -namespace boost { -namespace archive { -namespace iterators { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// insert line break every N characters -template< - class Base, - int N, - class CharType = typename boost::iterator_value::type -> -class insert_linebreaks : - public iterator_adaptor< - insert_linebreaks, - Base, - CharType, - single_pass_traversal_tag, - CharType - > -{ -private: - friend class boost::iterator_core_access; - typedef iterator_adaptor< - insert_linebreaks, - Base, - CharType, - single_pass_traversal_tag, - CharType - > super_t; - - bool equal(const insert_linebreaks & rhs) const { - return -// m_count == rhs.m_count -// && base_reference() == rhs.base_reference() - this->base_reference() == rhs.base_reference() - ; - } - - void increment() { - if(m_count == N){ - m_count = 0; - return; - } - ++m_count; - ++(this->base_reference()); - } - CharType dereference() const { - if(m_count == N) - return '\n'; - return * (this->base_reference()); - } - unsigned int m_count; -public: - // make composible buy using templated constructor - template - insert_linebreaks(T start) : - super_t(Base(static_cast< T >(start))), - m_count(0) - {} - // intel 7.1 doesn't like default copy constructor - insert_linebreaks(const insert_linebreaks & rhs) : - super_t(rhs.base_reference()), - m_count(rhs.m_count) - {} -}; - -} // namespace iterators -} // namespace archive -} // namespace boost - -#endif // BOOST_ARCHIVE_ITERATORS_INSERT_LINEBREAKS_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/istream_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/istream_iterator.hpp deleted file mode 100644 index a187f605e69..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/iterators/istream_iterator.hpp +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef BOOST_ARCHIVE_ITERATORS_ISTREAM_ITERATOR_HPP -#define BOOST_ARCHIVE_ITERATORS_ISTREAM_ITERATOR_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// istream_iterator.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// note: this is a custom version of the standard istream_iterator. -// This is necessary as the standard version doesn't work as expected -// for wchar_t based streams on systems for which wchar_t not a true -// type but rather a synonym for some integer type. - -#include // NULL -#include -#include - -namespace boost { -namespace archive { -namespace iterators { - -// given a type, make an input iterator based on a pointer to that type -template -class istream_iterator : - public boost::iterator_facade< - istream_iterator, - Elem, - std::input_iterator_tag, - Elem - > -{ - friend class boost::iterator_core_access; - typedef istream_iterator this_t ; - typedef typename boost::iterator_facade< - istream_iterator, - Elem, - std::input_iterator_tag, - Elem - > super_t; - typedef typename std::basic_istream istream_type; - - bool equal(const this_t & rhs) const { - // note: only works for comparison against end of stream - return m_istream == rhs.m_istream; - } - - //Access the value referred to - Elem dereference() const { - return static_cast(m_istream->peek()); - } - - void increment(){ - if(NULL != m_istream){ - m_istream->ignore(1); - } - } - - istream_type *m_istream; - Elem m_current_value; -public: - istream_iterator(istream_type & is) : - m_istream(& is) - { - //increment(); - } - - istream_iterator() : - m_istream(NULL), - m_current_value(NULL) - {} - - istream_iterator(const istream_iterator & rhs) : - m_istream(rhs.m_istream), - m_current_value(rhs.m_current_value) - {} -}; - -} // namespace iterators -} // namespace archive -} // namespace boost - -#endif // BOOST_ARCHIVE_ITERATORS_ISTREAM_ITERATOR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/mb_from_wchar.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/mb_from_wchar.hpp deleted file mode 100644 index 05df71c258e..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/iterators/mb_from_wchar.hpp +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP -#define BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// mb_from_wchar.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include // size_t -#ifndef BOOST_NO_CWCHAR -#include // mbstate_t -#endif -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::mbstate_t; -} // namespace std -#endif - -#include -#include - -namespace boost { -namespace archive { -namespace iterators { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// class used by text archives to translate wide strings and to char -// strings of the currently selected locale -template // the input iterator -class mb_from_wchar - : public boost::iterator_adaptor< - mb_from_wchar, - Base, - wchar_t, - single_pass_traversal_tag, - char - > -{ - friend class boost::iterator_core_access; - - typedef typename boost::iterator_adaptor< - mb_from_wchar, - Base, - wchar_t, - single_pass_traversal_tag, - char - > super_t; - - typedef mb_from_wchar this_t; - - char dereference_impl() { - if(! m_full){ - fill(); - m_full = true; - } - return m_buffer[m_bnext]; - } - - char dereference() const { - return (const_cast(this))->dereference_impl(); - } - // test for iterator equality - bool equal(const mb_from_wchar & rhs) const { - // once the value is filled, the base_reference has been incremented - // so don't permit comparison anymore. - return - 0 == m_bend - && 0 == m_bnext - && this->base_reference() == rhs.base_reference() - ; - } - - void fill(){ - wchar_t value = * this->base_reference(); - const wchar_t *wend; - char *bend; - std::codecvt_base::result r = m_codecvt_facet.out( - m_mbs, - & value, & value + 1, wend, - m_buffer, m_buffer + sizeof(m_buffer), bend - ); - BOOST_ASSERT(std::codecvt_base::ok == r); - m_bnext = 0; - m_bend = bend - m_buffer; - } - - void increment(){ - if(++m_bnext < m_bend) - return; - m_bend = - m_bnext = 0; - ++(this->base_reference()); - m_full = false; - } - - boost::archive::detail::utf8_codecvt_facet m_codecvt_facet; - std::mbstate_t m_mbs; - // buffer to handle pending characters - char m_buffer[9 /* MB_CUR_MAX */]; - std::size_t m_bend; - std::size_t m_bnext; - bool m_full; - -public: - // make composible buy using templated constructor - template - mb_from_wchar(T start) : - super_t(Base(static_cast< T >(start))), - m_mbs(std::mbstate_t()), - m_bend(0), - m_bnext(0), - m_full(false) - {} - // intel 7.1 doesn't like default copy constructor - mb_from_wchar(const mb_from_wchar & rhs) : - super_t(rhs.base_reference()), - m_bend(rhs.m_bend), - m_bnext(rhs.m_bnext), - m_full(rhs.m_full) - {} -}; - -} // namespace iterators -} // namespace archive -} // namespace boost - -#endif // BOOST_ARCHIVE_ITERATORS_MB_FROM_WCHAR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/ostream_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/ostream_iterator.hpp deleted file mode 100644 index 49a9b99034b..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/iterators/ostream_iterator.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef BOOST_ARCHIVE_ITERATORS_OSTREAM_ITERATOR_HPP -#define BOOST_ARCHIVE_ITERATORS_OSTREAM_ITERATOR_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// ostream_iterator.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// note: this is a custom version of the standard ostream_iterator. -// This is necessary as the standard version doesn't work as expected -// for wchar_t based streams on systems for which wchar_t not a true -// type but rather a synonym for some integer type. - -#include -#include - -namespace boost { -namespace archive { -namespace iterators { - -// given a type, make an input iterator based on a pointer to that type -template -class ostream_iterator : - public boost::iterator_facade< - ostream_iterator, - Elem, - std::output_iterator_tag, - ostream_iterator & - > -{ - friend class boost::iterator_core_access; - typedef ostream_iterator this_t ; - typedef Elem char_type; - typedef std::basic_ostream ostream_type; - - //emulate the behavior of std::ostream - ostream_iterator & dereference() const { - return const_cast(*this); - } - bool equal(const this_t & rhs) const { - return m_ostream == rhs.m_ostream; - } - void increment(){} -protected: - ostream_type *m_ostream; - void put_val(char_type e){ - if(NULL != m_ostream){ - m_ostream->put(e); - if(! m_ostream->good()) - m_ostream = NULL; - } - } -public: - this_t & operator=(char_type c){ - put_val(c); - return *this; - } - ostream_iterator(ostream_type & os) : - m_ostream (& os) - {} - ostream_iterator() : - m_ostream (NULL) - {} - ostream_iterator(const ostream_iterator & rhs) : - m_ostream (rhs.m_ostream) - {} -}; - -} // namespace iterators -} // namespace archive -} // namespace boost - -#endif // BOOST_ARCHIVE_ITERATORS_OSTREAM_ITERATOR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/remove_whitespace.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/remove_whitespace.hpp deleted file mode 100644 index c3580ab258a..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/iterators/remove_whitespace.hpp +++ /dev/null @@ -1,167 +0,0 @@ -#ifndef BOOST_ARCHIVE_ITERATORS_REMOVE_WHITESPACE_HPP -#define BOOST_ARCHIVE_ITERATORS_REMOVE_WHITESPACE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// remove_whitespace.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include -#include - -// here is the default standard implementation of the functor used -// by the filter iterator to remove spaces. Unfortunately usage -// of this implementation in combination with spirit trips a bug -// VC 6.5. The only way I can find to work around it is to -// implement a special non-standard version for this platform - -#ifndef BOOST_NO_CWCTYPE -#include // iswspace -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ using ::iswspace; } -#endif -#endif - -#include // isspace -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ using ::isspace; } -#endif - -#if defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER) -// this is required for the RW STL on Linux and Tru64. -#undef isspace -#undef iswspace -#endif - -namespace { // anonymous - -template -struct remove_whitespace_predicate; - -template<> -struct remove_whitespace_predicate -{ - bool operator()(unsigned char t){ - return ! std::isspace(t); - } -}; - -#ifndef BOOST_NO_CWCHAR -template<> -struct remove_whitespace_predicate -{ - bool operator()(wchar_t t){ - return ! std::iswspace(t); - } -}; -#endif - -} // namespace anonymous - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// convert base64 file data (including whitespace and padding) to binary - -namespace boost { -namespace archive { -namespace iterators { - -// custom version of filter iterator which doesn't look ahead further than -// necessary - -template -class filter_iterator - : public boost::iterator_adaptor< - filter_iterator, - Base, - use_default, - single_pass_traversal_tag - > -{ - friend class boost::iterator_core_access; - typedef typename boost::iterator_adaptor< - filter_iterator, - Base, - use_default, - single_pass_traversal_tag - > super_t; - typedef filter_iterator this_t; - typedef typename super_t::reference reference_type; - - reference_type dereference_impl(){ - if(! m_full){ - while(! m_predicate(* this->base_reference())) - ++(this->base_reference()); - m_full = true; - } - return * this->base_reference(); - } - - reference_type dereference() const { - return const_cast(this)->dereference_impl(); - } - - Predicate m_predicate; - bool m_full; -public: - // note: this function is public only because comeau compiler complained - // I don't know if this is because the compiler is wrong or what - void increment(){ - m_full = false; - ++(this->base_reference()); - } - filter_iterator(Base start) : - super_t(start), - m_full(false) - {} - filter_iterator(){} -}; - -template -class remove_whitespace : - public filter_iterator< - remove_whitespace_predicate< - typename boost::iterator_value::type - //typename Base::value_type - >, - Base - > -{ - friend class boost::iterator_core_access; - typedef filter_iterator< - remove_whitespace_predicate< - typename boost::iterator_value::type - //typename Base::value_type - >, - Base - > super_t; -public: -// remove_whitespace(){} // why is this needed? - // make composible buy using templated constructor - template - remove_whitespace(T start) : - super_t(Base(static_cast< T >(start))) - {} - // intel 7.1 doesn't like default copy constructor - remove_whitespace(const remove_whitespace & rhs) : - super_t(rhs.base_reference()) - {} -}; - -} // namespace iterators -} // namespace archive -} // namespace boost - -#endif // BOOST_ARCHIVE_ITERATORS_REMOVE_WHITESPACE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/transform_width.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/transform_width.hpp deleted file mode 100644 index 09c050a9274..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/iterators/transform_width.hpp +++ /dev/null @@ -1,177 +0,0 @@ -#ifndef BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP -#define BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// transform_width.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// iterator which takes elements of x bits and returns elements of y bits. -// used to change streams of 8 bit characters into streams of 6 bit characters. -// and vice-versa for implementing base64 encodeing/decoding. Be very careful -// when using and end iterator. end is only reliable detected when the input -// stream length is some common multiple of x and y. E.G. Base64 6 bit -// character and 8 bit bytes. Lowest common multiple is 24 => 4 6 bit characters -// or 3 8 bit characters - -#include -#include - -#include // std::min - -namespace boost { -namespace archive { -namespace iterators { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// class used by text archives to translate char strings to wchar_t -// strings of the currently selected locale -template< - class Base, - int BitsOut, - int BitsIn, - class CharType = typename boost::iterator_value::type // output character -> -class transform_width : - public boost::iterator_adaptor< - transform_width, - Base, - CharType, - single_pass_traversal_tag, - CharType - > -{ - friend class boost::iterator_core_access; - typedef typename boost::iterator_adaptor< - transform_width, - Base, - CharType, - single_pass_traversal_tag, - CharType - > super_t; - - typedef transform_width this_t; - typedef typename iterator_value::type base_value_type; - - void fill(); - - CharType dereference() const { - if(!m_buffer_out_full) - const_cast(this)->fill(); - return m_buffer_out; - } - - bool equal_impl(const this_t & rhs){ - if(BitsIn < BitsOut) // discard any left over bits - return this->base_reference() == rhs.base_reference(); - else{ - // BitsIn > BitsOut // zero fill - if(this->base_reference() == rhs.base_reference()){ - m_end_of_sequence = true; - return 0 == m_remaining_bits; - } - return false; - } - } - - // standard iterator interface - bool equal(const this_t & rhs) const { - return const_cast(this)->equal_impl(rhs); - } - - void increment(){ - m_buffer_out_full = false; - } - - bool m_buffer_out_full; - CharType m_buffer_out; - - // last read element from input - base_value_type m_buffer_in; - - // number of bits to left in the input buffer. - unsigned int m_remaining_bits; - - // flag to indicate we've reached end of data. - bool m_end_of_sequence; - -public: - // make composible buy using templated constructor - template - transform_width(T start) : - super_t(Base(static_cast< T >(start))), - m_buffer_out_full(false), - m_buffer_out(0), - // To disable GCC warning, but not truly necessary - //(m_buffer_in will be initialized later before being - //used because m_remaining_bits == 0) - m_buffer_in(0), - m_remaining_bits(0), - m_end_of_sequence(false) - {} - // intel 7.1 doesn't like default copy constructor - transform_width(const transform_width & rhs) : - super_t(rhs.base_reference()), - m_buffer_out_full(rhs.m_buffer_out_full), - m_buffer_out(rhs.m_buffer_out), - m_buffer_in(rhs.m_buffer_in), - m_remaining_bits(rhs.m_remaining_bits), - m_end_of_sequence(false) - {} -}; - -template< - class Base, - int BitsOut, - int BitsIn, - class CharType -> -void transform_width::fill() { - unsigned int missing_bits = BitsOut; - m_buffer_out = 0; - do{ - if(0 == m_remaining_bits){ - if(m_end_of_sequence){ - m_buffer_in = 0; - m_remaining_bits = missing_bits; - } - else{ - m_buffer_in = * this->base_reference()++; - m_remaining_bits = BitsIn; - } - } - - // append these bits to the next output - // up to the size of the output - unsigned int i = (std::min)(missing_bits, m_remaining_bits); - // shift interesting bits to least significant position - base_value_type j = m_buffer_in >> (m_remaining_bits - i); - // and mask off the un interesting higher bits - // note presumption of twos complement notation - j &= (1 << i) - 1; - // append then interesting bits to the output value - m_buffer_out <<= i; - m_buffer_out |= j; - - // and update counters - missing_bits -= i; - m_remaining_bits -= i; - }while(0 < missing_bits); - m_buffer_out_full = true; -} - -} // namespace iterators -} // namespace archive -} // namespace boost - -#endif // BOOST_ARCHIVE_ITERATORS_TRANSFORM_WIDTH_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/unescape.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/unescape.hpp deleted file mode 100644 index abf62406088..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/iterators/unescape.hpp +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef BOOST_ARCHIVE_ITERATORS_UNESCAPE_HPP -#define BOOST_ARCHIVE_ITERATORS_UNESCAPE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// unescape.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include - -namespace boost { -namespace archive { -namespace iterators { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// class used by text archives to translate char strings to wchar_t -// strings of the currently selected locale -template -class unescape - : public boost::iterator_adaptor< - unescape, - Base, - typename pointee::type, - single_pass_traversal_tag, - typename pointee::type - > -{ - friend class boost::iterator_core_access; - typedef typename boost::iterator_adaptor< - unescape, - Base, - typename pointee::type, - single_pass_traversal_tag, - typename pointee::type - > super_t; - - typedef unescape this_t; -public: - typedef typename this_t::value_type value_type; - typedef typename this_t::reference reference; -private: - value_type dereference_impl() { - if(! m_full){ - m_current_value = static_cast(this)->drain(); - m_full = true; - } - return m_current_value; - } - - reference dereference() const { - return const_cast(this)->dereference_impl(); - } - - value_type m_current_value; - bool m_full; - - void increment(){ - ++(this->base_reference()); - dereference_impl(); - m_full = false; - }; - -public: - - unescape(Base base) : - super_t(base), - m_full(false) - {} - -}; - -} // namespace iterators -} // namespace archive -} // namespace boost - -#endif // BOOST_ARCHIVE_ITERATORS_UNESCAPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/wchar_from_mb.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/wchar_from_mb.hpp deleted file mode 100644 index 2af8f6401f2..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/iterators/wchar_from_mb.hpp +++ /dev/null @@ -1,194 +0,0 @@ -#ifndef BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP -#define BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// wchar_from_mb.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include // size_t -#ifndef BOOST_NO_CWCHAR -#include // mbstate_t -#endif -#include // copy - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::mbstate_t; -} // namespace std -#endif -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace archive { -namespace iterators { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// class used by text archives to translate char strings to wchar_t -// strings of the currently selected locale -template -class wchar_from_mb - : public boost::iterator_adaptor< - wchar_from_mb, - Base, - wchar_t, - single_pass_traversal_tag, - wchar_t - > -{ - friend class boost::iterator_core_access; - typedef typename boost::iterator_adaptor< - wchar_from_mb, - Base, - wchar_t, - single_pass_traversal_tag, - wchar_t - > super_t; - - typedef wchar_from_mb this_t; - - void drain(); - - wchar_t dereference() const { - if(m_output.m_next == m_output.m_next_available) - return static_cast(0); - return * m_output.m_next; - } - - void increment(){ - if(m_output.m_next == m_output.m_next_available) - return; - if(++m_output.m_next == m_output.m_next_available){ - if(m_input.m_done) - return; - drain(); - } - } - - bool equal(this_t const & rhs) const { - return dereference() == rhs.dereference(); - } - - boost::archive::detail::utf8_codecvt_facet m_codecvt_facet; - std::mbstate_t m_mbs; - - template - struct sliding_buffer { - boost::array m_buffer; - typename boost::array::const_iterator m_next_available; - typename boost::array::iterator m_next; - bool m_done; - // default ctor - sliding_buffer() : - m_next_available(m_buffer.begin()), - m_next(m_buffer.begin()), - m_done(false) - {} - // copy ctor - sliding_buffer(const sliding_buffer & rhs) : - m_next_available( - std::copy( - rhs.m_buffer.begin(), - rhs.m_next_available, - m_buffer.begin() - ) - ), - m_next( - m_buffer.begin() + (rhs.m_next - rhs.m_buffer.begin()) - ), - m_done(rhs.m_done) - {} - }; - - sliding_buffer::type> m_input; - sliding_buffer::type> m_output; - -public: - // make composible buy using templated constructor - template - wchar_from_mb(T start) : - super_t(Base(static_cast< T >(start))), - m_mbs(std::mbstate_t()) - { - BOOST_ASSERT(std::mbsinit(&m_mbs)); - drain(); - } - // default constructor used as an end iterator - wchar_from_mb(){} - - // copy ctor - wchar_from_mb(const wchar_from_mb & rhs) : - super_t(rhs.base_reference()), - m_mbs(rhs.m_mbs), - m_input(rhs.m_input), - m_output(rhs.m_output) - {} -}; - -template -void wchar_from_mb::drain(){ - BOOST_ASSERT(! m_input.m_done); - for(;;){ - typename boost::iterators::iterator_reference::type c = *(this->base_reference()); - // a null character in a multibyte stream is takes as end of string - if(0 == c){ - m_input.m_done = true; - break; - } - ++(this->base_reference()); - * const_cast::type *>( - (m_input.m_next_available++) - ) = c; - // if input buffer is full - we're done for now - if(m_input.m_buffer.end() == m_input.m_next_available) - break; - } - const typename boost::iterators::iterator_value::type * input_new_start; - typename iterator_value::type * next_available; - - std::codecvt_base::result r = m_codecvt_facet.in( - m_mbs, - m_input.m_buffer.begin(), - m_input.m_next_available, - input_new_start, - m_output.m_buffer.begin(), - m_output.m_buffer.end(), - next_available - ); - BOOST_ASSERT(std::codecvt_base::ok == r); - m_output.m_next_available = next_available; - m_output.m_next = m_output.m_buffer.begin(); - - // we're done with some of the input so shift left. - m_input.m_next_available = std::copy( - input_new_start, - m_input.m_next_available, - m_input.m_buffer.begin() - ); - m_input.m_next = m_input.m_buffer.begin(); -} - -} // namespace iterators -} // namespace archive -} // namespace boost - -#endif // BOOST_ARCHIVE_ITERATORS_WCHAR_FROM_MB_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_escape.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_escape.hpp deleted file mode 100644 index c838a73b864..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_escape.hpp +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef BOOST_ARCHIVE_ITERATORS_XML_ESCAPE_HPP -#define BOOST_ARCHIVE_ITERATORS_XML_ESCAPE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// xml_escape.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -namespace boost { -namespace archive { -namespace iterators { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// insert escapes into xml text - -template -class xml_escape - : public escape, Base> -{ - friend class boost::iterator_core_access; - - typedef escape, Base> super_t; - -public: - char fill(const char * & bstart, const char * & bend); - wchar_t fill(const wchar_t * & bstart, const wchar_t * & bend); - - template - xml_escape(T start) : - super_t(Base(static_cast< T >(start))) - {} - // intel 7.1 doesn't like default copy constructor - xml_escape(const xml_escape & rhs) : - super_t(rhs.base_reference()) - {} -}; - -template -char xml_escape::fill( - const char * & bstart, - const char * & bend -){ - char current_value = * this->base_reference(); - switch(current_value){ - case '<': - bstart = "<"; - bend = bstart + 4; - break; - case '>': - bstart = ">"; - bend = bstart + 4; - break; - case '&': - bstart = "&"; - bend = bstart + 5; - break; - case '"': - bstart = """; - bend = bstart + 6; - break; - case '\'': - bstart = "'"; - bend = bstart + 6; - break; - default: - return current_value; - } - return *bstart; -} - -template -wchar_t xml_escape::fill( - const wchar_t * & bstart, - const wchar_t * & bend -){ - wchar_t current_value = * this->base_reference(); - switch(current_value){ - case '<': - bstart = L"<"; - bend = bstart + 4; - break; - case '>': - bstart = L">"; - bend = bstart + 4; - break; - case '&': - bstart = L"&"; - bend = bstart + 5; - break; - case '"': - bstart = L"""; - bend = bstart + 6; - break; - case '\'': - bstart = L"'"; - bend = bstart + 6; - break; - default: - return current_value; - } - return *bstart; -} - -} // namespace iterators -} // namespace archive -} // namespace boost - -#endif // BOOST_ARCHIVE_ITERATORS_XML_ESCAPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape.hpp deleted file mode 100644 index 69977404567..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape.hpp +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP -#define BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// xml_unescape.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include - -#include -#include - -namespace boost { -namespace archive { -namespace iterators { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// replace &??? xml escape sequences with the corresponding characters -template -class xml_unescape - : public unescape, Base> -{ - friend class boost::iterator_core_access; - typedef xml_unescape this_t; - typedef unescape super_t; - typedef typename boost::iterator_reference reference_type; - - reference_type dereference() const { - return unescape, Base>::dereference(); - } -public: - // workaround msvc 7.1 ICU crash - #if defined(BOOST_MSVC) - typedef int value_type; - #else - typedef typename this_t::value_type value_type; - #endif - - void drain_residue(const char *literal); - value_type drain(); - - template - xml_unescape(T start) : - super_t(Base(static_cast< T >(start))) - {} - // intel 7.1 doesn't like default copy constructor - xml_unescape(const xml_unescape & rhs) : - super_t(rhs.base_reference()) - {} -}; - -template -void xml_unescape::drain_residue(const char * literal){ - do{ - if(* literal != * ++(this->base_reference())) - boost::serialization::throw_exception( - dataflow_exception( - dataflow_exception::invalid_xml_escape_sequence - ) - ); - } - while('\0' != * ++literal); -} - -// note key constraint on this function is that can't "look ahead" any -// more than necessary into base iterator. Doing so would alter the base -// iterator refenence which would make subsequent iterator comparisons -// incorrect and thereby break the composiblity of iterators. -template -typename xml_unescape::value_type -//int -xml_unescape::drain(){ - value_type retval = * this->base_reference(); - if('&' != retval){ - return retval; - } - retval = * ++(this->base_reference()); - switch(retval){ - case 'l': // < - drain_residue("t;"); - retval = '<'; - break; - case 'g': // > - drain_residue("t;"); - retval = '>'; - break; - case 'a': - retval = * ++(this->base_reference()); - switch(retval){ - case 'p': // ' - drain_residue("os;"); - retval = '\''; - break; - case 'm': // & - drain_residue("p;"); - retval = '&'; - break; - } - break; - case 'q': - drain_residue("uot;"); - retval = '"'; - break; - } - return retval; -} - -} // namespace iterators -} // namespace archive -} // namespace boost - -#endif // BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape_exception.hpp b/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape_exception.hpp deleted file mode 100644 index 71a64378c20..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/iterators/xml_unescape_exception.hpp +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_EXCEPTION_HPP -#define BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_EXCEPTION_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// xml_unescape_exception.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifndef BOOST_NO_EXCEPTIONS -#include - -#include - -namespace boost { -namespace archive { -namespace iterators { - -////////////////////////////////////////////////////////////////////// -// exceptions thrown by xml_unescapes -// -class xml_unescape_exception : public std::exception -{ -public: - xml_unescape_exception() - {} - - virtual const char *what( ) const throw( ) - { - return "xml contained un-recognized escape code"; - } -}; - -} // namespace iterators -} // namespace archive -} // namespace boost - -#endif //BOOST_NO_EXCEPTIONS -#endif //BOOST_ARCHIVE_ITERATORS_XML_UNESCAPE_EXCEPTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_iarchive.hpp deleted file mode 100644 index 4a898a8ad16..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_iarchive.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP -#define BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// polymorphic_binary_iarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -class polymorphic_binary_iarchive : - public detail::polymorphic_iarchive_route -{ -public: - polymorphic_binary_iarchive(std::istream & is, unsigned int flags = 0) : - detail::polymorphic_iarchive_route(is, flags) - {} - ~polymorphic_binary_iarchive(){} -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE( - boost::archive::polymorphic_binary_iarchive -) - -#endif // BOOST_ARCHIVE_POLYMORPHIC_BINARY_IARCHIVE_HPP - diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_oarchive.hpp deleted file mode 100644 index 931b243feb8..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_binary_oarchive.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP -#define BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// polymorphic_binary_oarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include - -namespace boost { -namespace archive { - -typedef detail::polymorphic_oarchive_route< - binary_oarchive_impl< - binary_oarchive, - std::ostream::char_type, - std::ostream::traits_type - > - > polymorphic_binary_oarchive; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE( - boost::archive::polymorphic_binary_oarchive -) - -#endif // BOOST_ARCHIVE_POLYMORPHIC_BINARY_OARCHIVE_HPP - diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_iarchive.hpp deleted file mode 100644 index d3c59a9f0f4..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_iarchive.hpp +++ /dev/null @@ -1,168 +0,0 @@ -#ifndef BOOST_ARCHIVE_POLYMORPHIC_IARCHIVE_HPP -#define BOOST_ARCHIVE_POLYMORPHIC_IARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// polymorphic_iarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // std::size_t -#include // ULONG_MAX -#include - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include - -#include -#include -#include -#include - -#include -#include // must be the last header - -namespace boost { -namespace serialization { - class extended_type_info; -} // namespace serialization -namespace archive { -namespace detail { - class basic_iarchive; - class basic_iserializer; -} - -class polymorphic_iarchive; - -class BOOST_SYMBOL_VISIBLE polymorphic_iarchive_impl : - public detail::interface_iarchive -{ -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else - friend class detail::interface_iarchive; - friend class load_access; -#endif - // primitive types the only ones permitted by polymorphic archives - virtual void load(bool & t) = 0; - - virtual void load(char & t) = 0; - virtual void load(signed char & t) = 0; - virtual void load(unsigned char & t) = 0; - #ifndef BOOST_NO_CWCHAR - #ifndef BOOST_NO_INTRINSIC_WCHAR_T - virtual void load(wchar_t & t) = 0; - #endif - #endif - virtual void load(short & t) = 0; - virtual void load(unsigned short & t) = 0; - virtual void load(int & t) = 0; - virtual void load(unsigned int & t) = 0; - virtual void load(long & t) = 0; - virtual void load(unsigned long & t) = 0; - - #if defined(BOOST_HAS_LONG_LONG) - virtual void load(boost::long_long_type & t) = 0; - virtual void load(boost::ulong_long_type & t) = 0; - #elif defined(BOOST_HAS_MS_INT64) - virtual void load(__int64 & t) = 0; - virtual void load(unsigned __int64 & t) = 0; - #endif - - virtual void load(float & t) = 0; - virtual void load(double & t) = 0; - - // string types are treated as primitives - virtual void load(std::string & t) = 0; - #ifndef BOOST_NO_STD_WSTRING - virtual void load(std::wstring & t) = 0; - #endif - - // used for xml and other tagged formats - virtual void load_start(const char * name) = 0; - virtual void load_end(const char * name) = 0; - virtual void register_basic_serializer(const detail::basic_iserializer & bis) = 0; - virtual detail::helper_collection & get_helper_collection() = 0; - - // msvc and borland won't automatically pass these to the base class so - // make it explicit here - template - void load_override(T & t) - { - archive::load(* this->This(), t); - } - // special treatment for name-value pairs. - template - void load_override( - const boost::serialization::nvp< T > & t - ){ - load_start(t.name()); - archive::load(* this->This(), t.value()); - load_end(t.name()); - } -protected: - virtual ~polymorphic_iarchive_impl(){}; -public: - // utility function implemented by all legal archives - virtual void set_library_version(library_version_type archive_library_version) = 0; - virtual library_version_type get_library_version() const = 0; - virtual unsigned int get_flags() const = 0; - virtual void delete_created_pointers() = 0; - virtual void reset_object_address( - const void * new_address, - const void * old_address - ) = 0; - - virtual void load_binary(void * t, std::size_t size) = 0; - - // these are used by the serialization library implementation. - virtual void load_object( - void *t, - const detail::basic_iserializer & bis - ) = 0; - virtual const detail::basic_pointer_iserializer * load_pointer( - void * & t, - const detail::basic_pointer_iserializer * bpis_ptr, - const detail::basic_pointer_iserializer * (*finder)( - const boost::serialization::extended_type_info & type - ) - ) = 0; -}; - -} // namespace archive -} // namespace boost - -#include // pops abi_suffix.hpp pragmas - -namespace boost { -namespace archive { - -class BOOST_SYMBOL_VISIBLE polymorphic_iarchive : - public polymorphic_iarchive_impl -{ -public: - virtual ~polymorphic_iarchive(){}; -}; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::polymorphic_iarchive) - -#endif // BOOST_ARCHIVE_POLYMORPHIC_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_oarchive.hpp deleted file mode 100644 index edac4edb1e8..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_oarchive.hpp +++ /dev/null @@ -1,154 +0,0 @@ -#ifndef BOOST_ARCHIVE_POLYMORPHIC_OARCHIVE_HPP -#define BOOST_ARCHIVE_POLYMORPHIC_OARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// polymorphic_oarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // size_t -#include // ULONG_MAX -#include - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include -#include -#include -#include -#include - -#include -#include // must be the last header - -namespace boost { -namespace serialization { - class extended_type_info; -} // namespace serialization -namespace archive { -namespace detail { - class basic_oarchive; - class basic_oserializer; -} - -class polymorphic_oarchive; - -class BOOST_SYMBOL_VISIBLE polymorphic_oarchive_impl : - public detail::interface_oarchive -{ -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else - friend class detail::interface_oarchive; - friend class save_access; -#endif - // primitive types the only ones permitted by polymorphic archives - virtual void save(const bool t) = 0; - - virtual void save(const char t) = 0; - virtual void save(const signed char t) = 0; - virtual void save(const unsigned char t) = 0; - #ifndef BOOST_NO_CWCHAR - #ifndef BOOST_NO_INTRINSIC_WCHAR_T - virtual void save(const wchar_t t) = 0; - #endif - #endif - virtual void save(const short t) = 0; - virtual void save(const unsigned short t) = 0; - virtual void save(const int t) = 0; - virtual void save(const unsigned int t) = 0; - virtual void save(const long t) = 0; - virtual void save(const unsigned long t) = 0; - - #if defined(BOOST_HAS_LONG_LONG) - virtual void save(const boost::long_long_type t) = 0; - virtual void save(const boost::ulong_long_type t) = 0; - #elif defined(BOOST_HAS_MS_INT64) - virtual void save(const __int64 t) = 0; - virtual void save(const unsigned __int64 t) = 0; - #endif - - virtual void save(const float t) = 0; - virtual void save(const double t) = 0; - - // string types are treated as primitives - virtual void save(const std::string & t) = 0; - #ifndef BOOST_NO_STD_WSTRING - virtual void save(const std::wstring & t) = 0; - #endif - - virtual void save_null_pointer() = 0; - // used for xml and other tagged formats - virtual void save_start(const char * name) = 0; - virtual void save_end(const char * name) = 0; - virtual void register_basic_serializer(const detail::basic_oserializer & bos) = 0; - virtual detail::helper_collection & get_helper_collection() = 0; - - virtual void end_preamble() = 0; - - // msvc and borland won't automatically pass these to the base class so - // make it explicit here - template - void save_override(T & t) - { - archive::save(* this->This(), t); - } - // special treatment for name-value pairs. - template - void save_override( - const ::boost::serialization::nvp< T > & t - ){ - save_start(t.name()); - archive::save(* this->This(), t.const_value()); - save_end(t.name()); - } -protected: - virtual ~polymorphic_oarchive_impl(){}; -public: - // utility functions implemented by all legal archives - virtual unsigned int get_flags() const = 0; - virtual library_version_type get_library_version() const = 0; - virtual void save_binary(const void * t, std::size_t size) = 0; - - virtual void save_object( - const void *x, - const detail::basic_oserializer & bos - ) = 0; - virtual void save_pointer( - const void * t, - const detail::basic_pointer_oserializer * bpos_ptr - ) = 0; -}; - -// note: preserve naming symmetry -class BOOST_SYMBOL_VISIBLE polymorphic_oarchive : - public polymorphic_oarchive_impl -{ -public: - virtual ~polymorphic_oarchive(){}; -}; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::polymorphic_oarchive) - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_ARCHIVE_POLYMORPHIC_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_iarchive.hpp deleted file mode 100644 index 7bef2927865..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_iarchive.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP -#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// polymorphic_text_iarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -class polymorphic_text_iarchive : - public detail::polymorphic_iarchive_route -{ -public: - polymorphic_text_iarchive(std::istream & is, unsigned int flags = 0) : - detail::polymorphic_iarchive_route(is, flags) - {} - ~polymorphic_text_iarchive(){} -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE( - boost::archive::polymorphic_text_iarchive -) - -#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_IARCHIVE_HPP - diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_oarchive.hpp deleted file mode 100644 index 457aad9fd75..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_oarchive.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP -#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// polymorphic_text_oarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include - -namespace boost { -namespace archive { - -typedef detail::polymorphic_oarchive_route< - text_oarchive_impl -> polymorphic_text_oarchive; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE( - boost::archive::polymorphic_text_oarchive -) - -#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_OARCHIVE_HPP - diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_wiarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_wiarchive.hpp deleted file mode 100644 index 8466f05d6a6..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_wiarchive.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP -#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// polymorphic_text_wiarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifdef BOOST_NO_STD_WSTREAMBUF -#error "wide char i/o not supported on this platform" -#else - -#include -#include - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -class polymorphic_text_wiarchive : - public detail::polymorphic_iarchive_route -{ -public: - polymorphic_text_wiarchive(std::wistream & is, unsigned int flags = 0) : - detail::polymorphic_iarchive_route(is, flags) - {} - ~polymorphic_text_wiarchive(){} -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE( - boost::archive::polymorphic_text_wiarchive -) - -#endif // BOOST_NO_STD_WSTREAMBUF -#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_WIARCHIVE_HPP - diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_woarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_woarchive.hpp deleted file mode 100644 index 295625d1bcf..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_text_woarchive.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP -#define BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// polymorphic_text_oarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifdef BOOST_NO_STD_WSTREAMBUF -#error "wide char i/o not supported on this platform" -#else - -#include -#include - -namespace boost { -namespace archive { - -typedef detail::polymorphic_oarchive_route< - text_woarchive_impl -> polymorphic_text_woarchive; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE( - boost::archive::polymorphic_text_woarchive -) - -#endif // BOOST_NO_STD_WSTREAMBUF -#endif // BOOST_ARCHIVE_POLYMORPHIC_TEXT_WOARCHIVE_HPP - diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_iarchive.hpp deleted file mode 100644 index 4dc3f894b38..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_iarchive.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP -#define BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// polymorphic_xml_iarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -class polymorphic_xml_iarchive : - public detail::polymorphic_iarchive_route -{ -public: - polymorphic_xml_iarchive(std::istream & is, unsigned int flags = 0) : - detail::polymorphic_iarchive_route(is, flags) - {} - ~polymorphic_xml_iarchive(){} -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE( - boost::archive::polymorphic_xml_iarchive -) - -#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_IARCHIVE_HPP - diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_oarchive.hpp deleted file mode 100644 index 514f9e530a8..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_oarchive.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP -#define BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// polymorphic_xml_oarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include - -namespace boost { -namespace archive { - -typedef detail::polymorphic_oarchive_route< - xml_oarchive_impl -> polymorphic_xml_oarchive; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE( - boost::archive::polymorphic_xml_oarchive -) - -#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_OARCHIVE_HPP - diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_wiarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_wiarchive.hpp deleted file mode 100644 index d4ab731267f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_wiarchive.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP -#define BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// polymorphic_xml_wiarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifdef BOOST_NO_STD_WSTREAMBUF -#error "wide char i/o not supported on this platform" -#else - -#include -#include - -namespace boost { -namespace archive { - -class polymorphic_xml_wiarchive : - public detail::polymorphic_iarchive_route -{ -public: - polymorphic_xml_wiarchive(std::wistream & is, unsigned int flags = 0) : - detail::polymorphic_iarchive_route(is, flags) - {} - ~polymorphic_xml_wiarchive(){} -}; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE( - boost::archive::polymorphic_xml_wiarchive -) - -#endif // BOOST_NO_STD_WSTREAMBUF -#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_WIARCHIVE_HPP - diff --git a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_woarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_woarchive.hpp deleted file mode 100644 index dd8963fbb14..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/polymorphic_xml_woarchive.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP -#define BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// polymorphic_xml_oarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifdef BOOST_NO_STD_WSTREAMBUF -#error "wide char i/o not supported on this platform" -#else - -#include -#include - -namespace boost { -namespace archive { - -typedef detail::polymorphic_oarchive_route< - xml_woarchive_impl -> polymorphic_xml_woarchive; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE( - boost::archive::polymorphic_xml_woarchive -) - -#endif // BOOST_NO_STD_WSTREAMBUF -#endif // BOOST_ARCHIVE_POLYMORPHIC_XML_WOARCHIVE_HPP - diff --git a/contrib/libboost/boost_1_65_0/boost/archive/text_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/text_iarchive.hpp deleted file mode 100644 index d9d60adf0b8..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/text_iarchive.hpp +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef BOOST_ARCHIVE_TEXT_IARCHIVE_HPP -#define BOOST_ARCHIVE_TEXT_IARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// text_iarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include -#include -#include -#include -#include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -namespace detail { - template class interface_iarchive; -} // namespace detail - -template -class BOOST_SYMBOL_VISIBLE text_iarchive_impl : - public basic_text_iprimitive, - public basic_text_iarchive -{ -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else -protected: - friend class detail::interface_iarchive; - friend class load_access; -#endif - template - void load(T & t){ - basic_text_iprimitive::load(t); - } - void load(version_type & t){ - unsigned int v; - load(v); - t = version_type(v); - } - void load(boost::serialization::item_version_type & t){ - unsigned int v; - load(v); - t = boost::serialization::item_version_type(v); - } - BOOST_ARCHIVE_DECL void - load(char * t); - #ifndef BOOST_NO_INTRINSIC_WCHAR_T - BOOST_ARCHIVE_DECL void - load(wchar_t * t); - #endif - BOOST_ARCHIVE_DECL void - load(std::string &s); - #ifndef BOOST_NO_STD_WSTRING - BOOST_ARCHIVE_DECL void - load(std::wstring &ws); - #endif - template - void load_override(T & t){ - basic_text_iarchive::load_override(t); - } - BOOST_ARCHIVE_DECL void - load_override(class_name_type & t); - BOOST_ARCHIVE_DECL void - init(); - BOOST_ARCHIVE_DECL - text_iarchive_impl(std::istream & is, unsigned int flags); - // don't import inline definitions! leave this as a reminder. - //BOOST_ARCHIVE_DECL - ~text_iarchive_impl(){}; -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -class BOOST_SYMBOL_VISIBLE text_iarchive : - public text_iarchive_impl{ -public: - text_iarchive(std::istream & is_, unsigned int flags = 0) : - // note: added _ to suppress useless gcc warning - text_iarchive_impl(is_, flags) - {} - ~text_iarchive(){} -}; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_iarchive) - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_ARCHIVE_TEXT_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/text_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/text_oarchive.hpp deleted file mode 100644 index 9ba0dafffb4..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/text_oarchive.hpp +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef BOOST_ARCHIVE_TEXT_OARCHIVE_HPP -#define BOOST_ARCHIVE_TEXT_OARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// text_oarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include // std::size_t - -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include -#include -#include -#include -#include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -namespace detail { - template class interface_oarchive; -} // namespace detail - -template -class BOOST_SYMBOL_VISIBLE text_oarchive_impl : - /* protected ? */ public basic_text_oprimitive, - public basic_text_oarchive -{ -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else -protected: - friend class detail::interface_oarchive; - friend class basic_text_oarchive; - friend class save_access; -#endif - template - void save(const T & t){ - this->newtoken(); - basic_text_oprimitive::save(t); - } - void save(const version_type & t){ - save(static_cast(t)); - } - void save(const boost::serialization::item_version_type & t){ - save(static_cast(t)); - } - BOOST_ARCHIVE_DECL void - save(const char * t); - #ifndef BOOST_NO_INTRINSIC_WCHAR_T - BOOST_ARCHIVE_DECL void - save(const wchar_t * t); - #endif - BOOST_ARCHIVE_DECL void - save(const std::string &s); - #ifndef BOOST_NO_STD_WSTRING - BOOST_ARCHIVE_DECL void - save(const std::wstring &ws); - #endif - BOOST_ARCHIVE_DECL - text_oarchive_impl(std::ostream & os, unsigned int flags); - // don't import inline definitions! leave this as a reminder. - //BOOST_ARCHIVE_DECL - ~text_oarchive_impl(){}; -public: - BOOST_ARCHIVE_DECL void - save_binary(const void *address, std::size_t count); -}; - -// do not derive from this class. If you want to extend this functionality -// via inhertance, derived from text_oarchive_impl instead. This will -// preserve correct static polymorphism. -class BOOST_SYMBOL_VISIBLE text_oarchive : - public text_oarchive_impl -{ -public: - text_oarchive(std::ostream & os_, unsigned int flags = 0) : - // note: added _ to suppress useless gcc warning - text_oarchive_impl(os_, flags) - {} - ~text_oarchive(){} -}; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_oarchive) - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_ARCHIVE_TEXT_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/text_wiarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/text_wiarchive.hpp deleted file mode 100644 index 3adf068a51a..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/text_wiarchive.hpp +++ /dev/null @@ -1,137 +0,0 @@ -#ifndef BOOST_ARCHIVE_TEXT_WIARCHIVE_HPP -#define BOOST_ARCHIVE_TEXT_WIARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// text_wiarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifdef BOOST_NO_STD_WSTREAMBUF -#error "wide char i/o not supported on this platform" -#else - -#include - -#include -#include -#include -#include -#include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -namespace detail { - template class interface_iarchive; -} // namespace detail - -template -class BOOST_SYMBOL_VISIBLE text_wiarchive_impl : - public basic_text_iprimitive, - public basic_text_iarchive -{ -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else -protected: - #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) - // for some inexplicable reason insertion of "class" generates compile erro - // on msvc 7.1 - friend detail::interface_iarchive; - friend load_access; - #else - friend class detail::interface_iarchive; - friend class load_access; - #endif -#endif - template - void load(T & t){ - basic_text_iprimitive::load(t); - } - void load(version_type & t){ - unsigned int v; - load(v); - t = version_type(v); - } - void load(boost::serialization::item_version_type & t){ - unsigned int v; - load(v); - t = boost::serialization::item_version_type(v); - } - BOOST_WARCHIVE_DECL void - load(char * t); - #ifndef BOOST_NO_INTRINSIC_WCHAR_T - BOOST_WARCHIVE_DECL void - load(wchar_t * t); - #endif - BOOST_WARCHIVE_DECL void - load(std::string &s); - #ifndef BOOST_NO_STD_WSTRING - BOOST_WARCHIVE_DECL void - load(std::wstring &ws); - #endif - template - void load_override(T & t){ - basic_text_iarchive::load_override(t); - } - BOOST_WARCHIVE_DECL - text_wiarchive_impl(std::wistream & is, unsigned int flags); - ~text_wiarchive_impl(){}; -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -class BOOST_SYMBOL_VISIBLE text_wiarchive : - public text_wiarchive_impl{ -public: - text_wiarchive(std::wistream & is, unsigned int flags = 0) : - text_wiarchive_impl(is, flags) - {} - ~text_wiarchive(){} -}; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_wiarchive) - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_NO_STD_WSTREAMBUF -#endif // BOOST_ARCHIVE_TEXT_WIARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/text_woarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/text_woarchive.hpp deleted file mode 100644 index b6b4f8ed59a..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/text_woarchive.hpp +++ /dev/null @@ -1,155 +0,0 @@ -#ifndef BOOST_ARCHIVE_TEXT_WOARCHIVE_HPP -#define BOOST_ARCHIVE_TEXT_WOARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// text_woarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#ifdef BOOST_NO_STD_WSTREAMBUF -#error "wide char i/o not supported on this platform" -#else - -#include -#include // size_t - -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include -#include -#include -#include -#include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -namespace detail { - template class interface_oarchive; -} // namespace detail - -template -class BOOST_SYMBOL_VISIBLE text_woarchive_impl : - public basic_text_oprimitive, - public basic_text_oarchive -{ -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else -protected: - #if BOOST_WORKAROUND(BOOST_MSVC, < 1500) - // for some inexplicable reason insertion of "class" generates compile erro - // on msvc 7.1 - friend detail::interface_oarchive; - friend basic_text_oarchive; - friend save_access; - #else - friend class detail::interface_oarchive; - friend class basic_text_oarchive; - friend class save_access; - #endif -#endif - template - void save(const T & t){ - this->newtoken(); - basic_text_oprimitive::save(t); - } - void save(const version_type & t){ - save(static_cast(t)); - } - void save(const boost::serialization::item_version_type & t){ - save(static_cast(t)); - } - BOOST_WARCHIVE_DECL void - save(const char * t); - #ifndef BOOST_NO_INTRINSIC_WCHAR_T - BOOST_WARCHIVE_DECL void - save(const wchar_t * t); - #endif - BOOST_WARCHIVE_DECL void - save(const std::string &s); - #ifndef BOOST_NO_STD_WSTRING - BOOST_WARCHIVE_DECL void - save(const std::wstring &ws); - #endif - text_woarchive_impl(std::wostream & os, unsigned int flags) : - basic_text_oprimitive( - os, - 0 != (flags & no_codecvt) - ), - basic_text_oarchive(flags) - { - if(0 == (flags & no_header)) - basic_text_oarchive::init(); - } -public: - void save_binary(const void *address, std::size_t count){ - put(static_cast('\n')); - this->end_preamble(); - #if ! defined(__MWERKS__) - this->basic_text_oprimitive::save_binary( - #else - this->basic_text_oprimitive::save_binary( - #endif - address, - count - ); - put(static_cast('\n')); - this->delimiter = this->none; - } - -}; - -// we use the following because we can't use -// typedef text_oarchive_impl > text_oarchive; - -// do not derive from this class. If you want to extend this functionality -// via inhertance, derived from text_oarchive_impl instead. This will -// preserve correct static polymorphism. -class BOOST_SYMBOL_VISIBLE text_woarchive : - public text_woarchive_impl -{ -public: - text_woarchive(std::wostream & os, unsigned int flags = 0) : - text_woarchive_impl(os, flags) - {} - ~text_woarchive(){} -}; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::text_woarchive) - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_NO_STD_WSTREAMBUF -#endif // BOOST_ARCHIVE_TEXT_WOARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/tmpdir.hpp b/contrib/libboost/boost_1_65_0/boost/archive/tmpdir.hpp deleted file mode 100644 index 400d23b9f68..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/tmpdir.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef BOOST_ARCHIVE_TMPDIR_HPP -#define BOOST_ARCHIVE_TMPDIR_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// tmpdir.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // getenv -#include // NULL -//#include - -#include -#ifdef BOOST_NO_STDC_NAMESPACE -namespace std { - using ::getenv; -} -#endif - -namespace boost { -namespace archive { - -inline const char * tmpdir(){ - const char *dirname; - dirname = std::getenv("TMP"); - if(NULL == dirname) - dirname = std::getenv("TMPDIR"); - if(NULL == dirname) - dirname = std::getenv("TEMP"); - if(NULL == dirname){ - //BOOST_ASSERT(false); // no temp directory found - dirname = "."; - } - return dirname; -} - -} // archive -} // boost - -#endif // BOOST_ARCHIVE_TMPDIR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/wcslen.hpp b/contrib/libboost/boost_1_65_0/boost/archive/wcslen.hpp deleted file mode 100644 index 0b60004f095..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/wcslen.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef BOOST_ARCHIVE_WCSLEN_HPP -#define BOOST_ARCHIVE_WCSLEN_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// wcslen.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // size_t -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#ifndef BOOST_NO_CWCHAR - -// a couple of libraries which include wchar_t don't include -// wcslen - -#if defined(BOOST_DINKUMWARE_STDLIB) && BOOST_DINKUMWARE_STDLIB < 306 \ -|| defined(__LIBCOMO__) - -namespace std { -inline std::size_t wcslen(const wchar_t * ws) -{ - const wchar_t * eows = ws; - while(* eows != 0) - ++eows; - return eows - ws; -} -} // namespace std - -#else - -#ifndef BOOST_NO_CWCHAR -#include -#endif -#ifdef BOOST_NO_STDC_NAMESPACE -namespace std{ using ::wcslen; } -#endif - -#endif // wcslen - -#endif //BOOST_NO_CWCHAR - -#endif //BOOST_ARCHIVE_WCSLEN_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/xml_archive_exception.hpp b/contrib/libboost/boost_1_65_0/boost/archive/xml_archive_exception.hpp deleted file mode 100644 index 82c53ef5d3e..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/xml_archive_exception.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef BOOST_ARCHIVE_XML_ARCHIVE_EXCEPTION_HPP -#define BOOST_ARCHIVE_XML_ARCHIVE_EXCEPTION_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// xml_archive_exception.hpp: - -// (C) Copyright 2007 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -#include -#include -#include - -#include // must be the last header - -namespace boost { -namespace archive { - -////////////////////////////////////////////////////////////////////// -// exceptions thrown by xml archives -// -class BOOST_SYMBOL_VISIBLE xml_archive_exception : - public virtual boost::archive::archive_exception -{ -public: - typedef enum { - xml_archive_parsing_error, // see save_register - xml_archive_tag_mismatch, - xml_archive_tag_name_error - } exception_code; - BOOST_ARCHIVE_DECL xml_archive_exception( - exception_code c, - const char * e1 = NULL, - const char * e2 = NULL - ); - BOOST_ARCHIVE_DECL xml_archive_exception(xml_archive_exception const &) ; - virtual BOOST_ARCHIVE_DECL ~xml_archive_exception() BOOST_NOEXCEPT_OR_NOTHROW ; -}; - -}// namespace archive -}// namespace boost - -#include // pops abi_suffix.hpp pragmas - -#endif //BOOST_XML_ARCHIVE_ARCHIVE_EXCEPTION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/xml_iarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/xml_iarchive.hpp deleted file mode 100644 index abd2f9fc4e3..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/xml_iarchive.hpp +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef BOOST_ARCHIVE_XML_IARCHIVE_HPP -#define BOOST_ARCHIVE_XML_IARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// xml_iarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include -#include -#include -#include -#include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -namespace detail { - template class interface_iarchive; -} // namespace detail - -template -class basic_xml_grammar; -typedef basic_xml_grammar xml_grammar; - -template -class BOOST_SYMBOL_VISIBLE xml_iarchive_impl : - public basic_text_iprimitive, - public basic_xml_iarchive -{ -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else -protected: - friend class detail::interface_iarchive; - friend class basic_xml_iarchive; - friend class load_access; -#endif - // use boost:scoped_ptr to implement automatic deletion; - boost::scoped_ptr gimpl; - - std::istream & get_is(){ - return is; - } - template - void load(T & t){ - basic_text_iprimitive::load(t); - } - void - load(version_type & t){ - unsigned int v; - load(v); - t = version_type(v); - } - void - load(boost::serialization::item_version_type & t){ - unsigned int v; - load(v); - t = boost::serialization::item_version_type(v); - } - BOOST_ARCHIVE_DECL void - load(char * t); - #ifndef BOOST_NO_INTRINSIC_WCHAR_T - BOOST_ARCHIVE_DECL void - load(wchar_t * t); - #endif - BOOST_ARCHIVE_DECL void - load(std::string &s); - #ifndef BOOST_NO_STD_WSTRING - BOOST_ARCHIVE_DECL void - load(std::wstring &ws); - #endif - template - void load_override(T & t){ - basic_xml_iarchive::load_override(t); - } - BOOST_ARCHIVE_DECL void - load_override(class_name_type & t); - BOOST_ARCHIVE_DECL void - init(); - BOOST_ARCHIVE_DECL - xml_iarchive_impl(std::istream & is, unsigned int flags); - BOOST_ARCHIVE_DECL - ~xml_iarchive_impl(); -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -class BOOST_SYMBOL_VISIBLE xml_iarchive : - public xml_iarchive_impl{ -public: - xml_iarchive(std::istream & is, unsigned int flags = 0) : - xml_iarchive_impl(is, flags) - {} - ~xml_iarchive(){}; -}; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_iarchive) - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_ARCHIVE_XML_IARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/xml_oarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/xml_oarchive.hpp deleted file mode 100644 index eea12680372..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/xml_oarchive.hpp +++ /dev/null @@ -1,137 +0,0 @@ -#ifndef BOOST_ARCHIVE_XML_OARCHIVE_HPP -#define BOOST_ARCHIVE_XML_OARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// xml_oarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include // size_t -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include -#include -#include -#include -#include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -namespace detail { - template class interface_oarchive; -} // namespace detail - -template -class BOOST_SYMBOL_VISIBLE xml_oarchive_impl : - public basic_text_oprimitive, - public basic_xml_oarchive -{ -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else -protected: - friend class detail::interface_oarchive; - friend class basic_xml_oarchive; - friend class save_access; -#endif - template - void save(const T & t){ - basic_text_oprimitive::save(t); - } - void - save(const version_type & t){ - save(static_cast(t)); - } - void - save(const boost::serialization::item_version_type & t){ - save(static_cast(t)); - } - BOOST_ARCHIVE_DECL void - save(const char * t); - #ifndef BOOST_NO_INTRINSIC_WCHAR_T - BOOST_ARCHIVE_DECL void - save(const wchar_t * t); - #endif - BOOST_ARCHIVE_DECL void - save(const std::string &s); - #ifndef BOOST_NO_STD_WSTRING - BOOST_ARCHIVE_DECL void - save(const std::wstring &ws); - #endif - BOOST_ARCHIVE_DECL - xml_oarchive_impl(std::ostream & os, unsigned int flags); - BOOST_ARCHIVE_DECL - ~xml_oarchive_impl(); -public: - BOOST_ARCHIVE_DECL - void save_binary(const void *address, std::size_t count); -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -// we use the following because we can't use -// typedef xml_oarchive_impl > xml_oarchive; - -// do not derive from this class. If you want to extend this functionality -// via inhertance, derived from xml_oarchive_impl instead. This will -// preserve correct static polymorphism. -class BOOST_SYMBOL_VISIBLE xml_oarchive : - public xml_oarchive_impl -{ -public: - xml_oarchive(std::ostream & os, unsigned int flags = 0) : - xml_oarchive_impl(os, flags) - {} - ~xml_oarchive(){} -}; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_oarchive) - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_ARCHIVE_XML_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/xml_wiarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/xml_wiarchive.hpp deleted file mode 100644 index ac24289ac11..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/xml_wiarchive.hpp +++ /dev/null @@ -1,149 +0,0 @@ -#ifndef BOOST_ARCHIVE_XML_WIARCHIVE_HPP -#define BOOST_ARCHIVE_XML_WIARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// xml_wiarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifdef BOOST_NO_STD_WSTREAMBUF -#error "wide char i/o not supported on this platform" -#else - -#include - -#include -#include -#include -#include -#include -#include -// #include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -namespace detail { - template class interface_iarchive; -} // namespace detail - -template -class basic_xml_grammar; -typedef basic_xml_grammar xml_wgrammar; - -template -class BOOST_SYMBOL_VISIBLE xml_wiarchive_impl : - public basic_text_iprimitive, - public basic_xml_iarchive -{ -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else -protected: - friend class detail::interface_iarchive; - friend class basic_xml_iarchive; - friend class load_access; -#endif - boost::scoped_ptr gimpl; - std::wistream & get_is(){ - return is; - } - template - void - load(T & t){ - basic_text_iprimitive::load(t); - } - void - load(version_type & t){ - unsigned int v; - load(v); - t = version_type(v); - } - void - load(boost::serialization::item_version_type & t){ - unsigned int v; - load(v); - t = boost::serialization::item_version_type(v); - } - BOOST_WARCHIVE_DECL void - load(char * t); - #ifndef BOOST_NO_INTRINSIC_WCHAR_T - BOOST_WARCHIVE_DECL void - load(wchar_t * t); - #endif - BOOST_WARCHIVE_DECL void - load(std::string &s); - #ifndef BOOST_NO_STD_WSTRING - BOOST_WARCHIVE_DECL void - load(std::wstring &ws); - #endif - template - void load_override(T & t){ - basic_xml_iarchive::load_override(t); - } - BOOST_WARCHIVE_DECL void - load_override(class_name_type & t); - BOOST_WARCHIVE_DECL void - init(); - BOOST_WARCHIVE_DECL - xml_wiarchive_impl(std::wistream & is, unsigned int flags) ; - BOOST_WARCHIVE_DECL - ~xml_wiarchive_impl(); -}; - -} // namespace archive -} // namespace boost - -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -class BOOST_SYMBOL_VISIBLE xml_wiarchive : - public xml_wiarchive_impl{ -public: - xml_wiarchive(std::wistream & is, unsigned int flags = 0) : - xml_wiarchive_impl(is, flags) - {} - ~xml_wiarchive(){} -}; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_wiarchive) - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_NO_STD_WSTREAMBUF -#endif // BOOST_ARCHIVE_XML_WIARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/archive/xml_woarchive.hpp b/contrib/libboost/boost_1_65_0/boost/archive/xml_woarchive.hpp deleted file mode 100644 index cb7ce68cb6f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/archive/xml_woarchive.hpp +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef BOOST_ARCHIVE_XML_WOARCHIVE_HPP -#define BOOST_ARCHIVE_XML_WOARCHIVE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// xml_woarchive.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifdef BOOST_NO_STD_WSTREAMBUF -#error "wide char i/o not supported on this platform" -#else -#include // size_t -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include - -//#include -#include -#include -#include -#include -#include -//#include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace archive { - -namespace detail { - template class interface_oarchive; -} // namespace detail - -template -class BOOST_SYMBOL_VISIBLE xml_woarchive_impl : - public basic_text_oprimitive, - public basic_xml_oarchive -{ -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else -protected: - friend class detail::interface_oarchive; - friend class basic_xml_oarchive; - friend class save_access; -#endif - //void end_preamble(){ - // basic_xml_oarchive::end_preamble(); - //} - template - void - save(const T & t){ - basic_text_oprimitive::save(t); - } - void - save(const version_type & t){ - save(static_cast(t)); - } - void - save(const boost::serialization::item_version_type & t){ - save(static_cast(t)); - } - BOOST_WARCHIVE_DECL void - save(const char * t); - #ifndef BOOST_NO_INTRINSIC_WCHAR_T - BOOST_WARCHIVE_DECL void - save(const wchar_t * t); - #endif - BOOST_WARCHIVE_DECL void - save(const std::string &s); - #ifndef BOOST_NO_STD_WSTRING - BOOST_WARCHIVE_DECL void - save(const std::wstring &ws); - #endif - BOOST_WARCHIVE_DECL - xml_woarchive_impl(std::wostream & os, unsigned int flags); - BOOST_WARCHIVE_DECL - ~xml_woarchive_impl(); -public: - BOOST_WARCHIVE_DECL void - save_binary(const void *address, std::size_t count); - -}; - -// we use the following because we can't use -// typedef xml_woarchive_impl > xml_woarchive; - -// do not derive from this class. If you want to extend this functionality -// via inhertance, derived from xml_woarchive_impl instead. This will -// preserve correct static polymorphism. -class BOOST_SYMBOL_VISIBLE xml_woarchive : - public xml_woarchive_impl -{ -public: - xml_woarchive(std::wostream & os, unsigned int flags = 0) : - xml_woarchive_impl(os, flags) - {} - ~xml_woarchive(){} -}; - -} // namespace archive -} // namespace boost - -// required by export -BOOST_SERIALIZATION_REGISTER_ARCHIVE(boost::archive::xml_woarchive) - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_NO_STD_WSTREAMBUF -#endif // BOOST_ARCHIVE_XML_OARCHIVE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/foreach_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/foreach_fwd.hpp deleted file mode 100644 index 4e0bb370c2f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/foreach_fwd.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// foreach.hpp header file -// -// Copyright 2010 Eric Niebler. -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// See http://www.boost.org/libs/foreach for documentation -// -// Credits: -// Kazutoshi Satoda: for suggesting the need for a _fwd header for foreach's -// customization points. - -#ifndef BOOST_FOREACH_FWD_HPP -#define BOOST_FOREACH_FWD_HPP - -// This must be at global scope, hence the uglified name -enum boost_foreach_argument_dependent_lookup_hack -{ - boost_foreach_argument_dependent_lookup_hack_value -}; - -namespace boost -{ - -namespace foreach -{ - /////////////////////////////////////////////////////////////////////////////// - // boost::foreach::tag - // - typedef boost_foreach_argument_dependent_lookup_hack tag; - - /////////////////////////////////////////////////////////////////////////////// - // boost::foreach::is_lightweight_proxy - // Specialize this for user-defined collection types if they are inexpensive to copy. - // This tells BOOST_FOREACH it can avoid the rvalue/lvalue detection stuff. - template - struct is_lightweight_proxy; - - /////////////////////////////////////////////////////////////////////////////// - // boost::foreach::is_noncopyable - // Specialize this for user-defined collection types if they cannot be copied. - // This also tells BOOST_FOREACH to avoid the rvalue/lvalue detection stuff. - template - struct is_noncopyable; - -} // namespace foreach - -} // namespace boost - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/composite_key.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/composite_key.hpp deleted file mode 100644 index 787cdf83195..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/composite_key.hpp +++ /dev/null @@ -1,1513 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP -#define BOOST_MULTI_INDEX_COMPOSITE_KEY_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) -#include -#endif - -#if !defined(BOOST_NO_SFINAE) -#include -#endif - -#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ - !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -#include -#endif - -/* A composite key stores n key extractors and "computes" the - * result on a given value as a packed reference to the value and - * the composite key itself. Actual invocations to the component - * key extractors are lazily performed when executing an operation - * on composite_key results (equality, comparison, hashing.) - * As the other key extractors in Boost.MultiIndex, composite_key - * is overloaded to work on chained pointers to T and reference_wrappers - * of T. - */ - -/* This user_definable macro limits the number of elements of a composite - * key; useful for shortening resulting symbol names (MSVC++ 6.0, for - * instance has problems coping with very long symbol names.) - * NB: This cannot exceed the maximum number of arguments of - * boost::tuple. In Boost 1.32, the limit is 10. - */ - -#if !defined(BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE) -#define BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE 10 -#endif - -/* maximum number of key extractors in a composite key */ - -#if BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE<10 /* max length of a tuple */ -#define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE \ - BOOST_MULTI_INDEX_LIMIT_COMPOSITE_KEY_SIZE -#else -#define BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE 10 -#endif - -/* BOOST_PP_ENUM of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */ - -#define BOOST_MULTI_INDEX_CK_ENUM(macro,data) \ - BOOST_PP_ENUM(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,macro,data) - -/* BOOST_PP_ENUM_PARAMS of BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE elements */ - -#define BOOST_MULTI_INDEX_CK_ENUM_PARAMS(param) \ - BOOST_PP_ENUM_PARAMS(BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE,param) - -/* if n==0 -> text0 - * otherwise -> textn=tuples::null_type - */ - -#define BOOST_MULTI_INDEX_CK_TEMPLATE_PARM(z,n,text) \ - typename BOOST_PP_CAT(text,n) BOOST_PP_EXPR_IF(n,=tuples::null_type) - -/* const textn& kn=textn() */ - -#define BOOST_MULTI_INDEX_CK_CTOR_ARG(z,n,text) \ - const BOOST_PP_CAT(text,n)& BOOST_PP_CAT(k,n) = BOOST_PP_CAT(text,n)() - -/* typename list(0)::type */ - -#define BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N(z,n,list) \ - BOOST_DEDUCED_TYPENAME BOOST_PP_LIST_AT(list,0)< \ - BOOST_PP_LIST_AT(list,1),n \ - >::type - -namespace boost{ - -template class reference_wrapper; /* fwd decl. */ - -namespace multi_index{ - -namespace detail{ - -/* n-th key extractor of a composite key */ - -template -struct nth_key_from_value -{ - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename mpl::eval_if_c< - N::value, - tuples::element, - mpl::identity - >::type type; -}; - -/* nth_composite_key_##name::type yields - * functor >, or tuples::null_type - * if N exceeds the length of the composite key. - */ - -#define BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(name,functor) \ -template \ -struct BOOST_PP_CAT(key_,name) \ -{ \ - typedef functor type; \ -}; \ - \ -template<> \ -struct BOOST_PP_CAT(key_,name) \ -{ \ - typedef tuples::null_type type; \ -}; \ - \ -template \ -struct BOOST_PP_CAT(nth_composite_key_,name) \ -{ \ - typedef typename nth_key_from_value::type key_from_value; \ - typedef typename BOOST_PP_CAT(key_,name)::type type; \ -}; - -/* nth_composite_key_equal_to - * nth_composite_key_less - * nth_composite_key_greater - * nth_composite_key_hash - */ - -BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(equal_to,std::equal_to) -BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(less,std::less) -BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(greater,std::greater) -BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR(hash,boost::hash) - -/* used for defining equality and comparison ops of composite_key_result */ - -#define BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO(z,n,text) text - -struct generic_operator_equal -{ - template - bool operator()(const T& x,const Q& y)const{return x==y;} -}; - -typedef tuple< - BOOST_MULTI_INDEX_CK_ENUM( - BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO, - detail::generic_operator_equal)> generic_operator_equal_tuple; - -struct generic_operator_less -{ - template - bool operator()(const T& x,const Q& y)const{return x generic_operator_less_tuple; - -/* Metaprogramming machinery for implementing equality, comparison and - * hashing operations of composite_key_result. - * - * equal_* checks for equality between composite_key_results and - * between those and tuples, accepting a tuple of basic equality functors. - * compare_* does lexicographical comparison. - * hash_* computes a combination of elementwise hash values. - */ - -template -< - typename KeyCons1,typename Value1, - typename KeyCons2, typename Value2, - typename EqualCons -> -struct equal_ckey_ckey; /* fwd decl. */ - -template -< - typename KeyCons1,typename Value1, - typename KeyCons2, typename Value2, - typename EqualCons -> -struct equal_ckey_ckey_terminal -{ - static bool compare( - const KeyCons1&,const Value1&, - const KeyCons2&,const Value2&, - const EqualCons&) - { - return true; - } -}; - -template -< - typename KeyCons1,typename Value1, - typename KeyCons2, typename Value2, - typename EqualCons -> -struct equal_ckey_ckey_normal -{ - static bool compare( - const KeyCons1& c0,const Value1& v0, - const KeyCons2& c1,const Value2& v1, - const EqualCons& eq) - { - if(!eq.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return false; - return equal_ckey_ckey< - BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1, - BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2, - BOOST_DEDUCED_TYPENAME EqualCons::tail_type - >::compare(c0.get_tail(),v0,c1.get_tail(),v1,eq.get_tail()); - } -}; - -template -< - typename KeyCons1,typename Value1, - typename KeyCons2, typename Value2, - typename EqualCons -> -struct equal_ckey_ckey: - mpl::if_< - mpl::or_< - is_same, - is_same - >, - equal_ckey_ckey_terminal, - equal_ckey_ckey_normal - >::type -{ -}; - -template -< - typename KeyCons,typename Value, - typename ValCons,typename EqualCons -> -struct equal_ckey_cval; /* fwd decl. */ - -template -< - typename KeyCons,typename Value, - typename ValCons,typename EqualCons -> -struct equal_ckey_cval_terminal -{ - static bool compare( - const KeyCons&,const Value&,const ValCons&,const EqualCons&) - { - return true; - } - - static bool compare( - const ValCons&,const KeyCons&,const Value&,const EqualCons&) - { - return true; - } -}; - -template -< - typename KeyCons,typename Value, - typename ValCons,typename EqualCons -> -struct equal_ckey_cval_normal -{ - static bool compare( - const KeyCons& c,const Value& v,const ValCons& vc, - const EqualCons& eq) - { - if(!eq.get_head()(c.get_head()(v),vc.get_head()))return false; - return equal_ckey_cval< - BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, - BOOST_DEDUCED_TYPENAME ValCons::tail_type, - BOOST_DEDUCED_TYPENAME EqualCons::tail_type - >::compare(c.get_tail(),v,vc.get_tail(),eq.get_tail()); - } - - static bool compare( - const ValCons& vc,const KeyCons& c,const Value& v, - const EqualCons& eq) - { - if(!eq.get_head()(vc.get_head(),c.get_head()(v)))return false; - return equal_ckey_cval< - BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, - BOOST_DEDUCED_TYPENAME ValCons::tail_type, - BOOST_DEDUCED_TYPENAME EqualCons::tail_type - >::compare(vc.get_tail(),c.get_tail(),v,eq.get_tail()); - } -}; - -template -< - typename KeyCons,typename Value, - typename ValCons,typename EqualCons -> -struct equal_ckey_cval: - mpl::if_< - mpl::or_< - is_same, - is_same - >, - equal_ckey_cval_terminal, - equal_ckey_cval_normal - >::type -{ -}; - -template -< - typename KeyCons1,typename Value1, - typename KeyCons2, typename Value2, - typename CompareCons -> -struct compare_ckey_ckey; /* fwd decl. */ - -template -< - typename KeyCons1,typename Value1, - typename KeyCons2, typename Value2, - typename CompareCons -> -struct compare_ckey_ckey_terminal -{ - static bool compare( - const KeyCons1&,const Value1&, - const KeyCons2&,const Value2&, - const CompareCons&) - { - return false; - } -}; - -template -< - typename KeyCons1,typename Value1, - typename KeyCons2, typename Value2, - typename CompareCons -> -struct compare_ckey_ckey_normal -{ - static bool compare( - const KeyCons1& c0,const Value1& v0, - const KeyCons2& c1,const Value2& v1, - const CompareCons& comp) - { - if(comp.get_head()(c0.get_head()(v0),c1.get_head()(v1)))return true; - if(comp.get_head()(c1.get_head()(v1),c0.get_head()(v0)))return false; - return compare_ckey_ckey< - BOOST_DEDUCED_TYPENAME KeyCons1::tail_type,Value1, - BOOST_DEDUCED_TYPENAME KeyCons2::tail_type,Value2, - BOOST_DEDUCED_TYPENAME CompareCons::tail_type - >::compare(c0.get_tail(),v0,c1.get_tail(),v1,comp.get_tail()); - } -}; - -template -< - typename KeyCons1,typename Value1, - typename KeyCons2, typename Value2, - typename CompareCons -> -struct compare_ckey_ckey: - mpl::if_< - mpl::or_< - is_same, - is_same - >, - compare_ckey_ckey_terminal, - compare_ckey_ckey_normal - >::type -{ -}; - -template -< - typename KeyCons,typename Value, - typename ValCons,typename CompareCons -> -struct compare_ckey_cval; /* fwd decl. */ - -template -< - typename KeyCons,typename Value, - typename ValCons,typename CompareCons -> -struct compare_ckey_cval_terminal -{ - static bool compare( - const KeyCons&,const Value&,const ValCons&,const CompareCons&) - { - return false; - } - - static bool compare( - const ValCons&,const KeyCons&,const Value&,const CompareCons&) - { - return false; - } -}; - -template -< - typename KeyCons,typename Value, - typename ValCons,typename CompareCons -> -struct compare_ckey_cval_normal -{ - static bool compare( - const KeyCons& c,const Value& v,const ValCons& vc, - const CompareCons& comp) - { - if(comp.get_head()(c.get_head()(v),vc.get_head()))return true; - if(comp.get_head()(vc.get_head(),c.get_head()(v)))return false; - return compare_ckey_cval< - BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, - BOOST_DEDUCED_TYPENAME ValCons::tail_type, - BOOST_DEDUCED_TYPENAME CompareCons::tail_type - >::compare(c.get_tail(),v,vc.get_tail(),comp.get_tail()); - } - - static bool compare( - const ValCons& vc,const KeyCons& c,const Value& v, - const CompareCons& comp) - { - if(comp.get_head()(vc.get_head(),c.get_head()(v)))return true; - if(comp.get_head()(c.get_head()(v),vc.get_head()))return false; - return compare_ckey_cval< - BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, - BOOST_DEDUCED_TYPENAME ValCons::tail_type, - BOOST_DEDUCED_TYPENAME CompareCons::tail_type - >::compare(vc.get_tail(),c.get_tail(),v,comp.get_tail()); - } -}; - -template -< - typename KeyCons,typename Value, - typename ValCons,typename CompareCons -> -struct compare_ckey_cval: - mpl::if_< - mpl::or_< - is_same, - is_same - >, - compare_ckey_cval_terminal, - compare_ckey_cval_normal - >::type -{ -}; - -template -struct hash_ckey; /* fwd decl. */ - -template -struct hash_ckey_terminal -{ - static std::size_t hash( - const KeyCons&,const Value&,const HashCons&,std::size_t carry) - { - return carry; - } -}; - -template -struct hash_ckey_normal -{ - static std::size_t hash( - const KeyCons& c,const Value& v,const HashCons& h,std::size_t carry=0) - { - /* same hashing formula as boost::hash_combine */ - - carry^=h.get_head()(c.get_head()(v))+0x9e3779b9+(carry<<6)+(carry>>2); - return hash_ckey< - BOOST_DEDUCED_TYPENAME KeyCons::tail_type,Value, - BOOST_DEDUCED_TYPENAME HashCons::tail_type - >::hash(c.get_tail(),v,h.get_tail(),carry); - } -}; - -template -struct hash_ckey: - mpl::if_< - is_same, - hash_ckey_terminal, - hash_ckey_normal - >::type -{ -}; - -template -struct hash_cval; /* fwd decl. */ - -template -struct hash_cval_terminal -{ - static std::size_t hash(const ValCons&,const HashCons&,std::size_t carry) - { - return carry; - } -}; - -template -struct hash_cval_normal -{ - static std::size_t hash( - const ValCons& vc,const HashCons& h,std::size_t carry=0) - { - carry^=h.get_head()(vc.get_head())+0x9e3779b9+(carry<<6)+(carry>>2); - return hash_cval< - BOOST_DEDUCED_TYPENAME ValCons::tail_type, - BOOST_DEDUCED_TYPENAME HashCons::tail_type - >::hash(vc.get_tail(),h.get_tail(),carry); - } -}; - -template -struct hash_cval: - mpl::if_< - is_same, - hash_cval_terminal, - hash_cval_normal - >::type -{ -}; - -} /* namespace multi_index::detail */ - -/* composite_key_result */ - -#if defined(BOOST_MSVC) -#pragma warning(push) -#pragma warning(disable:4512) -#endif - -template -struct composite_key_result -{ - typedef CompositeKey composite_key_type; - typedef typename composite_key_type::value_type value_type; - - composite_key_result( - const composite_key_type& composite_key_,const value_type& value_): - composite_key(composite_key_),value(value_) - {} - - const composite_key_type& composite_key; - const value_type& value; -}; - -#if defined(BOOST_MSVC) -#pragma warning(pop) -#endif - -/* composite_key */ - -template< - typename Value, - BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,KeyFromValue) -> -struct composite_key: - private tuple -{ -private: - typedef tuple super; - -public: - typedef super key_extractor_tuple; - typedef Value value_type; - typedef composite_key_result result_type; - - composite_key( - BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,KeyFromValue)): - super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) - {} - - composite_key(const key_extractor_tuple& x):super(x){} - - const key_extractor_tuple& key_extractors()const{return *this;} - key_extractor_tuple& key_extractors(){return *this;} - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,result_type>::type -#else - result_type -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - result_type operator()(const value_type& x)const - { - return result_type(*this,x); - } - - result_type operator()(const reference_wrapper& x)const - { - return result_type(*this,x.get()); - } - - result_type operator()(const reference_wrapper& x)const - { - return result_type(*this,x.get()); - } -}; - -/* comparison operators */ - -/* == */ - -template -inline bool operator==( - const composite_key_result& x, - const composite_key_result& y) -{ - typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; - typedef typename CompositeKey1::value_type value_type1; - typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; - typedef typename CompositeKey2::value_type value_type2; - - BOOST_STATIC_ASSERT( - tuples::length::value== - tuples::length::value); - - return detail::equal_ckey_ckey< - key_extractor_tuple1,value_type1, - key_extractor_tuple2,value_type2, - detail::generic_operator_equal_tuple - >::compare( - x.composite_key.key_extractors(),x.value, - y.composite_key.key_extractors(),y.value, - detail::generic_operator_equal_tuple()); -} - -template< - typename CompositeKey, - BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) -> -inline bool operator==( - const composite_key_result& x, - const tuple& y) -{ - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename CompositeKey::value_type value_type; - typedef tuple key_tuple; - - BOOST_STATIC_ASSERT( - tuples::length::value== - tuples::length::value); - - return detail::equal_ckey_cval< - key_extractor_tuple,value_type, - key_tuple,detail::generic_operator_equal_tuple - >::compare( - x.composite_key.key_extractors(),x.value, - y,detail::generic_operator_equal_tuple()); -} - -template -< - BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), - typename CompositeKey -> -inline bool operator==( - const tuple& x, - const composite_key_result& y) -{ - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename CompositeKey::value_type value_type; - typedef tuple key_tuple; - - BOOST_STATIC_ASSERT( - tuples::length::value== - tuples::length::value); - - return detail::equal_ckey_cval< - key_extractor_tuple,value_type, - key_tuple,detail::generic_operator_equal_tuple - >::compare( - x,y.composite_key.key_extractors(), - y.value,detail::generic_operator_equal_tuple()); -} - -#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ - !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -template -inline bool operator==( - const composite_key_result& x, - const std::tuple& y) -{ - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename CompositeKey::value_type value_type; - typedef std::tuple key_tuple; - typedef typename detail::cons_stdtuple_ctor< - key_tuple>::result_type cons_key_tuple; - - BOOST_STATIC_ASSERT( - static_cast(tuples::length::value)== - std::tuple_size::value); - - return detail::equal_ckey_cval< - key_extractor_tuple,value_type, - cons_key_tuple,detail::generic_operator_equal_tuple - >::compare( - x.composite_key.key_extractors(),x.value, - detail::make_cons_stdtuple(y),detail::generic_operator_equal_tuple()); -} - -template -inline bool operator==( - const std::tuple& x, - const composite_key_result& y) -{ - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename CompositeKey::value_type value_type; - typedef std::tuple key_tuple; - typedef typename detail::cons_stdtuple_ctor< - key_tuple>::result_type cons_key_tuple; - - BOOST_STATIC_ASSERT( - static_cast(tuples::length::value)== - std::tuple_size::value); - - return detail::equal_ckey_cval< - key_extractor_tuple,value_type, - cons_key_tuple,detail::generic_operator_equal_tuple - >::compare( - detail::make_cons_stdtuple(x),y.composite_key.key_extractors(), - y.value,detail::generic_operator_equal_tuple()); -} -#endif - -/* < */ - -template -inline bool operator<( - const composite_key_result& x, - const composite_key_result& y) -{ - typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; - typedef typename CompositeKey1::value_type value_type1; - typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; - typedef typename CompositeKey2::value_type value_type2; - - return detail::compare_ckey_ckey< - key_extractor_tuple1,value_type1, - key_extractor_tuple2,value_type2, - detail::generic_operator_less_tuple - >::compare( - x.composite_key.key_extractors(),x.value, - y.composite_key.key_extractors(),y.value, - detail::generic_operator_less_tuple()); -} - -template -< - typename CompositeKey, - BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) -> -inline bool operator<( - const composite_key_result& x, - const tuple& y) -{ - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename CompositeKey::value_type value_type; - typedef tuple key_tuple; - - return detail::compare_ckey_cval< - key_extractor_tuple,value_type, - key_tuple,detail::generic_operator_less_tuple - >::compare( - x.composite_key.key_extractors(),x.value, - y,detail::generic_operator_less_tuple()); -} - -template -< - BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), - typename CompositeKey -> -inline bool operator<( - const tuple& x, - const composite_key_result& y) -{ - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename CompositeKey::value_type value_type; - typedef tuple key_tuple; - - return detail::compare_ckey_cval< - key_extractor_tuple,value_type, - key_tuple,detail::generic_operator_less_tuple - >::compare( - x,y.composite_key.key_extractors(), - y.value,detail::generic_operator_less_tuple()); -} - -#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ - !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -template -inline bool operator<( - const composite_key_result& x, - const std::tuple& y) -{ - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename CompositeKey::value_type value_type; - typedef std::tuple key_tuple; - typedef typename detail::cons_stdtuple_ctor< - key_tuple>::result_type cons_key_tuple; - - return detail::compare_ckey_cval< - key_extractor_tuple,value_type, - cons_key_tuple,detail::generic_operator_less_tuple - >::compare( - x.composite_key.key_extractors(),x.value, - detail::make_cons_stdtuple(y),detail::generic_operator_less_tuple()); -} - -template -inline bool operator<( - const std::tuple& x, - const composite_key_result& y) -{ - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename CompositeKey::value_type value_type; - typedef std::tuple key_tuple; - typedef typename detail::cons_stdtuple_ctor< - key_tuple>::result_type cons_key_tuple; - - return detail::compare_ckey_cval< - key_extractor_tuple,value_type, - cons_key_tuple,detail::generic_operator_less_tuple - >::compare( - detail::make_cons_stdtuple(x),y.composite_key.key_extractors(), - y.value,detail::generic_operator_less_tuple()); -} -#endif - -/* rest of comparison operators */ - -#define BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS(t1,t2,a1,a2) \ -template inline bool operator!=(const a1& x,const a2& y) \ -{ \ - return !(x==y); \ -} \ - \ -template inline bool operator>(const a1& x,const a2& y) \ -{ \ - return y inline bool operator>=(const a1& x,const a2& y) \ -{ \ - return !(x inline bool operator<=(const a1& x,const a2& y) \ -{ \ - return !(y, - composite_key_result -) - -BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( - typename CompositeKey, - BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), - composite_key_result, - tuple -) - -BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( - BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), - typename CompositeKey, - tuple, - composite_key_result -) - -#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ - !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( - typename CompositeKey, - typename... Values, - composite_key_result, - std::tuple -) - -BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS( - typename CompositeKey, - typename... Values, - std::tuple, - composite_key_result -) -#endif - -/* composite_key_equal_to */ - -template -< - BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Pred) -> -struct composite_key_equal_to: - private tuple -{ -private: - typedef tuple super; - -public: - typedef super key_eq_tuple; - - composite_key_equal_to( - BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Pred)): - super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) - {} - - composite_key_equal_to(const key_eq_tuple& x):super(x){} - - const key_eq_tuple& key_eqs()const{return *this;} - key_eq_tuple& key_eqs(){return *this;} - - template - bool operator()( - const composite_key_result & x, - const composite_key_result & y)const - { - typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; - typedef typename CompositeKey1::value_type value_type1; - typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; - typedef typename CompositeKey2::value_type value_type2; - - BOOST_STATIC_ASSERT( - tuples::length::value<= - tuples::length::value&& - tuples::length::value== - tuples::length::value); - - return detail::equal_ckey_ckey< - key_extractor_tuple1,value_type1, - key_extractor_tuple2,value_type2, - key_eq_tuple - >::compare( - x.composite_key.key_extractors(),x.value, - y.composite_key.key_extractors(),y.value, - key_eqs()); - } - - template - < - typename CompositeKey, - BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) - > - bool operator()( - const composite_key_result& x, - const tuple& y)const - { - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename CompositeKey::value_type value_type; - typedef tuple key_tuple; - - BOOST_STATIC_ASSERT( - tuples::length::value<= - tuples::length::value&& - tuples::length::value== - tuples::length::value); - - return detail::equal_ckey_cval< - key_extractor_tuple,value_type, - key_tuple,key_eq_tuple - >::compare(x.composite_key.key_extractors(),x.value,y,key_eqs()); - } - - template - < - BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), - typename CompositeKey - > - bool operator()( - const tuple& x, - const composite_key_result& y)const - { - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename CompositeKey::value_type value_type; - typedef tuple key_tuple; - - BOOST_STATIC_ASSERT( - tuples::length::value<= - tuples::length::value&& - tuples::length::value== - tuples::length::value); - - return detail::equal_ckey_cval< - key_extractor_tuple,value_type, - key_tuple,key_eq_tuple - >::compare(x,y.composite_key.key_extractors(),y.value,key_eqs()); - } - -#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ - !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template - bool operator()( - const composite_key_result& x, - const std::tuple& y)const - { - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename CompositeKey::value_type value_type; - typedef std::tuple key_tuple; - typedef typename detail::cons_stdtuple_ctor< - key_tuple>::result_type cons_key_tuple; - - BOOST_STATIC_ASSERT( - tuples::length::value<= - tuples::length::value&& - static_cast(tuples::length::value)== - std::tuple_size::value); - - return detail::equal_ckey_cval< - key_extractor_tuple,value_type, - cons_key_tuple,key_eq_tuple - >::compare( - x.composite_key.key_extractors(),x.value, - detail::make_cons_stdtuple(y),key_eqs()); - } - - template - bool operator()( - const std::tuple& x, - const composite_key_result& y)const - { - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename CompositeKey::value_type value_type; - typedef std::tuple key_tuple; - typedef typename detail::cons_stdtuple_ctor< - key_tuple>::result_type cons_key_tuple; - - BOOST_STATIC_ASSERT( - std::tuple_size::value<= - static_cast(tuples::length::value)&& - std::tuple_size::value== - static_cast(tuples::length::value)); - - return detail::equal_ckey_cval< - key_extractor_tuple,value_type, - cons_key_tuple,key_eq_tuple - >::compare( - detail::make_cons_stdtuple(x),y.composite_key.key_extractors(), - y.value,key_eqs()); - } -#endif -}; - -/* composite_key_compare */ - -template -< - BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Compare) -> -struct composite_key_compare: - private tuple -{ -private: - typedef tuple super; - -public: - typedef super key_comp_tuple; - - composite_key_compare( - BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Compare)): - super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) - {} - - composite_key_compare(const key_comp_tuple& x):super(x){} - - const key_comp_tuple& key_comps()const{return *this;} - key_comp_tuple& key_comps(){return *this;} - - template - bool operator()( - const composite_key_result & x, - const composite_key_result & y)const - { - typedef typename CompositeKey1::key_extractor_tuple key_extractor_tuple1; - typedef typename CompositeKey1::value_type value_type1; - typedef typename CompositeKey2::key_extractor_tuple key_extractor_tuple2; - typedef typename CompositeKey2::value_type value_type2; - - BOOST_STATIC_ASSERT( - tuples::length::value<= - tuples::length::value|| - tuples::length::value<= - tuples::length::value); - - return detail::compare_ckey_ckey< - key_extractor_tuple1,value_type1, - key_extractor_tuple2,value_type2, - key_comp_tuple - >::compare( - x.composite_key.key_extractors(),x.value, - y.composite_key.key_extractors(),y.value, - key_comps()); - } - -#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) - template - bool operator()( - const composite_key_result& x, - const Value& y)const - { - return operator()(x,boost::make_tuple(boost::cref(y))); - } -#endif - - template - < - typename CompositeKey, - BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value) - > - bool operator()( - const composite_key_result& x, - const tuple& y)const - { - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename CompositeKey::value_type value_type; - typedef tuple key_tuple; - - BOOST_STATIC_ASSERT( - tuples::length::value<= - tuples::length::value|| - tuples::length::value<= - tuples::length::value); - - return detail::compare_ckey_cval< - key_extractor_tuple,value_type, - key_tuple,key_comp_tuple - >::compare(x.composite_key.key_extractors(),x.value,y,key_comps()); - } - -#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) - template - bool operator()( - const Value& x, - const composite_key_result& y)const - { - return operator()(boost::make_tuple(boost::cref(x)),y); - } -#endif - - template - < - BOOST_MULTI_INDEX_CK_ENUM_PARAMS(typename Value), - typename CompositeKey - > - bool operator()( - const tuple& x, - const composite_key_result& y)const - { - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename CompositeKey::value_type value_type; - typedef tuple key_tuple; - - BOOST_STATIC_ASSERT( - tuples::length::value<= - tuples::length::value|| - tuples::length::value<= - tuples::length::value); - - return detail::compare_ckey_cval< - key_extractor_tuple,value_type, - key_tuple,key_comp_tuple - >::compare(x,y.composite_key.key_extractors(),y.value,key_comps()); - } - -#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ - !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template - bool operator()( - const composite_key_result& x, - const std::tuple& y)const - { - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename CompositeKey::value_type value_type; - typedef std::tuple key_tuple; - typedef typename detail::cons_stdtuple_ctor< - key_tuple>::result_type cons_key_tuple; - - BOOST_STATIC_ASSERT( - tuples::length::value<= - tuples::length::value|| - std::tuple_size::value<= - static_cast(tuples::length::value)); - - return detail::compare_ckey_cval< - key_extractor_tuple,value_type, - cons_key_tuple,key_comp_tuple - >::compare( - x.composite_key.key_extractors(),x.value, - detail::make_cons_stdtuple(y),key_comps()); - } - - template - bool operator()( - const std::tuple& x, - const composite_key_result& y)const - { - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename CompositeKey::value_type value_type; - typedef std::tuple key_tuple; - typedef typename detail::cons_stdtuple_ctor< - key_tuple>::result_type cons_key_tuple; - - BOOST_STATIC_ASSERT( - std::tuple_size::value<= - static_cast(tuples::length::value)|| - tuples::length::value<= - tuples::length::value); - - return detail::compare_ckey_cval< - key_extractor_tuple,value_type, - cons_key_tuple,key_comp_tuple - >::compare( - detail::make_cons_stdtuple(x),y.composite_key.key_extractors(), - y.value,key_comps()); - } -#endif -}; - -/* composite_key_hash */ - -template -< - BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_TEMPLATE_PARM,Hash) -> -struct composite_key_hash: - private tuple -{ -private: - typedef tuple super; - -public: - typedef super key_hasher_tuple; - - composite_key_hash( - BOOST_MULTI_INDEX_CK_ENUM(BOOST_MULTI_INDEX_CK_CTOR_ARG,Hash)): - super(BOOST_MULTI_INDEX_CK_ENUM_PARAMS(k)) - {} - - composite_key_hash(const key_hasher_tuple& x):super(x){} - - const key_hasher_tuple& key_hash_functions()const{return *this;} - key_hasher_tuple& key_hash_functions(){return *this;} - - template - std::size_t operator()(const composite_key_result & x)const - { - typedef typename CompositeKey::key_extractor_tuple key_extractor_tuple; - typedef typename CompositeKey::value_type value_type; - - BOOST_STATIC_ASSERT( - tuples::length::value== - tuples::length::value); - - return detail::hash_ckey< - key_extractor_tuple,value_type, - key_hasher_tuple - >::hash(x.composite_key.key_extractors(),x.value,key_hash_functions()); - } - - template - std::size_t operator()( - const tuple& x)const - { - typedef tuple key_tuple; - - BOOST_STATIC_ASSERT( - tuples::length::value== - tuples::length::value); - - return detail::hash_cval< - key_tuple,key_hasher_tuple - >::hash(x,key_hash_functions()); - } - -#if !defined(BOOST_NO_CXX11_HDR_TUPLE)&&\ - !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template - std::size_t operator()(const std::tuple& x)const - { - typedef std::tuple key_tuple; - typedef typename detail::cons_stdtuple_ctor< - key_tuple>::result_type cons_key_tuple; - - BOOST_STATIC_ASSERT( - std::tuple_size::value== - static_cast(tuples::length::value)); - - return detail::hash_cval< - cons_key_tuple,key_hasher_tuple - >::hash(detail::make_cons_stdtuple(x),key_hash_functions()); - } -#endif -}; - -/* Instantiations of the former functors with "natural" basic components: - * composite_key_result_equal_to uses std::equal_to of the values. - * composite_key_result_less uses std::less. - * composite_key_result_greater uses std::greater. - * composite_key_result_hash uses boost::hash. - */ - -#define BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER \ -composite_key_equal_to< \ - BOOST_MULTI_INDEX_CK_ENUM( \ - BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ - /* the argument is a PP list */ \ - (detail::nth_composite_key_equal_to, \ - (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ - BOOST_PP_NIL))) \ - > - -template -struct composite_key_result_equal_to: -BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS -BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER -{ -private: - typedef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER super; - -public: - typedef CompositeKeyResult first_argument_type; - typedef first_argument_type second_argument_type; - typedef bool result_type; - - using super::operator(); -}; - -#define BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER \ -composite_key_compare< \ - BOOST_MULTI_INDEX_CK_ENUM( \ - BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ - /* the argument is a PP list */ \ - (detail::nth_composite_key_less, \ - (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ - BOOST_PP_NIL))) \ - > - -template -struct composite_key_result_less: -BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS -BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER -{ -private: - typedef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER super; - -public: - typedef CompositeKeyResult first_argument_type; - typedef first_argument_type second_argument_type; - typedef bool result_type; - - using super::operator(); -}; - -#define BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER \ -composite_key_compare< \ - BOOST_MULTI_INDEX_CK_ENUM( \ - BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ - /* the argument is a PP list */ \ - (detail::nth_composite_key_greater, \ - (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ - BOOST_PP_NIL))) \ - > - -template -struct composite_key_result_greater: -BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS -BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER -{ -private: - typedef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER super; - -public: - typedef CompositeKeyResult first_argument_type; - typedef first_argument_type second_argument_type; - typedef bool result_type; - - using super::operator(); -}; - -#define BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER \ -composite_key_hash< \ - BOOST_MULTI_INDEX_CK_ENUM( \ - BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N, \ - /* the argument is a PP list */ \ - (detail::nth_composite_key_hash, \ - (BOOST_DEDUCED_TYPENAME CompositeKeyResult::composite_key_type, \ - BOOST_PP_NIL))) \ - > - -template -struct composite_key_result_hash: -BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS -BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER -{ -private: - typedef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER super; - -public: - typedef CompositeKeyResult argument_type; - typedef std::size_t result_type; - - using super::operator(); -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -/* Specializations of std::equal_to, std::less, std::greater and boost::hash - * for composite_key_results enabling interoperation with tuples of values. - */ - -namespace std{ - -template -struct equal_to >: - boost::multi_index::composite_key_result_equal_to< - boost::multi_index::composite_key_result - > -{ -}; - -template -struct less >: - boost::multi_index::composite_key_result_less< - boost::multi_index::composite_key_result - > -{ -}; - -template -struct greater >: - boost::multi_index::composite_key_result_greater< - boost::multi_index::composite_key_result - > -{ -}; - -} /* namespace std */ - -namespace boost{ - -template -struct hash >: - boost::multi_index::composite_key_result_hash< - boost::multi_index::composite_key_result - > -{ -}; - -} /* namespace boost */ - -#undef BOOST_MULTI_INDEX_CK_RESULT_HASH_SUPER -#undef BOOST_MULTI_INDEX_CK_RESULT_GREATER_SUPER -#undef BOOST_MULTI_INDEX_CK_RESULT_LESS_SUPER -#undef BOOST_MULTI_INDEX_CK_RESULT_EQUAL_TO_SUPER -#undef BOOST_MULTI_INDEX_CK_COMPLETE_COMP_OPS -#undef BOOST_MULTI_INDEX_CK_IDENTITY_ENUM_MACRO -#undef BOOST_MULTI_INDEX_CK_NTH_COMPOSITE_KEY_FUNCTOR -#undef BOOST_MULTI_INDEX_CK_APPLY_METAFUNCTION_N -#undef BOOST_MULTI_INDEX_CK_CTOR_ARG -#undef BOOST_MULTI_INDEX_CK_TEMPLATE_PARM -#undef BOOST_MULTI_INDEX_CK_ENUM_PARAMS -#undef BOOST_MULTI_INDEX_CK_ENUM -#undef BOOST_MULTI_INDEX_COMPOSITE_KEY_SIZE - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/access_specifier.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/access_specifier.hpp deleted file mode 100644 index f3346e836d4..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/access_specifier.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_ACCESS_SPECIFIER_HPP -#define BOOST_MULTI_INDEX_DETAIL_ACCESS_SPECIFIER_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include -#include - -/* In those compilers that do not accept the member template friend syntax, - * some protected and private sections might need to be specified as - * public. - */ - -#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) -#define BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS public -#define BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS public -#else -#define BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS protected -#define BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS private -#endif - -/* GCC does not correctly support in-class using declarations for template - * functions. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9810 - * MSVC 7.1/8.0 seem to have a similar problem, though the conditions in - * which the error happens are not that simple. I have yet to isolate this - * into a snippet suitable for bug reporting. - * Sun Studio also has this problem, which might be related, from the - * information gathered at Sun forums, with a known issue notified at the - * internal bug report 6421933. The bug is present up to Studio Express 2, - * the latest preview version of the future Sun Studio 12. As of this writing - * (October 2006) it is not known whether a fix will finally make it into the - * official Sun Studio 12. - */ - -#if BOOST_WORKAROUND(__GNUC__,==3)&&(__GNUC_MINOR__<4)||\ - BOOST_WORKAROUND(BOOST_MSVC,==1310)||\ - BOOST_WORKAROUND(BOOST_MSVC,==1400)||\ - BOOST_WORKAROUND(__SUNPRO_CC,BOOST_TESTED_AT(0x590)) -#define BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS public -#else -#define BOOST_MULTI_INDEX_PRIVATE_IF_USING_DECL_FOR_TEMPL_FUNCTIONS private -#endif - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/adl_swap.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/adl_swap.hpp deleted file mode 100644 index 02b06442290..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/adl_swap.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_ADL_SWAP_HPP -#define BOOST_MULTI_INDEX_DETAIL_ADL_SWAP_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template -void adl_swap(T& x,T& y) -{ - -#if !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) - using std::swap; - swap(x,y); -#else - std::swap(x,y); -#endif - -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/archive_constructed.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/archive_constructed.hpp deleted file mode 100644 index 0a7a26e0d4e..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/archive_constructed.hpp +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright 2003-2016 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_ARCHIVE_CONSTRUCTED_HPP -#define BOOST_MULTI_INDEX_DETAIL_ARCHIVE_CONSTRUCTED_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* constructs a stack-based object from a serialization archive */ - -template -struct archive_constructed:private noncopyable -{ - template - archive_constructed(Archive& ar,const unsigned int version) - { - serialization::load_construct_data_adl(ar,&get(),version); - BOOST_TRY{ - ar>>get(); - } - BOOST_CATCH(...){ - (&get())->~T(); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - template - archive_constructed(const char* name,Archive& ar,const unsigned int version) - { - serialization::load_construct_data_adl(ar,&get(),version); - BOOST_TRY{ - ar>>serialization::make_nvp(name,get()); - } - BOOST_CATCH(...){ - (&get())->~T(); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - ~archive_constructed() - { - (&get())->~T(); - } - -#include - - T& get(){return *reinterpret_cast(&space);} - -#include - -private: - typename aligned_storage::value>::type space; -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/auto_space.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/auto_space.hpp deleted file mode 100644 index 9d78c3a363f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/auto_space.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP -#define BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* auto_space provides uninitialized space suitably to store - * a given number of elements of a given type. - */ - -/* NB: it is not clear whether using an allocator to handle - * zero-sized arrays of elements is conformant or not. GCC 3.3.1 - * and prior fail here, other stdlibs handle the issue gracefully. - * To be on the safe side, the case n==0 is given special treatment. - * References: - * GCC Bugzilla, "standard allocator crashes when deallocating segment - * "of zero length", http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14176 - * C++ Standard Library Defect Report List (Revision 28), issue 199 - * "What does allocate(0) return?", - * http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#199 - */ - -template > -struct auto_space:private noncopyable -{ - typedef typename boost::detail::allocator::rebind_to< - Allocator,T - >::type::pointer pointer; - - explicit auto_space(const Allocator& al=Allocator(),std::size_t n=1): - al_(al),n_(n),data_(n_?al_.allocate(n_):pointer(0)) - {} - - ~auto_space() - { - if(n_)al_.deallocate(data_,n_); - } - - Allocator get_allocator()const{return al_;} - - pointer data()const{return data_;} - - void swap(auto_space& x) - { - if(al_!=x.al_)adl_swap(al_,x.al_); - std::swap(n_,x.n_); - std::swap(data_,x.data_); - } - -private: - typename boost::detail::allocator::rebind_to< - Allocator,T>::type al_; - std::size_t n_; - pointer data_; -}; - -template -void swap(auto_space& x,auto_space& y) -{ - x.swap(y); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/base_type.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/base_type.hpp deleted file mode 100644 index 8c9b62b716a..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/base_type.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_BASE_TYPE_HPP -#define BOOST_MULTI_INDEX_DETAIL_BASE_TYPE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* MPL machinery to construct a linear hierarchy of indices out of - * a index list. - */ - -struct index_applier -{ - template - struct apply - { - typedef typename IndexSpecifierMeta::type index_specifier; - typedef typename index_specifier:: - BOOST_NESTED_TEMPLATE index_class::type type; - }; -}; - -template -struct nth_layer -{ - BOOST_STATIC_CONSTANT(int,length=mpl::size::value); - - typedef typename mpl::eval_if_c< - N==length, - mpl::identity >, - mpl::apply2< - index_applier, - mpl::at_c, - nth_layer - > - >::type type; -}; - -template -struct multi_index_base_type:nth_layer<0,Value,IndexSpecifierList,Allocator> -{ - BOOST_STATIC_ASSERT(detail::is_index_list::value); -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bidir_node_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bidir_node_iterator.hpp deleted file mode 100644 index 9be5ec84b43..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bidir_node_iterator.hpp +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright 2003-2014 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_BIDIR_NODE_ITERATOR_HPP -#define BOOST_MULTI_INDEX_DETAIL_BIDIR_NODE_ITERATOR_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#include -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Iterator class for node-based indices with bidirectional - * iterators (ordered and sequenced indices.) - */ - -template -class bidir_node_iterator: - public bidirectional_iterator_helper< - bidir_node_iterator, - typename Node::value_type, - std::ptrdiff_t, - const typename Node::value_type*, - const typename Node::value_type&> -{ -public: - /* coverity[uninit_ctor]: suppress warning */ - bidir_node_iterator(){} - explicit bidir_node_iterator(Node* node_):node(node_){} - - const typename Node::value_type& operator*()const - { - return node->value(); - } - - bidir_node_iterator& operator++() - { - Node::increment(node); - return *this; - } - - bidir_node_iterator& operator--() - { - Node::decrement(node); - return *this; - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* Serialization. As for why the following is public, - * see explanation in safe_mode_iterator notes in safe_mode.hpp. - */ - - BOOST_SERIALIZATION_SPLIT_MEMBER() - - typedef typename Node::base_type node_base_type; - - template - void save(Archive& ar,const unsigned int)const - { - node_base_type* bnode=node; - ar< - void load(Archive& ar,const unsigned int) - { - node_base_type* bnode; - ar>>serialization::make_nvp("pointer",bnode); - node=static_cast(bnode); - } -#endif - - /* get_node is not to be used by the user */ - - typedef Node node_type; - - Node* get_node()const{return node;} - -private: - Node* node; -}; - -template -bool operator==( - const bidir_node_iterator& x, - const bidir_node_iterator& y) -{ - return x.get_node()==y.get_node(); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bucket_array.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bucket_array.hpp deleted file mode 100644 index d9fa434d9a9..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/bucket_array.hpp +++ /dev/null @@ -1,243 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_BUCKET_ARRAY_HPP -#define BOOST_MULTI_INDEX_DETAIL_BUCKET_ARRAY_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#include -#include -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* bucket structure for use by hashed indices */ - -#define BOOST_MULTI_INDEX_BA_SIZES_32BIT \ -(53ul)(97ul)(193ul)(389ul)(769ul) \ -(1543ul)(3079ul)(6151ul)(12289ul)(24593ul) \ -(49157ul)(98317ul)(196613ul)(393241ul)(786433ul) \ -(1572869ul)(3145739ul)(6291469ul)(12582917ul)(25165843ul) \ -(50331653ul)(100663319ul)(201326611ul)(402653189ul)(805306457ul) \ -(1610612741ul)(3221225473ul) - -#if ((((ULONG_MAX>>16)>>16)>>16)>>15)==0 /* unsigned long less than 64 bits */ -#define BOOST_MULTI_INDEX_BA_SIZES \ -BOOST_MULTI_INDEX_BA_SIZES_32BIT \ -(4294967291ul) -#else - /* obtained with aid from - * http://javaboutique.internet.com/prime_numb/ - * http://www.rsok.com/~jrm/next_ten_primes.html - * and verified with - * http://www.alpertron.com.ar/ECM.HTM - */ - -#define BOOST_MULTI_INDEX_BA_SIZES \ -BOOST_MULTI_INDEX_BA_SIZES_32BIT \ -(6442450939ul)(12884901893ul)(25769803751ul)(51539607551ul) \ -(103079215111ul)(206158430209ul)(412316860441ul)(824633720831ul) \ -(1649267441651ul)(3298534883309ul)(6597069766657ul)(13194139533299ul) \ -(26388279066623ul)(52776558133303ul)(105553116266489ul)(211106232532969ul) \ -(422212465066001ul)(844424930131963ul)(1688849860263953ul) \ -(3377699720527861ul)(6755399441055731ul)(13510798882111483ul) \ -(27021597764222939ul)(54043195528445957ul)(108086391056891903ul) \ -(216172782113783843ul)(432345564227567621ul)(864691128455135207ul) \ -(1729382256910270481ul)(3458764513820540933ul)(6917529027641081903ul) \ -(13835058055282163729ul)(18446744073709551557ul) -#endif - -template /* templatized to have in-header static var defs */ -class bucket_array_base:private noncopyable -{ -protected: - static const std::size_t sizes[ - BOOST_PP_SEQ_SIZE(BOOST_MULTI_INDEX_BA_SIZES)]; - - static std::size_t size_index(std::size_t n) - { - const std::size_t *bound=std::lower_bound(sizes,sizes+sizes_length,n); - if(bound==sizes+sizes_length)--bound; - return bound-sizes; - } - -#define BOOST_MULTI_INDEX_BA_POSITION_CASE(z,n,_) \ - case n:return hash%BOOST_PP_SEQ_ELEM(n,BOOST_MULTI_INDEX_BA_SIZES); - - static std::size_t position(std::size_t hash,std::size_t size_index_) - { - /* Accelerate hash%sizes[size_index_] by replacing with a switch on - * hash%Ci expressions, each Ci a compile-time constant, which the - * compiler can implement without using integer division. - */ - - switch(size_index_){ - default: /* never used */ - BOOST_PP_REPEAT( - BOOST_PP_SEQ_SIZE(BOOST_MULTI_INDEX_BA_SIZES), - BOOST_MULTI_INDEX_BA_POSITION_CASE,~) - } - } - -private: - static const std::size_t sizes_length; -}; - -template -const std::size_t bucket_array_base<_>::sizes[]={ - BOOST_PP_SEQ_ENUM(BOOST_MULTI_INDEX_BA_SIZES) -}; - -template -const std::size_t bucket_array_base<_>::sizes_length= - sizeof(bucket_array_base<_>::sizes)/ - sizeof(bucket_array_base<_>::sizes[0]); - -#undef BOOST_MULTI_INDEX_BA_POSITION_CASE -#undef BOOST_MULTI_INDEX_BA_SIZES -#undef BOOST_MULTI_INDEX_BA_SIZES_32BIT - -template -class bucket_array:bucket_array_base<> -{ - typedef bucket_array_base<> super; - typedef hashed_index_base_node_impl< - typename boost::detail::allocator::rebind_to< - Allocator, - char - >::type - > base_node_impl_type; - -public: - typedef typename base_node_impl_type::base_pointer base_pointer; - typedef typename base_node_impl_type::pointer pointer; - - bucket_array(const Allocator& al,pointer end_,std::size_t size_): - size_index_(super::size_index(size_)), - spc(al,super::sizes[size_index_]+1) - { - clear(end_); - } - - std::size_t size()const - { - return super::sizes[size_index_]; - } - - std::size_t position(std::size_t hash)const - { - return super::position(hash,size_index_); - } - - base_pointer begin()const{return buckets();} - base_pointer end()const{return buckets()+size();} - base_pointer at(std::size_t n)const{return buckets()+n;} - - void clear(pointer end_) - { - for(base_pointer x=begin(),y=end();x!=y;++x)x->prior()=pointer(0); - end()->prior()=end_->prior()=end_; - end_->next()=end(); - } - - void swap(bucket_array& x) - { - std::swap(size_index_,x.size_index_); - spc.swap(x.spc); - } - -private: - std::size_t size_index_; - auto_space spc; - - base_pointer buckets()const - { - return spc.data(); - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - friend class boost::serialization::access; - - /* bucket_arrays do not emit any kind of serialization info. They are - * fed to Boost.Serialization as hashed index iterators need to track - * them during serialization. - */ - - template - void serialize(Archive&,const unsigned int) - { - } -#endif -}; - -template -void swap(bucket_array& x,bucket_array& y) -{ - x.swap(y); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -/* bucket_arrays never get constructed directly by Boost.Serialization, - * as archives are always fed pointers to previously existent - * arrays. So, if this is called it means we are dealing with a - * somehow invalid archive. - */ - -#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) -namespace serialization{ -#else -namespace multi_index{ -namespace detail{ -#endif - -template -inline void load_construct_data( - Archive&,boost::multi_index::detail::bucket_array*, - const unsigned int) -{ - throw_exception( - archive::archive_exception(archive::archive_exception::other_exception)); -} - -#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) -} /* namespace serialization */ -#else -} /* namespace multi_index::detail */ -} /* namespace multi_index */ -#endif - -#endif - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/cons_stdtuple.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/cons_stdtuple.hpp deleted file mode 100644 index 855c5e06aa9..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/cons_stdtuple.hpp +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright 2003-2014 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_CONS_STDTUPLE_HPP -#define BOOST_MULTI_INDEX_DETAIL_CONS_STDTUPLE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* std::tuple wrapper providing the cons-based interface of boost::tuple for - * composite_key interoperability. - */ - -template -struct cons_stdtuple; - -struct cons_stdtuple_ctor_terminal -{ - typedef boost::tuples::null_type result_type; - - template - static result_type create(const StdTuple&) - { - return boost::tuples::null_type(); - } -}; - -template -struct cons_stdtuple_ctor_normal -{ - typedef cons_stdtuple result_type; - - static result_type create(const StdTuple& t) - { - return result_type(t); - } -}; - -template -struct cons_stdtuple_ctor: - boost::mpl::if_c< - N::value, - cons_stdtuple_ctor_normal, - cons_stdtuple_ctor_terminal - >::type -{}; - -template -struct cons_stdtuple -{ - typedef typename std::tuple_element::type head_type; - typedef cons_stdtuple_ctor tail_ctor; - typedef typename tail_ctor::result_type tail_type; - - cons_stdtuple(const StdTuple& t_):t(t_){} - - const head_type& get_head()const{return std::get(t);} - tail_type get_tail()const{return tail_ctor::create(t);} - - const StdTuple& t; -}; - -template -typename cons_stdtuple_ctor::result_type -make_cons_stdtuple(const StdTuple& t) -{ - return cons_stdtuple_ctor::create(t); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/converter.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/converter.hpp deleted file mode 100644 index 3e04a3e8295..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/converter.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_CONVERTER_HPP -#define BOOST_MULTI_INDEX_DETAIL_CONVERTER_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* converter offers means to access indices of a given multi_index_container - * and for convertibilty between index iterators, so providing a - * localized access point for get() and project() functions. - */ - -template -struct converter -{ - static const Index& index(const MultiIndexContainer& x){return x;} - static Index& index(MultiIndexContainer& x){return x;} - - static typename Index::const_iterator const_iterator( - const MultiIndexContainer& x,typename MultiIndexContainer::node_type* node) - { - return x.Index::make_iterator(node); - } - - static typename Index::iterator iterator( - MultiIndexContainer& x,typename MultiIndexContainer::node_type* node) - { - return x.Index::make_iterator(node); - } -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/copy_map.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/copy_map.hpp deleted file mode 100644 index 9a34b259cf3..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/copy_map.hpp +++ /dev/null @@ -1,142 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_COPY_MAP_HPP -#define BOOST_MULTI_INDEX_DETAIL_COPY_MAP_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* copy_map is used as an auxiliary structure during copy_() operations. - * When a container with n nodes is replicated, node_map holds the pairings - * between original and copied nodes, and provides a fast way to find a - * copied node from an original one. - * The semantics of the class are not simple, and no attempt has been made - * to enforce it: multi_index_container handles it right. On the other hand, - * the const interface, which is the one provided to index implementations, - * only allows for: - * - Enumeration of pairs of (original,copied) nodes (excluding the headers), - * - fast retrieval of copied nodes (including the headers.) - */ - -template -struct copy_map_entry -{ - copy_map_entry(Node* f,Node* s):first(f),second(s){} - - Node* first; - Node* second; - - bool operator<(const copy_map_entry& x)const - { - return std::less()(first,x.first); - } -}; - -template -class copy_map:private noncopyable -{ -public: - typedef const copy_map_entry* const_iterator; - - copy_map( - const Allocator& al,std::size_t size,Node* header_org,Node* header_cpy): - al_(al),size_(size),spc(al_,size_),n(0), - header_org_(header_org),header_cpy_(header_cpy),released(false) - {} - - ~copy_map() - { - if(!released){ - for(std::size_t i=0;isecond->value()); - deallocate((spc.data()+i)->second); - } - } - } - - const_iterator begin()const{return raw_ptr(spc.data());} - const_iterator end()const{return raw_ptr(spc.data()+n);} - - void clone(Node* node) - { - (spc.data()+n)->first=node; - (spc.data()+n)->second=raw_ptr(al_.allocate(1)); - BOOST_TRY{ - boost::detail::allocator::construct( - &(spc.data()+n)->second->value(),node->value()); - } - BOOST_CATCH(...){ - deallocate((spc.data()+n)->second); - BOOST_RETHROW; - } - BOOST_CATCH_END - ++n; - - if(n==size_){ - std::sort( - raw_ptr*>(spc.data()), - raw_ptr*>(spc.data())+size_); - } - } - - Node* find(Node* node)const - { - if(node==header_org_)return header_cpy_; - return std::lower_bound( - begin(),end(),copy_map_entry(node,0))->second; - } - - void release() - { - released=true; - } - -private: - typedef typename boost::detail::allocator::rebind_to< - Allocator,Node - >::type allocator_type; - typedef typename allocator_type::pointer allocator_pointer; - - allocator_type al_; - std::size_t size_; - auto_space,Allocator> spc; - std::size_t n; - Node* header_org_; - Node* header_cpy_; - bool released; - - void deallocate(Node* node) - { - al_.deallocate(static_cast(node),1); - } -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/do_not_copy_elements_tag.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/do_not_copy_elements_tag.hpp deleted file mode 100644 index f0fa7304253..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/do_not_copy_elements_tag.hpp +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_DO_NOT_COPY_ELEMENTS_TAG_HPP -#define BOOST_MULTI_INDEX_DETAIL_DO_NOT_COPY_ELEMENTS_TAG_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Used to mark a special ctor variant that copies the internal objects of - * a container but not its elements. - */ - -struct do_not_copy_elements_tag{}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/duplicates_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/duplicates_iterator.hpp deleted file mode 100644 index cbebf264045..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/duplicates_iterator.hpp +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP -#define BOOST_MULTI_INDEX_DETAIL_DUPLICATES_ITERATOR_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* duplicates_operator is given a range of ordered elements and - * passes only over those which are duplicated. - */ - -template -class duplicates_iterator -{ -public: - typedef typename Node::value_type value_type; - typedef std::ptrdiff_t difference_type; - typedef const typename Node::value_type* pointer; - typedef const typename Node::value_type& reference; - typedef std::forward_iterator_tag iterator_category; - - duplicates_iterator(Node* node_,Node* end_,Predicate pred_): - node(node_),begin_chunk(0),end(end_),pred(pred_) - { - advance(); - } - - duplicates_iterator(Node* end_,Predicate pred_): - node(end_),begin_chunk(end_),end(end_),pred(pred_) - { - } - - reference operator*()const - { - return node->value(); - } - - pointer operator->()const - { - return &node->value(); - } - - duplicates_iterator& operator++() - { - Node::increment(node); - sync(); - return *this; - } - - duplicates_iterator operator++(int) - { - duplicates_iterator tmp(*this); - ++(*this); - return tmp; - } - - Node* get_node()const{return node;} - -private: - void sync() - { - if(node!=end&&pred(begin_chunk->value(),node->value()))advance(); - } - - void advance() - { - for(Node* node2=node;node!=end;node=node2){ - Node::increment(node2); - if(node2!=end&&!pred(node->value(),node2->value()))break; - } - begin_chunk=node; - } - - Node* node; - Node* begin_chunk; - Node* end; - Predicate pred; -}; - -template -bool operator==( - const duplicates_iterator& x, - const duplicates_iterator& y) -{ - return x.get_node()==y.get_node(); -} - -template -bool operator!=( - const duplicates_iterator& x, - const duplicates_iterator& y) -{ - return !(x==y); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/has_tag.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/has_tag.hpp deleted file mode 100644 index 217b61143af..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/has_tag.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_HAS_TAG_HPP -#define BOOST_MULTI_INDEX_DETAIL_HAS_TAG_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* determines whether an index type has a given tag in its tag list */ - -template -struct has_tag -{ - template - struct apply:mpl::contains - { - }; -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_args.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_args.hpp deleted file mode 100644 index 81902f5a4a5..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_args.hpp +++ /dev/null @@ -1,105 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ARGS_HPP -#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ARGS_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Hashed index specifiers can be instantiated in two forms: - * - * (hashed_unique|hashed_non_unique)< - * KeyFromValue, - * Hash=boost::hash, - * Pred=std::equal_to > - * (hashed_unique|hashed_non_unique)< - * TagList, - * KeyFromValue, - * Hash=boost::hash, - * Pred=std::equal_to > - * - * hashed_index_args implements the machinery to accept this - * argument-dependent polymorphism. - */ - -template -struct index_args_default_hash -{ - typedef ::boost::hash type; -}; - -template -struct index_args_default_pred -{ - typedef std::equal_to type; -}; - -template -struct hashed_index_args -{ - typedef is_tag full_form; - - typedef typename mpl::if_< - full_form, - Arg1, - tag< > >::type tag_list_type; - typedef typename mpl::if_< - full_form, - Arg2, - Arg1>::type key_from_value_type; - typedef typename mpl::if_< - full_form, - Arg3, - Arg2>::type supplied_hash_type; - typedef typename mpl::eval_if< - mpl::is_na, - index_args_default_hash, - mpl::identity - >::type hash_type; - typedef typename mpl::if_< - full_form, - Arg4, - Arg3>::type supplied_pred_type; - typedef typename mpl::eval_if< - mpl::is_na, - index_args_default_pred, - mpl::identity - >::type pred_type; - - BOOST_STATIC_ASSERT(is_tag::value); - BOOST_STATIC_ASSERT(!mpl::is_na::value); - BOOST_STATIC_ASSERT(!mpl::is_na::value); - BOOST_STATIC_ASSERT(!mpl::is_na::value); -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_iterator.hpp deleted file mode 100644 index 8d063002a1d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_iterator.hpp +++ /dev/null @@ -1,166 +0,0 @@ -/* Copyright 2003-2014 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_HPP -#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#include -#include -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Iterator class for hashed indices. - */ - -struct hashed_index_global_iterator_tag{}; -struct hashed_index_local_iterator_tag{}; - -template -class hashed_index_iterator: - public forward_iterator_helper< - hashed_index_iterator, - typename Node::value_type, - std::ptrdiff_t, - const typename Node::value_type*, - const typename Node::value_type&> -{ -public: - /* coverity[uninit_ctor]: suppress warning */ - hashed_index_iterator(){} - hashed_index_iterator(Node* node_):node(node_){} - - const typename Node::value_type& operator*()const - { - return node->value(); - } - - hashed_index_iterator& operator++() - { - this->increment(Category()); - return *this; - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* Serialization. As for why the following is public, - * see explanation in safe_mode_iterator notes in safe_mode.hpp. - */ - - BOOST_SERIALIZATION_SPLIT_MEMBER() - - typedef typename Node::base_type node_base_type; - - template - void save(Archive& ar,const unsigned int)const - { - node_base_type* bnode=node; - ar< - void load(Archive& ar,const unsigned int version) - { - load(ar,version,Category()); - } - - template - void load( - Archive& ar,const unsigned int version,hashed_index_global_iterator_tag) - { - node_base_type* bnode; - ar>>serialization::make_nvp("pointer",bnode); - node=static_cast(bnode); - if(version<1){ - BucketArray* throw_away; /* consume unused ptr */ - ar>>serialization::make_nvp("pointer",throw_away); - } - } - - template - void load( - Archive& ar,const unsigned int version,hashed_index_local_iterator_tag) - { - node_base_type* bnode; - ar>>serialization::make_nvp("pointer",bnode); - node=static_cast(bnode); - if(version<1){ - BucketArray* buckets; - ar>>serialization::make_nvp("pointer",buckets); - if(buckets&&node&&node->impl()==buckets->end()->prior()){ - /* end local_iterators used to point to end node, now they are null */ - node=0; - } - } - } -#endif - - /* get_node is not to be used by the user */ - - typedef Node node_type; - - Node* get_node()const{return node;} - -private: - - void increment(hashed_index_global_iterator_tag) - { - Node::increment(node); - } - - void increment(hashed_index_local_iterator_tag) - { - Node::increment_local(node); - } - - Node* node; -}; - -template -bool operator==( - const hashed_index_iterator& x, - const hashed_index_iterator& y) -{ - return x.get_node()==y.get_node(); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -/* class version = 1 : hashed_index_iterator does no longer serialize a bucket - * array pointer. - */ - -namespace serialization { -template -struct version< - boost::multi_index::detail::hashed_index_iterator -> -{ - BOOST_STATIC_CONSTANT(int,value=1); -}; -} /* namespace serialization */ -#endif - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_node.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_node.hpp deleted file mode 100644 index 7788e810ac9..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/hash_index_node.hpp +++ /dev/null @@ -1,778 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_NODE_HPP -#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_NODE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Certain C++ requirements on unordered associative containers (see LWG issue - * #579) imply a data structure where nodes are linked in a single list, which - * in its turn forces implementors to add additional overhed per node to - * associate each with its corresponding bucket. Others resort to storing hash - * values, we use an alternative structure providing unconditional O(1) - * manipulation, even in situations of unfair hash distribution, plus some - * lookup speedups. For unique indices we maintain a doubly linked list of - * nodes except that if N is the first node of a bucket its associated - * bucket node is embedded between N and the preceding node in the following - * manner: - * - * +---+ +---+ +---+ +---+ - * <--+ |<--+ | <--+ |<--+ | - * ... | B0| | B1| ... | B1| | B2| ... - * | |-+ | +--> | |-+ | +--> - * +-+-+ | +---+ +-+-+ | +---+ - * | ^ | ^ - * | | | | - * | +-+ | +-+ - * | | | | - * v | v | - * --+---+---+---+-- --+---+---+---+-- - * ... | | B1| | ... | | B2| | ... - * --+---+---+---+-- --+---+---+---+-- - * - * - * The fist and last nodes of buckets can be checked with - * - * first node of a bucket: Npn != N - * last node of a bucket: Nnp != N - * - * (n and p short for ->next(), ->prior(), bucket nodes have prior pointers - * only). Pure insert and erase (without lookup) can be unconditionally done - * in O(1). - * For non-unique indices we add the following additional complexity: when - * there is a group of 3 or more equivalent elements, they are linked as - * follows: - * - * +-----------------------+ - * | v - * +---+ | +---+ +---+ +---+ - * | | +-+ | | |<--+ | - * | F | | S | ... | P | | L | - * | +-->| | | +-+ | | - * +---+ +---+ +---+ | +---+ - * ^ | - * +-----------------------+ - * - * F, S, P and L are the first, second, penultimate and last node in the - * group, respectively (S and P can coincide if the group has size 3.) This - * arrangement is used to skip equivalent elements in O(1) when doing lookup, - * while preserving O(1) insert/erase. The following invariants identify - * special positions (some of the operations have to be carefully implemented - * as Xnn is not valid if Xn points to a bucket): - * - * first node of a bucket: Npnp == N - * last node of a bucket: Nnpp == N - * first node of a group: Nnp != N && Nnppn == N - * second node of a group: Npn != N && Nppnn == N - * n-1 node of a group: Nnp != N && Nnnpp == N - * last node of a group: Npn != N && Npnnp == N - * - * The memory overhead is one pointer per bucket plus two pointers per node, - * probably unbeatable. The resulting structure is bidirectonally traversable, - * though currently we are just providing forward iteration. - */ - -template -struct hashed_index_node_impl; - -/* half-header (only prior() pointer) to use for the bucket array */ - -template -struct hashed_index_base_node_impl -{ - typedef typename - boost::detail::allocator::rebind_to< - Allocator,hashed_index_base_node_impl - >::type::pointer base_pointer; - typedef typename - boost::detail::allocator::rebind_to< - Allocator,hashed_index_base_node_impl - >::type::const_pointer const_base_pointer; - typedef typename - boost::detail::allocator::rebind_to< - Allocator, - hashed_index_node_impl - >::type::pointer pointer; - typedef typename - boost::detail::allocator::rebind_to< - Allocator, - hashed_index_node_impl - >::type::const_pointer const_pointer; - - pointer& prior(){return prior_;} - pointer prior()const{return prior_;} - -private: - pointer prior_; -}; - -/* full header (prior() and next()) for the nodes */ - -template -struct hashed_index_node_impl:hashed_index_base_node_impl -{ -private: - typedef hashed_index_base_node_impl super; - -public: - typedef typename super::base_pointer base_pointer; - typedef typename super::const_base_pointer const_base_pointer; - typedef typename super::pointer pointer; - typedef typename super::const_pointer const_pointer; - - base_pointer& next(){return next_;} - base_pointer next()const{return next_;} - - static pointer pointer_from(base_pointer x) - { - return static_cast( - static_cast( - raw_ptr(x))); - } - - static base_pointer base_pointer_from(pointer x) - { - return static_cast( - raw_ptr(x)); - } - -private: - base_pointer next_; -}; - -/* Boost.MultiIndex requires machinery to reverse unlink operations. A simple - * way to make a pointer-manipulation function undoable is to templatize - * its internal pointer assignments with a functor that, besides doing the - * assignment, keeps track of the original pointer values and can later undo - * the operations in reverse order. - */ - -struct default_assigner -{ - template void operator()(T& x,const T& val){x=val;} -}; - -template -struct unlink_undo_assigner -{ - typedef typename Node::base_pointer base_pointer; - typedef typename Node::pointer pointer; - - unlink_undo_assigner():pointer_track_count(0),base_pointer_track_count(0){} - - void operator()(pointer& x,pointer val) - { - pointer_tracks[pointer_track_count].x=&x; - pointer_tracks[pointer_track_count++].val=x; - x=val; - } - - void operator()(base_pointer& x,base_pointer val) - { - base_pointer_tracks[base_pointer_track_count].x=&x; - base_pointer_tracks[base_pointer_track_count++].val=x; - x=val; - } - - void operator()() /* undo op */ - { - /* in the absence of aliasing, restitution order is immaterial */ - - while(pointer_track_count--){ - *(pointer_tracks[pointer_track_count].x)= - pointer_tracks[pointer_track_count].val; - } - while(base_pointer_track_count--){ - *(base_pointer_tracks[base_pointer_track_count].x)= - base_pointer_tracks[base_pointer_track_count].val; - } - } - - struct pointer_track {pointer* x; pointer val;}; - struct base_pointer_track{base_pointer* x; base_pointer val;}; - - /* We know the maximum number of pointer and base pointer assignments that - * the two unlink versions do, so we can statically reserve the needed - * storage. - */ - - pointer_track pointer_tracks[3]; - int pointer_track_count; - base_pointer_track base_pointer_tracks[2]; - int base_pointer_track_count; -}; - -/* algorithmic stuff for unique and non-unique variants */ - -struct hashed_unique_tag{}; -struct hashed_non_unique_tag{}; - -template -struct hashed_index_node_alg; - -template -struct hashed_index_node_alg -{ - typedef typename Node::base_pointer base_pointer; - typedef typename Node::const_base_pointer const_base_pointer; - typedef typename Node::pointer pointer; - typedef typename Node::const_pointer const_pointer; - - static bool is_first_of_bucket(pointer x) - { - return x->prior()->next()!=base_pointer_from(x); - } - - static pointer after(pointer x) - { - return is_last_of_bucket(x)?x->next()->prior():pointer_from(x->next()); - } - - static pointer after_local(pointer x) - { - return is_last_of_bucket(x)?pointer(0):pointer_from(x->next()); - } - - static pointer next_to_inspect(pointer x) - { - return is_last_of_bucket(x)?pointer(0):pointer_from(x->next()); - } - - static void link(pointer x,base_pointer buc,pointer end) - { - if(buc->prior()==pointer(0)){ /* empty bucket */ - x->prior()=end->prior(); - x->next()=end->prior()->next(); - x->prior()->next()=buc; - buc->prior()=x; - end->prior()=x; - } - else{ - x->prior()=buc->prior()->prior(); - x->next()=base_pointer_from(buc->prior()); - buc->prior()=x; - x->next()->prior()=x; - } - } - - static void unlink(pointer x) - { - default_assigner assign; - unlink(x,assign); - } - - typedef unlink_undo_assigner unlink_undo; - - template - static void unlink(pointer x,Assigner& assign) - { - if(is_first_of_bucket(x)){ - if(is_last_of_bucket(x)){ - assign(x->prior()->next()->prior(),pointer(0)); - assign(x->prior()->next(),x->next()); - assign(x->next()->prior()->prior(),x->prior()); - } - else{ - assign(x->prior()->next()->prior(),pointer_from(x->next())); - assign(x->next()->prior(),x->prior()); - } - } - else if(is_last_of_bucket(x)){ - assign(x->prior()->next(),x->next()); - assign(x->next()->prior()->prior(),x->prior()); - } - else{ - assign(x->prior()->next(),x->next()); - assign(x->next()->prior(),x->prior()); - } - } - - /* used only at rehashing */ - - static void append(pointer x,pointer end) - { - x->prior()=end->prior(); - x->next()=end->prior()->next(); - x->prior()->next()=base_pointer_from(x); - end->prior()=x; - } - - static bool unlink_last(pointer end) - { - /* returns true iff bucket is emptied */ - - pointer x=end->prior(); - if(x->prior()->next()==base_pointer_from(x)){ - x->prior()->next()=x->next(); - end->prior()=x->prior(); - return false; - } - else{ - x->prior()->next()->prior()=pointer(0); - x->prior()->next()=x->next(); - end->prior()=x->prior(); - return true; - } - } - -private: - static pointer pointer_from(base_pointer x) - { - return Node::pointer_from(x); - } - - static base_pointer base_pointer_from(pointer x) - { - return Node::base_pointer_from(x); - } - - static bool is_last_of_bucket(pointer x) - { - return x->next()->prior()!=x; - } -}; - -template -struct hashed_index_node_alg -{ - typedef typename Node::base_pointer base_pointer; - typedef typename Node::const_base_pointer const_base_pointer; - typedef typename Node::pointer pointer; - typedef typename Node::const_pointer const_pointer; - - static bool is_first_of_bucket(pointer x) - { - return x->prior()->next()->prior()==x; - } - - static bool is_first_of_group(pointer x) - { - return - x->next()->prior()!=x&& - x->next()->prior()->prior()->next()==base_pointer_from(x); - } - - static pointer after(pointer x) - { - if(x->next()->prior()==x)return pointer_from(x->next()); - if(x->next()->prior()->prior()==x)return x->next()->prior(); - if(x->next()->prior()->prior()->next()==base_pointer_from(x)) - return pointer_from(x->next()); - return pointer_from(x->next())->next()->prior(); - } - - static pointer after_local(pointer x) - { - if(x->next()->prior()==x)return pointer_from(x->next()); - if(x->next()->prior()->prior()==x)return pointer(0); - if(x->next()->prior()->prior()->next()==base_pointer_from(x)) - return pointer_from(x->next()); - return pointer_from(x->next())->next()->prior(); - } - - static pointer next_to_inspect(pointer x) - { - if(x->next()->prior()==x)return pointer_from(x->next()); - if(x->next()->prior()->prior()==x)return pointer(0); - if(x->next()->prior()->next()->prior()!=x->next()->prior()) - return pointer(0); - return pointer_from(x->next()->prior()->next()); - } - - static void link(pointer x,base_pointer buc,pointer end) - { - if(buc->prior()==pointer(0)){ /* empty bucket */ - x->prior()=end->prior(); - x->next()=end->prior()->next(); - x->prior()->next()=buc; - buc->prior()=x; - end->prior()=x; - } - else{ - x->prior()=buc->prior()->prior(); - x->next()=base_pointer_from(buc->prior()); - buc->prior()=x; - x->next()->prior()=x; - } - }; - - static void link(pointer x,pointer first,pointer last) - { - x->prior()=first->prior(); - x->next()=base_pointer_from(first); - if(is_first_of_bucket(first)){ - x->prior()->next()->prior()=x; - } - else{ - x->prior()->next()=base_pointer_from(x); - } - - if(first==last){ - last->prior()=x; - } - else if(first->next()==base_pointer_from(last)){ - first->prior()=last; - first->next()=base_pointer_from(x); - } - else{ - pointer second=pointer_from(first->next()), - lastbutone=last->prior(); - second->prior()=first; - first->prior()=last; - lastbutone->next()=base_pointer_from(x); - } - } - - static void unlink(pointer x) - { - default_assigner assign; - unlink(x,assign); - } - - typedef unlink_undo_assigner unlink_undo; - - template - static void unlink(pointer x,Assigner& assign) - { - if(x->prior()->next()==base_pointer_from(x)){ - if(x->next()->prior()==x){ - left_unlink(x,assign); - right_unlink(x,assign); - } - else if(x->next()->prior()->prior()==x){ /* last of bucket */ - left_unlink(x,assign); - right_unlink_last_of_bucket(x,assign); - } - else if(x->next()->prior()->prior()->next()== - base_pointer_from(x)){ /* first of group size */ - left_unlink(x,assign); - right_unlink_first_of_group(x,assign); - } - else{ /* n-1 of group */ - unlink_last_but_one_of_group(x,assign); - } - } - else if(x->prior()->next()->prior()==x){ /* first of bucket */ - if(x->next()->prior()==x){ - left_unlink_first_of_bucket(x,assign); - right_unlink(x,assign); - } - else if(x->next()->prior()->prior()==x){ /* last of bucket */ - assign(x->prior()->next()->prior(),pointer(0)); - assign(x->prior()->next(),x->next()); - assign(x->next()->prior()->prior(),x->prior()); - } - else{ /* first of group */ - left_unlink_first_of_bucket(x,assign); - right_unlink_first_of_group(x,assign); - } - } - else if(x->next()->prior()->prior()==x){ /* last of group and bucket */ - left_unlink_last_of_group(x,assign); - right_unlink_last_of_bucket(x,assign); - } - else if(pointer_from(x->prior()->prior()->next()) - ->next()==base_pointer_from(x)){ /* second of group */ - unlink_second_of_group(x,assign); - } - else{ /* last of group, ~(last of bucket) */ - left_unlink_last_of_group(x,assign); - right_unlink(x,assign); - } - } - - /* used only at rehashing */ - - static void link_range( - pointer first,pointer last,base_pointer buc,pointer cend) - { - if(buc->prior()==pointer(0)){ /* empty bucket */ - first->prior()=cend->prior(); - last->next()=cend->prior()->next(); - first->prior()->next()=buc; - buc->prior()=first; - cend->prior()=last; - } - else{ - first->prior()=buc->prior()->prior(); - last->next()=base_pointer_from(buc->prior()); - buc->prior()=first; - last->next()->prior()=last; - } - } - - static void append_range(pointer first,pointer last,pointer cend) - { - first->prior()=cend->prior(); - last->next()=cend->prior()->next(); - first->prior()->next()=base_pointer_from(first); - cend->prior()=last; - } - - static std::pair unlink_last_group(pointer end) - { - /* returns first of group true iff bucket is emptied */ - - pointer x=end->prior(); - if(x->prior()->next()==base_pointer_from(x)){ - x->prior()->next()=x->next(); - end->prior()=x->prior(); - return std::make_pair(x,false); - } - else if(x->prior()->next()->prior()==x){ - x->prior()->next()->prior()=pointer(0); - x->prior()->next()=x->next(); - end->prior()=x->prior(); - return std::make_pair(x,true); - } - else{ - pointer y=pointer_from(x->prior()->next()); - - if(y->prior()->next()==base_pointer_from(y)){ - y->prior()->next()=x->next(); - end->prior()=y->prior(); - return std::make_pair(y,false); - } - else{ - y->prior()->next()->prior()=pointer(0); - y->prior()->next()=x->next(); - end->prior()=y->prior(); - return std::make_pair(y,true); - } - } - } - - static void unlink_range(pointer first,pointer last) - { - if(is_first_of_bucket(first)){ - if(is_last_of_bucket(last)){ - first->prior()->next()->prior()=pointer(0); - first->prior()->next()=last->next(); - last->next()->prior()->prior()=first->prior(); - } - else{ - first->prior()->next()->prior()=pointer_from(last->next()); - last->next()->prior()=first->prior(); - } - } - else if(is_last_of_bucket(last)){ - first->prior()->next()=last->next(); - last->next()->prior()->prior()=first->prior(); - } - else{ - first->prior()->next()=last->next(); - last->next()->prior()=first->prior(); - } - } - -private: - static pointer pointer_from(base_pointer x) - { - return Node::pointer_from(x); - } - - static base_pointer base_pointer_from(pointer x) - { - return Node::base_pointer_from(x); - } - - static bool is_last_of_bucket(pointer x) - { - return x->next()->prior()->prior()==x; - } - - template - static void left_unlink(pointer x,Assigner& assign) - { - assign(x->prior()->next(),x->next()); - } - - template - static void right_unlink(pointer x,Assigner& assign) - { - assign(x->next()->prior(),x->prior()); - } - - template - static void left_unlink_first_of_bucket(pointer x,Assigner& assign) - { - assign(x->prior()->next()->prior(),pointer_from(x->next())); - } - - template - static void right_unlink_last_of_bucket(pointer x,Assigner& assign) - { - assign(x->next()->prior()->prior(),x->prior()); - } - - template - static void right_unlink_first_of_group(pointer x,Assigner& assign) - { - pointer second=pointer_from(x->next()), - last=second->prior(), - lastbutone=last->prior(); - if(second==lastbutone){ - assign(second->next(),base_pointer_from(last)); - assign(second->prior(),x->prior()); - } - else{ - assign(lastbutone->next(),base_pointer_from(second)); - assign(second->next()->prior(),last); - assign(second->prior(),x->prior()); - } - } - - template - static void left_unlink_last_of_group(pointer x,Assigner& assign) - { - pointer lastbutone=x->prior(), - first=pointer_from(lastbutone->next()), - second=pointer_from(first->next()); - if(lastbutone==second){ - assign(lastbutone->prior(),first); - assign(lastbutone->next(),x->next()); - } - else{ - assign(second->prior(),lastbutone); - assign(lastbutone->prior()->next(),base_pointer_from(first)); - assign(lastbutone->next(),x->next()); - } - } - - template - static void unlink_last_but_one_of_group(pointer x,Assigner& assign) - { - pointer first=pointer_from(x->next()), - second=pointer_from(first->next()), - last=second->prior(); - if(second==x){ - assign(last->prior(),first); - assign(first->next(),base_pointer_from(last)); - } - else{ - assign(last->prior(),x->prior()); - assign(x->prior()->next(),base_pointer_from(first)); - } - } - - template - static void unlink_second_of_group(pointer x,Assigner& assign) - { - pointer last=x->prior(), - lastbutone=last->prior(), - first=pointer_from(lastbutone->next()); - if(lastbutone==x){ - assign(first->next(),base_pointer_from(last)); - assign(last->prior(),first); - } - else{ - assign(first->next(),x->next()); - assign(x->next()->prior(),last); - } - } -}; - -template -struct hashed_index_node_trampoline: - hashed_index_node_impl< - typename boost::detail::allocator::rebind_to< - typename Super::allocator_type, - char - >::type - > -{ - typedef typename boost::detail::allocator::rebind_to< - typename Super::allocator_type, - char - >::type impl_allocator_type; - typedef hashed_index_node_impl impl_type; -}; - -template -struct hashed_index_node: - Super,hashed_index_node_trampoline -{ -private: - typedef hashed_index_node_trampoline trampoline; - -public: - typedef typename trampoline::impl_type impl_type; - typedef hashed_index_node_alg< - impl_type,Category> node_alg; - typedef typename trampoline::base_pointer impl_base_pointer; - typedef typename trampoline::const_base_pointer const_impl_base_pointer; - typedef typename trampoline::pointer impl_pointer; - typedef typename trampoline::const_pointer const_impl_pointer; - - impl_pointer& prior(){return trampoline::prior();} - impl_pointer prior()const{return trampoline::prior();} - impl_base_pointer& next(){return trampoline::next();} - impl_base_pointer next()const{return trampoline::next();} - - impl_pointer impl() - { - return static_cast( - static_cast(static_cast(this))); - } - - const_impl_pointer impl()const - { - return static_cast( - static_cast(static_cast(this))); - } - - static hashed_index_node* from_impl(impl_pointer x) - { - return - static_cast( - static_cast( - raw_ptr(x))); - } - - static const hashed_index_node* from_impl(const_impl_pointer x) - { - return - static_cast( - static_cast( - raw_ptr(x))); - } - - /* interoperability with hashed_index_iterator */ - - static void increment(hashed_index_node*& x) - { - x=from_impl(node_alg::after(x->impl())); - } - - static void increment_local(hashed_index_node*& x) - { - x=from_impl(node_alg::after_local(x->impl())); - } -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/header_holder.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/header_holder.hpp deleted file mode 100644 index ca8a9b2edb1..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/header_holder.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright 2003-2008 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_HEADER_HOLDER_HPP -#define BOOST_MULTI_INDEX_DETAIL_HEADER_HOLDER_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* A utility class used to hold a pointer to the header node. - * The base from member idiom is used because index classes, which are - * superclasses of multi_index_container, need this header in construction - * time. The allocation is made by the allocator of the multi_index_container - * class --hence, this allocator needs also be stored resorting - * to the base from member trick. - */ - -template -struct header_holder:private noncopyable -{ - header_holder():member(final().allocate_node()){} - ~header_holder(){final().deallocate_node(&*member);} - - NodeTypePtr member; - -private: - Final& final(){return *static_cast(this);} -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ignore_wstrict_aliasing.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ignore_wstrict_aliasing.hpp deleted file mode 100644 index ae398456d1f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ignore_wstrict_aliasing.hpp +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright 2003-2016 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#include - -#if defined(BOOST_GCC)&&(BOOST_GCC>=4*10000+6*100) -#if !defined(BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wstrict-aliasing" -#else -#pragma GCC diagnostic pop -#endif -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_base.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_base.hpp deleted file mode 100644 index 99000ed4813..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_base.hpp +++ /dev/null @@ -1,293 +0,0 @@ -/* Copyright 2003-2014 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP -#define BOOST_MULTI_INDEX_DETAIL_INDEX_BASE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#include -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* The role of this class is threefold: - * - tops the linear hierarchy of indices. - * - terminates some cascading backbone function calls (insert_, etc.), - * - grants access to the backbone functions of the final - * multi_index_container class (for access restriction reasons, these - * cannot be called directly from the index classes.) - */ - -struct lvalue_tag{}; -struct rvalue_tag{}; -struct emplaced_tag{}; - -template -class index_base -{ -protected: - typedef index_node_base node_type; - typedef typename multi_index_node_type< - Value,IndexSpecifierList,Allocator>::type final_node_type; - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> final_type; - typedef tuples::null_type ctor_args_list; - typedef typename - boost::detail::allocator::rebind_to< - Allocator, - typename Allocator::value_type - >::type final_allocator_type; - typedef mpl::vector0<> index_type_list; - typedef mpl::vector0<> iterator_type_list; - typedef mpl::vector0<> const_iterator_type_list; - typedef copy_map< - final_node_type, - final_allocator_type> copy_map_type; - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - typedef index_saver< - node_type, - final_allocator_type> index_saver_type; - typedef index_loader< - node_type, - final_node_type, - final_allocator_type> index_loader_type; -#endif - -private: - typedef Value value_type; - -protected: - explicit index_base(const ctor_args_list&,const Allocator&){} - - index_base( - const index_base&, - do_not_copy_elements_tag) - {} - - void copy_( - const index_base&,const copy_map_type&) - {} - - final_node_type* insert_(const value_type& v,final_node_type*& x,lvalue_tag) - { - x=final().allocate_node(); - BOOST_TRY{ - boost::detail::allocator::construct(&x->value(),v); - } - BOOST_CATCH(...){ - final().deallocate_node(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - return x; - } - - final_node_type* insert_(const value_type& v,final_node_type*& x,rvalue_tag) - { - x=final().allocate_node(); - BOOST_TRY{ - /* This shoud have used a modified, T&&-compatible version of - * boost::detail::allocator::construct, but - * is too old and venerable to - * mess with; besides, it is a general internal utility and the imperfect - * perfect forwarding emulation of Boost.Move might break other libs. - */ - - new (&x->value()) value_type(boost::move(const_cast(v))); - } - BOOST_CATCH(...){ - final().deallocate_node(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - return x; - } - - final_node_type* insert_(const value_type&,final_node_type*& x,emplaced_tag) - { - return x; - } - - final_node_type* insert_( - const value_type& v,node_type*,final_node_type*& x,lvalue_tag) - { - return insert_(v,x,lvalue_tag()); - } - - final_node_type* insert_( - const value_type& v,node_type*,final_node_type*& x,rvalue_tag) - { - return insert_(v,x,rvalue_tag()); - } - - final_node_type* insert_( - const value_type&,node_type*,final_node_type*& x,emplaced_tag) - { - return x; - } - - void erase_(node_type* x) - { - boost::detail::allocator::destroy(&x->value()); - } - - void delete_node_(node_type* x) - { - boost::detail::allocator::destroy(&x->value()); - } - - void clear_(){} - - void swap_(index_base&){} - - void swap_elements_(index_base&){} - - bool replace_(const value_type& v,node_type* x,lvalue_tag) - { - x->value()=v; - return true; - } - - bool replace_(const value_type& v,node_type* x,rvalue_tag) - { - x->value()=boost::move(const_cast(v)); - return true; - } - - bool modify_(node_type*){return true;} - - bool modify_rollback_(node_type*){return true;} - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* serialization */ - - template - void save_(Archive&,const unsigned int,const index_saver_type&)const{} - - template - void load_(Archive&,const unsigned int,const index_loader_type&){} -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - bool invariant_()const{return true;} -#endif - - /* access to backbone memfuns of Final class */ - - final_type& final(){return *static_cast(this);} - const final_type& final()const{return *static_cast(this);} - - final_node_type* final_header()const{return final().header();} - - bool final_empty_()const{return final().empty_();} - std::size_t final_size_()const{return final().size_();} - std::size_t final_max_size_()const{return final().max_size_();} - - std::pair final_insert_(const value_type& x) - {return final().insert_(x);} - std::pair final_insert_rv_(const value_type& x) - {return final().insert_rv_(x);} - template - std::pair final_insert_ref_(const T& t) - {return final().insert_ref_(t);} - template - std::pair final_insert_ref_(T& t) - {return final().insert_ref_(t);} - - template - std::pair final_emplace_( - BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - return final().emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - } - - std::pair final_insert_( - const value_type& x,final_node_type* position) - {return final().insert_(x,position);} - std::pair final_insert_rv_( - const value_type& x,final_node_type* position) - {return final().insert_rv_(x,position);} - template - std::pair final_insert_ref_( - const T& t,final_node_type* position) - {return final().insert_ref_(t,position);} - template - std::pair final_insert_ref_( - T& t,final_node_type* position) - {return final().insert_ref_(t,position);} - - template - std::pair final_emplace_hint_( - final_node_type* position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - return final().emplace_hint_( - position,BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - } - - void final_erase_(final_node_type* x){final().erase_(x);} - - void final_delete_node_(final_node_type* x){final().delete_node_(x);} - void final_delete_all_nodes_(){final().delete_all_nodes_();} - void final_clear_(){final().clear_();} - - void final_swap_(final_type& x){final().swap_(x);} - - bool final_replace_( - const value_type& k,final_node_type* x) - {return final().replace_(k,x);} - bool final_replace_rv_( - const value_type& k,final_node_type* x) - {return final().replace_rv_(k,x);} - - template - bool final_modify_(Modifier& mod,final_node_type* x) - {return final().modify_(mod,x);} - - template - bool final_modify_(Modifier& mod,Rollback& back,final_node_type* x) - {return final().modify_(mod,back,x);} - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - void final_check_invariant_()const{final().check_invariant_();} -#endif -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_loader.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_loader.hpp deleted file mode 100644 index 71418a10e19..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_loader.hpp +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP -#define BOOST_MULTI_INDEX_DETAIL_INDEX_LOADER_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Counterpart of index_saver (check index_saver.hpp for serialization - * details.)* multi_index_container is in charge of supplying the info about - * the base sequence, and each index can subsequently load itself using the - * const interface of index_loader. - */ - -template -class index_loader:private noncopyable -{ -public: - index_loader(const Allocator& al,std::size_t size): - spc(al,size),size_(size),n(0),sorted(false) - { - } - - template - void add(Node* node,Archive& ar,const unsigned int) - { - ar>>serialization::make_nvp("position",*node); - entries()[n++]=node; - } - - template - void add_track(Node* node,Archive& ar,const unsigned int) - { - ar>>serialization::make_nvp("position",*node); - } - - /* A rearranger is passed two nodes, and is expected to - * reposition the second after the first. - * If the first node is 0, then the second should be moved - * to the beginning of the sequence. - */ - - template - void load(Rearranger r,Archive& ar,const unsigned int)const - { - FinalNode* prev=unchecked_load_node(ar); - if(!prev)return; - - if(!sorted){ - std::sort(entries(),entries()+size_); - sorted=true; - } - - check_node(prev); - - for(;;){ - for(;;){ - FinalNode* node=load_node(ar); - if(!node)break; - - if(node==prev)prev=0; - r(prev,node); - - prev=node; - } - prev=load_node(ar); - if(!prev)break; - } - } - -private: - Node** entries()const{return raw_ptr(spc.data());} - - /* We try to delay sorting as much as possible just in case it - * is not necessary, hence this version of load_node. - */ - - template - FinalNode* unchecked_load_node(Archive& ar)const - { - Node* node=0; - ar>>serialization::make_nvp("pointer",node); - return static_cast(node); - } - - template - FinalNode* load_node(Archive& ar)const - { - Node* node=0; - ar>>serialization::make_nvp("pointer",node); - check_node(node); - return static_cast(node); - } - - void check_node(Node* node)const - { - if(node!=0&&!std::binary_search(entries(),entries()+size_,node)){ - throw_exception( - archive::archive_exception( - archive::archive_exception::other_exception)); - } - } - - auto_space spc; - std::size_t size_; - std::size_t n; - mutable bool sorted; -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_matcher.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_matcher.hpp deleted file mode 100644 index 34d1f9d5a8d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_matcher.hpp +++ /dev/null @@ -1,249 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_MATCHER_HPP -#define BOOST_MULTI_INDEX_DETAIL_INDEX_MATCHER_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* index_matcher compares a sequence of elements against a - * base sequence, identifying those elements that belong to the - * longest subsequence which is ordered with respect to the base. - * For instance, if the base sequence is: - * - * 0 1 2 3 4 5 6 7 8 9 - * - * and the compared sequence (not necesarilly the same length): - * - * 1 4 2 3 0 7 8 9 - * - * the elements of the longest ordered subsequence are: - * - * 1 2 3 7 8 9 - * - * The algorithm for obtaining such a subsequence is called - * Patience Sorting, described in ch. 1 of: - * Aldous, D., Diaconis, P.: "Longest increasing subsequences: from - * patience sorting to the Baik-Deift-Johansson Theorem", Bulletin - * of the American Mathematical Society, vol. 36, no 4, pp. 413-432, - * July 1999. - * http://www.ams.org/bull/1999-36-04/S0273-0979-99-00796-X/ - * S0273-0979-99-00796-X.pdf - * - * This implementation is not fully generic since it assumes that - * the sequences given are pointed to by index iterators (having a - * get_node() memfun.) - */ - -namespace index_matcher{ - -/* The algorithm stores the nodes of the base sequence and a number - * of "piles" that are dynamically updated during the calculation - * stage. From a logical point of view, nodes form an independent - * sequence from piles. They are stored together so as to minimize - * allocated memory. - */ - -struct entry -{ - entry(void* node_,std::size_t pos_=0):node(node_),pos(pos_){} - - /* node stuff */ - - void* node; - std::size_t pos; - entry* previous; - bool ordered; - - struct less_by_node - { - bool operator()( - const entry& x,const entry& y)const - { - return std::less()(x.node,y.node); - } - }; - - /* pile stuff */ - - std::size_t pile_top; - entry* pile_top_entry; - - struct less_by_pile_top - { - bool operator()( - const entry& x,const entry& y)const - { - return x.pile_top -class algorithm_base:private noncopyable -{ -protected: - algorithm_base(const Allocator& al,std::size_t size): - spc(al,size),size_(size),n_(0),sorted(false) - { - } - - void add(void* node) - { - entries()[n_]=entry(node,n_); - ++n_; - } - - void begin_algorithm()const - { - if(!sorted){ - std::sort(entries(),entries()+size_,entry::less_by_node()); - sorted=true; - } - num_piles=0; - } - - void add_node_to_algorithm(void* node)const - { - entry* ent= - std::lower_bound( - entries(),entries()+size_, - entry(node),entry::less_by_node()); /* localize entry */ - ent->ordered=false; - std::size_t n=ent->pos; /* get its position */ - - entry dummy(0); - dummy.pile_top=n; - - entry* pile_ent= /* find the first available pile */ - std::lower_bound( /* to stack the entry */ - entries(),entries()+num_piles, - dummy,entry::less_by_pile_top()); - - pile_ent->pile_top=n; /* stack the entry */ - pile_ent->pile_top_entry=ent; - - /* if not the first pile, link entry to top of the preceding pile */ - if(pile_ent>&entries()[0]){ - ent->previous=(pile_ent-1)->pile_top_entry; - } - - if(pile_ent==&entries()[num_piles]){ /* new pile? */ - ++num_piles; - } - } - - void finish_algorithm()const - { - if(num_piles>0){ - /* Mark those elements which are in their correct position, i.e. those - * belonging to the longest increasing subsequence. These are those - * elements linked from the top of the last pile. - */ - - entry* ent=entries()[num_piles-1].pile_top_entry; - for(std::size_t n=num_piles;n--;){ - ent->ordered=true; - ent=ent->previous; - } - } - } - - bool is_ordered(void * node)const - { - return std::lower_bound( - entries(),entries()+size_, - entry(node),entry::less_by_node())->ordered; - } - -private: - entry* entries()const{return raw_ptr(spc.data());} - - auto_space spc; - std::size_t size_; - std::size_t n_; - mutable bool sorted; - mutable std::size_t num_piles; -}; - -/* The algorithm has three phases: - * - Initialization, during which the nodes of the base sequence are added. - * - Execution. - * - Results querying, through the is_ordered memfun. - */ - -template -class algorithm:private algorithm_base -{ - typedef algorithm_base super; - -public: - algorithm(const Allocator& al,std::size_t size):super(al,size){} - - void add(Node* node) - { - super::add(node); - } - - template - void execute(IndexIterator first,IndexIterator last)const - { - super::begin_algorithm(); - - for(IndexIterator it=first;it!=last;++it){ - add_node_to_algorithm(get_node(it)); - } - - super::finish_algorithm(); - } - - bool is_ordered(Node* node)const - { - return super::is_ordered(node); - } - -private: - void add_node_to_algorithm(Node* node)const - { - super::add_node_to_algorithm(node); - } - - template - static Node* get_node(IndexIterator it) - { - return static_cast(it.get_node()); - } -}; - -} /* namespace multi_index::detail::index_matcher */ - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_node_base.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_node_base.hpp deleted file mode 100644 index 1a1f0cae4be..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_node_base.hpp +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright 2003-2016 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_NODE_BASE_HPP -#define BOOST_MULTI_INDEX_DETAIL_INDEX_NODE_BASE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#include -#include -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* index_node_base tops the node hierarchy of multi_index_container. It holds - * the value of the element contained. - */ - -template -struct pod_value_holder -{ - typename aligned_storage< - sizeof(Value), - alignment_of::value - >::type space; -}; - -template -struct index_node_base:private pod_value_holder -{ - typedef index_node_base base_type; /* used for serialization purposes */ - typedef Value value_type; - typedef Allocator allocator_type; - -#include - - value_type& value() - { - return *reinterpret_cast(&this->space); - } - - const value_type& value()const - { - return *reinterpret_cast(&this->space); - } - -#include - - static index_node_base* from_value(const value_type* p) - { - return static_cast( - reinterpret_cast*>( /* std 9.2.17 */ - const_cast(p))); - } - -private: -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - friend class boost::serialization::access; - - /* nodes do not emit any kind of serialization info. They are - * fed to Boost.Serialization so that pointers to nodes are - * tracked correctly. - */ - - template - void serialize(Archive&,const unsigned int) - { - } -#endif -}; - -template -Node* node_from_value(const Value* p) -{ - typedef typename Node::allocator_type allocator_type; - return static_cast( - index_node_base::from_value(p)); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -/* Index nodes never get constructed directly by Boost.Serialization, - * as archives are always fed pointers to previously existent - * nodes. So, if this is called it means we are dealing with a - * somehow invalid archive. - */ - -#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) -namespace serialization{ -#else -namespace multi_index{ -namespace detail{ -#endif - -template -inline void load_construct_data( - Archive&,boost::multi_index::detail::index_node_base*, - const unsigned int) -{ - throw_exception( - archive::archive_exception(archive::archive_exception::other_exception)); -} - -#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) -} /* namespace serialization */ -#else -} /* namespace multi_index::detail */ -} /* namespace multi_index */ -#endif - -#endif - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_saver.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_saver.hpp deleted file mode 100644 index ae09d4eba4f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/index_saver.hpp +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP -#define BOOST_MULTI_INDEX_DETAIL_INDEX_SAVER_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* index_saver accepts a base sequence of previously saved elements - * and saves a possibly reordered subsequence in an efficient manner, - * serializing only the information needed to rearrange the subsequence - * based on the original order of the base. - * multi_index_container is in charge of supplying the info about the - * base sequence, and each index can subsequently save itself using the - * const interface of index_saver. - */ - -template -class index_saver:private noncopyable -{ -public: - index_saver(const Allocator& al,std::size_t size):alg(al,size){} - - template - void add(Node* node,Archive& ar,const unsigned int) - { - ar< - void add_track(Node* node,Archive& ar,const unsigned int) - { - ar< - void save( - IndexIterator first,IndexIterator last,Archive& ar, - const unsigned int)const - { - /* calculate ordered positions */ - - alg.execute(first,last); - - /* Given a consecutive subsequence of displaced elements - * x1,...,xn, the following information is serialized: - * - * p0,p1,...,pn,0 - * - * where pi is a pointer to xi and p0 is a pointer to the element - * preceding x1. Crealy, from this information is possible to - * restore the original order on loading time. If x1 is the first - * element in the sequence, the following is serialized instead: - * - * p1,p1,...,pn,0 - * - * For each subsequence of n elements, n+2 pointers are serialized. - * An optimization policy is applied: consider for instance the - * sequence - * - * a,B,c,D - * - * where B and D are displaced, but c is in its correct position. - * Applying the schema described above we would serialize 6 pointers: - * - * p(a),p(B),0 - * p(c),p(D),0 - * - * but this can be reduced to 5 pointers by treating c as a displaced - * element: - * - * p(a),p(B),p(c),p(D),0 - */ - - std::size_t last_saved=3; /* distance to last pointer saved */ - for(IndexIterator it=first,prev=first;it!=last;prev=it++,++last_saved){ - if(!alg.is_ordered(get_node(it))){ - if(last_saved>1)save_node(get_node(prev),ar); - save_node(get_node(it),ar); - last_saved=0; - } - else if(last_saved==2)save_node(null_node(),ar); - } - if(last_saved<=2)save_node(null_node(),ar); - - /* marks the end of the serialization info for [first,last) */ - - save_node(null_node(),ar); - } - -private: - template - static Node* get_node(IndexIterator it) - { - return it.get_node(); - } - - static Node* null_node(){return 0;} - - template - static void save_node(Node* node,Archive& ar) - { - ar< alg; -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/invariant_assert.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/invariant_assert.hpp deleted file mode 100644 index c6c547c7c33..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/invariant_assert.hpp +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_INVARIANT_ASSERT_HPP -#define BOOST_MULTI_INDEX_DETAIL_INVARIANT_ASSERT_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#if !defined(BOOST_MULTI_INDEX_INVARIANT_ASSERT) -#include -#define BOOST_MULTI_INDEX_INVARIANT_ASSERT BOOST_ASSERT -#endif - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_index_list.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_index_list.hpp deleted file mode 100644 index f6a24218b81..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_index_list.hpp +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_IS_INDEX_LIST_HPP -#define BOOST_MULTI_INDEX_DETAIL_IS_INDEX_LIST_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template -struct is_index_list -{ - BOOST_STATIC_CONSTANT(bool,mpl_sequence=mpl::is_sequence::value); - BOOST_STATIC_CONSTANT(bool,non_empty=!mpl::empty::value); - BOOST_STATIC_CONSTANT(bool,value=mpl_sequence&&non_empty); -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_transparent.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_transparent.hpp deleted file mode 100644 index 72036d257e2..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/is_transparent.hpp +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright 2003-2014 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_IS_TRANSPARENT_HPP -#define BOOST_MULTI_INDEX_DETAIL_IS_TRANSPARENT_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Metafunction that checks if f(arg,arg2) executes without argument type - * conversion. By default (i.e. when it cannot be determined) it evaluates to - * true. - */ - -template -struct is_transparent:mpl::true_{}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#if !defined(BOOST_NO_SFINAE)&&!defined(BOOST_NO_SFINAE_EXPR)&& \ - !defined(BOOST_NO_CXX11_DECLTYPE)&& \ - (defined(BOOST_NO_CXX11_FINAL)||defined(BOOST_IS_FINAL)) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -struct not_is_transparent_result_type{}; - -template -struct is_transparent_class_helper:F -{ - using F::operator(); - template - not_is_transparent_result_type operator()(const T&,const Q&)const; -}; - -template -struct is_transparent_class:mpl::true_{}; - -template -struct is_transparent_class< - F,Arg1,Arg2, - typename enable_if< - is_same< - decltype( - declval >()( - declval(),declval()) - ), - not_is_transparent_result_type - > - >::type ->:mpl::false_{}; - -template -struct is_transparent< - F,Arg1,Arg2, - typename enable_if< - mpl::and_< - is_class, - mpl::not_ > /* is_transparent_class_helper derives from F */ - > - >::type ->:is_transparent_class{}; - -template -struct is_transparent_function:mpl::true_{}; - -template -struct is_transparent_function< - F,Arg1,Arg2, - typename enable_if< - mpl::or_< - mpl::not_::arg1_type,const Arg1&>, - is_same::arg1_type,Arg1> - > >, - mpl::not_::arg2_type,const Arg2&>, - is_same::arg2_type,Arg2> - > > - > - >::type ->:mpl::false_{}; - -template -struct is_transparent< - F,Arg1,Arg2, - typename enable_if< - is_function::type> - >::type ->:is_transparent_function::type,Arg1,Arg2>{}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/iter_adaptor.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/iter_adaptor.hpp deleted file mode 100644 index 7a032350b36..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/iter_adaptor.hpp +++ /dev/null @@ -1,321 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP -#define BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Poor man's version of boost::iterator_adaptor. Used instead of the - * original as compile times for the latter are significantly higher. - * The interface is not replicated exactly, only to the extent necessary - * for internal consumption. - */ - -/* NB. The purpose of the (non-inclass) global operators ==, < and - defined - * above is to partially alleviate a problem of MSVC++ 6.0 by * which - * friend-injected operators on T are not visible if T is instantiated only - * in template code where T is a dependent type. - */ - -class iter_adaptor_access -{ -public: - template - static typename Class::reference dereference(const Class& x) - { - return x.dereference(); - } - - template - static bool equal(const Class& x,const Class& y) - { - return x.equal(y); - } - - template - static void increment(Class& x) - { - x.increment(); - } - - template - static void decrement(Class& x) - { - x.decrement(); - } - - template - static void advance(Class& x,typename Class::difference_type n) - { - x.advance(n); - } - - template - static typename Class::difference_type distance_to( - const Class& x,const Class& y) - { - return x.distance_to(y); - } -}; - -template -struct iter_adaptor_selector; - -template -class forward_iter_adaptor_base: - public forward_iterator_helper< - Derived, - typename Base::value_type, - typename Base::difference_type, - typename Base::pointer, - typename Base::reference> -{ -public: - typedef typename Base::reference reference; - - reference operator*()const - { - return iter_adaptor_access::dereference(final()); - } - - friend bool operator==(const Derived& x,const Derived& y) - { - return iter_adaptor_access::equal(x,y); - } - - Derived& operator++() - { - iter_adaptor_access::increment(final()); - return final(); - } - -private: - Derived& final(){return *static_cast(this);} - const Derived& final()const{return *static_cast(this);} -}; - -template -bool operator==( - const forward_iter_adaptor_base& x, - const forward_iter_adaptor_base& y) -{ - return iter_adaptor_access::equal( - static_cast(x),static_cast(y)); -} - -template<> -struct iter_adaptor_selector -{ - template - struct apply - { - typedef forward_iter_adaptor_base type; - }; -}; - -template -class bidirectional_iter_adaptor_base: - public bidirectional_iterator_helper< - Derived, - typename Base::value_type, - typename Base::difference_type, - typename Base::pointer, - typename Base::reference> -{ -public: - typedef typename Base::reference reference; - - reference operator*()const - { - return iter_adaptor_access::dereference(final()); - } - - friend bool operator==(const Derived& x,const Derived& y) - { - return iter_adaptor_access::equal(x,y); - } - - Derived& operator++() - { - iter_adaptor_access::increment(final()); - return final(); - } - - Derived& operator--() - { - iter_adaptor_access::decrement(final()); - return final(); - } - -private: - Derived& final(){return *static_cast(this);} - const Derived& final()const{return *static_cast(this);} -}; - -template -bool operator==( - const bidirectional_iter_adaptor_base& x, - const bidirectional_iter_adaptor_base& y) -{ - return iter_adaptor_access::equal( - static_cast(x),static_cast(y)); -} - -template<> -struct iter_adaptor_selector -{ - template - struct apply - { - typedef bidirectional_iter_adaptor_base type; - }; -}; - -template -class random_access_iter_adaptor_base: - public random_access_iterator_helper< - Derived, - typename Base::value_type, - typename Base::difference_type, - typename Base::pointer, - typename Base::reference> -{ -public: - typedef typename Base::reference reference; - typedef typename Base::difference_type difference_type; - - reference operator*()const - { - return iter_adaptor_access::dereference(final()); - } - - friend bool operator==(const Derived& x,const Derived& y) - { - return iter_adaptor_access::equal(x,y); - } - - friend bool operator<(const Derived& x,const Derived& y) - { - return iter_adaptor_access::distance_to(x,y)>0; - } - - Derived& operator++() - { - iter_adaptor_access::increment(final()); - return final(); - } - - Derived& operator--() - { - iter_adaptor_access::decrement(final()); - return final(); - } - - Derived& operator+=(difference_type n) - { - iter_adaptor_access::advance(final(),n); - return final(); - } - - Derived& operator-=(difference_type n) - { - iter_adaptor_access::advance(final(),-n); - return final(); - } - - friend difference_type operator-(const Derived& x,const Derived& y) - { - return iter_adaptor_access::distance_to(y,x); - } - -private: - Derived& final(){return *static_cast(this);} - const Derived& final()const{return *static_cast(this);} -}; - -template -bool operator==( - const random_access_iter_adaptor_base& x, - const random_access_iter_adaptor_base& y) -{ - return iter_adaptor_access::equal( - static_cast(x),static_cast(y)); -} - -template -bool operator<( - const random_access_iter_adaptor_base& x, - const random_access_iter_adaptor_base& y) -{ - return iter_adaptor_access::distance_to( - static_cast(x),static_cast(y))>0; -} - -template -typename random_access_iter_adaptor_base::difference_type -operator-( - const random_access_iter_adaptor_base& x, - const random_access_iter_adaptor_base& y) -{ - return iter_adaptor_access::distance_to( - static_cast(y),static_cast(x)); -} - -template<> -struct iter_adaptor_selector -{ - template - struct apply - { - typedef random_access_iter_adaptor_base type; - }; -}; - -template -struct iter_adaptor_base -{ - typedef iter_adaptor_selector< - typename Base::iterator_category> selector; - typedef typename mpl::apply2< - selector,Derived,Base>::type type; -}; - -template -class iter_adaptor:public iter_adaptor_base::type -{ -protected: - iter_adaptor(){} - explicit iter_adaptor(const Base& b_):b(b_){} - - const Base& base_reference()const{return b;} - Base& base_reference(){return b;} - -private: - Base b; -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/modify_key_adaptor.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/modify_key_adaptor.hpp deleted file mode 100644 index 6df89b18386..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/modify_key_adaptor.hpp +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_MODIFY_KEY_ADAPTOR_HPP -#define BOOST_MULTI_INDEX_DETAIL_MODIFY_KEY_ADAPTOR_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Functional adaptor to resolve modify_key as a call to modify. - * Preferred over compose_f_gx and stuff cause it eliminates problems - * with references to references, dealing with function pointers, etc. - */ - -template -struct modify_key_adaptor -{ - - modify_key_adaptor(Fun f_,KeyFromValue kfv_):f(f_),kfv(kfv_){} - - void operator()(Value& x) - { - f(kfv(x)); - } - -private: - Fun f; - KeyFromValue kfv; -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/no_duplicate_tags.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/no_duplicate_tags.hpp deleted file mode 100644 index ba216ed82cf..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/no_duplicate_tags.hpp +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_NO_DUPLICATE_TAGS_HPP -#define BOOST_MULTI_INDEX_DETAIL_NO_DUPLICATE_TAGS_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* no_duplicate_tags check at compile-time that a tag list - * has no duplicate tags. - * The algorithm deserves some explanation: tags - * are sequentially inserted into a mpl::set if they were - * not already present. Due to the magic of mpl::set - * (mpl::has_key is contant time), this operation takes linear - * time, and even MSVC++ 6.5 handles it gracefully (other obvious - * solutions are quadratic.) - */ - -struct duplicate_tag_mark{}; - -struct duplicate_tag_marker -{ - template - struct apply - { - typedef mpl::s_item< - typename mpl::if_,duplicate_tag_mark,Tag>::type, - MplSet - > type; - }; -}; - -template -struct no_duplicate_tags -{ - typedef typename mpl::fold< - TagList, - mpl::set0<>, - duplicate_tag_marker - >::type aux; - - BOOST_STATIC_CONSTANT( - bool,value=!(mpl::has_key::value)); -}; - -/* Variant for an index list: duplication is checked - * across all the indices. - */ - -struct duplicate_tag_list_marker -{ - template - struct apply:mpl::fold< - BOOST_DEDUCED_TYPENAME Index::tag_list, - MplSet, - duplicate_tag_marker> - { - }; -}; - -template -struct no_duplicate_tags_in_index_list -{ - typedef typename mpl::fold< - IndexList, - mpl::set0<>, - duplicate_tag_list_marker - >::type aux; - - BOOST_STATIC_CONSTANT( - bool,value=!(mpl::has_key::value)); -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/node_type.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/node_type.hpp deleted file mode 100644 index 7fe85cf968b..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/node_type.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_NODE_TYPE_HPP -#define BOOST_MULTI_INDEX_DETAIL_NODE_TYPE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* MPL machinery to construct the internal node type associated to an - * index list. - */ - -struct index_node_applier -{ - template - struct apply - { - typedef typename mpl::deref::type index_specifier; - typedef typename index_specifier:: - BOOST_NESTED_TEMPLATE node_class::type type; - }; -}; - -template -struct multi_index_node_type -{ - BOOST_STATIC_ASSERT(detail::is_index_list::value); - - typedef typename mpl::reverse_iter_fold< - IndexSpecifierList, - index_node_base, - mpl::bind2 - >::type type; -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_args.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_args.hpp deleted file mode 100644 index 3e2641f2f4d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_args.hpp +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_ARGS_HPP -#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_ARGS_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Oredered index specifiers can be instantiated in two forms: - * - * (ordered_unique|ordered_non_unique)< - * KeyFromValue,Compare=std::less > - * (ordered_unique|ordered_non_unique)< - * TagList,KeyFromValue,Compare=std::less > - * - * index_args implements the machinery to accept this argument-dependent - * polymorphism. - */ - -template -struct index_args_default_compare -{ - typedef std::less type; -}; - -template -struct ordered_index_args -{ - typedef is_tag full_form; - - typedef typename mpl::if_< - full_form, - Arg1, - tag< > >::type tag_list_type; - typedef typename mpl::if_< - full_form, - Arg2, - Arg1>::type key_from_value_type; - typedef typename mpl::if_< - full_form, - Arg3, - Arg2>::type supplied_compare_type; - typedef typename mpl::eval_if< - mpl::is_na, - index_args_default_compare, - mpl::identity - >::type compare_type; - - BOOST_STATIC_ASSERT(is_tag::value); - BOOST_STATIC_ASSERT(!mpl::is_na::value); - BOOST_STATIC_ASSERT(!mpl::is_na::value); -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl.hpp deleted file mode 100644 index 040cb989630..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl.hpp +++ /dev/null @@ -1,1567 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - * - * The internal implementation of red-black trees is based on that of SGI STL - * stl_tree.h file: - * - * Copyright (c) 1996,1997 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_HPP -#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#include -#include -#include -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) -#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) \ - detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(x,&ordered_index_impl::check_invariant_); \ - BOOST_JOIN(check_invariant_,__LINE__).touch(); -#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT \ - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(*this) -#else -#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x) -#define BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* ordered_index adds a layer of ordered indexing to a given Super and accepts - * an augmenting policy for optional addition of order statistics. - */ - -/* Most of the implementation of unique and non-unique indices is - * shared. We tell from one another on instantiation time by using - * these tags. - */ - -struct ordered_unique_tag{}; -struct ordered_non_unique_tag{}; - -template< - typename KeyFromValue,typename Compare, - typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy -> -class ordered_index; - -template< - typename KeyFromValue,typename Compare, - typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy -> -class ordered_index_impl: - BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - ,public safe_mode::safe_container< - ordered_index_impl< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy> > -#endif - -{ -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the - * lifetime of const references bound to temporaries --precisely what - * scopeguards are. - */ - -#pragma parse_mfunc_templ off -#endif - - typedef typename SuperMeta::type super; - -protected: - typedef ordered_index_node< - AugmentPolicy,typename super::node_type> node_type; - -protected: /* for the benefit of AugmentPolicy::augmented_interface */ - typedef typename node_type::impl_type node_impl_type; - typedef typename node_impl_type::pointer node_impl_pointer; - -public: - /* types */ - - typedef typename KeyFromValue::result_type key_type; - typedef typename node_type::value_type value_type; - typedef KeyFromValue key_from_value; - typedef Compare key_compare; - typedef value_comparison< - value_type,KeyFromValue,Compare> value_compare; - typedef tuple ctor_args; - typedef typename super::final_allocator_type allocator_type; - typedef typename allocator_type::reference reference; - typedef typename allocator_type::const_reference const_reference; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef safe_mode::safe_iterator< - bidir_node_iterator, - ordered_index_impl> iterator; -#else - typedef bidir_node_iterator iterator; -#endif - - typedef iterator const_iterator; - - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef typename allocator_type::pointer pointer; - typedef typename allocator_type::const_pointer const_pointer; - typedef typename - boost::reverse_iterator reverse_iterator; - typedef typename - boost::reverse_iterator const_reverse_iterator; - typedef TagList tag_list; - -protected: - typedef typename super::final_node_type final_node_type; - typedef tuples::cons< - ctor_args, - typename super::ctor_args_list> ctor_args_list; - typedef typename mpl::push_front< - typename super::index_type_list, - ordered_index< - KeyFromValue,Compare, - SuperMeta,TagList,Category,AugmentPolicy - > >::type index_type_list; - typedef typename mpl::push_front< - typename super::iterator_type_list, - iterator>::type iterator_type_list; - typedef typename mpl::push_front< - typename super::const_iterator_type_list, - const_iterator>::type const_iterator_type_list; - typedef typename super::copy_map_type copy_map_type; - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - typedef typename super::index_saver_type index_saver_type; - typedef typename super::index_loader_type index_loader_type; -#endif - -protected: -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef safe_mode::safe_container< - ordered_index_impl> safe_super; -#endif - - typedef typename call_traits< - value_type>::param_type value_param_type; - typedef typename call_traits< - key_type>::param_type key_param_type; - - /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL - * expansion. - */ - - typedef std::pair emplace_return_type; - -public: - - /* construct/copy/destroy - * Default and copy ctors are in the protected section as indices are - * not supposed to be created on their own. No range ctor either. - * Assignment operators defined at ordered_index rather than here. - */ - - allocator_type get_allocator()const BOOST_NOEXCEPT - { - return this->final().get_allocator(); - } - - /* iterators */ - - iterator - begin()BOOST_NOEXCEPT{return make_iterator(leftmost());} - const_iterator - begin()const BOOST_NOEXCEPT{return make_iterator(leftmost());} - iterator - end()BOOST_NOEXCEPT{return make_iterator(header());} - const_iterator - end()const BOOST_NOEXCEPT{return make_iterator(header());} - reverse_iterator - rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} - const_reverse_iterator - rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} - reverse_iterator - rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} - const_reverse_iterator - rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} - const_iterator - cbegin()const BOOST_NOEXCEPT{return begin();} - const_iterator - cend()const BOOST_NOEXCEPT{return end();} - const_reverse_iterator - crbegin()const BOOST_NOEXCEPT{return rbegin();} - const_reverse_iterator - crend()const BOOST_NOEXCEPT{return rend();} - - iterator iterator_to(const value_type& x) - { - return make_iterator(node_from_value(&x)); - } - - const_iterator iterator_to(const value_type& x)const - { - return make_iterator(node_from_value(&x)); - } - - /* capacity */ - - bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} - size_type size()const BOOST_NOEXCEPT{return this->final_size_();} - size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} - - /* modifiers */ - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( - emplace_return_type,emplace,emplace_impl) - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( - iterator,emplace_hint,emplace_hint_impl,iterator,position) - - std::pair insert(const value_type& x) - { - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_(x); - return std::pair(make_iterator(p.first),p.second); - } - - std::pair insert(BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_rv_(x); - return std::pair(make_iterator(p.first),p.second); - } - - iterator insert(iterator position,const value_type& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_( - x,static_cast(position.get_node())); - return make_iterator(p.first); - } - - iterator insert(iterator position,BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_rv_( - x,static_cast(position.get_node())); - return make_iterator(p.first); - } - - template - void insert(InputIterator first,InputIterator last) - { - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - node_type* hint=header(); /* end() */ - for(;first!=last;++first){ - hint=this->final_insert_ref_( - *first,static_cast(hint)).first; - node_type::increment(hint); - } - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - void insert(std::initializer_list list) - { - insert(list.begin(),list.end()); - } -#endif - - iterator erase(iterator position) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - this->final_erase_(static_cast(position++.get_node())); - return position; - } - - size_type erase(key_param_type x) - { - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - std::pair p=equal_range(x); - size_type s=0; - while(p.first!=p.second){ - p.first=erase(p.first); - ++s; - } - return s; - } - - iterator erase(iterator first,iterator last) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); - BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - while(first!=last){ - first=erase(first); - } - return first; - } - - bool replace(iterator position,const value_type& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - return this->final_replace_( - x,static_cast(position.get_node())); - } - - bool replace(iterator position,BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - return this->final_replace_rv_( - x,static_cast(position.get_node())); - } - - template - bool modify(iterator position,Modifier mod) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer on safe mode code chokes if this - * this is not added. Left it for all compilers as it does no - * harm. - */ - - position.detach(); -#endif - - return this->final_modify_( - mod,static_cast(position.get_node())); - } - - template - bool modify(iterator position,Modifier mod,Rollback back_) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer on safe mode code chokes if this - * this is not added. Left it for all compilers as it does no - * harm. - */ - - position.detach(); -#endif - - return this->final_modify_( - mod,back_,static_cast(position.get_node())); - } - - template - bool modify_key(iterator position,Modifier mod) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - return modify( - position,modify_key_adaptor(mod,key)); - } - - template - bool modify_key(iterator position,Modifier mod,Rollback back_) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - return modify( - position, - modify_key_adaptor(mod,key), - modify_key_adaptor(back_,key)); - } - - void swap( - ordered_index< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x) - { - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF(x); - this->final_swap_(x.final()); - } - - void clear()BOOST_NOEXCEPT - { - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - this->final_clear_(); - } - - /* observers */ - - key_from_value key_extractor()const{return key;} - key_compare key_comp()const{return comp_;} - value_compare value_comp()const{return value_compare(key,comp_);} - - /* set operations */ - - /* Internally, these ops rely on const_iterator being the same - * type as iterator. - */ - - template - iterator find(const CompatibleKey& x)const - { - return make_iterator(ordered_index_find(root(),header(),key,x,comp_)); - } - - template - iterator find( - const CompatibleKey& x,const CompatibleCompare& comp)const - { - return make_iterator(ordered_index_find(root(),header(),key,x,comp)); - } - - template - size_type count(const CompatibleKey& x)const - { - return count(x,comp_); - } - - template - size_type count(const CompatibleKey& x,const CompatibleCompare& comp)const - { - std::pair p=equal_range(x,comp); - size_type n=std::distance(p.first,p.second); - return n; - } - - template - iterator lower_bound(const CompatibleKey& x)const - { - return make_iterator( - ordered_index_lower_bound(root(),header(),key,x,comp_)); - } - - template - iterator lower_bound( - const CompatibleKey& x,const CompatibleCompare& comp)const - { - return make_iterator( - ordered_index_lower_bound(root(),header(),key,x,comp)); - } - - template - iterator upper_bound(const CompatibleKey& x)const - { - return make_iterator( - ordered_index_upper_bound(root(),header(),key,x,comp_)); - } - - template - iterator upper_bound( - const CompatibleKey& x,const CompatibleCompare& comp)const - { - return make_iterator( - ordered_index_upper_bound(root(),header(),key,x,comp)); - } - - template - std::pair equal_range( - const CompatibleKey& x)const - { - std::pair p= - ordered_index_equal_range(root(),header(),key,x,comp_); - return std::pair( - make_iterator(p.first),make_iterator(p.second)); - } - - template - std::pair equal_range( - const CompatibleKey& x,const CompatibleCompare& comp)const - { - std::pair p= - ordered_index_equal_range(root(),header(),key,x,comp); - return std::pair( - make_iterator(p.first),make_iterator(p.second)); - } - - /* range */ - - template - std::pair - range(LowerBounder lower,UpperBounder upper)const - { - typedef typename mpl::if_< - is_same, - BOOST_DEDUCED_TYPENAME mpl::if_< - is_same, - both_unbounded_tag, - lower_unbounded_tag - >::type, - BOOST_DEDUCED_TYPENAME mpl::if_< - is_same, - upper_unbounded_tag, - none_unbounded_tag - >::type - >::type dispatch; - - return range(lower,upper,dispatch()); - } - -BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: - ordered_index_impl(const ctor_args_list& args_list,const allocator_type& al): - super(args_list.get_tail(),al), - key(tuples::get<0>(args_list.get_head())), - comp_(tuples::get<1>(args_list.get_head())) - { - empty_initialize(); - } - - ordered_index_impl( - const ordered_index_impl< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x): - super(x), - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super(), -#endif - - key(x.key), - comp_(x.comp_) - { - /* Copy ctor just takes the key and compare objects from x. The rest is - * done in a subsequent call to copy_(). - */ - } - - ordered_index_impl( - const ordered_index_impl< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x, - do_not_copy_elements_tag): - super(x,do_not_copy_elements_tag()), - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super(), -#endif - - key(x.key), - comp_(x.comp_) - { - empty_initialize(); - } - - ~ordered_index_impl() - { - /* the container is guaranteed to be empty by now */ - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - iterator make_iterator(node_type* node){return iterator(node,this);} - const_iterator make_iterator(node_type* node)const - {return const_iterator(node,const_cast(this));} -#else - iterator make_iterator(node_type* node){return iterator(node);} - const_iterator make_iterator(node_type* node)const - {return const_iterator(node);} -#endif - - void copy_( - const ordered_index_impl< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x, - const copy_map_type& map) - { - if(!x.root()){ - empty_initialize(); - } - else{ - header()->color()=x.header()->color(); - AugmentPolicy::copy(x.header()->impl(),header()->impl()); - - node_type* root_cpy=map.find(static_cast(x.root())); - header()->parent()=root_cpy->impl(); - - node_type* leftmost_cpy=map.find( - static_cast(x.leftmost())); - header()->left()=leftmost_cpy->impl(); - - node_type* rightmost_cpy=map.find( - static_cast(x.rightmost())); - header()->right()=rightmost_cpy->impl(); - - typedef typename copy_map_type::const_iterator copy_map_iterator; - for(copy_map_iterator it=map.begin(),it_end=map.end();it!=it_end;++it){ - node_type* org=it->first; - node_type* cpy=it->second; - - cpy->color()=org->color(); - AugmentPolicy::copy(org->impl(),cpy->impl()); - - node_impl_pointer parent_org=org->parent(); - if(parent_org==node_impl_pointer(0))cpy->parent()=node_impl_pointer(0); - else{ - node_type* parent_cpy=map.find( - static_cast(node_type::from_impl(parent_org))); - cpy->parent()=parent_cpy->impl(); - if(parent_org->left()==org->impl()){ - parent_cpy->left()=cpy->impl(); - } - else if(parent_org->right()==org->impl()){ - /* header() does not satisfy this nor the previous check */ - parent_cpy->right()=cpy->impl(); - } - } - - if(org->left()==node_impl_pointer(0)) - cpy->left()=node_impl_pointer(0); - if(org->right()==node_impl_pointer(0)) - cpy->right()=node_impl_pointer(0); - } - } - - super::copy_(x,map); - } - - template - final_node_type* insert_( - value_param_type v,final_node_type*& x,Variant variant) - { - link_info inf; - if(!link_point(key(v),inf,Category())){ - return static_cast(node_type::from_impl(inf.pos)); - } - - final_node_type* res=super::insert_(v,x,variant); - if(res==x){ - node_impl_type::link( - static_cast(x)->impl(),inf.side,inf.pos,header()->impl()); - } - return res; - } - - template - final_node_type* insert_( - value_param_type v,node_type* position,final_node_type*& x,Variant variant) - { - link_info inf; - if(!hinted_link_point(key(v),position,inf,Category())){ - return static_cast(node_type::from_impl(inf.pos)); - } - - final_node_type* res=super::insert_(v,position,x,variant); - if(res==x){ - node_impl_type::link( - static_cast(x)->impl(),inf.side,inf.pos,header()->impl()); - } - return res; - } - - void erase_(node_type* x) - { - node_impl_type::rebalance_for_erase( - x->impl(),header()->parent(),header()->left(),header()->right()); - super::erase_(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - } - - void delete_all_nodes_() - { - delete_all_nodes(root()); - } - - void clear_() - { - super::clear_(); - empty_initialize(); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::detach_dereferenceable_iterators(); -#endif - } - - void swap_( - ordered_index_impl< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x) - { - std::swap(key,x.key); - std::swap(comp_,x.comp_); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::swap(x); -#endif - - super::swap_(x); - } - - void swap_elements_( - ordered_index_impl< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x) - { -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::swap(x); -#endif - - super::swap_elements_(x); - } - - template - bool replace_(value_param_type v,node_type* x,Variant variant) - { - if(in_place(v,x,Category())){ - return super::replace_(v,x,variant); - } - - node_type* next=x; - node_type::increment(next); - - node_impl_type::rebalance_for_erase( - x->impl(),header()->parent(),header()->left(),header()->right()); - - BOOST_TRY{ - link_info inf; - if(link_point(key(v),inf,Category())&&super::replace_(v,x,variant)){ - node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); - return true; - } - node_impl_type::restore(x->impl(),next->impl(),header()->impl()); - return false; - } - BOOST_CATCH(...){ - node_impl_type::restore(x->impl(),next->impl(),header()->impl()); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - bool modify_(node_type* x) - { - bool b; - BOOST_TRY{ - b=in_place(x->value(),x,Category()); - } - BOOST_CATCH(...){ - erase_(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - if(!b){ - node_impl_type::rebalance_for_erase( - x->impl(),header()->parent(),header()->left(),header()->right()); - BOOST_TRY{ - link_info inf; - if(!link_point(key(x->value()),inf,Category())){ - super::erase_(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - return false; - } - node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); - } - BOOST_CATCH(...){ - super::erase_(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - BOOST_TRY{ - if(!super::modify_(x)){ - node_impl_type::rebalance_for_erase( - x->impl(),header()->parent(),header()->left(),header()->right()); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - return false; - } - else return true; - } - BOOST_CATCH(...){ - node_impl_type::rebalance_for_erase( - x->impl(),header()->parent(),header()->left(),header()->right()); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - bool modify_rollback_(node_type* x) - { - if(in_place(x->value(),x,Category())){ - return super::modify_rollback_(x); - } - - node_type* next=x; - node_type::increment(next); - - node_impl_type::rebalance_for_erase( - x->impl(),header()->parent(),header()->left(),header()->right()); - - BOOST_TRY{ - link_info inf; - if(link_point(key(x->value()),inf,Category())&& - super::modify_rollback_(x)){ - node_impl_type::link(x->impl(),inf.side,inf.pos,header()->impl()); - return true; - } - node_impl_type::restore(x->impl(),next->impl(),header()->impl()); - return false; - } - BOOST_CATCH(...){ - node_impl_type::restore(x->impl(),next->impl(),header()->impl()); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* serialization */ - - template - void save_( - Archive& ar,const unsigned int version,const index_saver_type& sm)const - { - save_(ar,version,sm,Category()); - } - - template - void load_(Archive& ar,const unsigned int version,const index_loader_type& lm) - { - load_(ar,version,lm,Category()); - } -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - bool invariant_()const - { - if(size()==0||begin()==end()){ - if(size()!=0||begin()!=end()|| - header()->left()!=header()->impl()|| - header()->right()!=header()->impl())return false; - } - else{ - if((size_type)std::distance(begin(),end())!=size())return false; - - std::size_t len=node_impl_type::black_count( - leftmost()->impl(),root()->impl()); - for(const_iterator it=begin(),it_end=end();it!=it_end;++it){ - node_type* x=it.get_node(); - node_type* left_x=node_type::from_impl(x->left()); - node_type* right_x=node_type::from_impl(x->right()); - - if(x->color()==red){ - if((left_x&&left_x->color()==red)|| - (right_x&&right_x->color()==red))return false; - } - if(left_x&&comp_(key(x->value()),key(left_x->value())))return false; - if(right_x&&comp_(key(right_x->value()),key(x->value())))return false; - if(!left_x&&!right_x&& - node_impl_type::black_count(x->impl(),root()->impl())!=len) - return false; - if(!AugmentPolicy::invariant(x->impl()))return false; - } - - if(leftmost()->impl()!=node_impl_type::minimum(root()->impl())) - return false; - if(rightmost()->impl()!=node_impl_type::maximum(root()->impl())) - return false; - } - - return super::invariant_(); - } - - - /* This forwarding function eases things for the boost::mem_fn construct - * in BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT. Actually, - * final_check_invariant is already an inherited member function of - * ordered_index_impl. - */ - void check_invariant_()const{this->final_check_invariant_();} -#endif - -protected: /* for the benefit of AugmentPolicy::augmented_interface */ - node_type* header()const{return this->final_header();} - node_type* root()const{return node_type::from_impl(header()->parent());} - node_type* leftmost()const{return node_type::from_impl(header()->left());} - node_type* rightmost()const{return node_type::from_impl(header()->right());} - -private: - void empty_initialize() - { - header()->color()=red; - /* used to distinguish header() from root, in iterator.operator++ */ - - header()->parent()=node_impl_pointer(0); - header()->left()=header()->impl(); - header()->right()=header()->impl(); - } - - struct link_info - { - /* coverity[uninit_ctor]: suppress warning */ - link_info():side(to_left){} - - ordered_index_side side; - node_impl_pointer pos; - }; - - bool link_point(key_param_type k,link_info& inf,ordered_unique_tag) - { - node_type* y=header(); - node_type* x=root(); - bool c=true; - while(x){ - y=x; - c=comp_(k,key(x->value())); - x=node_type::from_impl(c?x->left():x->right()); - } - node_type* yy=y; - if(c){ - if(yy==leftmost()){ - inf.side=to_left; - inf.pos=y->impl(); - return true; - } - else node_type::decrement(yy); - } - - if(comp_(key(yy->value()),k)){ - inf.side=c?to_left:to_right; - inf.pos=y->impl(); - return true; - } - else{ - inf.pos=yy->impl(); - return false; - } - } - - bool link_point(key_param_type k,link_info& inf,ordered_non_unique_tag) - { - node_type* y=header(); - node_type* x=root(); - bool c=true; - while (x){ - y=x; - c=comp_(k,key(x->value())); - x=node_type::from_impl(c?x->left():x->right()); - } - inf.side=c?to_left:to_right; - inf.pos=y->impl(); - return true; - } - - bool lower_link_point(key_param_type k,link_info& inf,ordered_non_unique_tag) - { - node_type* y=header(); - node_type* x=root(); - bool c=false; - while (x){ - y=x; - c=comp_(key(x->value()),k); - x=node_type::from_impl(c?x->right():x->left()); - } - inf.side=c?to_right:to_left; - inf.pos=y->impl(); - return true; - } - - bool hinted_link_point( - key_param_type k,node_type* position,link_info& inf,ordered_unique_tag) - { - if(position->impl()==header()->left()){ - if(size()>0&&comp_(k,key(position->value()))){ - inf.side=to_left; - inf.pos=position->impl(); - return true; - } - else return link_point(k,inf,ordered_unique_tag()); - } - else if(position==header()){ - if(comp_(key(rightmost()->value()),k)){ - inf.side=to_right; - inf.pos=rightmost()->impl(); - return true; - } - else return link_point(k,inf,ordered_unique_tag()); - } - else{ - node_type* before=position; - node_type::decrement(before); - if(comp_(key(before->value()),k)&&comp_(k,key(position->value()))){ - if(before->right()==node_impl_pointer(0)){ - inf.side=to_right; - inf.pos=before->impl(); - return true; - } - else{ - inf.side=to_left; - inf.pos=position->impl(); - return true; - } - } - else return link_point(k,inf,ordered_unique_tag()); - } - } - - bool hinted_link_point( - key_param_type k,node_type* position,link_info& inf,ordered_non_unique_tag) - { - if(position->impl()==header()->left()){ - if(size()>0&&!comp_(key(position->value()),k)){ - inf.side=to_left; - inf.pos=position->impl(); - return true; - } - else return lower_link_point(k,inf,ordered_non_unique_tag()); - } - else if(position==header()){ - if(!comp_(k,key(rightmost()->value()))){ - inf.side=to_right; - inf.pos=rightmost()->impl(); - return true; - } - else return link_point(k,inf,ordered_non_unique_tag()); - } - else{ - node_type* before=position; - node_type::decrement(before); - if(!comp_(k,key(before->value()))){ - if(!comp_(key(position->value()),k)){ - if(before->right()==node_impl_pointer(0)){ - inf.side=to_right; - inf.pos=before->impl(); - return true; - } - else{ - inf.side=to_left; - inf.pos=position->impl(); - return true; - } - } - else return lower_link_point(k,inf,ordered_non_unique_tag()); - } - else return link_point(k,inf,ordered_non_unique_tag()); - } - } - - void delete_all_nodes(node_type* x) - { - if(!x)return; - - delete_all_nodes(node_type::from_impl(x->left())); - delete_all_nodes(node_type::from_impl(x->right())); - this->final_delete_node_(static_cast(x)); - } - - bool in_place(value_param_type v,node_type* x,ordered_unique_tag) - { - node_type* y; - if(x!=leftmost()){ - y=x; - node_type::decrement(y); - if(!comp_(key(y->value()),key(v)))return false; - } - - y=x; - node_type::increment(y); - return y==header()||comp_(key(v),key(y->value())); - } - - bool in_place(value_param_type v,node_type* x,ordered_non_unique_tag) - { - node_type* y; - if(x!=leftmost()){ - y=x; - node_type::decrement(y); - if(comp_(key(v),key(y->value())))return false; - } - - y=x; - node_type::increment(y); - return y==header()||!comp_(key(y->value()),key(v)); - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - void detach_iterators(node_type* x) - { - iterator it=make_iterator(x); - safe_mode::detach_equivalent_iterators(it); - } -#endif - - template - std::pair emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - std::pairp= - this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - return std::pair(make_iterator(p.first),p.second); - } - - template - iterator emplace_hint_impl( - iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT; - std::pairp= - this->final_emplace_hint_( - static_cast(position.get_node()), - BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - return make_iterator(p.first); - } - - template - std::pair - range(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const - { - node_type* y=header(); - node_type* z=root(); - - while(z){ - if(!lower(key(z->value()))){ - z=node_type::from_impl(z->right()); - } - else if(!upper(key(z->value()))){ - y=z; - z=node_type::from_impl(z->left()); - } - else{ - return std::pair( - make_iterator( - lower_range(node_type::from_impl(z->left()),z,lower)), - make_iterator( - upper_range(node_type::from_impl(z->right()),y,upper))); - } - } - - return std::pair(make_iterator(y),make_iterator(y)); - } - - template - std::pair - range(LowerBounder,UpperBounder upper,lower_unbounded_tag)const - { - return std::pair( - begin(), - make_iterator(upper_range(root(),header(),upper))); - } - - template - std::pair - range(LowerBounder lower,UpperBounder,upper_unbounded_tag)const - { - return std::pair( - make_iterator(lower_range(root(),header(),lower)), - end()); - } - - template - std::pair - range(LowerBounder,UpperBounder,both_unbounded_tag)const - { - return std::pair(begin(),end()); - } - - template - node_type * lower_range(node_type* top,node_type* y,LowerBounder lower)const - { - while(top){ - if(lower(key(top->value()))){ - y=top; - top=node_type::from_impl(top->left()); - } - else top=node_type::from_impl(top->right()); - } - - return y; - } - - template - node_type * upper_range(node_type* top,node_type* y,UpperBounder upper)const - { - while(top){ - if(!upper(key(top->value()))){ - y=top; - top=node_type::from_impl(top->left()); - } - else top=node_type::from_impl(top->right()); - } - - return y; - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - template - void save_( - Archive& ar,const unsigned int version,const index_saver_type& sm, - ordered_unique_tag)const - { - super::save_(ar,version,sm); - } - - template - void load_( - Archive& ar,const unsigned int version,const index_loader_type& lm, - ordered_unique_tag) - { - super::load_(ar,version,lm); - } - - template - void save_( - Archive& ar,const unsigned int version,const index_saver_type& sm, - ordered_non_unique_tag)const - { - typedef duplicates_iterator dup_iterator; - - sm.save( - dup_iterator(begin().get_node(),end().get_node(),value_comp()), - dup_iterator(end().get_node(),value_comp()), - ar,version); - super::save_(ar,version,sm); - } - - template - void load_( - Archive& ar,const unsigned int version,const index_loader_type& lm, - ordered_non_unique_tag) - { - lm.load( - ::boost::bind( - &ordered_index_impl::rearranger,this, - ::boost::arg<1>(),::boost::arg<2>()), - ar,version); - super::load_(ar,version,lm); - } - - void rearranger(node_type* position,node_type *x) - { - if(!position||comp_(key(position->value()),key(x->value()))){ - position=lower_bound(key(x->value())).get_node(); - } - else if(comp_(key(x->value()),key(position->value()))){ - /* inconsistent rearrangement */ - throw_exception( - archive::archive_exception( - archive::archive_exception::other_exception)); - } - else node_type::increment(position); - - if(position!=x){ - node_impl_type::rebalance_for_erase( - x->impl(),header()->parent(),header()->left(),header()->right()); - node_impl_type::restore( - x->impl(),position->impl(),header()->impl()); - } - } -#endif /* serialization */ - -protected: /* for the benefit of AugmentPolicy::augmented_interface */ - key_from_value key; - key_compare comp_; - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -#pragma parse_mfunc_templ reset -#endif -}; - -template< - typename KeyFromValue,typename Compare, - typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy -> -class ordered_index: - public AugmentPolicy::template augmented_interface< - ordered_index_impl< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy - > - >::type -{ - typedef typename AugmentPolicy::template - augmented_interface< - ordered_index_impl< - KeyFromValue,Compare, - SuperMeta,TagList,Category,AugmentPolicy - > - >::type super; -public: - typedef typename super::ctor_args_list ctor_args_list; - typedef typename super::allocator_type allocator_type; - typedef typename super::iterator iterator; - - /* construct/copy/destroy - * Default and copy ctors are in the protected section as indices are - * not supposed to be created on their own. No range ctor either. - */ - - ordered_index& operator=(const ordered_index& x) - { - this->final()=x.final(); - return *this; - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - ordered_index& operator=( - std::initializer_list list) - { - this->final()=list; - return *this; - } -#endif - -protected: - ordered_index( - const ctor_args_list& args_list,const allocator_type& al): - super(args_list,al){} - - ordered_index(const ordered_index& x):super(x){}; - - ordered_index(const ordered_index& x,do_not_copy_elements_tag): - super(x,do_not_copy_elements_tag()){}; -}; - -/* comparison */ - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator==( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) -{ - return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); -} - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator<( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) -{ - return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); -} - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator!=( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) -{ - return !(x==y); -} - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator>( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) -{ - return y -bool operator>=( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) -{ - return !(x -bool operator<=( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y) -{ - return !(x>y); -} - -/* specialized algorithms */ - -template< - typename KeyFromValue,typename Compare, - typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy -> -void swap( - ordered_index< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x, - ordered_index< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& y) -{ - x.swap(y); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -/* Boost.Foreach compatibility */ - -template< - typename KeyFromValue,typename Compare, - typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy -> -inline boost::mpl::true_* boost_foreach_is_noncopyable( - boost::multi_index::detail::ordered_index< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>*&, - boost_foreach_argument_dependent_lookup_hack) -{ - return 0; -} - -#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT -#undef BOOST_MULTI_INDEX_ORD_INDEX_CHECK_INVARIANT_OF - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl_fwd.hpp deleted file mode 100644 index 6590ef05fdd..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_impl_fwd.hpp +++ /dev/null @@ -1,128 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_FWD_HPP -#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_IMPL_FWD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template< - typename KeyFromValue,typename Compare, - typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy -> -class ordered_index; - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator==( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator<( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator!=( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator>( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator>=( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); - -template< - typename KeyFromValue1,typename Compare1, - typename SuperMeta1,typename TagList1,typename Category1, - typename AugmentPolicy1, - typename KeyFromValue2,typename Compare2, - typename SuperMeta2,typename TagList2,typename Category2, - typename AugmentPolicy2 -> -bool operator<=( - const ordered_index< - KeyFromValue1,Compare1,SuperMeta1,TagList1,Category1,AugmentPolicy1>& x, - const ordered_index< - KeyFromValue2,Compare2,SuperMeta2,TagList2,Category2,AugmentPolicy2>& y); - -template< - typename KeyFromValue,typename Compare, - typename SuperMeta,typename TagList,typename Category,typename AugmentPolicy -> -void swap( - ordered_index< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& x, - ordered_index< - KeyFromValue,Compare,SuperMeta,TagList,Category,AugmentPolicy>& y); - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_node.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_node.hpp deleted file mode 100644 index e7af0377fb9..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_node.hpp +++ /dev/null @@ -1,658 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - * - * The internal implementation of red-black trees is based on that of SGI STL - * stl_tree.h file: - * - * Copyright (c) 1996,1997 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_NODE_HPP -#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_NODE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include - -#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES) -#include -#include -#include -#include -#include -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* definition of red-black nodes for ordered_index */ - -enum ordered_index_color{red=false,black=true}; -enum ordered_index_side{to_left=false,to_right=true}; - -template -struct ordered_index_node_impl; /* fwd decl. */ - -template -struct ordered_index_node_std_base -{ - typedef typename - boost::detail::allocator::rebind_to< - Allocator, - ordered_index_node_impl - >::type::pointer pointer; - typedef typename - boost::detail::allocator::rebind_to< - Allocator, - ordered_index_node_impl - >::type::const_pointer const_pointer; - typedef ordered_index_color& color_ref; - typedef pointer& parent_ref; - - ordered_index_color& color(){return color_;} - ordered_index_color color()const{return color_;} - pointer& parent(){return parent_;} - pointer parent()const{return parent_;} - pointer& left(){return left_;} - pointer left()const{return left_;} - pointer& right(){return right_;} - pointer right()const{return right_;} - -private: - ordered_index_color color_; - pointer parent_; - pointer left_; - pointer right_; -}; - -#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES) -/* If ordered_index_node_impl has even alignment, we can use the least - * significant bit of one of the ordered_index_node_impl pointers to - * store color information. This typically reduces the size of - * ordered_index_node_impl by 25%. - */ - -#if defined(BOOST_MSVC) -/* This code casts pointers to an integer type that has been computed - * to be large enough to hold the pointer, however the metaprogramming - * logic is not always spotted by the VC++ code analyser that issues a - * long list of warnings. - */ - -#pragma warning(push) -#pragma warning(disable:4312 4311) -#endif - -template -struct ordered_index_node_compressed_base -{ - typedef ordered_index_node_impl< - AugmentPolicy,Allocator>* pointer; - typedef const ordered_index_node_impl< - AugmentPolicy,Allocator>* const_pointer; - - struct color_ref - { - color_ref(uintptr_type* r_):r(r_){} - - operator ordered_index_color()const - { - return ordered_index_color(*r&uintptr_type(1)); - } - - color_ref& operator=(ordered_index_color c) - { - *r&=~uintptr_type(1); - *r|=uintptr_type(c); - return *this; - } - - color_ref& operator=(const color_ref& x) - { - return operator=(x.operator ordered_index_color()); - } - - private: - uintptr_type* r; - }; - - struct parent_ref - { - parent_ref(uintptr_type* r_):r(r_){} - - operator pointer()const - { - return (pointer)(void*)(*r&~uintptr_type(1)); - } - - parent_ref& operator=(pointer p) - { - *r=((uintptr_type)(void*)p)|(*r&uintptr_type(1)); - return *this; - } - - parent_ref& operator=(const parent_ref& x) - { - return operator=(x.operator pointer()); - } - - pointer operator->()const - { - return operator pointer(); - } - - private: - uintptr_type* r; - }; - - color_ref color(){return color_ref(&parentcolor_);} - ordered_index_color color()const - { - return ordered_index_color(parentcolor_&uintptr_type(1)); - } - - parent_ref parent(){return parent_ref(&parentcolor_);} - pointer parent()const - { - return (pointer)(void*)(parentcolor_&~uintptr_type(1)); - } - - pointer& left(){return left_;} - pointer left()const{return left_;} - pointer& right(){return right_;} - pointer right()const{return right_;} - -private: - uintptr_type parentcolor_; - pointer left_; - pointer right_; -}; -#if defined(BOOST_MSVC) -#pragma warning(pop) -#endif -#endif - -template -struct ordered_index_node_impl_base: - -#if !defined(BOOST_MULTI_INDEX_DISABLE_COMPRESSED_ORDERED_INDEX_NODES) - AugmentPolicy::template augmented_node< - typename mpl::if_c< - !(has_uintptr_type::value)|| - (alignment_of< - ordered_index_node_compressed_base - >::value%2)|| - !(is_same< - typename boost::detail::allocator::rebind_to< - Allocator, - ordered_index_node_impl - >::type::pointer, - ordered_index_node_impl*>::value), - ordered_index_node_std_base, - ordered_index_node_compressed_base - >::type - >::type -#else - AugmentPolicy::template augmented_node< - ordered_index_node_std_base - >::type -#endif - -{}; - -template -struct ordered_index_node_impl: - ordered_index_node_impl_base -{ -private: - typedef ordered_index_node_impl_base super; - -public: - typedef typename super::color_ref color_ref; - typedef typename super::parent_ref parent_ref; - typedef typename super::pointer pointer; - typedef typename super::const_pointer const_pointer; - - /* interoperability with bidir_node_iterator */ - - static void increment(pointer& x) - { - if(x->right()!=pointer(0)){ - x=x->right(); - while(x->left()!=pointer(0))x=x->left(); - } - else{ - pointer y=x->parent(); - while(x==y->right()){ - x=y; - y=y->parent(); - } - if(x->right()!=y)x=y; - } - } - - static void decrement(pointer& x) - { - if(x->color()==red&&x->parent()->parent()==x){ - x=x->right(); - } - else if(x->left()!=pointer(0)){ - pointer y=x->left(); - while(y->right()!=pointer(0))y=y->right(); - x=y; - }else{ - pointer y=x->parent(); - while(x==y->left()){ - x=y; - y=y->parent(); - } - x=y; - } - } - - /* algorithmic stuff */ - - static void rotate_left(pointer x,parent_ref root) - { - pointer y=x->right(); - x->right()=y->left(); - if(y->left()!=pointer(0))y->left()->parent()=x; - y->parent()=x->parent(); - - if(x==root) root=y; - else if(x==x->parent()->left())x->parent()->left()=y; - else x->parent()->right()=y; - y->left()=x; - x->parent()=y; - AugmentPolicy::rotate_left(x,y); - } - - static pointer minimum(pointer x) - { - while(x->left()!=pointer(0))x=x->left(); - return x; - } - - static pointer maximum(pointer x) - { - while(x->right()!=pointer(0))x=x->right(); - return x; - } - - static void rotate_right(pointer x,parent_ref root) - { - pointer y=x->left(); - x->left()=y->right(); - if(y->right()!=pointer(0))y->right()->parent()=x; - y->parent()=x->parent(); - - if(x==root) root=y; - else if(x==x->parent()->right())x->parent()->right()=y; - else x->parent()->left()=y; - y->right()=x; - x->parent()=y; - AugmentPolicy::rotate_right(x,y); - } - - static void rebalance(pointer x,parent_ref root) - { - x->color()=red; - while(x!=root&&x->parent()->color()==red){ - if(x->parent()==x->parent()->parent()->left()){ - pointer y=x->parent()->parent()->right(); - if(y!=pointer(0)&&y->color()==red){ - x->parent()->color()=black; - y->color()=black; - x->parent()->parent()->color()=red; - x=x->parent()->parent(); - } - else{ - if(x==x->parent()->right()){ - x=x->parent(); - rotate_left(x,root); - } - x->parent()->color()=black; - x->parent()->parent()->color()=red; - rotate_right(x->parent()->parent(),root); - } - } - else{ - pointer y=x->parent()->parent()->left(); - if(y!=pointer(0)&&y->color()==red){ - x->parent()->color()=black; - y->color()=black; - x->parent()->parent()->color()=red; - x=x->parent()->parent(); - } - else{ - if(x==x->parent()->left()){ - x=x->parent(); - rotate_right(x,root); - } - x->parent()->color()=black; - x->parent()->parent()->color()=red; - rotate_left(x->parent()->parent(),root); - } - } - } - root->color()=black; - } - - static void link( - pointer x,ordered_index_side side,pointer position,pointer header) - { - if(side==to_left){ - position->left()=x; /* also makes leftmost=x when parent==header */ - if(position==header){ - header->parent()=x; - header->right()=x; - } - else if(position==header->left()){ - header->left()=x; /* maintain leftmost pointing to min node */ - } - } - else{ - position->right()=x; - if(position==header->right()){ - header->right()=x; /* maintain rightmost pointing to max node */ - } - } - x->parent()=position; - x->left()=pointer(0); - x->right()=pointer(0); - AugmentPolicy::add(x,pointer(header->parent())); - ordered_index_node_impl::rebalance(x,header->parent()); - } - - static pointer rebalance_for_erase( - pointer z,parent_ref root,pointer& leftmost,pointer& rightmost) - { - pointer y=z; - pointer x=pointer(0); - pointer x_parent=pointer(0); - if(y->left()==pointer(0)){ /* z has at most one non-null child. y==z. */ - x=y->right(); /* x might be null */ - } - else{ - if(y->right()==pointer(0)){ /* z has exactly one non-null child. y==z. */ - x=y->left(); /* x is not null */ - } - else{ /* z has two non-null children. Set y to */ - y=y->right(); /* z's successor. x might be null. */ - while(y->left()!=pointer(0))y=y->left(); - x=y->right(); - } - } - AugmentPolicy::remove(y,pointer(root)); - if(y!=z){ - AugmentPolicy::copy(z,y); - z->left()->parent()=y; /* relink y in place of z. y is z's successor */ - y->left()=z->left(); - if(y!=z->right()){ - x_parent=y->parent(); - if(x!=pointer(0))x->parent()=y->parent(); - y->parent()->left()=x; /* y must be a child of left */ - y->right()=z->right(); - z->right()->parent()=y; - } - else{ - x_parent=y; - } - - if(root==z) root=y; - else if(z->parent()->left()==z)z->parent()->left()=y; - else z->parent()->right()=y; - y->parent()=z->parent(); - ordered_index_color c=y->color(); - y->color()=z->color(); - z->color()=c; - y=z; /* y now points to node to be actually deleted */ - } - else{ /* y==z */ - x_parent=y->parent(); - if(x!=pointer(0))x->parent()=y->parent(); - if(root==z){ - root=x; - } - else{ - if(z->parent()->left()==z)z->parent()->left()=x; - else z->parent()->right()=x; - } - if(leftmost==z){ - if(z->right()==pointer(0)){ /* z->left() must be null also */ - leftmost=z->parent(); - } - else{ - leftmost=minimum(x); /* makes leftmost==header if z==root */ - } - } - if(rightmost==z){ - if(z->left()==pointer(0)){ /* z->right() must be null also */ - rightmost=z->parent(); - } - else{ /* x==z->left() */ - rightmost=maximum(x); /* makes rightmost==header if z==root */ - } - } - } - if(y->color()!=red){ - while(x!=root&&(x==pointer(0)|| x->color()==black)){ - if(x==x_parent->left()){ - pointer w=x_parent->right(); - if(w->color()==red){ - w->color()=black; - x_parent->color()=red; - rotate_left(x_parent,root); - w=x_parent->right(); - } - if((w->left()==pointer(0)||w->left()->color()==black) && - (w->right()==pointer(0)||w->right()->color()==black)){ - w->color()=red; - x=x_parent; - x_parent=x_parent->parent(); - } - else{ - if(w->right()==pointer(0 ) - || w->right()->color()==black){ - if(w->left()!=pointer(0)) w->left()->color()=black; - w->color()=red; - rotate_right(w,root); - w=x_parent->right(); - } - w->color()=x_parent->color(); - x_parent->color()=black; - if(w->right()!=pointer(0))w->right()->color()=black; - rotate_left(x_parent,root); - break; - } - } - else{ /* same as above,with right <-> left */ - pointer w=x_parent->left(); - if(w->color()==red){ - w->color()=black; - x_parent->color()=red; - rotate_right(x_parent,root); - w=x_parent->left(); - } - if((w->right()==pointer(0)||w->right()->color()==black) && - (w->left()==pointer(0)||w->left()->color()==black)){ - w->color()=red; - x=x_parent; - x_parent=x_parent->parent(); - } - else{ - if(w->left()==pointer(0)||w->left()->color()==black){ - if(w->right()!=pointer(0))w->right()->color()=black; - w->color()=red; - rotate_left(w,root); - w=x_parent->left(); - } - w->color()=x_parent->color(); - x_parent->color()=black; - if(w->left()!=pointer(0))w->left()->color()=black; - rotate_right(x_parent,root); - break; - } - } - } - if(x!=pointer(0))x->color()=black; - } - return y; - } - - static void restore(pointer x,pointer position,pointer header) - { - if(position->left()==pointer(0)||position->left()==header){ - link(x,to_left,position,header); - } - else{ - decrement(position); - link(x,to_right,position,header); - } - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - static std::size_t black_count(pointer node,pointer root) - { - if(node==pointer(0))return 0; - std::size_t sum=0; - for(;;){ - if(node->color()==black)++sum; - if(node==root)break; - node=node->parent(); - } - return sum; - } -#endif -}; - -template -struct ordered_index_node_trampoline: - ordered_index_node_impl< - AugmentPolicy, - typename boost::detail::allocator::rebind_to< - typename Super::allocator_type, - char - >::type - > -{ - typedef ordered_index_node_impl< - AugmentPolicy, - typename boost::detail::allocator::rebind_to< - typename Super::allocator_type, - char - >::type - > impl_type; -}; - -template -struct ordered_index_node: - Super,ordered_index_node_trampoline -{ -private: - typedef ordered_index_node_trampoline trampoline; - -public: - typedef typename trampoline::impl_type impl_type; - typedef typename trampoline::color_ref impl_color_ref; - typedef typename trampoline::parent_ref impl_parent_ref; - typedef typename trampoline::pointer impl_pointer; - typedef typename trampoline::const_pointer const_impl_pointer; - - impl_color_ref color(){return trampoline::color();} - ordered_index_color color()const{return trampoline::color();} - impl_parent_ref parent(){return trampoline::parent();} - impl_pointer parent()const{return trampoline::parent();} - impl_pointer& left(){return trampoline::left();} - impl_pointer left()const{return trampoline::left();} - impl_pointer& right(){return trampoline::right();} - impl_pointer right()const{return trampoline::right();} - - impl_pointer impl() - { - return static_cast( - static_cast(static_cast(this))); - } - - const_impl_pointer impl()const - { - return static_cast( - static_cast(static_cast(this))); - } - - static ordered_index_node* from_impl(impl_pointer x) - { - return - static_cast( - static_cast( - raw_ptr(x))); - } - - static const ordered_index_node* from_impl(const_impl_pointer x) - { - return - static_cast( - static_cast( - raw_ptr(x))); - } - - /* interoperability with bidir_node_iterator */ - - static void increment(ordered_index_node*& x) - { - impl_pointer xi=x->impl(); - trampoline::increment(xi); - x=from_impl(xi); - } - - static void decrement(ordered_index_node*& x) - { - impl_pointer xi=x->impl(); - trampoline::decrement(xi); - x=from_impl(xi); - } -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_ops.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_ops.hpp deleted file mode 100644 index 84d5cacae19..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/ord_index_ops.hpp +++ /dev/null @@ -1,266 +0,0 @@ -/* Copyright 2003-2014 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - * - * The internal implementation of red-black trees is based on that of SGI STL - * stl_tree.h file: - * - * Copyright (c) 1996,1997 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_OPS_HPP -#define BOOST_MULTI_INDEX_DETAIL_ORD_INDEX_OPS_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Common code for index memfuns having templatized and - * non-templatized versions. - * Implementation note: When CompatibleKey is consistently promoted to - * KeyFromValue::result_type for comparison, the promotion is made once in - * advance to increase efficiency. - */ - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline Node* ordered_index_find( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp) -{ - typedef typename KeyFromValue::result_type key_type; - - return ordered_index_find( - top,y,key,x,comp, - mpl::and_< - promotes_1st_arg, - promotes_2nd_arg >()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleCompare -> -inline Node* ordered_index_find( - Node* top,Node* y,const KeyFromValue& key, - const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, - const CompatibleCompare& comp,mpl::true_) -{ - return ordered_index_find(top,y,key,x,comp,mpl::false_()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline Node* ordered_index_find( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp,mpl::false_) -{ - Node* y0=y; - - while (top){ - if(!comp(key(top->value()),x)){ - y=top; - top=Node::from_impl(top->left()); - } - else top=Node::from_impl(top->right()); - } - - return (y==y0||comp(x,key(y->value())))?y0:y; -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline Node* ordered_index_lower_bound( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp) -{ - typedef typename KeyFromValue::result_type key_type; - - return ordered_index_lower_bound( - top,y,key,x,comp, - promotes_2nd_arg()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleCompare -> -inline Node* ordered_index_lower_bound( - Node* top,Node* y,const KeyFromValue& key, - const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, - const CompatibleCompare& comp,mpl::true_) -{ - return ordered_index_lower_bound(top,y,key,x,comp,mpl::false_()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline Node* ordered_index_lower_bound( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp,mpl::false_) -{ - while(top){ - if(!comp(key(top->value()),x)){ - y=top; - top=Node::from_impl(top->left()); - } - else top=Node::from_impl(top->right()); - } - - return y; -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline Node* ordered_index_upper_bound( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp) -{ - typedef typename KeyFromValue::result_type key_type; - - return ordered_index_upper_bound( - top,y,key,x,comp, - promotes_1st_arg()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleCompare -> -inline Node* ordered_index_upper_bound( - Node* top,Node* y,const KeyFromValue& key, - const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, - const CompatibleCompare& comp,mpl::true_) -{ - return ordered_index_upper_bound(top,y,key,x,comp,mpl::false_()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline Node* ordered_index_upper_bound( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp,mpl::false_) -{ - while(top){ - if(comp(x,key(top->value()))){ - y=top; - top=Node::from_impl(top->left()); - } - else top=Node::from_impl(top->right()); - } - - return y; -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::pair ordered_index_equal_range( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp) -{ - typedef typename KeyFromValue::result_type key_type; - - return ordered_index_equal_range( - top,y,key,x,comp, - mpl::and_< - promotes_1st_arg, - promotes_2nd_arg >()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleCompare -> -inline std::pair ordered_index_equal_range( - Node* top,Node* y,const KeyFromValue& key, - const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, - const CompatibleCompare& comp,mpl::true_) -{ - return ordered_index_equal_range(top,y,key,x,comp,mpl::false_()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::pair ordered_index_equal_range( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp,mpl::false_) -{ - while(top){ - if(comp(key(top->value()),x)){ - top=Node::from_impl(top->right()); - } - else if(comp(x,key(top->value()))){ - y=top; - top=Node::from_impl(top->left()); - } - else{ - return std::pair( - ordered_index_lower_bound( - Node::from_impl(top->left()),top,key,x,comp,mpl::false_()), - ordered_index_upper_bound( - Node::from_impl(top->right()),y,key,x,comp,mpl::false_())); - } - } - - return std::pair(y,y); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/promotes_arg.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/promotes_arg.hpp deleted file mode 100644 index 7a11b6e9fbe..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/promotes_arg.hpp +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright 2003-2017 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_PROMOTES_ARG_HPP -#define BOOST_MULTI_INDEX_DETAIL_PROMOTES_ARG_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include - -/* Metafunctions to check if f(arg1,arg2) promotes either arg1 to the type of - * arg2 or viceversa. By default, (i.e. if it cannot be determined), no - * promotion is assumed. - */ - -#if BOOST_WORKAROUND(BOOST_MSVC,<1400) - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template -struct promotes_1st_arg:mpl::false_{}; - -template -struct promotes_2nd_arg:mpl::false_{}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#else - -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template -struct promotes_1st_arg: - mpl::and_< - mpl::not_ >, - is_convertible, - is_transparent - > -{}; - -template -struct promotes_2nd_arg: - mpl::and_< - mpl::not_ >, - is_convertible, - is_transparent - > -{}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/raw_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/raw_ptr.hpp deleted file mode 100644 index c32007435c0..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/raw_ptr.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_RAW_PTR_HPP -#define BOOST_MULTI_INDEX_DETAIL_RAW_PTR_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* gets the underlying pointer of a pointer-like value */ - -template -inline RawPointer raw_ptr(RawPointer const& p,mpl::true_) -{ - return p; -} - -template -inline RawPointer raw_ptr(Pointer const& p,mpl::false_) -{ - return p==Pointer(0)?0:&*p; -} - -template -inline RawPointer raw_ptr(Pointer const& p) -{ - return raw_ptr(p,is_same()); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/restore_wstrict_aliasing.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/restore_wstrict_aliasing.hpp deleted file mode 100644 index ee2c799d5a8..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/restore_wstrict_aliasing.hpp +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright 2003-2016 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#define BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING -#include -#undef BOOST_MULTI_INDEX_DETAIL_RESTORE_WSTRICT_ALIASING diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_loader.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_loader.hpp deleted file mode 100644 index 4b00345a6d9..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_loader.hpp +++ /dev/null @@ -1,173 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_LOADER_HPP -#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_LOADER_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* This class implements a serialization rearranger for random access - * indices. In order to achieve O(n) performance, the following strategy - * is followed: the nodes of the index are handled as if in a bidirectional - * list, where the next pointers are stored in the original - * random_access_index_ptr_array and the prev pointers are stored in - * an auxiliary array. Rearranging of nodes in such a bidirectional list - * is constant time. Once all the arrangements are performed (on destruction - * time) the list is traversed in reverse order and - * pointers are swapped and set accordingly so that they recover its - * original semantics ( *(node->up())==node ) while retaining the - * new order. - */ - -template -class random_access_index_loader_base:private noncopyable -{ -protected: - typedef random_access_index_node_impl< - typename boost::detail::allocator::rebind_to< - Allocator, - char - >::type - > node_impl_type; - typedef typename node_impl_type::pointer node_impl_pointer; - typedef random_access_index_ptr_array ptr_array; - - random_access_index_loader_base(const Allocator& al_,ptr_array& ptrs_): - al(al_), - ptrs(ptrs_), - header(*ptrs.end()), - prev_spc(al,0), - preprocessed(false) - {} - - ~random_access_index_loader_base() - { - if(preprocessed) - { - node_impl_pointer n=header; - next(n)=n; - - for(std::size_t i=ptrs.size();i--;){ - n=prev(n); - std::size_t d=position(n); - if(d!=i){ - node_impl_pointer m=prev(next_at(i)); - std::swap(m->up(),n->up()); - next_at(d)=next_at(i); - std::swap(prev_at(d),prev_at(i)); - } - next(n)=n; - } - } - } - - void rearrange(node_impl_pointer position_,node_impl_pointer x) - { - preprocess(); /* only incur this penalty if rearrange() is ever called */ - if(position_==node_impl_pointer(0))position_=header; - next(prev(x))=next(x); - prev(next(x))=prev(x); - prev(x)=position_; - next(x)=next(position_); - next(prev(x))=prev(next(x))=x; - } - -private: - void preprocess() - { - if(!preprocessed){ - /* get space for the auxiliary prev array */ - auto_space tmp(al,ptrs.size()+1); - prev_spc.swap(tmp); - - /* prev_spc elements point to the prev nodes */ - std::rotate_copy( - &*ptrs.begin(),&*ptrs.end(),&*ptrs.end()+1,&*prev_spc.data()); - - /* ptrs elements point to the next nodes */ - std::rotate(&*ptrs.begin(),&*ptrs.begin()+1,&*ptrs.end()+1); - - preprocessed=true; - } - } - - std::size_t position(node_impl_pointer x)const - { - return (std::size_t)(x->up()-ptrs.begin()); - } - - node_impl_pointer& next_at(std::size_t n)const - { - return *ptrs.at(n); - } - - node_impl_pointer& prev_at(std::size_t n)const - { - return *(prev_spc.data()+n); - } - - node_impl_pointer& next(node_impl_pointer x)const - { - return *(x->up()); - } - - node_impl_pointer& prev(node_impl_pointer x)const - { - return prev_at(position(x)); - } - - Allocator al; - ptr_array& ptrs; - node_impl_pointer header; - auto_space prev_spc; - bool preprocessed; -}; - -template -class random_access_index_loader: - private random_access_index_loader_base -{ - typedef random_access_index_loader_base super; - typedef typename super::node_impl_pointer node_impl_pointer; - typedef typename super::ptr_array ptr_array; - -public: - random_access_index_loader(const Allocator& al_,ptr_array& ptrs_): - super(al_,ptrs_) - {} - - void rearrange(Node* position_,Node *x) - { - super::rearrange( - position_?position_->impl():node_impl_pointer(0),x->impl()); - } -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_node.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_node.hpp deleted file mode 100644 index ad61ea25dda..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_node.hpp +++ /dev/null @@ -1,273 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_NODE_HPP -#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_NODE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template -struct random_access_index_node_impl -{ - typedef typename - boost::detail::allocator::rebind_to< - Allocator,random_access_index_node_impl - >::type::pointer pointer; - typedef typename - boost::detail::allocator::rebind_to< - Allocator,random_access_index_node_impl - >::type::const_pointer const_pointer; - typedef typename - boost::detail::allocator::rebind_to< - Allocator,pointer - >::type::pointer ptr_pointer; - - ptr_pointer& up(){return up_;} - ptr_pointer up()const{return up_;} - - /* interoperability with rnd_node_iterator */ - - static void increment(pointer& x) - { - x=*(x->up()+1); - } - - static void decrement(pointer& x) - { - x=*(x->up()-1); - } - - static void advance(pointer& x,std::ptrdiff_t n) - { - x=*(x->up()+n); - } - - static std::ptrdiff_t distance(pointer x,pointer y) - { - return y->up()-x->up(); - } - - /* algorithmic stuff */ - - static void relocate(ptr_pointer pos,ptr_pointer x) - { - pointer n=*x; - if(xup()=pos-1; - } - else{ - while(x!=pos){ - *x=*(x-1); - (*x)->up()=x; - --x; - } - *pos=n; - n->up()=pos; - } - }; - - static void relocate(ptr_pointer pos,ptr_pointer first,ptr_pointer last) - { - ptr_pointer begin,middle,end; - if(posup()=begin+j; - break; - } - else{ - *(begin+j)=*(begin+k); - (*(begin+j))->up()=begin+j; - } - - if(kup()=begin+k; - break; - } - else{ - *(begin+k)=*(begin+j); - (*(begin+k))->up()=begin+k; - } - } - } - }; - - static void extract(ptr_pointer x,ptr_pointer pend) - { - --pend; - while(x!=pend){ - *x=*(x+1); - (*x)->up()=x; - ++x; - } - } - - static void transfer( - ptr_pointer pbegin0,ptr_pointer pend0,ptr_pointer pbegin1) - { - while(pbegin0!=pend0){ - *pbegin1=*pbegin0++; - (*pbegin1)->up()=pbegin1; - ++pbegin1; - } - } - - static void reverse(ptr_pointer pbegin,ptr_pointer pend) - { - std::ptrdiff_t d=(pend-pbegin)/2; - for(std::ptrdiff_t i=0;iup()=pbegin; - (*pend)->up()=pend; - ++pbegin; - } - } - -private: - ptr_pointer up_; -}; - -template -struct random_access_index_node_trampoline: - random_access_index_node_impl< - typename boost::detail::allocator::rebind_to< - typename Super::allocator_type, - char - >::type - > -{ - typedef random_access_index_node_impl< - typename boost::detail::allocator::rebind_to< - typename Super::allocator_type, - char - >::type - > impl_type; -}; - -template -struct random_access_index_node: - Super,random_access_index_node_trampoline -{ -private: - typedef random_access_index_node_trampoline trampoline; - -public: - typedef typename trampoline::impl_type impl_type; - typedef typename trampoline::pointer impl_pointer; - typedef typename trampoline::const_pointer const_impl_pointer; - typedef typename trampoline::ptr_pointer impl_ptr_pointer; - - impl_ptr_pointer& up(){return trampoline::up();} - impl_ptr_pointer up()const{return trampoline::up();} - - impl_pointer impl() - { - return static_cast( - static_cast(static_cast(this))); - } - - const_impl_pointer impl()const - { - return static_cast( - static_cast(static_cast(this))); - } - - static random_access_index_node* from_impl(impl_pointer x) - { - return - static_cast( - static_cast( - raw_ptr(x))); - } - - static const random_access_index_node* from_impl(const_impl_pointer x) - { - return - static_cast( - static_cast( - raw_ptr(x))); - } - - /* interoperability with rnd_node_iterator */ - - static void increment(random_access_index_node*& x) - { - impl_pointer xi=x->impl(); - trampoline::increment(xi); - x=from_impl(xi); - } - - static void decrement(random_access_index_node*& x) - { - impl_pointer xi=x->impl(); - trampoline::decrement(xi); - x=from_impl(xi); - } - - static void advance(random_access_index_node*& x,std::ptrdiff_t n) - { - impl_pointer xi=x->impl(); - trampoline::advance(xi,n); - x=from_impl(xi); - } - - static std::ptrdiff_t distance( - random_access_index_node* x,random_access_index_node* y) - { - return trampoline::distance(x->impl(),y->impl()); - } -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ops.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ops.hpp deleted file mode 100644 index f5e76e4441f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ops.hpp +++ /dev/null @@ -1,203 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_OPS_HPP -#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_OPS_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Common code for random_access_index memfuns having templatized and - * non-templatized versions. - */ - -template -Node* random_access_index_remove( - random_access_index_ptr_array& ptrs,Predicate pred) -{ - typedef typename Node::value_type value_type; - typedef typename Node::impl_ptr_pointer impl_ptr_pointer; - - impl_ptr_pointer first=ptrs.begin(), - res=first, - last=ptrs.end(); - for(;first!=last;++first){ - if(!pred( - const_cast(Node::from_impl(*first)->value()))){ - if(first!=res){ - std::swap(*first,*res); - (*first)->up()=first; - (*res)->up()=res; - } - ++res; - } - } - return Node::from_impl(*res); -} - -template -Node* random_access_index_unique( - random_access_index_ptr_array& ptrs,BinaryPredicate binary_pred) -{ - typedef typename Node::value_type value_type; - typedef typename Node::impl_ptr_pointer impl_ptr_pointer; - - impl_ptr_pointer first=ptrs.begin(), - res=first, - last=ptrs.end(); - if(first!=last){ - for(;++first!=last;){ - if(!binary_pred( - const_cast(Node::from_impl(*res)->value()), - const_cast(Node::from_impl(*first)->value()))){ - ++res; - if(first!=res){ - std::swap(*first,*res); - (*first)->up()=first; - (*res)->up()=res; - } - } - } - ++res; - } - return Node::from_impl(*res); -} - -template -void random_access_index_inplace_merge( - const Allocator& al, - random_access_index_ptr_array& ptrs, - BOOST_DEDUCED_TYPENAME Node::impl_ptr_pointer first1,Compare comp) -{ - typedef typename Node::value_type value_type; - typedef typename Node::impl_pointer impl_pointer; - typedef typename Node::impl_ptr_pointer impl_ptr_pointer; - - auto_space spc(al,ptrs.size()); - - impl_ptr_pointer first0=ptrs.begin(), - last0=first1, - last1=ptrs.end(), - out=spc.data(); - while(first0!=last0&&first1!=last1){ - if(comp( - const_cast(Node::from_impl(*first1)->value()), - const_cast(Node::from_impl(*first0)->value()))){ - *out++=*first1++; - } - else{ - *out++=*first0++; - } - } - std::copy(&*first0,&*last0,&*out); - std::copy(&*first1,&*last1,&*out); - - first1=ptrs.begin(); - out=spc.data(); - while(first1!=last1){ - *first1=*out++; - (*first1)->up()=first1; - ++first1; - } -} - -/* sorting */ - -/* auxiliary stuff */ - -template -struct random_access_index_sort_compare -{ - typedef typename Node::impl_pointer first_argument_type; - typedef typename Node::impl_pointer second_argument_type; - typedef bool result_type; - - random_access_index_sort_compare(Compare comp_=Compare()):comp(comp_){} - - bool operator()( - typename Node::impl_pointer x,typename Node::impl_pointer y)const - { - typedef typename Node::value_type value_type; - - return comp( - const_cast(Node::from_impl(x)->value()), - const_cast(Node::from_impl(y)->value())); - } - -private: - Compare comp; -}; - -template -void random_access_index_sort( - const Allocator& al, - random_access_index_ptr_array& ptrs, - Compare comp) -{ - /* The implementation is extremely simple: an auxiliary - * array of pointers is sorted using stdlib facilities and - * then used to rearrange the index. This is suboptimal - * in space and time, but has some advantages over other - * possible approaches: - * - Use std::stable_sort() directly on ptrs using some - * special iterator in charge of maintaining pointers - * and up() pointers in sync: we cannot guarantee - * preservation of the container invariants in the face of - * exceptions, if, for instance, std::stable_sort throws - * when ptrs transitorily contains duplicate elements. - * - Rewrite the internal algorithms of std::stable_sort - * adapted for this case: besides being a fair amount of - * work, making a stable sort compatible with Boost.MultiIndex - * invariants (basically, no duplicates or missing elements - * even if an exception is thrown) is complicated, error-prone - * and possibly won't perform much better than the - * solution adopted. - */ - - if(ptrs.size()<=1)return; - - typedef typename Node::impl_pointer impl_pointer; - typedef typename Node::impl_ptr_pointer impl_ptr_pointer; - typedef random_access_index_sort_compare< - Node,Compare> ptr_compare; - - impl_ptr_pointer first=ptrs.begin(); - impl_ptr_pointer last=ptrs.end(); - auto_space< - impl_pointer, - Allocator> spc(al,ptrs.size()); - impl_ptr_pointer buf=spc.data(); - - std::copy(&*first,&*last,&*buf); - std::stable_sort(&*buf,&*buf+ptrs.size(),ptr_compare(comp)); - - while(first!=last){ - *first=*buf++; - (*first)->up()=first; - ++first; - } -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ptr_array.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ptr_array.hpp deleted file mode 100644 index bae1c851b8e..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_index_ptr_array.hpp +++ /dev/null @@ -1,144 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_RND_INDEX_PTR_ARRAY_HPP -#define BOOST_MULTI_INDEX_DETAIL_RND_INDEX_PTR_ARRAY_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* pointer structure for use by random access indices */ - -template -class random_access_index_ptr_array:private noncopyable -{ - typedef random_access_index_node_impl< - typename boost::detail::allocator::rebind_to< - Allocator, - char - >::type - > node_impl_type; - -public: - typedef typename node_impl_type::pointer value_type; - typedef typename boost::detail::allocator::rebind_to< - Allocator,value_type - >::type::pointer pointer; - - random_access_index_ptr_array( - const Allocator& al,value_type end_,std::size_t sz): - size_(sz), - capacity_(sz), - spc(al,capacity_+1) - { - *end()=end_; - end_->up()=end(); - } - - std::size_t size()const{return size_;} - std::size_t capacity()const{return capacity_;} - - void room_for_one() - { - if(size_==capacity_){ - reserve(capacity_<=10?15:capacity_+capacity_/2); - } - } - - void reserve(std::size_t c) - { - if(c>capacity_)set_capacity(c); - } - - void shrink_to_fit() - { - if(capacity_>size_)set_capacity(size_); - } - - pointer begin()const{return ptrs();} - pointer end()const{return ptrs()+size_;} - pointer at(std::size_t n)const{return ptrs()+n;} - - void push_back(value_type x) - { - *(end()+1)=*end(); - (*(end()+1))->up()=end()+1; - *end()=x; - (*end())->up()=end(); - ++size_; - } - - void erase(value_type x) - { - node_impl_type::extract(x->up(),end()+1); - --size_; - } - - void clear() - { - *begin()=*end(); - (*begin())->up()=begin(); - size_=0; - } - - void swap(random_access_index_ptr_array& x) - { - std::swap(size_,x.size_); - std::swap(capacity_,x.capacity_); - spc.swap(x.spc); - } - -private: - std::size_t size_; - std::size_t capacity_; - auto_space spc; - - pointer ptrs()const - { - return spc.data(); - } - - void set_capacity(std::size_t c) - { - auto_space spc1(spc.get_allocator(),c+1); - node_impl_type::transfer(begin(),end()+1,spc1.data()); - spc.swap(spc1); - capacity_=c; - } -}; - -template -void swap( - random_access_index_ptr_array& x, - random_access_index_ptr_array& y) -{ - x.swap(y); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_node_iterator.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_node_iterator.hpp deleted file mode 100644 index 48026132fb7..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnd_node_iterator.hpp +++ /dev/null @@ -1,140 +0,0 @@ -/* Copyright 2003-2014 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_RND_NODE_ITERATOR_HPP -#define BOOST_MULTI_INDEX_DETAIL_RND_NODE_ITERATOR_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#include -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Iterator class for node-based indices with random access iterators. */ - -template -class rnd_node_iterator: - public random_access_iterator_helper< - rnd_node_iterator, - typename Node::value_type, - std::ptrdiff_t, - const typename Node::value_type*, - const typename Node::value_type&> -{ -public: - /* coverity[uninit_ctor]: suppress warning */ - rnd_node_iterator(){} - explicit rnd_node_iterator(Node* node_):node(node_){} - - const typename Node::value_type& operator*()const - { - return node->value(); - } - - rnd_node_iterator& operator++() - { - Node::increment(node); - return *this; - } - - rnd_node_iterator& operator--() - { - Node::decrement(node); - return *this; - } - - rnd_node_iterator& operator+=(std::ptrdiff_t n) - { - Node::advance(node,n); - return *this; - } - - rnd_node_iterator& operator-=(std::ptrdiff_t n) - { - Node::advance(node,-n); - return *this; - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* Serialization. As for why the following is public, - * see explanation in safe_mode_iterator notes in safe_mode.hpp. - */ - - BOOST_SERIALIZATION_SPLIT_MEMBER() - - typedef typename Node::base_type node_base_type; - - template - void save(Archive& ar,const unsigned int)const - { - node_base_type* bnode=node; - ar< - void load(Archive& ar,const unsigned int) - { - node_base_type* bnode; - ar>>serialization::make_nvp("pointer",bnode); - node=static_cast(bnode); - } -#endif - - /* get_node is not to be used by the user */ - - typedef Node node_type; - - Node* get_node()const{return node;} - -private: - Node* node; -}; - -template -bool operator==( - const rnd_node_iterator& x, - const rnd_node_iterator& y) -{ - return x.get_node()==y.get_node(); -} - -template -bool operator<( - const rnd_node_iterator& x, - const rnd_node_iterator& y) -{ - return Node::distance(x.get_node(),y.get_node())>0; -} - -template -std::ptrdiff_t operator-( - const rnd_node_iterator& x, - const rnd_node_iterator& y) -{ - return Node::distance(y.get_node(),x.get_node()); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnk_index_ops.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnk_index_ops.hpp deleted file mode 100644 index fb233cf4973..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/rnk_index_ops.hpp +++ /dev/null @@ -1,300 +0,0 @@ -/* Copyright 2003-2017 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_RNK_INDEX_OPS_HPP -#define BOOST_MULTI_INDEX_DETAIL_RNK_INDEX_OPS_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Common code for ranked_index memfuns having templatized and - * non-templatized versions. - */ - -template -inline std::size_t ranked_node_size(Pointer x) -{ - return x!=Pointer(0)?x->size:0; -} - -template -inline Pointer ranked_index_nth(std::size_t n,Pointer end_) -{ - Pointer top=end_->parent(); - if(top==Pointer(0)||n>=top->size)return end_; - - for(;;){ - std::size_t s=ranked_node_size(top->left()); - if(n==s)return top; - if(nleft(); - else{ - top=top->right(); - n-=s+1; - } - } -} - -template -inline std::size_t ranked_index_rank(Pointer x,Pointer end_) -{ - Pointer top=end_->parent(); - if(top==Pointer(0))return 0; - if(x==end_)return top->size; - - std::size_t s=ranked_node_size(x->left()); - while(x!=top){ - Pointer z=x->parent(); - if(x==z->right()){ - s+=ranked_node_size(z->left())+1; - } - x=z; - } - return s; -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::size_t ranked_index_find_rank( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp) -{ - typedef typename KeyFromValue::result_type key_type; - - return ranked_index_find_rank( - top,y,key,x,comp, - mpl::and_< - promotes_1st_arg, - promotes_2nd_arg >()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleCompare -> -inline std::size_t ranked_index_find_rank( - Node* top,Node* y,const KeyFromValue& key, - const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, - const CompatibleCompare& comp,mpl::true_) -{ - return ranked_index_find_rank(top,y,key,x,comp,mpl::false_()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::size_t ranked_index_find_rank( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp,mpl::false_) -{ - if(!top)return 0; - - std::size_t s=top->impl()->size, - s0=s; - Node* y0=y; - - do{ - if(!comp(key(top->value()),x)){ - y=top; - s-=ranked_node_size(y->right())+1; - top=Node::from_impl(top->left()); - } - else top=Node::from_impl(top->right()); - }while(top); - - return (y==y0||comp(x,key(y->value())))?s0:s; -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::size_t ranked_index_lower_bound_rank( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp) -{ - typedef typename KeyFromValue::result_type key_type; - - return ranked_index_lower_bound_rank( - top,y,key,x,comp, - promotes_2nd_arg()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleCompare -> -inline std::size_t ranked_index_lower_bound_rank( - Node* top,Node* y,const KeyFromValue& key, - const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, - const CompatibleCompare& comp,mpl::true_) -{ - return ranked_index_lower_bound_rank(top,y,key,x,comp,mpl::false_()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::size_t ranked_index_lower_bound_rank( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp,mpl::false_) -{ - if(!top)return 0; - - std::size_t s=top->impl()->size; - - do{ - if(!comp(key(top->value()),x)){ - y=top; - s-=ranked_node_size(y->right())+1; - top=Node::from_impl(top->left()); - } - else top=Node::from_impl(top->right()); - }while(top); - - return s; -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::size_t ranked_index_upper_bound_rank( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp) -{ - typedef typename KeyFromValue::result_type key_type; - - return ranked_index_upper_bound_rank( - top,y,key,x,comp, - promotes_1st_arg()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleCompare -> -inline std::size_t ranked_index_upper_bound_rank( - Node* top,Node* y,const KeyFromValue& key, - const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, - const CompatibleCompare& comp,mpl::true_) -{ - return ranked_index_upper_bound_rank(top,y,key,x,comp,mpl::false_()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::size_t ranked_index_upper_bound_rank( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp,mpl::false_) -{ - if(!top)return 0; - - std::size_t s=top->impl()->size; - - do{ - if(comp(x,key(top->value()))){ - y=top; - s-=ranked_node_size(y->right())+1; - top=Node::from_impl(top->left()); - } - else top=Node::from_impl(top->right()); - }while(top); - - return s; -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::pair ranked_index_equal_range_rank( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp) -{ - typedef typename KeyFromValue::result_type key_type; - - return ranked_index_equal_range_rank( - top,y,key,x,comp, - mpl::and_< - promotes_1st_arg, - promotes_2nd_arg >()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleCompare -> -inline std::pair ranked_index_equal_range_rank( - Node* top,Node* y,const KeyFromValue& key, - const BOOST_DEDUCED_TYPENAME KeyFromValue::result_type& x, - const CompatibleCompare& comp,mpl::true_) -{ - return ranked_index_equal_range_rank(top,y,key,x,comp,mpl::false_()); -} - -template< - typename Node,typename KeyFromValue, - typename CompatibleKey,typename CompatibleCompare -> -inline std::pair ranked_index_equal_range_rank( - Node* top,Node* y,const KeyFromValue& key,const CompatibleKey& x, - const CompatibleCompare& comp,mpl::false_) -{ - if(!top)return std::pair(0,0); - - std::size_t s=top->impl()->size; - - do{ - if(comp(key(top->value()),x)){ - top=Node::from_impl(top->right()); - } - else if(comp(x,key(top->value()))){ - y=top; - s-=ranked_node_size(y->right())+1; - top=Node::from_impl(top->left()); - } - else{ - return std::pair( - s-top->impl()->size+ - ranked_index_lower_bound_rank( - Node::from_impl(top->left()),top,key,x,comp,mpl::false_()), - s-ranked_node_size(top->right())+ - ranked_index_upper_bound_rank( - Node::from_impl(top->right()),y,key,x,comp,mpl::false_())); - } - }while(top); - - return std::pair(s,s); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/safe_mode.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/safe_mode.hpp deleted file mode 100644 index 905270e9fb3..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/safe_mode.hpp +++ /dev/null @@ -1,588 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_SAFE_MODE_HPP -#define BOOST_MULTI_INDEX_DETAIL_SAFE_MODE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -/* Safe mode machinery, in the spirit of Cay Hortmann's "Safe STL" - * (http://www.horstmann.com/safestl.html). - * In this mode, containers of type Container are derived from - * safe_container, and their corresponding iterators - * are wrapped with safe_iterator. These classes provide - * an internal record of which iterators are at a given moment associated - * to a given container, and properly mark the iterators as invalid - * when the container gets destroyed. - * Iterators are chained in a single attached list, whose header is - * kept by the container. More elaborate data structures would yield better - * performance, but I decided to keep complexity to a minimum since - * speed is not an issue here. - * Safe mode iterators automatically check that only proper operations - * are performed on them: for instance, an invalid iterator cannot be - * dereferenced. Additionally, a set of utilty macros and functions are - * provided that serve to implement preconditions and cooperate with - * the framework within the container. - * Iterators can also be unchecked, i.e. they do not have info about - * which container they belong in. This situation arises when the iterator - * is restored from a serialization archive: only information on the node - * is available, and it is not possible to determine to which container - * the iterator is associated to. The only sensible policy is to assume - * unchecked iterators are valid, though this can certainly generate false - * positive safe mode checks. - * This is not a full-fledged safe mode framework, and is only intended - * for use within the limits of Boost.MultiIndex. - */ - -/* Assertion macros. These resolve to no-ops if - * !defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE). - */ - -#if !defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) -#undef BOOST_MULTI_INDEX_SAFE_MODE_ASSERT -#define BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(expr,error_code) ((void)0) -#else -#if !defined(BOOST_MULTI_INDEX_SAFE_MODE_ASSERT) -#include -#define BOOST_MULTI_INDEX_SAFE_MODE_ASSERT(expr,error_code) BOOST_ASSERT(expr) -#endif -#endif - -#define BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_valid_iterator(it), \ - safe_mode::invalid_iterator); - -#define BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(it) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_dereferenceable_iterator(it), \ - safe_mode::not_dereferenceable_iterator); - -#define BOOST_MULTI_INDEX_CHECK_INCREMENTABLE_ITERATOR(it) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_incrementable_iterator(it), \ - safe_mode::not_incrementable_iterator); - -#define BOOST_MULTI_INDEX_CHECK_DECREMENTABLE_ITERATOR(it) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_decrementable_iterator(it), \ - safe_mode::not_decrementable_iterator); - -#define BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,cont) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_is_owner(it,cont), \ - safe_mode::not_owner); - -#define BOOST_MULTI_INDEX_CHECK_SAME_OWNER(it0,it1) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_same_owner(it0,it1), \ - safe_mode::not_same_owner); - -#define BOOST_MULTI_INDEX_CHECK_VALID_RANGE(it0,it1) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_valid_range(it0,it1), \ - safe_mode::invalid_range); - -#define BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(it,it0,it1) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_outside_range(it,it0,it1), \ - safe_mode::inside_range); - -#define BOOST_MULTI_INDEX_CHECK_IN_BOUNDS(it,n) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_in_bounds(it,n), \ - safe_mode::out_of_bounds); - -#define BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(cont0,cont1) \ - BOOST_MULTI_INDEX_SAFE_MODE_ASSERT( \ - safe_mode::check_different_container(cont0,cont1), \ - safe_mode::same_container); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#include -#endif - -#if defined(BOOST_HAS_THREADS) -#include -#endif - -namespace boost{ - -namespace multi_index{ - -namespace safe_mode{ - -/* Checking routines. Assume the best for unchecked iterators - * (i.e. they pass the checking when there is not enough info - * to know.) - */ - -template -inline bool check_valid_iterator(const Iterator& it) -{ - return it.valid()||it.unchecked(); -} - -template -inline bool check_dereferenceable_iterator(const Iterator& it) -{ - return (it.valid()&&it!=it.owner()->end())||it.unchecked(); -} - -template -inline bool check_incrementable_iterator(const Iterator& it) -{ - return (it.valid()&&it!=it.owner()->end())||it.unchecked(); -} - -template -inline bool check_decrementable_iterator(const Iterator& it) -{ - return (it.valid()&&it!=it.owner()->begin())||it.unchecked(); -} - -template -inline bool check_is_owner( - const Iterator& it,const typename Iterator::container_type& cont) -{ - return (it.valid()&&it.owner()==&cont)||it.unchecked(); -} - -template -inline bool check_same_owner(const Iterator& it0,const Iterator& it1) -{ - return (it0.valid()&&it1.valid()&&it0.owner()==it1.owner())|| - it0.unchecked()||it1.unchecked(); -} - -template -inline bool check_valid_range(const Iterator& it0,const Iterator& it1) -{ - if(!check_same_owner(it0,it1))return false; - - if(it0.valid()){ - Iterator last=it0.owner()->end(); - if(it1==last)return true; - - for(Iterator first=it0;first!=last;++first){ - if(first==it1)return true; - } - return false; - } - return true; -} - -template -inline bool check_outside_range( - const Iterator& it,const Iterator& it0,const Iterator& it1) -{ - if(!check_same_owner(it0,it1))return false; - - if(it0.valid()){ - Iterator last=it0.owner()->end(); - bool found=false; - - Iterator first=it0; - for(;first!=last;++first){ - if(first==it1)break; - - /* crucial that this check goes after previous break */ - - if(first==it)found=true; - } - if(first!=it1)return false; - return !found; - } - return true; -} - -template -inline bool check_in_bounds(const Iterator& it,Difference n) -{ - if(it.unchecked())return true; - if(!it.valid()) return false; - if(n>0) return it.owner()->end()-it>=n; - else return it.owner()->begin()-it<=n; -} - -template -inline bool check_different_container( - const Container& cont0,const Container& cont1) -{ - return &cont0!=&cont1; -} - -/* Invalidates all iterators equivalent to that given. Safe containers - * must call this when deleting elements: the safe mode framework cannot - * perform this operation automatically without outside help. - */ - -template -inline void detach_equivalent_iterators(Iterator& it) -{ - if(it.valid()){ - { -#if defined(BOOST_HAS_THREADS) - boost::detail::lightweight_mutex::scoped_lock lock(it.cont->mutex); -#endif - - Iterator *prev_,*next_; - for( - prev_=static_cast(&it.cont->header); - (next_=static_cast(prev_->next))!=0;){ - if(next_!=&it&&*next_==it){ - prev_->next=next_->next; - next_->cont=0; - } - else prev_=next_; - } - } - it.detach(); - } -} - -template class safe_container; /* fwd decl. */ - -} /* namespace multi_index::safe_mode */ - -namespace detail{ - -class safe_container_base; /* fwd decl. */ - -class safe_iterator_base -{ -public: - bool valid()const{return cont!=0;} - bool unchecked()const{return unchecked_;} - - inline void detach(); - - void uncheck() - { - detach(); - unchecked_=true; - } - -protected: - safe_iterator_base():cont(0),next(0),unchecked_(false){} - - explicit safe_iterator_base(safe_container_base* cont_): - unchecked_(false) - { - attach(cont_); - } - - safe_iterator_base(const safe_iterator_base& it): - unchecked_(it.unchecked_) - { - attach(it.cont); - } - - safe_iterator_base& operator=(const safe_iterator_base& it) - { - unchecked_=it.unchecked_; - safe_container_base* new_cont=it.cont; - if(cont!=new_cont){ - detach(); - attach(new_cont); - } - return *this; - } - - ~safe_iterator_base() - { - detach(); - } - - const safe_container_base* owner()const{return cont;} - -BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS: - friend class safe_container_base; - -#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) - template friend class safe_mode::safe_container; - template friend - void safe_mode::detach_equivalent_iterators(Iterator&); -#endif - - inline void attach(safe_container_base* cont_); - - safe_container_base* cont; - safe_iterator_base* next; - bool unchecked_; -}; - -class safe_container_base:private noncopyable -{ -public: - safe_container_base(){} - -BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: - friend class safe_iterator_base; - -#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) - template friend - void safe_mode::detach_equivalent_iterators(Iterator&); -#endif - - ~safe_container_base() - { - /* Detaches all remaining iterators, which by now will - * be those pointing to the end of the container. - */ - - for(safe_iterator_base* it=header.next;it;it=it->next)it->cont=0; - header.next=0; - } - - void swap(safe_container_base& x) - { - for(safe_iterator_base* it0=header.next;it0;it0=it0->next)it0->cont=&x; - for(safe_iterator_base* it1=x.header.next;it1;it1=it1->next)it1->cont=this; - std::swap(header.cont,x.header.cont); - std::swap(header.next,x.header.next); - } - - safe_iterator_base header; - -#if defined(BOOST_HAS_THREADS) - boost::detail::lightweight_mutex mutex; -#endif -}; - -void safe_iterator_base::attach(safe_container_base* cont_) -{ - cont=cont_; - if(cont){ -#if defined(BOOST_HAS_THREADS) - boost::detail::lightweight_mutex::scoped_lock lock(cont->mutex); -#endif - - next=cont->header.next; - cont->header.next=this; - } -} - -void safe_iterator_base::detach() -{ - if(cont){ -#if defined(BOOST_HAS_THREADS) - boost::detail::lightweight_mutex::scoped_lock lock(cont->mutex); -#endif - - safe_iterator_base *prev_,*next_; - for(prev_=&cont->header;(next_=prev_->next)!=this;prev_=next_){} - prev_->next=next; - cont=0; - } -} - -} /* namespace multi_index::detail */ - -namespace safe_mode{ - -/* In order to enable safe mode on a container: - * - The container must derive from safe_container, - * - iterators must be generated via safe_iterator, which adapts a - * preexistent unsafe iterator class. - */ - -template -class safe_container; - -template -class safe_iterator: - public detail::iter_adaptor,Iterator>, - public detail::safe_iterator_base -{ - typedef detail::iter_adaptor super; - typedef detail::safe_iterator_base safe_super; - -public: - typedef Container container_type; - typedef typename Iterator::reference reference; - typedef typename Iterator::difference_type difference_type; - - safe_iterator(){} - explicit safe_iterator(safe_container* cont_): - safe_super(cont_){} - template - safe_iterator(const T0& t0,safe_container* cont_): - super(Iterator(t0)),safe_super(cont_){} - template - safe_iterator( - const T0& t0,const T1& t1,safe_container* cont_): - super(Iterator(t0,t1)),safe_super(cont_){} - - safe_iterator& operator=(const safe_iterator& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x); - this->base_reference()=x.base_reference(); - safe_super::operator=(x); - return *this; - } - - const container_type* owner()const - { - return - static_cast( - static_cast*>( - this->safe_super::owner())); - } - - /* get_node is not to be used by the user */ - - typedef typename Iterator::node_type node_type; - - node_type* get_node()const{return this->base_reference().get_node();} - -private: - friend class boost::multi_index::detail::iter_adaptor_access; - - reference dereference()const - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(*this); - return *(this->base_reference()); - } - - bool equal(const safe_iterator& x)const - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x); - BOOST_MULTI_INDEX_CHECK_SAME_OWNER(*this,x); - return this->base_reference()==x.base_reference(); - } - - void increment() - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); - BOOST_MULTI_INDEX_CHECK_INCREMENTABLE_ITERATOR(*this); - ++(this->base_reference()); - } - - void decrement() - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); - BOOST_MULTI_INDEX_CHECK_DECREMENTABLE_ITERATOR(*this); - --(this->base_reference()); - } - - void advance(difference_type n) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); - BOOST_MULTI_INDEX_CHECK_IN_BOUNDS(*this,n); - this->base_reference()+=n; - } - - difference_type distance_to(const safe_iterator& x)const - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(x); - BOOST_MULTI_INDEX_CHECK_SAME_OWNER(*this,x); - return x.base_reference()-this->base_reference(); - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* Serialization. Note that Iterator::save and Iterator:load - * are assumed to be defined and public: at first sight it seems - * like we could have resorted to the public serialization interface - * for doing the forwarding to the adapted iterator class: - * ar<>base_reference(); - * but this would cause incompatibilities if a saving - * program is in safe mode and the loading program is not, or - * viceversa --in safe mode, the archived iterator data is one layer - * deeper, this is especially relevant with XML archives. - * It'd be nice if Boost.Serialization provided some forwarding - * facility for use by adaptor classes. - */ - - friend class boost::serialization::access; - - BOOST_SERIALIZATION_SPLIT_MEMBER() - - template - void save(Archive& ar,const unsigned int version)const - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(*this); - this->base_reference().save(ar,version); - } - - template - void load(Archive& ar,const unsigned int version) - { - this->base_reference().load(ar,version); - safe_super::uncheck(); - } -#endif -}; - -template -class safe_container:public detail::safe_container_base -{ - typedef detail::safe_container_base super; - -public: - void detach_dereferenceable_iterators() - { - typedef typename Container::iterator iterator; - - iterator end_=static_cast(this)->end(); - iterator *prev_,*next_; - for( - prev_=static_cast(&this->header); - (next_=static_cast(prev_->next))!=0;){ - if(*next_!=end_){ - prev_->next=next_->next; - next_->cont=0; - } - else prev_=next_; - } - } - - void swap(safe_container& x) - { - super::swap(x); - } -}; - -} /* namespace multi_index::safe_mode */ - -} /* namespace multi_index */ - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -namespace serialization{ -template -struct version< - boost::multi_index::safe_mode::safe_iterator -> -{ - BOOST_STATIC_CONSTANT( - int,value=boost::serialization::version::value); -}; -} /* namespace serialization */ -#endif - -} /* namespace boost */ - -#endif /* BOOST_MULTI_INDEX_ENABLE_SAFE_MODE */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/scope_guard.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/scope_guard.hpp deleted file mode 100644 index 116f8f50415..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/scope_guard.hpp +++ /dev/null @@ -1,453 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_SCOPE_GUARD_HPP -#define BOOST_MULTI_INDEX_DETAIL_SCOPE_GUARD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Until some official version of the ScopeGuard idiom makes it into Boost, - * we locally define our own. This is a merely reformated version of - * ScopeGuard.h as defined in: - * Alexandrescu, A., Marginean, P.:"Generic: Change the Way You - * Write Exception-Safe Code - Forever", C/C++ Users Jornal, Dec 2000, - * http://www.drdobbs.com/184403758 - * with the following modifications: - * - General pretty formatting (pretty to my taste at least.) - * - Naming style changed to standard C++ library requirements. - * - Added scope_guard_impl4 and obj_scope_guard_impl3, (Boost.MultiIndex - * needs them). A better design would provide guards for many more - * arguments through the Boost Preprocessor Library. - * - Added scope_guard_impl_base::touch (see below.) - * - Removed RefHolder and ByRef, whose functionality is provided - * already by Boost.Ref. - * - Removed static make_guard's and make_obj_guard's, so that the code - * will work even if BOOST_NO_MEMBER_TEMPLATES is defined. This forces - * us to move some private ctors to public, though. - * - * NB: CodeWarrior Pro 8 seems to have problems looking up safe_execute - * without an explicit qualification. - * - * We also define the following variants of the idiom: - * - * - make_guard_if_c( ... ) - * - make_guard_if( ... ) - * - make_obj_guard_if_c( ... ) - * - make_obj_guard_if( ... ) - * which may be used with a compile-time constant to yield - * a "null_guard" if the boolean compile-time parameter is false, - * or conversely, the guard is only constructed if the constant is true. - * This is useful to avoid extra tagging, because the returned - * null_guard can be optimzed comlpetely away by the compiler. - */ - -class scope_guard_impl_base -{ -public: - scope_guard_impl_base():dismissed_(false){} - void dismiss()const{dismissed_=true;} - - /* This helps prevent some "unused variable" warnings under, for instance, - * GCC 3.2. - */ - void touch()const{} - -protected: - ~scope_guard_impl_base(){} - - scope_guard_impl_base(const scope_guard_impl_base& other): - dismissed_(other.dismissed_) - { - other.dismiss(); - } - - template - static void safe_execute(J& j){ - BOOST_TRY{ - if(!j.dismissed_)j.execute(); - } - BOOST_CATCH(...){} - BOOST_CATCH_END - } - - mutable bool dismissed_; - -private: - scope_guard_impl_base& operator=(const scope_guard_impl_base&); -}; - -typedef const scope_guard_impl_base& scope_guard; - -struct null_guard : public scope_guard_impl_base -{ - template< class T1 > - null_guard( const T1& ) - { } - - template< class T1, class T2 > - null_guard( const T1&, const T2& ) - { } - - template< class T1, class T2, class T3 > - null_guard( const T1&, const T2&, const T3& ) - { } - - template< class T1, class T2, class T3, class T4 > - null_guard( const T1&, const T2&, const T3&, const T4& ) - { } - - template< class T1, class T2, class T3, class T4, class T5 > - null_guard( const T1&, const T2&, const T3&, const T4&, const T5& ) - { } -}; - -template< bool cond, class T > -struct null_guard_return -{ - typedef typename boost::mpl::if_c::type type; -}; - -template -class scope_guard_impl0:public scope_guard_impl_base -{ -public: - scope_guard_impl0(F fun):fun_(fun){} - ~scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);} - void execute(){fun_();} - -protected: - - F fun_; -}; - -template -inline scope_guard_impl0 make_guard(F fun) -{ - return scope_guard_impl0(fun); -} - -template -inline typename null_guard_return >::type -make_guard_if_c(F fun) -{ - return typename null_guard_return >::type(fun); -} - -template -inline typename null_guard_return >::type -make_guard_if(F fun) -{ - return make_guard_if(fun); -} - -template -class scope_guard_impl1:public scope_guard_impl_base -{ -public: - scope_guard_impl1(F fun,P1 p1):fun_(fun),p1_(p1){} - ~scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);} - void execute(){fun_(p1_);} - -protected: - F fun_; - const P1 p1_; -}; - -template -inline scope_guard_impl1 make_guard(F fun,P1 p1) -{ - return scope_guard_impl1(fun,p1); -} - -template -inline typename null_guard_return >::type -make_guard_if_c(F fun,P1 p1) -{ - return typename null_guard_return >::type(fun,p1); -} - -template -inline typename null_guard_return >::type -make_guard_if(F fun,P1 p1) -{ - return make_guard_if_c(fun,p1); -} - -template -class scope_guard_impl2:public scope_guard_impl_base -{ -public: - scope_guard_impl2(F fun,P1 p1,P2 p2):fun_(fun),p1_(p1),p2_(p2){} - ~scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);} - void execute(){fun_(p1_,p2_);} - -protected: - F fun_; - const P1 p1_; - const P2 p2_; -}; - -template -inline scope_guard_impl2 make_guard(F fun,P1 p1,P2 p2) -{ - return scope_guard_impl2(fun,p1,p2); -} - -template -inline typename null_guard_return >::type -make_guard_if_c(F fun,P1 p1,P2 p2) -{ - return typename null_guard_return >::type(fun,p1,p2); -} - -template -inline typename null_guard_return >::type -make_guard_if(F fun,P1 p1,P2 p2) -{ - return make_guard_if_c(fun,p1,p2); -} - -template -class scope_guard_impl3:public scope_guard_impl_base -{ -public: - scope_guard_impl3(F fun,P1 p1,P2 p2,P3 p3):fun_(fun),p1_(p1),p2_(p2),p3_(p3){} - ~scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);} - void execute(){fun_(p1_,p2_,p3_);} - -protected: - F fun_; - const P1 p1_; - const P2 p2_; - const P3 p3_; -}; - -template -inline scope_guard_impl3 make_guard(F fun,P1 p1,P2 p2,P3 p3) -{ - return scope_guard_impl3(fun,p1,p2,p3); -} - -template -inline typename null_guard_return >::type -make_guard_if_c(F fun,P1 p1,P2 p2,P3 p3) -{ - return typename null_guard_return >::type(fun,p1,p2,p3); -} - -template -inline typename null_guard_return< C::value,scope_guard_impl3 >::type -make_guard_if(F fun,P1 p1,P2 p2,P3 p3) -{ - return make_guard_if_c(fun,p1,p2,p3); -} - -template -class scope_guard_impl4:public scope_guard_impl_base -{ -public: - scope_guard_impl4(F fun,P1 p1,P2 p2,P3 p3,P4 p4): - fun_(fun),p1_(p1),p2_(p2),p3_(p3),p4_(p4){} - ~scope_guard_impl4(){scope_guard_impl_base::safe_execute(*this);} - void execute(){fun_(p1_,p2_,p3_,p4_);} - -protected: - F fun_; - const P1 p1_; - const P2 p2_; - const P3 p3_; - const P4 p4_; -}; - -template -inline scope_guard_impl4 make_guard( - F fun,P1 p1,P2 p2,P3 p3,P4 p4) -{ - return scope_guard_impl4(fun,p1,p2,p3,p4); -} - -template -inline typename null_guard_return >::type -make_guard_if_c( - F fun,P1 p1,P2 p2,P3 p3,P4 p4) -{ - return typename null_guard_return >::type(fun,p1,p2,p3,p4); -} - -template -inline typename null_guard_return >::type -make_guard_if( - F fun,P1 p1,P2 p2,P3 p3,P4 p4) -{ - return make_guard_if_c(fun,p1,p2,p3,p4); -} - -template -class obj_scope_guard_impl0:public scope_guard_impl_base -{ -public: - obj_scope_guard_impl0(Obj& obj,MemFun mem_fun):obj_(obj),mem_fun_(mem_fun){} - ~obj_scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);} - void execute(){(obj_.*mem_fun_)();} - -protected: - Obj& obj_; - MemFun mem_fun_; -}; - -template -inline obj_scope_guard_impl0 make_obj_guard(Obj& obj,MemFun mem_fun) -{ - return obj_scope_guard_impl0(obj,mem_fun); -} - -template -inline typename null_guard_return >::type -make_obj_guard_if_c(Obj& obj,MemFun mem_fun) -{ - return typename null_guard_return >::type(obj,mem_fun); -} - -template -inline typename null_guard_return >::type -make_obj_guard_if(Obj& obj,MemFun mem_fun) -{ - return make_obj_guard_if_c(obj,mem_fun); -} - -template -class obj_scope_guard_impl1:public scope_guard_impl_base -{ -public: - obj_scope_guard_impl1(Obj& obj,MemFun mem_fun,P1 p1): - obj_(obj),mem_fun_(mem_fun),p1_(p1){} - ~obj_scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);} - void execute(){(obj_.*mem_fun_)(p1_);} - -protected: - Obj& obj_; - MemFun mem_fun_; - const P1 p1_; -}; - -template -inline obj_scope_guard_impl1 make_obj_guard( - Obj& obj,MemFun mem_fun,P1 p1) -{ - return obj_scope_guard_impl1(obj,mem_fun,p1); -} - -template -inline typename null_guard_return >::type -make_obj_guard_if_c( Obj& obj,MemFun mem_fun,P1 p1) -{ - return typename null_guard_return >::type(obj,mem_fun,p1); -} - -template -inline typename null_guard_return >::type -make_obj_guard_if( Obj& obj,MemFun mem_fun,P1 p1) -{ - return make_obj_guard_if_c(obj,mem_fun,p1); -} - -template -class obj_scope_guard_impl2:public scope_guard_impl_base -{ -public: - obj_scope_guard_impl2(Obj& obj,MemFun mem_fun,P1 p1,P2 p2): - obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2) - {} - ~obj_scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);} - void execute(){(obj_.*mem_fun_)(p1_,p2_);} - -protected: - Obj& obj_; - MemFun mem_fun_; - const P1 p1_; - const P2 p2_; -}; - -template -inline obj_scope_guard_impl2 -make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2) -{ - return obj_scope_guard_impl2(obj,mem_fun,p1,p2); -} - -template -inline typename null_guard_return >::type -make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2) -{ - return typename null_guard_return >::type(obj,mem_fun,p1,p2); -} - -template -inline typename null_guard_return >::type -make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2) -{ - return make_obj_guard_if_c(obj,mem_fun,p1,p2); -} - -template -class obj_scope_guard_impl3:public scope_guard_impl_base -{ -public: - obj_scope_guard_impl3(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3): - obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2),p3_(p3) - {} - ~obj_scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);} - void execute(){(obj_.*mem_fun_)(p1_,p2_,p3_);} - -protected: - Obj& obj_; - MemFun mem_fun_; - const P1 p1_; - const P2 p2_; - const P3 p3_; -}; - -template -inline obj_scope_guard_impl3 -make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3) -{ - return obj_scope_guard_impl3(obj,mem_fun,p1,p2,p3); -} - -template -inline typename null_guard_return >::type -make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3) -{ - return typename null_guard_return >::type(obj,mem_fun,p1,p2,p3); -} - -template -inline typename null_guard_return >::type -make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3) -{ - return make_obj_guard_if_c(obj,mem_fun,p1,p2,p3); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_node.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_node.hpp deleted file mode 100644 index 85b345af938..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_node.hpp +++ /dev/null @@ -1,217 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_NODE_HPP -#define BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_NODE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* doubly-linked node for use by sequenced_index */ - -template -struct sequenced_index_node_impl -{ - typedef typename - boost::detail::allocator::rebind_to< - Allocator,sequenced_index_node_impl - >::type::pointer pointer; - typedef typename - boost::detail::allocator::rebind_to< - Allocator,sequenced_index_node_impl - >::type::const_pointer const_pointer; - - pointer& prior(){return prior_;} - pointer prior()const{return prior_;} - pointer& next(){return next_;} - pointer next()const{return next_;} - - /* interoperability with bidir_node_iterator */ - - static void increment(pointer& x){x=x->next();} - static void decrement(pointer& x){x=x->prior();} - - /* algorithmic stuff */ - - static void link(pointer x,pointer header) - { - x->prior()=header->prior(); - x->next()=header; - x->prior()->next()=x->next()->prior()=x; - }; - - static void unlink(pointer x) - { - x->prior()->next()=x->next(); - x->next()->prior()=x->prior(); - } - - static void relink(pointer position,pointer x) - { - unlink(x); - x->prior()=position->prior(); - x->next()=position; - x->prior()->next()=x->next()->prior()=x; - } - - static void relink(pointer position,pointer x,pointer y) - { - /* position is assumed not to be in [x,y) */ - - if(x!=y){ - pointer z=y->prior(); - x->prior()->next()=y; - y->prior()=x->prior(); - x->prior()=position->prior(); - z->next()=position; - x->prior()->next()=x; - z->next()->prior()=z; - } - } - - static void reverse(pointer header) - { - pointer x=header; - do{ - pointer y=x->next(); - std::swap(x->prior(),x->next()); - x=y; - }while(x!=header); - } - - static void swap(pointer x,pointer y) - { - /* This swap function does not exchange the header nodes, - * but rather their pointers. This is *not* used for implementing - * sequenced_index::swap. - */ - - if(x->next()!=x){ - if(y->next()!=y){ - std::swap(x->next(),y->next()); - std::swap(x->prior(),y->prior()); - x->next()->prior()=x->prior()->next()=x; - y->next()->prior()=y->prior()->next()=y; - } - else{ - y->next()=x->next(); - y->prior()=x->prior(); - x->next()=x->prior()=x; - y->next()->prior()=y->prior()->next()=y; - } - } - else if(y->next()!=y){ - x->next()=y->next(); - x->prior()=y->prior(); - y->next()=y->prior()=y; - x->next()->prior()=x->prior()->next()=x; - } - } - -private: - pointer prior_; - pointer next_; -}; - -template -struct sequenced_index_node_trampoline: - sequenced_index_node_impl< - typename boost::detail::allocator::rebind_to< - typename Super::allocator_type, - char - >::type - > -{ - typedef sequenced_index_node_impl< - typename boost::detail::allocator::rebind_to< - typename Super::allocator_type, - char - >::type - > impl_type; -}; - -template -struct sequenced_index_node:Super,sequenced_index_node_trampoline -{ -private: - typedef sequenced_index_node_trampoline trampoline; - -public: - typedef typename trampoline::impl_type impl_type; - typedef typename trampoline::pointer impl_pointer; - typedef typename trampoline::const_pointer const_impl_pointer; - - impl_pointer& prior(){return trampoline::prior();} - impl_pointer prior()const{return trampoline::prior();} - impl_pointer& next(){return trampoline::next();} - impl_pointer next()const{return trampoline::next();} - - impl_pointer impl() - { - return static_cast( - static_cast(static_cast(this))); - } - - const_impl_pointer impl()const - { - return static_cast( - static_cast(static_cast(this))); - } - - static sequenced_index_node* from_impl(impl_pointer x) - { - return - static_cast( - static_cast( - raw_ptr(x))); - } - - static const sequenced_index_node* from_impl(const_impl_pointer x) - { - return - static_cast( - static_cast( - raw_ptr(x))); - } - - /* interoperability with bidir_node_iterator */ - - static void increment(sequenced_index_node*& x) - { - impl_pointer xi=x->impl(); - trampoline::increment(xi); - x=from_impl(xi); - } - - static void decrement(sequenced_index_node*& x) - { - impl_pointer xi=x->impl(); - trampoline::decrement(xi); - x=from_impl(xi); - } -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_ops.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_ops.hpp deleted file mode 100644 index 142bdd9dd9a..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/seq_index_ops.hpp +++ /dev/null @@ -1,203 +0,0 @@ -/* Copyright 2003-2016 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_OPS_HPP -#define BOOST_MULTI_INDEX_DETAIL_SEQ_INDEX_OPS_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Common code for sequenced_index memfuns having templatized and - * non-templatized versions. - */ - -template -void sequenced_index_remove(SequencedIndex& x,Predicate pred) -{ - typedef typename SequencedIndex::iterator iterator; - iterator first=x.begin(),last=x.end(); - while(first!=last){ - if(pred(*first))x.erase(first++); - else ++first; - } -} - -template -void sequenced_index_unique(SequencedIndex& x,BinaryPredicate binary_pred) -{ - typedef typename SequencedIndex::iterator iterator; - iterator first=x.begin(); - iterator last=x.end(); - if(first!=last){ - for(iterator middle=first;++middle!=last;middle=first){ - if(binary_pred(*middle,*first))x.erase(middle); - else first=middle; - } - } -} - -template -void sequenced_index_merge(SequencedIndex& x,SequencedIndex& y,Compare comp) -{ - typedef typename SequencedIndex::iterator iterator; - if(&x!=&y){ - iterator first0=x.begin(),last0=x.end(); - iterator first1=y.begin(),last1=y.end(); - while(first0!=last0&&first1!=last1){ - if(comp(*first1,*first0))x.splice(first0,y,first1++); - else ++first0; - } - x.splice(last0,y,first1,last1); - } -} - -/* sorting */ - -/* auxiliary stuff */ - -template -void sequenced_index_collate( - BOOST_DEDUCED_TYPENAME Node::impl_type* x, - BOOST_DEDUCED_TYPENAME Node::impl_type* y, - Compare comp) -{ - typedef typename Node::impl_type impl_type; - typedef typename Node::impl_pointer impl_pointer; - - impl_pointer first0=x->next(); - impl_pointer last0=x; - impl_pointer first1=y->next(); - impl_pointer last1=y; - while(first0!=last0&&first1!=last1){ - if(comp( - Node::from_impl(first1)->value(),Node::from_impl(first0)->value())){ - impl_pointer tmp=first1->next(); - impl_type::relink(first0,first1); - first1=tmp; - } - else first0=first0->next(); - } - impl_type::relink(last0,first1,last1); -} - -/* Some versions of CGG require a bogus typename in counter_spc - * inside sequenced_index_sort if the following is defined - * also inside sequenced_index_sort. - */ - -BOOST_STATIC_CONSTANT( - std::size_t, - sequenced_index_sort_max_fill= - (std::size_t)std::numeric_limits::digits+1); - -#include - -template -void sequenced_index_sort(Node* header,Compare comp) -{ - /* Musser's mergesort, see http://www.cs.rpi.edu/~musser/gp/List/lists1.html. - * The implementation is a little convoluted: in the original code - * counter elements and carry are std::lists: here we do not want - * to use multi_index instead, so we do things at a lower level, managing - * directly the internal node representation. - * Incidentally, the implementations I've seen of this algorithm (SGI, - * Dinkumware, STLPort) are not exception-safe: this is. Moreover, we do not - * use any dynamic storage. - */ - - if(header->next()==header->impl()|| - header->next()->next()==header->impl())return; - - typedef typename Node::impl_type impl_type; - typedef typename Node::impl_pointer impl_pointer; - - typedef typename aligned_storage< - sizeof(impl_type), - alignment_of::value - >::type carry_spc_type; - carry_spc_type carry_spc; - impl_type& carry= - *reinterpret_cast(&carry_spc); - typedef typename aligned_storage< - sizeof( - impl_type - [sequenced_index_sort_max_fill]), - alignment_of< - impl_type - [sequenced_index_sort_max_fill] - >::value - >::type counter_spc_type; - counter_spc_type counter_spc; - impl_type* counter= - reinterpret_cast(&counter_spc); - std::size_t fill=0; - - carry.prior()=carry.next()=static_cast(&carry); - counter[0].prior()=counter[0].next()=static_cast(&counter[0]); - - BOOST_TRY{ - while(header->next()!=header->impl()){ - impl_type::relink(carry.next(),header->next()); - std::size_t i=0; - while(i(&counter[i])){ - sequenced_index_collate(&carry,&counter[i++],comp); - } - impl_type::swap( - static_cast(&carry), - static_cast(&counter[i])); - if(i==fill){ - ++fill; - counter[fill].prior()=counter[fill].next()= - static_cast(&counter[fill]); - } - } - - for(std::size_t i=1;i(&counter[i],&counter[i-1],comp); - } - impl_type::swap( - header->impl(),static_cast(&counter[fill-1])); - } - BOOST_CATCH(...) - { - impl_type::relink( - header->impl(),carry.next(),static_cast(&carry)); - for(std::size_t i=0;i<=fill;++i){ - impl_type::relink( - header->impl(),counter[i].next(), - static_cast(&counter[i])); - } - BOOST_RETHROW; - } - BOOST_CATCH_END -} - -#include - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/serialization_version.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/serialization_version.hpp deleted file mode 100644 index ccd8bb4f791..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/serialization_version.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_SERIALIZATION_VERSION_HPP -#define BOOST_MULTI_INDEX_DETAIL_SERIALIZATION_VERSION_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* Helper class for storing and retrieving a given type serialization class - * version while avoiding saving the number multiple times in the same - * archive. - * Behavior undefined if template partial specialization is not supported. - */ - -template -struct serialization_version -{ - serialization_version(): - value(boost::serialization::version::value){} - - serialization_version& operator=(unsigned int x){value=x;return *this;}; - - operator unsigned int()const{return value;} - -private: - friend class boost::serialization::access; - - BOOST_SERIALIZATION_SPLIT_MEMBER() - - template - void save(Archive&,const unsigned int)const{} - - template - void load(Archive&,const unsigned int version) - { - this->value=version; - } - - unsigned int value; -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -namespace serialization { -template -struct version > -{ - BOOST_STATIC_CONSTANT(int,value=version::value); -}; -} /* namespace serialization */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/uintptr_type.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/uintptr_type.hpp deleted file mode 100644 index 9c92d01d4de..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/uintptr_type.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_UINTPTR_TYPE_HPP -#define BOOST_MULTI_INDEX_DETAIL_UINTPTR_TYPE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* has_uintptr_type is an MPL integral constant determining whether - * there exists an unsigned integral type with the same size as - * void *. - * uintptr_type is such a type if has_uintptr is true, or unsigned int - * otherwise. - * Note that uintptr_type is more restrictive than C99 uintptr_t, - * where an integral type with size greater than that of void * - * would be conformant. - */ - -templatestruct uintptr_candidates; -template<>struct uintptr_candidates<-1>{typedef unsigned int type;}; -template<>struct uintptr_candidates<0> {typedef unsigned int type;}; -template<>struct uintptr_candidates<1> {typedef unsigned short type;}; -template<>struct uintptr_candidates<2> {typedef unsigned long type;}; - -#if defined(BOOST_HAS_LONG_LONG) -template<>struct uintptr_candidates<3> {typedef boost::ulong_long_type type;}; -#else -template<>struct uintptr_candidates<3> {typedef unsigned int type;}; -#endif - -#if defined(BOOST_HAS_MS_INT64) -template<>struct uintptr_candidates<4> {typedef unsigned __int64 type;}; -#else -template<>struct uintptr_candidates<4> {typedef unsigned int type;}; -#endif - -struct uintptr_aux -{ - BOOST_STATIC_CONSTANT(int,index= - sizeof(void*)==sizeof(uintptr_candidates<0>::type)?0: - sizeof(void*)==sizeof(uintptr_candidates<1>::type)?1: - sizeof(void*)==sizeof(uintptr_candidates<2>::type)?2: - sizeof(void*)==sizeof(uintptr_candidates<3>::type)?3: - sizeof(void*)==sizeof(uintptr_candidates<4>::type)?4:-1); - - BOOST_STATIC_CONSTANT(bool,has_uintptr_type=(index>=0)); - - typedef uintptr_candidates::type type; -}; - -typedef mpl::bool_ has_uintptr_type; -typedef uintptr_aux::type uintptr_type; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/unbounded.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/unbounded.hpp deleted file mode 100644 index dc09be1770d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/unbounded.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_UNBOUNDED_HPP -#define BOOST_MULTI_INDEX_DETAIL_UNBOUNDED_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include - -namespace boost{ - -namespace multi_index{ - -/* dummy type and variable for use in ordered_index::range() */ - -/* ODR-abiding technique shown at the example attached to - * http://lists.boost.org/Archives/boost/2006/07/108355.php - */ - -namespace detail{class unbounded_helper;} - -detail::unbounded_helper unbounded(detail::unbounded_helper); - -namespace detail{ - -class unbounded_helper -{ - unbounded_helper(){} - unbounded_helper(const unbounded_helper&){} - friend unbounded_helper multi_index::unbounded(unbounded_helper); -}; - -typedef unbounded_helper (*unbounded_type)(unbounded_helper); - -} /* namespace multi_index::detail */ - -inline detail::unbounded_helper unbounded(detail::unbounded_helper) -{ - return detail::unbounded_helper(); -} - -/* tags used in the implementation of range */ - -namespace detail{ - -struct none_unbounded_tag{}; -struct lower_unbounded_tag{}; -struct upper_unbounded_tag{}; -struct both_unbounded_tag{}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/value_compare.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/value_compare.hpp deleted file mode 100644 index ac42e8779aa..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/value_compare.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_VALUE_COMPARE_HPP -#define BOOST_MULTI_INDEX_DETAIL_VALUE_COMPARE_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template -struct value_comparison -{ - typedef Value first_argument_type; - typedef Value second_argument_type; - typedef bool result_type; - - value_comparison( - const KeyFromValue& key_=KeyFromValue(),const Compare& comp_=Compare()): - key(key_),comp(comp_) - { - } - - bool operator()( - typename call_traits::param_type x, - typename call_traits::param_type y)const - { - return comp(key(x),key(y)); - } - -private: - KeyFromValue key; - Compare comp; -}; - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/vartempl_support.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/detail/vartempl_support.hpp deleted file mode 100644 index 06ff430f4be..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/detail/vartempl_support.hpp +++ /dev/null @@ -1,247 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP -#define BOOST_MULTI_INDEX_DETAIL_VARTEMPL_SUPPORT_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -/* Utilities for emulation of variadic template functions. Variadic packs are - * replaced by lists of BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS parameters: - * - * - typename... Args --> BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK - * - Args&&... args --> BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK - * - std::forward(args)... --> BOOST_MULTI_INDEX_FORWARD_PARAM_PACK - * - * Forwarding emulated with Boost.Move. A template functions foo_imp - * defined in such way accepts *exactly* BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS - * arguments: variable number of arguments is emulated by providing a set of - * overloads foo forwarding to foo_impl with - * - * BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL - * BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG (initial extra arg) - * - * which fill the extra args with boost::multi_index::detail::noarg's. - * boost::multi_index::detail::vartempl_placement_new works the opposite - * way: it acceps a full a pointer x to Value and a - * BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK and forwards to - * new(x) Value(args) where args is the argument pack after discarding - * noarg's. - * - * Emulation decays to the real thing when the compiler supports variadic - * templates and move semantics natively. - */ - -#include - -#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)||\ - defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS) -#define BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS 5 -#endif - -#define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK \ -BOOST_PP_ENUM_PARAMS( \ - BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,typename T) - -#define BOOST_MULTI_INDEX_VARTEMPL_ARG(z,n,_) \ -BOOST_FWD_REF(BOOST_PP_CAT(T,n)) BOOST_PP_CAT(t,n) - -#define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK \ -BOOST_PP_ENUM( \ - BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ - BOOST_MULTI_INDEX_VARTEMPL_ARG,~) - -#define BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG(z,n,_) \ -boost::forward(BOOST_PP_CAT(t,n)) - -#define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK \ -BOOST_PP_ENUM( \ - BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ - BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) - -namespace boost{namespace multi_index{namespace detail{ -struct noarg{}; -}}} - -/* call vartempl function without args */ - -#define BOOST_MULTI_INDEX_NULL_PARAM_PACK \ -BOOST_PP_ENUM_PARAMS( \ - BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS, \ - boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) - -#define BOOST_MULTI_INDEX_TEMPLATE_N(n) \ -template - -#define BOOST_MULTI_INDEX_TEMPLATE_0(n) - -#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX(z,n,data) \ -BOOST_PP_IF(n, \ - BOOST_MULTI_INDEX_TEMPLATE_N, \ - BOOST_MULTI_INDEX_TEMPLATE_0)(n) \ -BOOST_PP_SEQ_ELEM(0,data) /* ret */ \ -BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \ - BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \ -{ \ - return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \ - BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \ - BOOST_PP_COMMA_IF( \ - BOOST_PP_AND( \ - n,BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n))) \ - BOOST_PP_ENUM_PARAMS( \ - BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ - boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \ - ); \ -} - -#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \ - ret,name_from,name_to) \ -BOOST_PP_REPEAT_FROM_TO( \ - 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_AUX, \ - (ret)(name_from)(name_to)) - -#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX( \ - z,n,data) \ -BOOST_PP_IF(n, \ - BOOST_MULTI_INDEX_TEMPLATE_N, \ - BOOST_MULTI_INDEX_TEMPLATE_0)(n) \ -BOOST_PP_SEQ_ELEM(0,data) /* ret */ \ -BOOST_PP_SEQ_ELEM(1,data) /* name_from */ ( \ - BOOST_PP_SEQ_ELEM(3,data) BOOST_PP_SEQ_ELEM(4,data) /* extra arg */\ - BOOST_PP_COMMA_IF(n) \ - BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~)) \ -{ \ - return BOOST_PP_SEQ_ELEM(2,data) /* name_to */ ( \ - BOOST_PP_SEQ_ELEM(4,data) /* extra_arg_name */ \ - BOOST_PP_COMMA_IF(n) \ - BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~) \ - BOOST_PP_COMMA_IF( \ - BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \ - BOOST_PP_ENUM_PARAMS( \ - BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ - boost::multi_index::detail::noarg() BOOST_PP_INTERCEPT) \ - ); \ -} - -#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \ - ret,name_from,name_to,extra_arg_type,extra_arg_name) \ -BOOST_PP_REPEAT_FROM_TO( \ - 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG_AUX, \ - (ret)(name_from)(name_to)(extra_arg_type)(extra_arg_name)) - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -#define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX(z,n,name) \ -template< \ - typename Value \ - BOOST_PP_COMMA_IF(n) \ - BOOST_PP_ENUM_PARAMS(n,typename T) \ -> \ -Value* name( \ - Value* x \ - BOOST_PP_COMMA_IF(n) \ - BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_ARG,~) \ - BOOST_PP_COMMA_IF( \ - BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n)) \ - BOOST_PP_ENUM_PARAMS( \ - BOOST_PP_SUB(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,n), \ - BOOST_FWD_REF(noarg) BOOST_PP_INTERCEPT)) \ -{ \ - return new(x) Value( \ - BOOST_PP_ENUM(n,BOOST_MULTI_INDEX_VARTEMPL_FORWARD_ARG,~)); \ -} - -#define BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(name) \ -BOOST_PP_REPEAT_FROM_TO( \ - 0,BOOST_PP_ADD(BOOST_MULTI_INDEX_LIMIT_VARTEMPL_ARGS,1), \ - BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX, \ - name) - -BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW(vartempl_placement_new) - -#undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW_AUX -#undef BOOST_MULTI_INDEX_VARTEMPL_TO_PLACEMENT_NEW - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#else - -/* native variadic templates support */ - -#include - -#define BOOST_MULTI_INDEX_TEMPLATE_PARAM_PACK typename... Args -#define BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK Args&&... args -#define BOOST_MULTI_INDEX_FORWARD_PARAM_PACK std::forward(args)... -#define BOOST_MULTI_INDEX_NULL_PARAM_PACK - -#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( \ - ret,name_from,name_to) \ -template ret name_from(Args&&... args) \ -{ \ - return name_to(std::forward(args)...); \ -} - -#define BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( \ - ret,name_from,name_to,extra_arg_type,extra_arg_name) \ -template ret name_from( \ - extra_arg_type extra_arg_name,Args&&... args) \ -{ \ - return name_to(extra_arg_name,std::forward(args)...); \ -} - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template -Value* vartempl_placement_new(Value*x,Args&&... args) -{ - return new(x) Value(std::forward(args)...); -} - -} /* namespace multi_index::detail */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/global_fun.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/global_fun.hpp deleted file mode 100644 index 2c13769100c..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/global_fun.hpp +++ /dev/null @@ -1,185 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_GLOBAL_FUN_HPP -#define BOOST_MULTI_INDEX_GLOBAL_FUN_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_NO_SFINAE) -#include -#endif - -namespace boost{ - -template class reference_wrapper; /* fwd decl. */ - -namespace multi_index{ - -namespace detail{ - -/* global_fun is a read-only key extractor from Value based on a given global - * (or static member) function with signature: - * - * Type f([const] Value [&]); - * - * Additionally, global_fun and const_global_fun are overloaded to support - * referece_wrappers of Value and "chained pointers" to Value's. By chained - * pointer to T we mean a type P such that, given a p of Type P - * *...n...*x is convertible to T&, for some n>=1. - * Examples of chained pointers are raw and smart pointers, iterators and - * arbitrary combinations of these (vg. T** or unique_ptr.) - */ - -template -struct const_ref_global_fun_base -{ - typedef typename remove_reference::type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type>::type -#else - Type -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type operator()(Value x)const - { - return PtrToFunction(x); - } - - Type operator()( - const reference_wrapper< - typename remove_reference::type>& x)const - { - return operator()(x.get()); - } - - Type operator()( - const reference_wrapper< - typename remove_const< - typename remove_reference::type>::type>& x - -#if BOOST_WORKAROUND(BOOST_MSVC,==1310) -/* http://lists.boost.org/Archives/boost/2015/10/226135.php */ - ,int=0 -#endif - - )const - { - return operator()(x.get()); - } -}; - -template -struct non_const_ref_global_fun_base -{ - typedef typename remove_reference::type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type>::type -#else - Type -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type operator()(Value x)const - { - return PtrToFunction(x); - } - - Type operator()( - const reference_wrapper< - typename remove_reference::type>& x)const - { - return operator()(x.get()); - } -}; - -template -struct non_ref_global_fun_base -{ - typedef typename remove_reference::type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type>::type -#else - Type -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type operator()(const Value& x)const - { - return PtrToFunction(x); - } - - Type operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } - - Type operator()( - const reference_wrapper::type>& x)const - { - return operator()(x.get()); - } -}; - -} /* namespace multi_index::detail */ - -template -struct global_fun: - mpl::if_c< - is_reference::value, - typename mpl::if_c< - is_const::type>::value, - detail::const_ref_global_fun_base, - detail::non_const_ref_global_fun_base - >::type, - detail::non_ref_global_fun_base - >::type -{ -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index.hpp deleted file mode 100644 index 352d0c13f17..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index.hpp +++ /dev/null @@ -1,1725 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_HASHED_INDEX_HPP -#define BOOST_MULTI_INDEX_HASHED_INDEX_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) -#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x) \ - detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(x,&hashed_index::check_invariant_); \ - BOOST_JOIN(check_invariant_,__LINE__).touch(); -#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT \ - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(*this) -#else -#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x) -#define BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* hashed_index adds a layer of hashed indexing to a given Super */ - -/* Most of the implementation of unique and non-unique indices is - * shared. We tell from one another on instantiation time by using - * Category tags defined in hash_index_node.hpp. - */ - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -class hashed_index: - BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - ,public safe_mode::safe_container< - hashed_index > -#endif - -{ -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the - * lifetime of const references bound to temporaries --precisely what - * scopeguards are. - */ - -#pragma parse_mfunc_templ off -#endif - - typedef typename SuperMeta::type super; - -protected: - typedef hashed_index_node< - typename super::node_type,Category> node_type; - -private: - typedef typename node_type::node_alg node_alg; - typedef typename node_type::impl_type node_impl_type; - typedef typename node_impl_type::pointer node_impl_pointer; - typedef typename node_impl_type::base_pointer node_impl_base_pointer; - typedef bucket_array< - typename super::final_allocator_type> bucket_array_type; - -public: - /* types */ - - typedef typename KeyFromValue::result_type key_type; - typedef typename node_type::value_type value_type; - typedef KeyFromValue key_from_value; - typedef Hash hasher; - typedef Pred key_equal; - typedef tuple ctor_args; - typedef typename super::final_allocator_type allocator_type; - typedef typename allocator_type::pointer pointer; - typedef typename allocator_type::const_pointer const_pointer; - typedef typename allocator_type::reference reference; - typedef typename allocator_type::const_reference const_reference; - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef safe_mode::safe_iterator< - hashed_index_iterator< - node_type,bucket_array_type, - hashed_index_global_iterator_tag>, - hashed_index> iterator; -#else - typedef hashed_index_iterator< - node_type,bucket_array_type, - hashed_index_global_iterator_tag> iterator; -#endif - - typedef iterator const_iterator; - - typedef hashed_index_iterator< - node_type,bucket_array_type, - hashed_index_local_iterator_tag> local_iterator; - typedef local_iterator const_local_iterator; - - typedef TagList tag_list; - -protected: - typedef typename super::final_node_type final_node_type; - typedef tuples::cons< - ctor_args, - typename super::ctor_args_list> ctor_args_list; - typedef typename mpl::push_front< - typename super::index_type_list, - hashed_index>::type index_type_list; - typedef typename mpl::push_front< - typename super::iterator_type_list, - iterator>::type iterator_type_list; - typedef typename mpl::push_front< - typename super::const_iterator_type_list, - const_iterator>::type const_iterator_type_list; - typedef typename super::copy_map_type copy_map_type; - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - typedef typename super::index_saver_type index_saver_type; - typedef typename super::index_loader_type index_loader_type; -#endif - -private: -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef safe_mode::safe_container< - hashed_index> safe_super; -#endif - - typedef typename call_traits::param_type value_param_type; - typedef typename call_traits< - key_type>::param_type key_param_type; - - /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL - * expansion. - */ - - typedef std::pair emplace_return_type; - -public: - - /* construct/destroy/copy - * Default and copy ctors are in the protected section as indices are - * not supposed to be created on their own. No range ctor either. - */ - - hashed_index& operator=( - const hashed_index& x) - { - this->final()=x.final(); - return *this; - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - hashed_index& operator=( - std::initializer_list list) - { - this->final()=list; - return *this; - } -#endif - - allocator_type get_allocator()const BOOST_NOEXCEPT - { - return this->final().get_allocator(); - } - - /* size and capacity */ - - bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} - size_type size()const BOOST_NOEXCEPT{return this->final_size_();} - size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} - - /* iterators */ - - iterator begin()BOOST_NOEXCEPT - {return make_iterator(node_type::from_impl(header()->next()->prior()));} - const_iterator begin()const BOOST_NOEXCEPT - {return make_iterator(node_type::from_impl(header()->next()->prior()));} - iterator end()BOOST_NOEXCEPT{return make_iterator(header());} - const_iterator end()const BOOST_NOEXCEPT{return make_iterator(header());} - const_iterator cbegin()const BOOST_NOEXCEPT{return begin();} - const_iterator cend()const BOOST_NOEXCEPT{return end();} - - iterator iterator_to(const value_type& x) - { - return make_iterator(node_from_value(&x)); - } - - const_iterator iterator_to(const value_type& x)const - { - return make_iterator(node_from_value(&x)); - } - - /* modifiers */ - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( - emplace_return_type,emplace,emplace_impl) - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( - iterator,emplace_hint,emplace_hint_impl,iterator,position) - - std::pair insert(const value_type& x) - { - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_(x); - return std::pair(make_iterator(p.first),p.second); - } - - std::pair insert(BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_rv_(x); - return std::pair(make_iterator(p.first),p.second); - } - - iterator insert(iterator position,const value_type& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_( - x,static_cast(position.get_node())); - return make_iterator(p.first); - } - - iterator insert(iterator position,BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_rv_( - x,static_cast(position.get_node())); - return make_iterator(p.first); - } - - template - void insert(InputIterator first,InputIterator last) - { - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - for(;first!=last;++first)this->final_insert_ref_(*first); - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - void insert(std::initializer_list list) - { - insert(list.begin(),list.end()); - } -#endif - - iterator erase(iterator position) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - this->final_erase_(static_cast(position++.get_node())); - return position; - } - - size_type erase(key_param_type k) - { - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - - std::size_t buc=buckets.position(hash_(k)); - for(node_impl_pointer x=buckets.at(buc)->prior(); - x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ - if(eq_(k,key(node_type::from_impl(x)->value()))){ - node_impl_pointer y=end_of_range(x); - size_type s=0; - do{ - node_impl_pointer z=node_alg::after(x); - this->final_erase_( - static_cast(node_type::from_impl(x))); - x=z; - ++s; - }while(x!=y); - return s; - } - } - return 0; - } - - iterator erase(iterator first,iterator last) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); - BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - while(first!=last){ - first=erase(first); - } - return first; - } - - bool replace(iterator position,const value_type& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - return this->final_replace_( - x,static_cast(position.get_node())); - } - - bool replace(iterator position,BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - return this->final_replace_rv_( - x,static_cast(position.get_node())); - } - - template - bool modify(iterator position,Modifier mod) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer on safe mode code chokes if this - * this is not added. Left it for all compilers as it does no - * harm. - */ - - position.detach(); -#endif - - return this->final_modify_( - mod,static_cast(position.get_node())); - } - - template - bool modify(iterator position,Modifier mod,Rollback back_) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer on safe mode code chokes if this - * this is not added. Left it for all compilers as it does no - * harm. - */ - - position.detach(); -#endif - - return this->final_modify_( - mod,back_,static_cast(position.get_node())); - } - - template - bool modify_key(iterator position,Modifier mod) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - return modify( - position,modify_key_adaptor(mod,key)); - } - - template - bool modify_key(iterator position,Modifier mod,Rollback back_) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - return modify( - position, - modify_key_adaptor(mod,key), - modify_key_adaptor(back_,key)); - } - - void clear()BOOST_NOEXCEPT - { - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - this->final_clear_(); - } - - void swap(hashed_index& x) - { - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF(x); - this->final_swap_(x.final()); - } - - /* observers */ - - key_from_value key_extractor()const{return key;} - hasher hash_function()const{return hash_;} - key_equal key_eq()const{return eq_;} - - /* lookup */ - - /* Internally, these ops rely on const_iterator being the same - * type as iterator. - */ - - /* Implementation note: When CompatibleKey is consistently promoted to - * KeyFromValue::result_type for equality comparison, the promotion is made - * once in advance to increase efficiency. - */ - - template - iterator find(const CompatibleKey& k)const - { - return find(k,hash_,eq_); - } - - template< - typename CompatibleKey,typename CompatibleHash,typename CompatiblePred - > - iterator find( - const CompatibleKey& k, - const CompatibleHash& hash,const CompatiblePred& eq)const - { - return find( - k,hash,eq,promotes_1st_arg()); - } - - template - size_type count(const CompatibleKey& k)const - { - return count(k,hash_,eq_); - } - - template< - typename CompatibleKey,typename CompatibleHash,typename CompatiblePred - > - size_type count( - const CompatibleKey& k, - const CompatibleHash& hash,const CompatiblePred& eq)const - { - return count( - k,hash,eq,promotes_1st_arg()); - } - - template - std::pair equal_range(const CompatibleKey& k)const - { - return equal_range(k,hash_,eq_); - } - - template< - typename CompatibleKey,typename CompatibleHash,typename CompatiblePred - > - std::pair equal_range( - const CompatibleKey& k, - const CompatibleHash& hash,const CompatiblePred& eq)const - { - return equal_range( - k,hash,eq,promotes_1st_arg()); - } - - /* bucket interface */ - - size_type bucket_count()const BOOST_NOEXCEPT{return buckets.size();} - size_type max_bucket_count()const BOOST_NOEXCEPT{return static_cast(-1);} - - size_type bucket_size(size_type n)const - { - size_type res=0; - for(node_impl_pointer x=buckets.at(n)->prior(); - x!=node_impl_pointer(0);x=node_alg::after_local(x)){ - ++res; - } - return res; - } - - size_type bucket(key_param_type k)const - { - return buckets.position(hash_(k)); - } - - local_iterator begin(size_type n) - { - return const_cast(this)->begin(n); - } - - const_local_iterator begin(size_type n)const - { - node_impl_pointer x=buckets.at(n)->prior(); - if(x==node_impl_pointer(0))return end(n); - return make_local_iterator(node_type::from_impl(x)); - } - - local_iterator end(size_type n) - { - return const_cast(this)->end(n); - } - - const_local_iterator end(size_type)const - { - return make_local_iterator(0); - } - - const_local_iterator cbegin(size_type n)const{return begin(n);} - const_local_iterator cend(size_type n)const{return end(n);} - - local_iterator local_iterator_to(const value_type& x) - { - return make_local_iterator(node_from_value(&x)); - } - - const_local_iterator local_iterator_to(const value_type& x)const - { - return make_local_iterator(node_from_value(&x)); - } - - /* hash policy */ - - float load_factor()const BOOST_NOEXCEPT - {return static_cast(size())/bucket_count();} - float max_load_factor()const BOOST_NOEXCEPT{return mlf;} - void max_load_factor(float z){mlf=z;calculate_max_load();} - - void rehash(size_type n) - { - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - if(size()<=max_load&&n<=bucket_count())return; - - size_type bc =(std::numeric_limits::max)(); - float fbc=static_cast(1+size()/mlf); - if(bc>fbc){ - bc=static_cast(fbc); - if(bc(std::ceil(static_cast(n)/mlf))); - } - -BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: - hashed_index(const ctor_args_list& args_list,const allocator_type& al): - super(args_list.get_tail(),al), - key(tuples::get<1>(args_list.get_head())), - hash_(tuples::get<2>(args_list.get_head())), - eq_(tuples::get<3>(args_list.get_head())), - buckets(al,header()->impl(),tuples::get<0>(args_list.get_head())), - mlf(1.0f) - { - calculate_max_load(); - } - - hashed_index( - const hashed_index& x): - super(x), - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super(), -#endif - - key(x.key), - hash_(x.hash_), - eq_(x.eq_), - buckets(x.get_allocator(),header()->impl(),x.buckets.size()), - mlf(x.mlf), - max_load(x.max_load) - { - /* Copy ctor just takes the internal configuration objects from x. The rest - * is done in subsequent call to copy_(). - */ - } - - hashed_index( - const hashed_index& x, - do_not_copy_elements_tag): - super(x,do_not_copy_elements_tag()), - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super(), -#endif - - key(x.key), - hash_(x.hash_), - eq_(x.eq_), - buckets(x.get_allocator(),header()->impl(),0), - mlf(1.0f) - { - calculate_max_load(); - } - - ~hashed_index() - { - /* the container is guaranteed to be empty by now */ - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - iterator make_iterator(node_type* node) - { - return iterator(node,this); - } - - const_iterator make_iterator(node_type* node)const - { - return const_iterator(node,const_cast(this)); - } -#else - iterator make_iterator(node_type* node) - { - return iterator(node); - } - - const_iterator make_iterator(node_type* node)const - { - return const_iterator(node); - } -#endif - - local_iterator make_local_iterator(node_type* node) - { - return local_iterator(node); - } - - const_local_iterator make_local_iterator(node_type* node)const - { - return const_local_iterator(node); - } - - void copy_( - const hashed_index& x, - const copy_map_type& map) - { - copy_(x,map,Category()); - } - - void copy_( - const hashed_index& x, - const copy_map_type& map,hashed_unique_tag) - { - if(x.size()!=0){ - node_impl_pointer end_org=x.header()->impl(), - org=end_org, - cpy=header()->impl(); - do{ - node_impl_pointer prev_org=org->prior(), - prev_cpy= - static_cast(map.find(static_cast( - node_type::from_impl(prev_org))))->impl(); - cpy->prior()=prev_cpy; - if(node_alg::is_first_of_bucket(org)){ - node_impl_base_pointer buc_org=prev_org->next(), - buc_cpy= - buckets.begin()+(buc_org-x.buckets.begin()); - prev_cpy->next()=buc_cpy; - buc_cpy->prior()=cpy; - } - else{ - prev_cpy->next()=node_impl_type::base_pointer_from(cpy); - } - org=prev_org; - cpy=prev_cpy; - }while(org!=end_org); - } - - super::copy_(x,map); - } - - void copy_( - const hashed_index& x, - const copy_map_type& map,hashed_non_unique_tag) - { - if(x.size()!=0){ - node_impl_pointer end_org=x.header()->impl(), - org=end_org, - cpy=header()->impl(); - do{ - node_impl_pointer next_org=node_alg::after(org), - next_cpy= - static_cast(map.find(static_cast( - node_type::from_impl(next_org))))->impl(); - if(node_alg::is_first_of_bucket(next_org)){ - node_impl_base_pointer buc_org=org->next(), - buc_cpy= - buckets.begin()+(buc_org-x.buckets.begin()); - cpy->next()=buc_cpy; - buc_cpy->prior()=next_cpy; - next_cpy->prior()=cpy; - } - else{ - if(org->next()==node_impl_type::base_pointer_from(next_org)){ - cpy->next()=node_impl_type::base_pointer_from(next_cpy); - } - else{ - cpy->next()= - node_impl_type::base_pointer_from( - static_cast(map.find(static_cast( - node_type::from_impl( - node_impl_type::pointer_from(org->next())))))->impl()); - } - - if(next_org->prior()!=org){ - next_cpy->prior()= - static_cast(map.find(static_cast( - node_type::from_impl(next_org->prior()))))->impl(); - } - else{ - next_cpy->prior()=cpy; - } - } - org=next_org; - cpy=next_cpy; - }while(org!=end_org); - } - - super::copy_(x,map); - } - - template - final_node_type* insert_( - value_param_type v,final_node_type*& x,Variant variant) - { - reserve_for_insert(size()+1); - - std::size_t buc=find_bucket(v); - link_info pos(buckets.at(buc)); - if(!link_point(v,pos)){ - return static_cast( - node_type::from_impl(node_impl_type::pointer_from(pos))); - } - - final_node_type* res=super::insert_(v,x,variant); - if(res==x)link(static_cast(x),pos); - return res; - } - - template - final_node_type* insert_( - value_param_type v,node_type* position,final_node_type*& x,Variant variant) - { - reserve_for_insert(size()+1); - - std::size_t buc=find_bucket(v); - link_info pos(buckets.at(buc)); - if(!link_point(v,pos)){ - return static_cast( - node_type::from_impl(node_impl_type::pointer_from(pos))); - } - - final_node_type* res=super::insert_(v,position,x,variant); - if(res==x)link(static_cast(x),pos); - return res; - } - - void erase_(node_type* x) - { - unlink(x); - super::erase_(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - } - - void delete_all_nodes_() - { - delete_all_nodes_(Category()); - } - - void delete_all_nodes_(hashed_unique_tag) - { - for(node_impl_pointer x_end=header()->impl(),x=x_end->prior();x!=x_end;){ - node_impl_pointer y=x->prior(); - this->final_delete_node_( - static_cast(node_type::from_impl(x))); - x=y; - } - } - - void delete_all_nodes_(hashed_non_unique_tag) - { - for(node_impl_pointer x_end=header()->impl(),x=x_end->prior();x!=x_end;){ - node_impl_pointer y=x->prior(); - if(y->next()!=node_impl_type::base_pointer_from(x)&& - y->next()->prior()!=x){ /* n-1 of group */ - /* Make the second node prior() pointer back-linked so that it won't - * refer to a deleted node when the time for its own destruction comes. - */ - - node_impl_pointer first=node_impl_type::pointer_from(y->next()); - first->next()->prior()=first; - } - this->final_delete_node_( - static_cast(node_type::from_impl(x))); - x=y; - } - } - - void clear_() - { - super::clear_(); - buckets.clear(header()->impl()); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::detach_dereferenceable_iterators(); -#endif - } - - void swap_( - hashed_index& x) - { - std::swap(key,x.key); - std::swap(hash_,x.hash_); - std::swap(eq_,x.eq_); - buckets.swap(x.buckets); - std::swap(mlf,x.mlf); - std::swap(max_load,x.max_load); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::swap(x); -#endif - - super::swap_(x); - } - - void swap_elements_( - hashed_index& x) - { - buckets.swap(x.buckets); - std::swap(mlf,x.mlf); - std::swap(max_load,x.max_load); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::swap(x); -#endif - - super::swap_elements_(x); - } - - template - bool replace_(value_param_type v,node_type* x,Variant variant) - { - if(eq_(key(v),key(x->value()))){ - return super::replace_(v,x,variant); - } - - unlink_undo undo; - unlink(x,undo); - - BOOST_TRY{ - std::size_t buc=find_bucket(v); - link_info pos(buckets.at(buc)); - if(link_point(v,pos)&&super::replace_(v,x,variant)){ - link(x,pos); - return true; - } - undo(); - return false; - } - BOOST_CATCH(...){ - undo(); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - bool modify_(node_type* x) - { - std::size_t buc; - bool b; - BOOST_TRY{ - buc=find_bucket(x->value()); - b=in_place(x->impl(),key(x->value()),buc); - } - BOOST_CATCH(...){ - erase_(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - if(!b){ - unlink(x); - BOOST_TRY{ - link_info pos(buckets.at(buc)); - if(!link_point(x->value(),pos)){ - super::erase_(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - return false; - } - link(x,pos); - } - BOOST_CATCH(...){ - super::erase_(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - BOOST_TRY{ - if(!super::modify_(x)){ - unlink(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - return false; - } - else return true; - } - BOOST_CATCH(...){ - unlink(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - bool modify_rollback_(node_type* x) - { - std::size_t buc=find_bucket(x->value()); - if(in_place(x->impl(),key(x->value()),buc)){ - return super::modify_rollback_(x); - } - - unlink_undo undo; - unlink(x,undo); - - BOOST_TRY{ - link_info pos(buckets.at(buc)); - if(link_point(x->value(),pos)&&super::modify_rollback_(x)){ - link(x,pos); - return true; - } - undo(); - return false; - } - BOOST_CATCH(...){ - undo(); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - /* comparison */ - -#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) - /* defect macro refers to class, not function, templates, but anyway */ - - template - friend bool operator==( - const hashed_index&,const hashed_index& y); -#endif - - bool equals(const hashed_index& x)const{return equals(x,Category());} - - bool equals(const hashed_index& x,hashed_unique_tag)const - { - if(size()!=x.size())return false; - for(const_iterator it=begin(),it_end=end(),it2_end=x.end(); - it!=it_end;++it){ - const_iterator it2=x.find(key(*it)); - if(it2==it2_end||!(*it==*it2))return false; - } - return true; - } - - bool equals(const hashed_index& x,hashed_non_unique_tag)const - { - if(size()!=x.size())return false; - for(const_iterator it=begin(),it_end=end();it!=it_end;){ - const_iterator it2,it2_last; - boost::tie(it2,it2_last)=x.equal_range(key(*it)); - if(it2==it2_last)return false; - - const_iterator it_last=make_iterator( - node_type::from_impl(end_of_range(it.get_node()->impl()))); - if(std::distance(it,it_last)!=std::distance(it2,it2_last))return false; - - /* From is_permutation code in - * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3068.pdf - */ - - for(;it!=it_last;++it,++it2){ - if(!(*it==*it2))break; - } - if(it!=it_last){ - for(const_iterator scan=it;scan!=it_last;++scan){ - if(std::find(it,scan,*scan)!=scan)continue; - std::ptrdiff_t matches=std::count(it2,it2_last,*scan); - if(matches==0||matches!=std::count(scan,it_last,*scan))return false; - } - it=it_last; - } - } - return true; - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* serialization */ - - template - void save_( - Archive& ar,const unsigned int version,const index_saver_type& sm)const - { - ar< - void load_(Archive& ar,const unsigned int version,const index_loader_type& lm) - { - ar>>serialization::make_nvp("position",buckets); - super::load_(ar,version,lm); - } -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - bool invariant_()const - { - if(size()==0||begin()==end()){ - if(size()!=0||begin()!=end())return false; - } - else{ - size_type s0=0; - for(const_iterator it=begin(),it_end=end();it!=it_end;++it,++s0){} - if(s0!=size())return false; - - size_type s1=0; - for(size_type buc=0;bucfinal_check_invariant_();} -#endif - -private: - node_type* header()const{return this->final_header();} - - std::size_t find_bucket(value_param_type v)const - { - return bucket(key(v)); - } - - struct link_info_non_unique - { - link_info_non_unique(node_impl_base_pointer pos): - first(pos),last(node_impl_base_pointer(0)){} - - operator const node_impl_base_pointer&()const{return this->first;} - - node_impl_base_pointer first,last; - }; - - typedef typename mpl::if_< - is_same, - node_impl_base_pointer, - link_info_non_unique - >::type link_info; - - bool link_point(value_param_type v,link_info& pos) - { - return link_point(v,pos,Category()); - } - - bool link_point( - value_param_type v,node_impl_base_pointer& pos,hashed_unique_tag) - { - for(node_impl_pointer x=pos->prior();x!=node_impl_pointer(0); - x=node_alg::after_local(x)){ - if(eq_(key(v),key(node_type::from_impl(x)->value()))){ - pos=node_impl_type::base_pointer_from(x); - return false; - } - } - return true; - } - - bool link_point( - value_param_type v,link_info_non_unique& pos,hashed_non_unique_tag) - { - for(node_impl_pointer x=pos.first->prior();x!=node_impl_pointer(0); - x=node_alg::next_to_inspect(x)){ - if(eq_(key(v),key(node_type::from_impl(x)->value()))){ - pos.first=node_impl_type::base_pointer_from(x); - pos.last=node_impl_type::base_pointer_from(last_of_range(x)); - return true; - } - } - return true; - } - - node_impl_pointer last_of_range(node_impl_pointer x)const - { - return last_of_range(x,Category()); - } - - node_impl_pointer last_of_range(node_impl_pointer x,hashed_unique_tag)const - { - return x; - } - - node_impl_pointer last_of_range( - node_impl_pointer x,hashed_non_unique_tag)const - { - node_impl_base_pointer y=x->next(); - node_impl_pointer z=y->prior(); - if(z==x){ /* range of size 1 or 2 */ - node_impl_pointer yy=node_impl_type::pointer_from(y); - return - eq_( - key(node_type::from_impl(x)->value()), - key(node_type::from_impl(yy)->value()))?yy:x; - } - else if(z->prior()==x) /* last of bucket */ - return x; - else /* group of size>2 */ - return z; - } - - node_impl_pointer end_of_range(node_impl_pointer x)const - { - return end_of_range(x,Category()); - } - - node_impl_pointer end_of_range(node_impl_pointer x,hashed_unique_tag)const - { - return node_alg::after(last_of_range(x)); - } - - node_impl_pointer end_of_range( - node_impl_pointer x,hashed_non_unique_tag)const - { - node_impl_base_pointer y=x->next(); - node_impl_pointer z=y->prior(); - if(z==x){ /* range of size 1 or 2 */ - node_impl_pointer yy=node_impl_type::pointer_from(y); - if(!eq_( - key(node_type::from_impl(x)->value()), - key(node_type::from_impl(yy)->value())))yy=x; - return yy->next()->prior()==yy? - node_impl_type::pointer_from(yy->next()): - yy->next()->prior(); - } - else if(z->prior()==x) /* last of bucket */ - return z; - else /* group of size>2 */ - return z->next()->prior()==z? - node_impl_type::pointer_from(z->next()): - z->next()->prior(); - } - - void link(node_type* x,const link_info& pos) - { - link(x,pos,Category()); - } - - void link(node_type* x,node_impl_base_pointer pos,hashed_unique_tag) - { - node_alg::link(x->impl(),pos,header()->impl()); - } - - void link(node_type* x,const link_info_non_unique& pos,hashed_non_unique_tag) - { - if(pos.last==node_impl_base_pointer(0)){ - node_alg::link(x->impl(),pos.first,header()->impl()); - } - else{ - node_alg::link( - x->impl(), - node_impl_type::pointer_from(pos.first), - node_impl_type::pointer_from(pos.last)); - } - } - - void unlink(node_type* x) - { - node_alg::unlink(x->impl()); - } - - typedef typename node_alg::unlink_undo unlink_undo; - - void unlink(node_type* x,unlink_undo& undo) - { - node_alg::unlink(x->impl(),undo); - } - - void calculate_max_load() - { - float fml=static_cast(mlf*static_cast(bucket_count())); - max_load=(std::numeric_limits::max)(); - if(max_load>fml)max_load=static_cast(fml); - } - - void reserve_for_insert(size_type n) - { - if(n>max_load){ - size_type bc =(std::numeric_limits::max)(); - float fbc=static_cast(1+static_cast(n)/mlf); - if(bc>fbc)bc =static_cast(fbc); - unchecked_rehash(bc); - } - } - - void unchecked_rehash(size_type n){unchecked_rehash(n,Category());} - - void unchecked_rehash(size_type n,hashed_unique_tag) - { - node_impl_type cpy_end_node; - node_impl_pointer cpy_end=node_impl_pointer(&cpy_end_node), - end_=header()->impl(); - bucket_array_type buckets_cpy(get_allocator(),cpy_end,n); - - if(size()!=0){ - auto_space< - std::size_t,allocator_type> hashes(get_allocator(),size()); - auto_space< - node_impl_pointer,allocator_type> node_ptrs(get_allocator(),size()); - std::size_t i=0,size_=size(); - bool within_bucket=false; - BOOST_TRY{ - for(;i!=size_;++i){ - node_impl_pointer x=end_->prior(); - - /* only this can possibly throw */ - std::size_t h=hash_(key(node_type::from_impl(x)->value())); - - hashes.data()[i]=h; - node_ptrs.data()[i]=x; - within_bucket=!node_alg::unlink_last(end_); - node_alg::link(x,buckets_cpy.at(buckets_cpy.position(h)),cpy_end); - } - } - BOOST_CATCH(...){ - if(i!=0){ - std::size_t prev_buc=buckets.position(hashes.data()[i-1]); - if(!within_bucket)prev_buc=~prev_buc; - - for(std::size_t j=i;j--;){ - std::size_t buc=buckets.position(hashes.data()[j]); - node_impl_pointer x=node_ptrs.data()[j]; - if(buc==prev_buc)node_alg::append(x,end_); - else node_alg::link(x,buckets.at(buc),end_); - prev_buc=buc; - } - } - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - end_->prior()=cpy_end->prior()!=cpy_end?cpy_end->prior():end_; - end_->next()=cpy_end->next(); - end_->prior()->next()->prior()=end_->next()->prior()->prior()=end_; - buckets.swap(buckets_cpy); - calculate_max_load(); - } - - void unchecked_rehash(size_type n,hashed_non_unique_tag) - { - node_impl_type cpy_end_node; - node_impl_pointer cpy_end=node_impl_pointer(&cpy_end_node), - end_=header()->impl(); - bucket_array_type buckets_cpy(get_allocator(),cpy_end,n); - - if(size()!=0){ - auto_space< - std::size_t,allocator_type> hashes(get_allocator(),size()); - auto_space< - node_impl_pointer,allocator_type> node_ptrs(get_allocator(),size()); - std::size_t i=0; - bool within_bucket=false; - BOOST_TRY{ - for(;;++i){ - node_impl_pointer x=end_->prior(); - if(x==end_)break; - - /* only this can possibly throw */ - std::size_t h=hash_(key(node_type::from_impl(x)->value())); - - hashes.data()[i]=h; - node_ptrs.data()[i]=x; - std::pair p= - node_alg::unlink_last_group(end_); - node_alg::link_range( - p.first,x,buckets_cpy.at(buckets_cpy.position(h)),cpy_end); - within_bucket=!(p.second); - } - } - BOOST_CATCH(...){ - if(i!=0){ - std::size_t prev_buc=buckets.position(hashes.data()[i-1]); - if(!within_bucket)prev_buc=~prev_buc; - - for(std::size_t j=i;j--;){ - std::size_t buc=buckets.position(hashes.data()[j]); - node_impl_pointer x=node_ptrs.data()[j], - y= - x->prior()->next()!=node_impl_type::base_pointer_from(x)&& - x->prior()->next()->prior()!=x? - node_impl_type::pointer_from(x->prior()->next()):x; - node_alg::unlink_range(y,x); - if(buc==prev_buc)node_alg::append_range(y,x,end_); - else node_alg::link_range(y,x,buckets.at(buc),end_); - prev_buc=buc; - } - } - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - end_->prior()=cpy_end->prior()!=cpy_end?cpy_end->prior():end_; - end_->next()=cpy_end->next(); - end_->prior()->next()->prior()=end_->next()->prior()->prior()=end_; - buckets.swap(buckets_cpy); - calculate_max_load(); - } - - bool in_place(node_impl_pointer x,key_param_type k,std::size_t buc)const - { - return in_place(x,k,buc,Category()); - } - - bool in_place( - node_impl_pointer x,key_param_type k,std::size_t buc, - hashed_unique_tag)const - { - bool found=false; - for(node_impl_pointer y=buckets.at(buc)->prior(); - y!=node_impl_pointer(0);y=node_alg::after_local(y)){ - if(y==x)found=true; - else if(eq_(k,key(node_type::from_impl(y)->value())))return false; - } - return found; - } - - bool in_place( - node_impl_pointer x,key_param_type k,std::size_t buc, - hashed_non_unique_tag)const - { - bool found=false; - int range_size=0; - for(node_impl_pointer y=buckets.at(buc)->prior();y!=node_impl_pointer(0);){ - if(node_alg::is_first_of_group(y)){ /* group of 3 or more */ - if(y==x){ - /* in place <-> equal to some other member of the group */ - return eq_( - k, - key(node_type::from_impl( - node_impl_type::pointer_from(y->next()))->value())); - } - else{ - node_impl_pointer z= - node_alg::after_local(y->next()->prior()); /* end of range */ - if(eq_(k,key(node_type::from_impl(y)->value()))){ - if(found)return false; /* x lies outside */ - do{ - if(y==x)return true; - y=node_alg::after_local(y); - }while(y!=z); - return false; /* x not found */ - } - else{ - if(range_size==1&&!found)return false; - if(range_size==2)return found; - range_size=0; - y=z; /* skip range (and potentially x, too, which is fine) */ - } - } - } - else{ /* group of 1 or 2 */ - if(y==x){ - if(range_size==1)return true; - range_size=1; - found=true; - } - else if(eq_(k,key(node_type::from_impl(y)->value()))){ - if(range_size==0&&found)return false; - if(range_size==1&&!found)return false; - if(range_size==2)return false; - ++range_size; - } - else{ - if(range_size==1&&!found)return false; - if(range_size==2)return found; - range_size=0; - } - y=node_alg::after_local(y); - } - } - return found; - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - void detach_iterators(node_type* x) - { - iterator it=make_iterator(x); - safe_mode::detach_equivalent_iterators(it); - } -#endif - - template - std::pair emplace_impl(BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - std::pairp= - this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - return std::pair(make_iterator(p.first),p.second); - } - - template - iterator emplace_hint_impl( - iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT; - std::pairp= - this->final_emplace_hint_( - static_cast(position.get_node()), - BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - return make_iterator(p.first); - } - - template< - typename CompatibleHash,typename CompatiblePred - > - iterator find( - const key_type& k, - const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const - { - return find(k,hash,eq,mpl::false_()); - } - - template< - typename CompatibleKey,typename CompatibleHash,typename CompatiblePred - > - iterator find( - const CompatibleKey& k, - const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const - { - std::size_t buc=buckets.position(hash(k)); - for(node_impl_pointer x=buckets.at(buc)->prior(); - x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ - if(eq(k,key(node_type::from_impl(x)->value()))){ - return make_iterator(node_type::from_impl(x)); - } - } - return end(); - } - - template< - typename CompatibleHash,typename CompatiblePred - > - size_type count( - const key_type& k, - const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const - { - return count(k,hash,eq,mpl::false_()); - } - - template< - typename CompatibleKey,typename CompatibleHash,typename CompatiblePred - > - size_type count( - const CompatibleKey& k, - const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const - { - std::size_t buc=buckets.position(hash(k)); - for(node_impl_pointer x=buckets.at(buc)->prior(); - x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ - if(eq(k,key(node_type::from_impl(x)->value()))){ - size_type res=0; - node_impl_pointer y=end_of_range(x); - do{ - ++res; - x=node_alg::after(x); - }while(x!=y); - return res; - } - } - return 0; - } - - template< - typename CompatibleHash,typename CompatiblePred - > - std::pair equal_range( - const key_type& k, - const CompatibleHash& hash,const CompatiblePred& eq,mpl::true_)const - { - return equal_range(k,hash,eq,mpl::false_()); - } - - template< - typename CompatibleKey,typename CompatibleHash,typename CompatiblePred - > - std::pair equal_range( - const CompatibleKey& k, - const CompatibleHash& hash,const CompatiblePred& eq,mpl::false_)const - { - std::size_t buc=buckets.position(hash(k)); - for(node_impl_pointer x=buckets.at(buc)->prior(); - x!=node_impl_pointer(0);x=node_alg::next_to_inspect(x)){ - if(eq(k,key(node_type::from_impl(x)->value()))){ - return std::pair( - make_iterator(node_type::from_impl(x)), - make_iterator(node_type::from_impl(end_of_range(x)))); - } - } - return std::pair(end(),end()); - } - - key_from_value key; - hasher hash_; - key_equal eq_; - bucket_array_type buckets; - float mlf; - size_type max_load; - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -#pragma parse_mfunc_templ reset -#endif -}; - -/* comparison */ - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -bool operator==( - const hashed_index& x, - const hashed_index& y) -{ - return x.equals(y); -} - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -bool operator!=( - const hashed_index& x, - const hashed_index& y) -{ - return !(x==y); -} - -/* specialized algorithms */ - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -void swap( - hashed_index& x, - hashed_index& y) -{ - x.swap(y); -} - -} /* namespace multi_index::detail */ - -/* hashed index specifiers */ - -template -struct hashed_unique -{ - typedef typename detail::hashed_index_args< - Arg1,Arg2,Arg3,Arg4> index_args; - typedef typename index_args::tag_list_type::type tag_list_type; - typedef typename index_args::key_from_value_type key_from_value_type; - typedef typename index_args::hash_type hash_type; - typedef typename index_args::pred_type pred_type; - - template - struct node_class - { - typedef detail::hashed_index_node type; - }; - - template - struct index_class - { - typedef detail::hashed_index< - key_from_value_type,hash_type,pred_type, - SuperMeta,tag_list_type,detail::hashed_unique_tag> type; - }; -}; - -template -struct hashed_non_unique -{ - typedef typename detail::hashed_index_args< - Arg1,Arg2,Arg3,Arg4> index_args; - typedef typename index_args::tag_list_type::type tag_list_type; - typedef typename index_args::key_from_value_type key_from_value_type; - typedef typename index_args::hash_type hash_type; - typedef typename index_args::pred_type pred_type; - - template - struct node_class - { - typedef detail::hashed_index_node< - Super,detail::hashed_non_unique_tag> type; - }; - - template - struct index_class - { - typedef detail::hashed_index< - key_from_value_type,hash_type,pred_type, - SuperMeta,tag_list_type,detail::hashed_non_unique_tag> type; - }; -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -/* Boost.Foreach compatibility */ - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -inline boost::mpl::true_* boost_foreach_is_noncopyable( - boost::multi_index::detail::hashed_index< - KeyFromValue,Hash,Pred,SuperMeta,TagList,Category>*&, - boost_foreach_argument_dependent_lookup_hack) -{ - return 0; -} - -#undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT -#undef BOOST_MULTI_INDEX_HASHED_INDEX_CHECK_INVARIANT_OF - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index_fwd.hpp deleted file mode 100644 index d77e36c321b..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/hashed_index_fwd.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_HASHED_INDEX_FWD_HPP -#define BOOST_MULTI_INDEX_HASHED_INDEX_FWD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -class hashed_index; - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -bool operator==( - const hashed_index& x, - const hashed_index& y); - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -bool operator!=( - const hashed_index& x, - const hashed_index& y); - -template< - typename KeyFromValue,typename Hash,typename Pred, - typename SuperMeta,typename TagList,typename Category -> -void swap( - hashed_index& x, - hashed_index& y); - -} /* namespace multi_index::detail */ - -/* hashed_index specifiers */ - -template< - typename Arg1,typename Arg2=mpl::na, - typename Arg3=mpl::na,typename Arg4=mpl::na -> -struct hashed_unique; - -template< - typename Arg1,typename Arg2=mpl::na, - typename Arg3=mpl::na,typename Arg4=mpl::na -> -struct hashed_non_unique; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/identity.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/identity.hpp deleted file mode 100644 index 6c832ce1562..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/identity.hpp +++ /dev/null @@ -1,145 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_IDENTITY_HPP -#define BOOST_MULTI_INDEX_IDENTITY_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_NO_SFINAE) -#include -#endif - -namespace boost{ - -template class reference_wrapper; /* fwd decl. */ - -namespace multi_index{ - -namespace detail{ - -/* identity is a do-nothing key extractor that returns the [const] Type& - * object passed. - * Additionally, identity is overloaded to support referece_wrappers - * of Type and "chained pointers" to Type's. By chained pointer to Type we - * mean a type P such that, given a p of type P - * *...n...*x is convertible to Type&, for some n>=1. - * Examples of chained pointers are raw and smart pointers, iterators and - * arbitrary combinations of these (vg. Type** or unique_ptr.) - */ - -template -struct const_identity_base -{ - typedef Type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if,Type&>::type -#else - Type& -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type& operator()(Type& x)const - { - return x; - } - - Type& operator()(const reference_wrapper& x)const - { - return x.get(); - } - - Type& operator()( - const reference_wrapper::type>& x - -#if BOOST_WORKAROUND(BOOST_MSVC,==1310) -/* http://lists.boost.org/Archives/boost/2015/10/226135.php */ - ,int=0 -#endif - - )const - { - return x.get(); - } -}; - -template -struct non_const_identity_base -{ - typedef Type result_type; - - /* templatized for pointer-like types */ - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type&>::type -#else - Type& -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - const Type& operator()(const Type& x)const - { - return x; - } - - Type& operator()(Type& x)const - { - return x; - } - - const Type& operator()(const reference_wrapper& x)const - { - return x.get(); - } - - Type& operator()(const reference_wrapper& x)const - { - return x.get(); - } -}; - -} /* namespace multi_index::detail */ - -template -struct identity: - mpl::if_c< - is_const::value, - detail::const_identity_base,detail::non_const_identity_base - >::type -{ -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/identity_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/identity_fwd.hpp deleted file mode 100644 index af6bd55ef5f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/identity_fwd.hpp +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_IDENTITY_FWD_HPP -#define BOOST_MULTI_INDEX_IDENTITY_FWD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -namespace boost{ - -namespace multi_index{ - -template struct identity; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/indexed_by.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/indexed_by.hpp deleted file mode 100644 index d2217e39166..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/indexed_by.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_INDEXED_BY_HPP -#define BOOST_MULTI_INDEX_INDEXED_BY_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include - -/* An alias to mpl::vector used to hide MPL from the user. - * indexed_by contains the index specifiers for instantiation - * of a multi_index_container. - */ - -/* This user_definable macro limits the number of elements of an index list; - * useful for shortening resulting symbol names (MSVC++ 6.0, for instance, - * has problems coping with very long symbol names.) - */ - -#if !defined(BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE) -#define BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE BOOST_MPL_LIMIT_VECTOR_SIZE -#endif - -#if BOOST_MULTI_INDEX_LIMIT_INDEXED_BY_SIZE -struct indexed_by: - mpl::vector -{ -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#undef BOOST_MULTI_INDEX_INDEXED_BY_TEMPLATE_PARM -#undef BOOST_MULTI_INDEX_INDEXED_BY_SIZE - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/key_extractors.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/key_extractors.hpp deleted file mode 100644 index 60179ba2339..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/key_extractors.hpp +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_KEY_EXTRACTORS_HPP -#define BOOST_MULTI_INDEX_KEY_EXTRACTORS_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include -#include -#include -#include -#include - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/mem_fun.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/mem_fun.hpp deleted file mode 100644 index 111c386c5f5..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/mem_fun.hpp +++ /dev/null @@ -1,205 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_MEM_FUN_HPP -#define BOOST_MULTI_INDEX_MEM_FUN_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include - -#if !defined(BOOST_NO_SFINAE) -#include -#endif - -namespace boost{ - -template class reference_wrapper; /* fwd decl. */ - -namespace multi_index{ - -/* mem_fun implements a read-only key extractor based on a given non-const - * member function of a class. - * const_mem_fun does the same for const member functions. - * Additionally, mem_fun and const_mem_fun are overloaded to support - * referece_wrappers of T and "chained pointers" to T's. By chained pointer - * to T we mean a type P such that, given a p of Type P - * *...n...*x is convertible to T&, for some n>=1. - * Examples of chained pointers are raw and smart pointers, iterators and - * arbitrary combinations of these (vg. T** or unique_ptr.) - */ - -template -struct const_mem_fun -{ - typedef typename remove_reference::type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type>::type -#else - Type -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type operator()(const Class& x)const - { - return (x.*PtrToMemberFunction)(); - } - - Type operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } - - Type operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } -}; - -template -struct mem_fun -{ - typedef typename remove_reference::type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type>::type -#else - Type -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type operator()(Class& x)const - { - return (x.*PtrToMemberFunction)(); - } - - Type operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } -}; - -/* MSVC++ 6.0 has problems with const member functions as non-type template - * parameters, somehow it takes them as non-const. const_mem_fun_explicit - * workarounds this deficiency by accepting an extra type parameter that - * specifies the signature of the member function. The workaround was found at: - * Daniel, C.:"Re: weird typedef problem in VC", - * news:microsoft.public.vc.language, 21st nov 2002, - * http://groups.google.com/groups? - * hl=en&lr=&ie=UTF-8&selm=ukwvg3O0BHA.1512%40tkmsftngp05 - * - * MSVC++ 6.0 support has been dropped and [const_]mem_fun_explicit is - * deprecated. - */ - -template< - class Class,typename Type, - typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction> -struct const_mem_fun_explicit -{ - typedef typename remove_reference::type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type>::type -#else - Type -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type operator()(const Class& x)const - { - return (x.*PtrToMemberFunction)(); - } - - Type operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } - - Type operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } -}; - -template< - class Class,typename Type, - typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction> -struct mem_fun_explicit -{ - typedef typename remove_reference::type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type>::type -#else - Type -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type operator()(Class& x)const - { - return (x.*PtrToMemberFunction)(); - } - - Type operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } -}; - -/* BOOST_MULTI_INDEX_CONST_MEM_FUN and BOOST_MULTI_INDEX_MEM_FUN used to - * resolve to [const_]mem_fun_explicit for MSVC++ 6.0 and to - * [const_]mem_fun otherwise. Support for this compiler having been dropped, - * they are now just wrappers over [const_]mem_fun kept for backwards- - * compatibility reasons. - */ - -#define BOOST_MULTI_INDEX_CONST_MEM_FUN(Class,Type,MemberFunName) \ -::boost::multi_index::const_mem_fun< Class,Type,&Class::MemberFunName > -#define BOOST_MULTI_INDEX_MEM_FUN(Class,Type,MemberFunName) \ -::boost::multi_index::mem_fun< Class,Type,&Class::MemberFunName > - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/member.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/member.hpp deleted file mode 100644 index a8e645074a2..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/member.hpp +++ /dev/null @@ -1,262 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_MEMBER_HPP -#define BOOST_MULTI_INDEX_MEMBER_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include - -#if !defined(BOOST_NO_SFINAE) -#include -#endif - -namespace boost{ - -template class reference_wrapper; /* fwd decl. */ - -namespace multi_index{ - -namespace detail{ - -/* member is a read/write key extractor for accessing a given - * member of a class. - * Additionally, member is overloaded to support referece_wrappers - * of T and "chained pointers" to T's. By chained pointer to T we mean - * a type P such that, given a p of Type P - * *...n...*x is convertible to T&, for some n>=1. - * Examples of chained pointers are raw and smart pointers, iterators and - * arbitrary combinations of these (vg. T** or unique_ptr.) - */ - -template -struct const_member_base -{ - typedef Type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type&>::type -#else - Type& -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type& operator()(const Class& x)const - { - return x.*PtrToMember; - } - - Type& operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } - - Type& operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } -}; - -template -struct non_const_member_base -{ - typedef Type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type&>::type -#else - Type& -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - const Type& operator()(const Class& x)const - { - return x.*PtrToMember; - } - - Type& operator()(Class& x)const - { - return x.*PtrToMember; - } - - const Type& operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } - - Type& operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } -}; - -} /* namespace multi_index::detail */ - -template -struct member: - mpl::if_c< - is_const::value, - detail::const_member_base, - detail::non_const_member_base - >::type -{ -}; - -namespace detail{ - -/* MSVC++ 6.0 does not support properly pointers to members as - * non-type template arguments, as reported in - * http://support.microsoft.com/default.aspx?scid=kb;EN-US;249045 - * A similar problem (though not identical) is shown by MSVC++ 7.0. - * We provide an alternative to member<> accepting offsets instead - * of pointers to members. This happens to work even for non-POD - * types (although the standard forbids use of offsetof on these), - * so it serves as a workaround in this compiler for all practical - * purposes. - * Surprisingly enough, other compilers, like Intel C++ 7.0/7.1 and - * Visual Age 6.0, have similar bugs. This replacement of member<> - * can be used for them too. - * - * Support for such old compilers is dropped and - * [non_]const_member_offset_base is deprecated. - */ - -template -struct const_member_offset_base -{ - typedef Type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type&>::type -#else - Type& -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - Type& operator()(const Class& x)const - { - return *static_cast( - static_cast( - static_cast( - static_cast(&x))+OffsetOfMember)); - } - - Type& operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } - - Type& operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } -}; - -template -struct non_const_member_offset_base -{ - typedef Type result_type; - - template - -#if !defined(BOOST_NO_SFINAE) - typename disable_if< - is_convertible,Type&>::type -#else - Type& -#endif - - operator()(const ChainedPtr& x)const - { - return operator()(*x); - } - - const Type& operator()(const Class& x)const - { - return *static_cast( - static_cast( - static_cast( - static_cast(&x))+OffsetOfMember)); - } - - Type& operator()(Class& x)const - { - return *static_cast( - static_cast( - static_cast(static_cast(&x))+OffsetOfMember)); - } - - const Type& operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } - - Type& operator()(const reference_wrapper& x)const - { - return operator()(x.get()); - } -}; - -} /* namespace multi_index::detail */ - -template -struct member_offset: - mpl::if_c< - is_const::value, - detail::const_member_offset_base, - detail::non_const_member_offset_base - >::type -{ -}; - -/* BOOST_MULTI_INDEX_MEMBER resolves to member in the normal cases, - * and to member_offset as a workaround in those defective compilers for - * which BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS is defined. - */ - -#if defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS) -#define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) \ -::boost::multi_index::member_offset< Class,Type,offsetof(Class,MemberName) > -#else -#define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) \ -::boost::multi_index::member< Class,Type,&Class::MemberName > -#endif - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index.hpp deleted file mode 100644 index 5bcd69de8c9..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index.hpp +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_ORDERED_INDEX_HPP -#define BOOST_MULTI_INDEX_ORDERED_INDEX_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* no augment policy for plain ordered indices */ - -struct null_augment_policy -{ - template - struct augmented_interface - { - typedef OrderedIndexImpl type; - }; - - template - struct augmented_node - { - typedef OrderedIndexNodeImpl type; - }; - - template static void add(Pointer,Pointer){} - template static void remove(Pointer,Pointer){} - template static void copy(Pointer,Pointer){} - template static void rotate_left(Pointer,Pointer){} - template static void rotate_right(Pointer,Pointer){} - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - template static bool invariant(Pointer){return true;} - -#endif -}; - -} /* namespace multi_index::detail */ - -/* ordered_index specifiers */ - -template -struct ordered_unique -{ - typedef typename detail::ordered_index_args< - Arg1,Arg2,Arg3> index_args; - typedef typename index_args::tag_list_type::type tag_list_type; - typedef typename index_args::key_from_value_type key_from_value_type; - typedef typename index_args::compare_type compare_type; - - template - struct node_class - { - typedef detail::ordered_index_node type; - }; - - template - struct index_class - { - typedef detail::ordered_index< - key_from_value_type,compare_type, - SuperMeta,tag_list_type,detail::ordered_unique_tag, - detail::null_augment_policy> type; - }; -}; - -template -struct ordered_non_unique -{ - typedef detail::ordered_index_args< - Arg1,Arg2,Arg3> index_args; - typedef typename index_args::tag_list_type::type tag_list_type; - typedef typename index_args::key_from_value_type key_from_value_type; - typedef typename index_args::compare_type compare_type; - - template - struct node_class - { - typedef detail::ordered_index_node type; - }; - - template - struct index_class - { - typedef detail::ordered_index< - key_from_value_type,compare_type, - SuperMeta,tag_list_type,detail::ordered_non_unique_tag, - detail::null_augment_policy> type; - }; -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index_fwd.hpp deleted file mode 100644 index fe44aaf860d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/ordered_index_fwd.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_ORDERED_INDEX_FWD_HPP -#define BOOST_MULTI_INDEX_ORDERED_INDEX_FWD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include -#include - -namespace boost{ - -namespace multi_index{ - -/* ordered_index specifiers */ - -template -struct ordered_unique; - -template -struct ordered_non_unique; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index.hpp deleted file mode 100644 index fe1884ddd38..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index.hpp +++ /dev/null @@ -1,1167 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_HPP -#define BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) -#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x) \ - detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(x,&random_access_index::check_invariant_); \ - BOOST_JOIN(check_invariant_,__LINE__).touch(); -#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT \ - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(*this) -#else -#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x) -#define BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* random_access_index adds a layer of random access indexing - * to a given Super - */ - -template -class random_access_index: - BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - ,public safe_mode::safe_container< - random_access_index > -#endif - -{ -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the - * lifetime of const references bound to temporaries --precisely what - * scopeguards are. - */ - -#pragma parse_mfunc_templ off -#endif - - typedef typename SuperMeta::type super; - -protected: - typedef random_access_index_node< - typename super::node_type> node_type; - -private: - typedef typename node_type::impl_type node_impl_type; - typedef random_access_index_ptr_array< - typename super::final_allocator_type> ptr_array; - typedef typename ptr_array::pointer node_impl_ptr_pointer; - -public: - /* types */ - - typedef typename node_type::value_type value_type; - typedef tuples::null_type ctor_args; - typedef typename super::final_allocator_type allocator_type; - typedef typename allocator_type::reference reference; - typedef typename allocator_type::const_reference const_reference; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef safe_mode::safe_iterator< - rnd_node_iterator, - random_access_index> iterator; -#else - typedef rnd_node_iterator iterator; -#endif - - typedef iterator const_iterator; - - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef typename allocator_type::pointer pointer; - typedef typename allocator_type::const_pointer const_pointer; - typedef typename - boost::reverse_iterator reverse_iterator; - typedef typename - boost::reverse_iterator const_reverse_iterator; - typedef TagList tag_list; - -protected: - typedef typename super::final_node_type final_node_type; - typedef tuples::cons< - ctor_args, - typename super::ctor_args_list> ctor_args_list; - typedef typename mpl::push_front< - typename super::index_type_list, - random_access_index>::type index_type_list; - typedef typename mpl::push_front< - typename super::iterator_type_list, - iterator>::type iterator_type_list; - typedef typename mpl::push_front< - typename super::const_iterator_type_list, - const_iterator>::type const_iterator_type_list; - typedef typename super::copy_map_type copy_map_type; - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - typedef typename super::index_saver_type index_saver_type; - typedef typename super::index_loader_type index_loader_type; -#endif - -private: -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef safe_mode::safe_container< - random_access_index> safe_super; -#endif - - typedef typename call_traits< - value_type>::param_type value_param_type; - - /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL - * expansion. - */ - - typedef std::pair emplace_return_type; - -public: - - /* construct/copy/destroy - * Default and copy ctors are in the protected section as indices are - * not supposed to be created on their own. No range ctor either. - */ - - random_access_index& operator=( - const random_access_index& x) - { - this->final()=x.final(); - return *this; - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - random_access_index& operator=( - std::initializer_list list) - { - this->final()=list; - return *this; - } -#endif - - template - void assign(InputIterator first,InputIterator last) - { - assign_iter(first,last,mpl::not_ >()); - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - void assign(std::initializer_list list) - { - assign(list.begin(),list.end()); - } -#endif - - void assign(size_type n,value_param_type value) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - clear(); - for(size_type i=0;ifinal().get_allocator(); - } - - /* iterators */ - - iterator begin()BOOST_NOEXCEPT - {return make_iterator(node_type::from_impl(*ptrs.begin()));} - const_iterator begin()const BOOST_NOEXCEPT - {return make_iterator(node_type::from_impl(*ptrs.begin()));} - iterator - end()BOOST_NOEXCEPT{return make_iterator(header());} - const_iterator - end()const BOOST_NOEXCEPT{return make_iterator(header());} - reverse_iterator - rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} - const_reverse_iterator - rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} - reverse_iterator - rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} - const_reverse_iterator - rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} - const_iterator - cbegin()const BOOST_NOEXCEPT{return begin();} - const_iterator - cend()const BOOST_NOEXCEPT{return end();} - const_reverse_iterator - crbegin()const BOOST_NOEXCEPT{return rbegin();} - const_reverse_iterator - crend()const BOOST_NOEXCEPT{return rend();} - - iterator iterator_to(const value_type& x) - { - return make_iterator(node_from_value(&x)); - } - - const_iterator iterator_to(const value_type& x)const - { - return make_iterator(node_from_value(&x)); - } - - /* capacity */ - - bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} - size_type size()const BOOST_NOEXCEPT{return this->final_size_();} - size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} - size_type capacity()const BOOST_NOEXCEPT{return ptrs.capacity();} - - void reserve(size_type n) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - ptrs.reserve(n); - } - - void shrink_to_fit() - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - ptrs.shrink_to_fit(); - } - - void resize(size_type n) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - if(n>size()) - for(size_type m=n-size();m--;) - this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK); - else if(nsize())for(size_type m=n-size();m--;)this->final_insert_(x); - else if(nvalue(); - } - - const_reference at(size_type n)const - { - if(n>=size())throw_exception(std::out_of_range("random access index")); - return node_type::from_impl(*ptrs.at(n))->value(); - } - - const_reference front()const{return operator[](0);} - const_reference back()const{return operator[](size()-1);} - - /* modifiers */ - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( - emplace_return_type,emplace_front,emplace_front_impl) - - std::pair push_front(const value_type& x) - {return insert(begin(),x);} - std::pair push_front(BOOST_RV_REF(value_type) x) - {return insert(begin(),boost::move(x));} - void pop_front(){erase(begin());} - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( - emplace_return_type,emplace_back,emplace_back_impl) - - std::pair push_back(const value_type& x) - {return insert(end(),x);} - std::pair push_back(BOOST_RV_REF(value_type) x) - {return insert(end(),boost::move(x));} - void pop_back(){erase(--end());} - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( - emplace_return_type,emplace,emplace_impl,iterator,position) - - std::pair insert(iterator position,const value_type& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_(x); - if(p.second&&position.get_node()!=header()){ - relocate(position.get_node(),p.first); - } - return std::pair(make_iterator(p.first),p.second); - } - - std::pair insert(iterator position,BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_rv_(x); - if(p.second&&position.get_node()!=header()){ - relocate(position.get_node(),p.first); - } - return std::pair(make_iterator(p.first),p.second); - } - - void insert(iterator position,size_type n,value_param_type x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - size_type s=0; - BOOST_TRY{ - while(n--){ - if(push_back(x).second)++s; - } - } - BOOST_CATCH(...){ - relocate(position,end()-s,end()); - BOOST_RETHROW; - } - BOOST_CATCH_END - relocate(position,end()-s,end()); - } - - template - void insert(iterator position,InputIterator first,InputIterator last) - { - insert_iter(position,first,last,mpl::not_ >()); - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - void insert(iterator position,std::initializer_list list) - { - insert(position,list.begin(),list.end()); - } -#endif - - iterator erase(iterator position) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - this->final_erase_(static_cast(position++.get_node())); - return position; - } - - iterator erase(iterator first,iterator last) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); - BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - difference_type n=last-first; - relocate(end(),first,last); - while(n--)pop_back(); - return last; - } - - bool replace(iterator position,const value_type& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - return this->final_replace_( - x,static_cast(position.get_node())); - } - - bool replace(iterator position,BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - return this->final_replace_rv_( - x,static_cast(position.get_node())); - } - - template - bool modify(iterator position,Modifier mod) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer on safe mode code chokes if this - * this is not added. Left it for all compilers as it does no - * harm. - */ - - position.detach(); -#endif - - return this->final_modify_( - mod,static_cast(position.get_node())); - } - - template - bool modify(iterator position,Modifier mod,Rollback back_) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer on safe mode code chokes if this - * this is not added. Left it for all compilers as it does no - * harm. - */ - - position.detach(); -#endif - - return this->final_modify_( - mod,back_,static_cast(position.get_node())); - } - - void swap(random_access_index& x) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF(x); - this->final_swap_(x.final()); - } - - void clear()BOOST_NOEXCEPT - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - this->final_clear_(); - } - - /* list operations */ - - void splice(iterator position,random_access_index& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(*this,x); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - iterator first=x.begin(),last=x.end(); - size_type n=0; - BOOST_TRY{ - while(first!=last){ - if(push_back(*first).second){ - first=x.erase(first); - ++n; - } - else ++first; - } - } - BOOST_CATCH(...){ - relocate(position,end()-n,end()); - BOOST_RETHROW; - } - BOOST_CATCH_END - relocate(position,end()-n,end()); - } - - void splice( - iterator position,random_access_index& x,iterator i) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - if(&x==this)relocate(position,i); - else{ - if(insert(position,*i).second){ - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following - * workaround is needed. Left it for all compilers as it does no - * harm. - */ - i.detach(); - x.erase(x.make_iterator(i.get_node())); -#else - x.erase(i); -#endif - - } - } - } - - void splice( - iterator position,random_access_index& x, - iterator first,iterator last) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x); - BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - if(&x==this)relocate(position,first,last); - else{ - size_type n=0; - BOOST_TRY{ - while(first!=last){ - if(push_back(*first).second){ - first=x.erase(first); - ++n; - } - else ++first; - } - } - BOOST_CATCH(...){ - relocate(position,end()-n,end()); - BOOST_RETHROW; - } - BOOST_CATCH_END - relocate(position,end()-n,end()); - } - } - - void remove(value_param_type value) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - difference_type n= - end()-make_iterator( - random_access_index_remove( - ptrs, - ::boost::bind(std::equal_to(),::boost::arg<1>(),value))); - while(n--)pop_back(); - } - - template - void remove_if(Predicate pred) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - difference_type n= - end()-make_iterator(random_access_index_remove(ptrs,pred)); - while(n--)pop_back(); - } - - void unique() - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - difference_type n= - end()-make_iterator( - random_access_index_unique( - ptrs,std::equal_to())); - while(n--)pop_back(); - } - - template - void unique(BinaryPredicate binary_pred) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - difference_type n= - end()-make_iterator( - random_access_index_unique(ptrs,binary_pred)); - while(n--)pop_back(); - } - - void merge(random_access_index& x) - { - if(this!=&x){ - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - size_type s=size(); - splice(end(),x); - random_access_index_inplace_merge( - get_allocator(),ptrs,ptrs.at(s),std::less()); - } - } - - template - void merge(random_access_index& x,Compare comp) - { - if(this!=&x){ - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - size_type s=size(); - splice(end(),x); - random_access_index_inplace_merge( - get_allocator(),ptrs,ptrs.at(s),comp); - } - } - - void sort() - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - random_access_index_sort( - get_allocator(),ptrs,std::less()); - } - - template - void sort(Compare comp) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - random_access_index_sort( - get_allocator(),ptrs,comp); - } - - void reverse()BOOST_NOEXCEPT - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - node_impl_type::reverse(ptrs.begin(),ptrs.end()); - } - - /* rearrange operations */ - - void relocate(iterator position,iterator i) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - if(position!=i)relocate(position.get_node(),i.get_node()); - } - - void relocate(iterator position,iterator first,iterator last) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); - BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); - BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - if(position!=last)relocate( - position.get_node(),first.get_node(),last.get_node()); - } - - template - void rearrange(InputIterator first) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - for(node_impl_ptr_pointer p0=ptrs.begin(),p0_end=ptrs.end(); - p0!=p0_end;++first,++p0){ - const value_type& v1=*first; - node_impl_ptr_pointer p1=node_from_value(&v1)->up(); - - std::swap(*p0,*p1); - (*p0)->up()=p0; - (*p1)->up()=p1; - } - } - -BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: - random_access_index( - const ctor_args_list& args_list,const allocator_type& al): - super(args_list.get_tail(),al), - ptrs(al,header()->impl(),0) - { - } - - random_access_index(const random_access_index& x): - super(x), - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super(), -#endif - - ptrs(x.get_allocator(),header()->impl(),x.size()) - { - /* The actual copying takes place in subsequent call to copy_(). - */ - } - - random_access_index( - const random_access_index& x,do_not_copy_elements_tag): - super(x,do_not_copy_elements_tag()), - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super(), -#endif - - ptrs(x.get_allocator(),header()->impl(),0) - { - } - - ~random_access_index() - { - /* the container is guaranteed to be empty by now */ - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - iterator make_iterator(node_type* node){return iterator(node,this);} - const_iterator make_iterator(node_type* node)const - {return const_iterator(node,const_cast(this));} -#else - iterator make_iterator(node_type* node){return iterator(node);} - const_iterator make_iterator(node_type* node)const - {return const_iterator(node);} -#endif - - void copy_( - const random_access_index& x,const copy_map_type& map) - { - for(node_impl_ptr_pointer begin_org=x.ptrs.begin(), - begin_cpy=ptrs.begin(), - end_org=x.ptrs.end(); - begin_org!=end_org;++begin_org,++begin_cpy){ - *begin_cpy= - static_cast( - map.find( - static_cast( - node_type::from_impl(*begin_org))))->impl(); - (*begin_cpy)->up()=begin_cpy; - } - - super::copy_(x,map); - } - - template - final_node_type* insert_( - value_param_type v,final_node_type*& x,Variant variant) - { - ptrs.room_for_one(); - final_node_type* res=super::insert_(v,x,variant); - if(res==x)ptrs.push_back(static_cast(x)->impl()); - return res; - } - - template - final_node_type* insert_( - value_param_type v,node_type* position,final_node_type*& x,Variant variant) - { - ptrs.room_for_one(); - final_node_type* res=super::insert_(v,position,x,variant); - if(res==x)ptrs.push_back(static_cast(x)->impl()); - return res; - } - - void erase_(node_type* x) - { - ptrs.erase(x->impl()); - super::erase_(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - } - - void delete_all_nodes_() - { - for(node_impl_ptr_pointer x=ptrs.begin(),x_end=ptrs.end();x!=x_end;++x){ - this->final_delete_node_( - static_cast(node_type::from_impl(*x))); - } - } - - void clear_() - { - super::clear_(); - ptrs.clear(); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::detach_dereferenceable_iterators(); -#endif - } - - void swap_(random_access_index& x) - { - ptrs.swap(x.ptrs); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::swap(x); -#endif - - super::swap_(x); - } - - void swap_elements_(random_access_index& x) - { - ptrs.swap(x.ptrs); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::swap(x); -#endif - - super::swap_elements_(x); - } - - template - bool replace_(value_param_type v,node_type* x,Variant variant) - { - return super::replace_(v,x,variant); - } - - bool modify_(node_type* x) - { - BOOST_TRY{ - if(!super::modify_(x)){ - ptrs.erase(x->impl()); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - return false; - } - else return true; - } - BOOST_CATCH(...){ - ptrs.erase(x->impl()); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - bool modify_rollback_(node_type* x) - { - return super::modify_rollback_(x); - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* serialization */ - - template - void save_( - Archive& ar,const unsigned int version,const index_saver_type& sm)const - { - sm.save(begin(),end(),ar,version); - super::save_(ar,version,sm); - } - - template - void load_( - Archive& ar,const unsigned int version,const index_loader_type& lm) - { - { - typedef random_access_index_loader loader; - - loader ld(get_allocator(),ptrs); - lm.load( - ::boost::bind( - &loader::rearrange,&ld,::boost::arg<1>(),::boost::arg<2>()), - ar,version); - } /* exit scope so that ld frees its resources */ - super::load_(ar,version,lm); - } -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - bool invariant_()const - { - if(size()>capacity())return false; - if(size()==0||begin()==end()){ - if(size()!=0||begin()!=end())return false; - } - else{ - size_type s=0; - for(const_iterator it=begin(),it_end=end();;++it,++s){ - if(*(it.get_node()->up())!=it.get_node()->impl())return false; - if(it==it_end)break; - } - if(s!=size())return false; - } - - return super::invariant_(); - } - - /* This forwarding function eases things for the boost::mem_fn construct - * in BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT. Actually, - * final_check_invariant is already an inherited member function of index. - */ - void check_invariant_()const{this->final_check_invariant_();} -#endif - -private: - node_type* header()const{return this->final_header();} - - static void relocate(node_type* position,node_type* x) - { - node_impl_type::relocate(position->up(),x->up()); - } - - static void relocate(node_type* position,node_type* first,node_type* last) - { - node_impl_type::relocate( - position->up(),first->up(),last->up()); - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - void detach_iterators(node_type* x) - { - iterator it=make_iterator(x); - safe_mode::detach_equivalent_iterators(it); - } -#endif - - template - void assign_iter(InputIterator first,InputIterator last,mpl::true_) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - clear(); - for(;first!=last;++first)this->final_insert_ref_(*first); - } - - void assign_iter(size_type n,value_param_type value,mpl::false_) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - clear(); - for(size_type i=0;i - void insert_iter( - iterator position,InputIterator first,InputIterator last,mpl::true_) - { - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - size_type s=0; - BOOST_TRY{ - for(;first!=last;++first){ - if(this->final_insert_ref_(*first).second)++s; - } - } - BOOST_CATCH(...){ - relocate(position,end()-s,end()); - BOOST_RETHROW; - } - BOOST_CATCH_END - relocate(position,end()-s,end()); - } - - void insert_iter( - iterator position,size_type n,value_param_type x,mpl::false_) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - size_type s=0; - BOOST_TRY{ - while(n--){ - if(push_back(x).second)++s; - } - } - BOOST_CATCH(...){ - relocate(position,end()-s,end()); - BOOST_RETHROW; - } - BOOST_CATCH_END - relocate(position,end()-s,end()); - } - - template - std::pair emplace_front_impl( - BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - } - - template - std::pair emplace_back_impl( - BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - } - - template - std::pair emplace_impl( - iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT; - std::pair p= - this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - if(p.second&&position.get_node()!=header()){ - relocate(position.get_node(),p.first); - } - return std::pair(make_iterator(p.first),p.second); - } - - ptr_array ptrs; - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -#pragma parse_mfunc_templ reset -#endif -}; - -/* comparison */ - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator==( - const random_access_index& x, - const random_access_index& y) -{ - return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); -} - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator<( - const random_access_index& x, - const random_access_index& y) -{ - return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); -} - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator!=( - const random_access_index& x, - const random_access_index& y) -{ - return !(x==y); -} - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator>( - const random_access_index& x, - const random_access_index& y) -{ - return y -bool operator>=( - const random_access_index& x, - const random_access_index& y) -{ - return !(x -bool operator<=( - const random_access_index& x, - const random_access_index& y) -{ - return !(x>y); -} - -/* specialized algorithms */ - -template -void swap( - random_access_index& x, - random_access_index& y) -{ - x.swap(y); -} - -} /* namespace multi_index::detail */ - -/* random access index specifier */ - -template -struct random_access -{ - BOOST_STATIC_ASSERT(detail::is_tag::value); - - template - struct node_class - { - typedef detail::random_access_index_node type; - }; - - template - struct index_class - { - typedef detail::random_access_index< - SuperMeta,typename TagList::type> type; - }; -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -/* Boost.Foreach compatibility */ - -template -inline boost::mpl::true_* boost_foreach_is_noncopyable( - boost::multi_index::detail::random_access_index*&, - boost_foreach_argument_dependent_lookup_hack) -{ - return 0; -} - -#undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT -#undef BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT_OF - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index_fwd.hpp deleted file mode 100644 index 2ea19295426..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/random_access_index_fwd.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_FWD_HPP -#define BOOST_MULTI_INDEX_RANDOM_ACCESS_INDEX_FWD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template -class random_access_index; - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator==( - const random_access_index& x, - const random_access_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator<( - const random_access_index& x, - const random_access_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator!=( - const random_access_index& x, - const random_access_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator>( - const random_access_index& x, - const random_access_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator>=( - const random_access_index& x, - const random_access_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator<=( - const random_access_index& x, - const random_access_index& y); - -template -void swap( - random_access_index& x, - random_access_index& y); - -} /* namespace multi_index::detail */ - -/* index specifiers */ - -template > -struct random_access; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index.hpp deleted file mode 100644 index 4b24c4f5937..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index.hpp +++ /dev/null @@ -1,382 +0,0 @@ -/* Copyright 2003-2017 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_RANKED_INDEX_HPP -#define BOOST_MULTI_INDEX_RANKED_INDEX_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* ranked_index augments a given ordered index to provide rank operations */ - -template -struct ranked_node:OrderedIndexNodeImpl -{ - std::size_t size; -}; - -template -class ranked_index:public OrderedIndexImpl -{ - typedef OrderedIndexImpl super; - -protected: - typedef typename super::node_type node_type; - typedef typename super::node_impl_pointer node_impl_pointer; - -public: - typedef typename super::ctor_args_list ctor_args_list; - typedef typename super::allocator_type allocator_type; - typedef typename super::iterator iterator; - - /* rank operations */ - - iterator nth(std::size_t n)const - { - return this->make_iterator(node_type::from_impl( - ranked_index_nth(n,this->header()->impl()))); - } - - std::size_t rank(iterator position)const - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - - return ranked_index_rank( - position.get_node()->impl(),this->header()->impl()); - } - - template - std::size_t find_rank(const CompatibleKey& x)const - { - return ranked_index_find_rank( - this->root(),this->header(),this->key,x,this->comp_); - } - - template - std::size_t find_rank( - const CompatibleKey& x,const CompatibleCompare& comp)const - { - return ranked_index_find_rank( - this->root(),this->header(),this->key,x,comp); - } - - template - std::size_t lower_bound_rank(const CompatibleKey& x)const - { - return ranked_index_lower_bound_rank( - this->root(),this->header(),this->key,x,this->comp_); - } - - template - std::size_t lower_bound_rank( - const CompatibleKey& x,const CompatibleCompare& comp)const - { - return ranked_index_lower_bound_rank( - this->root(),this->header(),this->key,x,comp); - } - - template - std::size_t upper_bound_rank(const CompatibleKey& x)const - { - return ranked_index_upper_bound_rank( - this->root(),this->header(),this->key,x,this->comp_); - } - - template - std::size_t upper_bound_rank( - const CompatibleKey& x,const CompatibleCompare& comp)const - { - return ranked_index_upper_bound_rank( - this->root(),this->header(),this->key,x,comp); - } - - template - std::pair equal_range_rank( - const CompatibleKey& x)const - { - return ranked_index_equal_range_rank( - this->root(),this->header(),this->key,x,this->comp_); - } - - template - std::pair equal_range_rank( - const CompatibleKey& x,const CompatibleCompare& comp)const - { - return ranked_index_equal_range_rank( - this->root(),this->header(),this->key,x,comp); - } - - template - std::pair - range_rank(LowerBounder lower,UpperBounder upper)const - { - typedef typename mpl::if_< - is_same, - BOOST_DEDUCED_TYPENAME mpl::if_< - is_same, - both_unbounded_tag, - lower_unbounded_tag - >::type, - BOOST_DEDUCED_TYPENAME mpl::if_< - is_same, - upper_unbounded_tag, - none_unbounded_tag - >::type - >::type dispatch; - - return range_rank(lower,upper,dispatch()); - } - -protected: - ranked_index(const ranked_index& x):super(x){}; - - ranked_index(const ranked_index& x,do_not_copy_elements_tag): - super(x,do_not_copy_elements_tag()){}; - - ranked_index( - const ctor_args_list& args_list,const allocator_type& al): - super(args_list,al){} - -private: - template - std::pair - range_rank(LowerBounder lower,UpperBounder upper,none_unbounded_tag)const - { - node_type* y=this->header(); - node_type* z=this->root(); - - if(!z)return std::pair(0,0); - - std::size_t s=z->impl()->size; - - do{ - if(!lower(this->key(z->value()))){ - z=node_type::from_impl(z->right()); - } - else if(!upper(this->key(z->value()))){ - y=z; - s-=ranked_node_size(y->right())+1; - z=node_type::from_impl(z->left()); - } - else{ - return std::pair( - s-z->impl()->size+ - lower_range_rank(node_type::from_impl(z->left()),z,lower), - s-ranked_node_size(z->right())+ - upper_range_rank(node_type::from_impl(z->right()),y,upper)); - } - }while(z); - - return std::pair(s,s); - } - - template - std::pair - range_rank(LowerBounder,UpperBounder upper,lower_unbounded_tag)const - { - return std::pair( - 0, - upper_range_rank(this->root(),this->header(),upper)); - } - - template - std::pair - range_rank(LowerBounder lower,UpperBounder,upper_unbounded_tag)const - { - return std::pair( - lower_range_rank(this->root(),this->header(),lower), - this->size()); - } - - template - std::pair - range_rank(LowerBounder,UpperBounder,both_unbounded_tag)const - { - return std::pair(0,this->size()); - } - - template - std::size_t - lower_range_rank(node_type* top,node_type* y,LowerBounder lower)const - { - if(!top)return 0; - - std::size_t s=top->impl()->size; - - do{ - if(lower(this->key(top->value()))){ - y=top; - s-=ranked_node_size(y->right())+1; - top=node_type::from_impl(top->left()); - } - else top=node_type::from_impl(top->right()); - }while(top); - - return s; - } - - template - std::size_t - upper_range_rank(node_type* top,node_type* y,UpperBounder upper)const - { - if(!top)return 0; - - std::size_t s=top->impl()->size; - - do{ - if(!upper(this->key(top->value()))){ - y=top; - s-=ranked_node_size(y->right())+1; - top=node_type::from_impl(top->left()); - } - else top=node_type::from_impl(top->right()); - }while(top); - - return s; - } -}; - -/* augmenting policy for ordered_index */ - -struct rank_policy -{ - template - struct augmented_node - { - typedef ranked_node type; - }; - - template - struct augmented_interface - { - typedef ranked_index type; - }; - - /* algorithmic stuff */ - - template - static void add(Pointer x,Pointer root) - { - x->size=1; - while(x!=root){ - x=x->parent(); - ++(x->size); - } - } - - template - static void remove(Pointer x,Pointer root) - { - while(x!=root){ - x=x->parent(); - --(x->size); - } - } - - template - static void copy(Pointer x,Pointer y) - { - y->size=x->size; - } - - template - static void rotate_left(Pointer x,Pointer y) /* in: x==y->left() */ - { - y->size=x->size; - x->size=ranked_node_size(x->left())+ranked_node_size(x->right())+1; - } - - template - static void rotate_right(Pointer x,Pointer y) /* in: x==y->right() */ - { - rotate_left(x,y); - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - template - static bool invariant(Pointer x) - { - return x->size==ranked_node_size(x->left())+ranked_node_size(x->right())+1; - } -#endif -}; - -} /* namespace multi_index::detail */ - -/* ranked_index specifiers */ - -template -struct ranked_unique -{ - typedef typename detail::ordered_index_args< - Arg1,Arg2,Arg3> index_args; - typedef typename index_args::tag_list_type::type tag_list_type; - typedef typename index_args::key_from_value_type key_from_value_type; - typedef typename index_args::compare_type compare_type; - - template - struct node_class - { - typedef detail::ordered_index_node type; - }; - - template - struct index_class - { - typedef detail::ordered_index< - key_from_value_type,compare_type, - SuperMeta,tag_list_type,detail::ordered_unique_tag, - detail::rank_policy> type; - }; -}; - -template -struct ranked_non_unique -{ - typedef detail::ordered_index_args< - Arg1,Arg2,Arg3> index_args; - typedef typename index_args::tag_list_type::type tag_list_type; - typedef typename index_args::key_from_value_type key_from_value_type; - typedef typename index_args::compare_type compare_type; - - template - struct node_class - { - typedef detail::ordered_index_node type; - }; - - template - struct index_class - { - typedef detail::ordered_index< - key_from_value_type,compare_type, - SuperMeta,tag_list_type,detail::ordered_non_unique_tag, - detail::rank_policy> type; - }; -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index_fwd.hpp deleted file mode 100644 index 380d3480736..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/ranked_index_fwd.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_RANKED_INDEX_FWD_HPP -#define BOOST_MULTI_INDEX_RANKED_INDEX_FWD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include -#include - -namespace boost{ - -namespace multi_index{ - -/* ranked_index specifiers */ - -template -struct ranked_unique; - -template -struct ranked_non_unique; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/safe_mode_errors.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/safe_mode_errors.hpp deleted file mode 100644 index 1904706edec..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/safe_mode_errors.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_SAFE_MODE_ERRORS_HPP -#define BOOST_MULTI_INDEX_SAFE_MODE_ERRORS_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -namespace boost{ - -namespace multi_index{ - -namespace safe_mode{ - -/* Error codes for Boost.MultiIndex safe mode. These go in a separate - * header so that the user can include it when redefining - * BOOST_MULTI_INDEX_SAFE_MODE_ASSERT prior to the inclusion of - * any other header of Boost.MultiIndex. - */ - -enum error_code -{ - invalid_iterator=0, - not_dereferenceable_iterator, - not_incrementable_iterator, - not_decrementable_iterator, - not_owner, - not_same_owner, - invalid_range, - inside_range, - out_of_bounds, - same_container -}; - -} /* namespace multi_index::safe_mode */ - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index.hpp deleted file mode 100644 index 424eebc376d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index.hpp +++ /dev/null @@ -1,1062 +0,0 @@ -/* Copyright 2003-2015 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_SEQUENCED_INDEX_HPP -#define BOOST_MULTI_INDEX_SEQUENCED_INDEX_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) -#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) \ - detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(x,&sequenced_index::check_invariant_); \ - BOOST_JOIN(check_invariant_,__LINE__).touch(); -#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT \ - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(*this) -#else -#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x) -#define BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT -#endif - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -/* sequenced_index adds a layer of sequenced indexing to a given Super */ - -template -class sequenced_index: - BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS SuperMeta::type - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - ,public safe_mode::safe_container< - sequenced_index > -#endif - -{ -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the - * lifetime of const references bound to temporaries --precisely what - * scopeguards are. - */ - -#pragma parse_mfunc_templ off -#endif - - typedef typename SuperMeta::type super; - -protected: - typedef sequenced_index_node< - typename super::node_type> node_type; - -private: - typedef typename node_type::impl_type node_impl_type; - -public: - /* types */ - - typedef typename node_type::value_type value_type; - typedef tuples::null_type ctor_args; - typedef typename super::final_allocator_type allocator_type; - typedef typename allocator_type::reference reference; - typedef typename allocator_type::const_reference const_reference; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef safe_mode::safe_iterator< - bidir_node_iterator, - sequenced_index> iterator; -#else - typedef bidir_node_iterator iterator; -#endif - - typedef iterator const_iterator; - - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef typename allocator_type::pointer pointer; - typedef typename allocator_type::const_pointer const_pointer; - typedef typename - boost::reverse_iterator reverse_iterator; - typedef typename - boost::reverse_iterator const_reverse_iterator; - typedef TagList tag_list; - -protected: - typedef typename super::final_node_type final_node_type; - typedef tuples::cons< - ctor_args, - typename super::ctor_args_list> ctor_args_list; - typedef typename mpl::push_front< - typename super::index_type_list, - sequenced_index>::type index_type_list; - typedef typename mpl::push_front< - typename super::iterator_type_list, - iterator>::type iterator_type_list; - typedef typename mpl::push_front< - typename super::const_iterator_type_list, - const_iterator>::type const_iterator_type_list; - typedef typename super::copy_map_type copy_map_type; - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - typedef typename super::index_saver_type index_saver_type; - typedef typename super::index_loader_type index_loader_type; -#endif - -private: -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef safe_mode::safe_container< - sequenced_index> safe_super; -#endif - - typedef typename call_traits::param_type value_param_type; - - /* Needed to avoid commas in BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL - * expansion. - */ - - typedef std::pair emplace_return_type; - -public: - - /* construct/copy/destroy - * Default and copy ctors are in the protected section as indices are - * not supposed to be created on their own. No range ctor either. - */ - - sequenced_index& operator=( - const sequenced_index& x) - { - this->final()=x.final(); - return *this; - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - sequenced_index& operator=( - std::initializer_list list) - { - this->final()=list; - return *this; - } -#endif - - template - void assign(InputIterator first,InputIterator last) - { - assign_iter(first,last,mpl::not_ >()); - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - void assign(std::initializer_list list) - { - assign(list.begin(),list.end()); - } -#endif - - void assign(size_type n,value_param_type value) - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - clear(); - for(size_type i=0;ifinal().get_allocator(); - } - - /* iterators */ - - iterator begin()BOOST_NOEXCEPT - {return make_iterator(node_type::from_impl(header()->next()));} - const_iterator begin()const BOOST_NOEXCEPT - {return make_iterator(node_type::from_impl(header()->next()));} - iterator - end()BOOST_NOEXCEPT{return make_iterator(header());} - const_iterator - end()const BOOST_NOEXCEPT{return make_iterator(header());} - reverse_iterator - rbegin()BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} - const_reverse_iterator - rbegin()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(end());} - reverse_iterator - rend()BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} - const_reverse_iterator - rend()const BOOST_NOEXCEPT{return boost::make_reverse_iterator(begin());} - const_iterator - cbegin()const BOOST_NOEXCEPT{return begin();} - const_iterator - cend()const BOOST_NOEXCEPT{return end();} - const_reverse_iterator - crbegin()const BOOST_NOEXCEPT{return rbegin();} - const_reverse_iterator - crend()const BOOST_NOEXCEPT{return rend();} - - iterator iterator_to(const value_type& x) - { - return make_iterator(node_from_value(&x)); - } - - const_iterator iterator_to(const value_type& x)const - { - return make_iterator(node_from_value(&x)); - } - - /* capacity */ - - bool empty()const BOOST_NOEXCEPT{return this->final_empty_();} - size_type size()const BOOST_NOEXCEPT{return this->final_size_();} - size_type max_size()const BOOST_NOEXCEPT{return this->final_max_size_();} - - void resize(size_type n) - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - if(n>size()){ - for(size_type m=n-size();m--;) - this->final_emplace_(BOOST_MULTI_INDEX_NULL_PARAM_PACK); - } - else if(nsize())insert(end(),n-size(),x); - else if(n push_front(const value_type& x) - {return insert(begin(),x);} - std::pair push_front(BOOST_RV_REF(value_type) x) - {return insert(begin(),boost::move(x));} - void pop_front(){erase(begin());} - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL( - emplace_return_type,emplace_back,emplace_back_impl) - - std::pair push_back(const value_type& x) - {return insert(end(),x);} - std::pair push_back(BOOST_RV_REF(value_type) x) - {return insert(end(),boost::move(x));} - void pop_back(){erase(--end());} - - BOOST_MULTI_INDEX_OVERLOADS_TO_VARTEMPL_EXTRA_ARG( - emplace_return_type,emplace,emplace_impl,iterator,position) - - std::pair insert(iterator position,const value_type& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_(x); - if(p.second&&position.get_node()!=header()){ - relink(position.get_node(),p.first); - } - return std::pair(make_iterator(p.first),p.second); - } - - std::pair insert(iterator position,BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - std::pair p=this->final_insert_rv_(x); - if(p.second&&position.get_node()!=header()){ - relink(position.get_node(),p.first); - } - return std::pair(make_iterator(p.first),p.second); - } - - void insert(iterator position,size_type n,value_param_type x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - for(size_type i=0;i - void insert(iterator position,InputIterator first,InputIterator last) - { - insert_iter(position,first,last,mpl::not_ >()); - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - void insert(iterator position,std::initializer_list list) - { - insert(position,list.begin(),list.end()); - } -#endif - - iterator erase(iterator position) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - this->final_erase_(static_cast(position++.get_node())); - return position; - } - - iterator erase(iterator first,iterator last) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); - BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - while(first!=last){ - first=erase(first); - } - return first; - } - - bool replace(iterator position,const value_type& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - return this->final_replace_( - x,static_cast(position.get_node())); - } - - bool replace(iterator position,BOOST_RV_REF(value_type) x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - return this->final_replace_rv_( - x,static_cast(position.get_node())); - } - - template - bool modify(iterator position,Modifier mod) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer on safe mode code chokes if this - * this is not added. Left it for all compilers as it does no - * harm. - */ - - position.detach(); -#endif - - return this->final_modify_( - mod,static_cast(position.get_node())); - } - - template - bool modify(iterator position,Modifier mod,Rollback back_) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer on safe mode code chokes if this - * this is not added. Left it for all compilers as it does no - * harm. - */ - - position.detach(); -#endif - - return this->final_modify_( - mod,back_,static_cast(position.get_node())); - } - - void swap(sequenced_index& x) - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF(x); - this->final_swap_(x.final()); - } - - void clear()BOOST_NOEXCEPT - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - this->final_clear_(); - } - - /* list operations */ - - void splice(iterator position,sequenced_index& x) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_DIFFERENT_CONTAINER(*this,x); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - iterator first=x.begin(),last=x.end(); - while(first!=last){ - if(insert(position,*first).second)first=x.erase(first); - else ++first; - } - } - - void splice(iterator position,sequenced_index& x,iterator i) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,x); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - if(&x==this){ - if(position!=i)relink(position.get_node(),i.get_node()); - } - else{ - if(insert(position,*i).second){ - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - /* MSVC++ 6.0 optimizer has a hard time with safe mode, and the following - * workaround is needed. Left it for all compilers as it does no - * harm. - */ - i.detach(); - x.erase(x.make_iterator(i.get_node())); -#else - x.erase(i); -#endif - - } - } - } - - void splice( - iterator position,sequenced_index& x, - iterator first,iterator last) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,x); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,x); - BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - if(&x==this){ - BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last); - if(position!=last)relink( - position.get_node(),first.get_node(),last.get_node()); - } - else{ - while(first!=last){ - if(insert(position,*first).second)first=x.erase(first); - else ++first; - } - } - } - - void remove(value_param_type value) - { - sequenced_index_remove( - *this, - ::boost::bind(std::equal_to(),::boost::arg<1>(),value)); - } - - template - void remove_if(Predicate pred) - { - sequenced_index_remove(*this,pred); - } - - void unique() - { - sequenced_index_unique(*this,std::equal_to()); - } - - template - void unique(BinaryPredicate binary_pred) - { - sequenced_index_unique(*this,binary_pred); - } - - void merge(sequenced_index& x) - { - sequenced_index_merge(*this,x,std::less()); - } - - template - void merge(sequenced_index& x,Compare comp) - { - sequenced_index_merge(*this,x,comp); - } - - void sort() - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - sequenced_index_sort(header(),std::less()); - } - - template - void sort(Compare comp) - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - sequenced_index_sort(header(),comp); - } - - void reverse()BOOST_NOEXCEPT - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - node_impl_type::reverse(header()->impl()); - } - - /* rearrange operations */ - - void relocate(iterator position,iterator i) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(i); - BOOST_MULTI_INDEX_CHECK_DEREFERENCEABLE_ITERATOR(i); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(i,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - if(position!=i)relink(position.get_node(),i.get_node()); - } - - void relocate(iterator position,iterator first,iterator last) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first); - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this); - BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last); - BOOST_MULTI_INDEX_CHECK_OUTSIDE_RANGE(position,first,last); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - if(position!=last)relink( - position.get_node(),first.get_node(),last.get_node()); - } - - template - void rearrange(InputIterator first) - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - node_type* pos=header(); - for(size_type s=size();s--;){ - const value_type& v=*first++; - relink(pos,node_from_value(&v)); - } - } - -BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: - sequenced_index(const ctor_args_list& args_list,const allocator_type& al): - super(args_list.get_tail(),al) - { - empty_initialize(); - } - - sequenced_index(const sequenced_index& x): - super(x) - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - ,safe_super() -#endif - - { - /* the actual copying takes place in subsequent call to copy_() */ - } - - sequenced_index( - const sequenced_index& x,do_not_copy_elements_tag): - super(x,do_not_copy_elements_tag()) - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - ,safe_super() -#endif - - { - empty_initialize(); - } - - ~sequenced_index() - { - /* the container is guaranteed to be empty by now */ - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - iterator make_iterator(node_type* node){return iterator(node,this);} - const_iterator make_iterator(node_type* node)const - {return const_iterator(node,const_cast(this));} -#else - iterator make_iterator(node_type* node){return iterator(node);} - const_iterator make_iterator(node_type* node)const - {return const_iterator(node);} -#endif - - void copy_( - const sequenced_index& x,const copy_map_type& map) - { - node_type* org=x.header(); - node_type* cpy=header(); - do{ - node_type* next_org=node_type::from_impl(org->next()); - node_type* next_cpy=map.find(static_cast(next_org)); - cpy->next()=next_cpy->impl(); - next_cpy->prior()=cpy->impl(); - org=next_org; - cpy=next_cpy; - }while(org!=x.header()); - - super::copy_(x,map); - } - - template - final_node_type* insert_( - value_param_type v,final_node_type*& x,Variant variant) - { - final_node_type* res=super::insert_(v,x,variant); - if(res==x)link(static_cast(x)); - return res; - } - - template - final_node_type* insert_( - value_param_type v,node_type* position,final_node_type*& x,Variant variant) - { - final_node_type* res=super::insert_(v,position,x,variant); - if(res==x)link(static_cast(x)); - return res; - } - - void erase_(node_type* x) - { - unlink(x); - super::erase_(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - } - - void delete_all_nodes_() - { - for(node_type* x=node_type::from_impl(header()->next());x!=header();){ - node_type* y=node_type::from_impl(x->next()); - this->final_delete_node_(static_cast(x)); - x=y; - } - } - - void clear_() - { - super::clear_(); - empty_initialize(); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::detach_dereferenceable_iterators(); -#endif - } - - void swap_(sequenced_index& x) - { -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::swap(x); -#endif - - super::swap_(x); - } - - void swap_elements_(sequenced_index& x) - { -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - safe_super::swap(x); -#endif - - super::swap_elements_(x); - } - - template - bool replace_(value_param_type v,node_type* x,Variant variant) - { - return super::replace_(v,x,variant); - } - - bool modify_(node_type* x) - { - BOOST_TRY{ - if(!super::modify_(x)){ - unlink(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - return false; - } - else return true; - } - BOOST_CATCH(...){ - unlink(x); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - detach_iterators(x); -#endif - - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - bool modify_rollback_(node_type* x) - { - return super::modify_rollback_(x); - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* serialization */ - - template - void save_( - Archive& ar,const unsigned int version,const index_saver_type& sm)const - { - sm.save(begin(),end(),ar,version); - super::save_(ar,version,sm); - } - - template - void load_( - Archive& ar,const unsigned int version,const index_loader_type& lm) - { - lm.load( - ::boost::bind( - &sequenced_index::rearranger,this,::boost::arg<1>(),::boost::arg<2>()), - ar,version); - super::load_(ar,version,lm); - } -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - bool invariant_()const - { - if(size()==0||begin()==end()){ - if(size()!=0||begin()!=end()|| - header()->next()!=header()->impl()|| - header()->prior()!=header()->impl())return false; - } - else{ - size_type s=0; - for(const_iterator it=begin(),it_end=end();it!=it_end;++it,++s){ - if(it.get_node()->next()->prior()!=it.get_node()->impl())return false; - if(it.get_node()->prior()->next()!=it.get_node()->impl())return false; - } - if(s!=size())return false; - } - - return super::invariant_(); - } - - /* This forwarding function eases things for the boost::mem_fn construct - * in BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT. Actually, - * final_check_invariant is already an inherited member function of index. - */ - void check_invariant_()const{this->final_check_invariant_();} -#endif - -private: - node_type* header()const{return this->final_header();} - - void empty_initialize() - { - header()->prior()=header()->next()=header()->impl(); - } - - void link(node_type* x) - { - node_impl_type::link(x->impl(),header()->impl()); - }; - - static void unlink(node_type* x) - { - node_impl_type::unlink(x->impl()); - } - - static void relink(node_type* position,node_type* x) - { - node_impl_type::relink(position->impl(),x->impl()); - } - - static void relink(node_type* position,node_type* first,node_type* last) - { - node_impl_type::relink( - position->impl(),first->impl(),last->impl()); - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - void rearranger(node_type* position,node_type *x) - { - if(!position)position=header(); - node_type::increment(position); - if(position!=x)relink(position,x); - } -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - void detach_iterators(node_type* x) - { - iterator it=make_iterator(x); - safe_mode::detach_equivalent_iterators(it); - } -#endif - - template - void assign_iter(InputIterator first,InputIterator last,mpl::true_) - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - clear(); - for(;first!=last;++first)this->final_insert_ref_(*first); - } - - void assign_iter(size_type n,value_param_type value,mpl::false_) - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - clear(); - for(size_type i=0;i - void insert_iter( - iterator position,InputIterator first,InputIterator last,mpl::true_) - { - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - for(;first!=last;++first){ - std::pair p= - this->final_insert_ref_(*first); - if(p.second&&position.get_node()!=header()){ - relink(position.get_node(),p.first); - } - } - } - - void insert_iter( - iterator position,size_type n,value_param_type x,mpl::false_) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - for(size_type i=0;i - std::pair emplace_front_impl( - BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - return emplace_impl(begin(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - } - - template - std::pair emplace_back_impl( - BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - return emplace_impl(end(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - } - - template - std::pair emplace_impl( - iterator position,BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(position); - BOOST_MULTI_INDEX_CHECK_IS_OWNER(position,*this); - BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT; - std::pair p= - this->final_emplace_(BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - if(p.second&&position.get_node()!=header()){ - relink(position.get_node(),p.first); - } - return std::pair(make_iterator(p.first),p.second); - } - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -#pragma parse_mfunc_templ reset -#endif -}; - -/* comparison */ - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator==( - const sequenced_index& x, - const sequenced_index& y) -{ - return x.size()==y.size()&&std::equal(x.begin(),x.end(),y.begin()); -} - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator<( - const sequenced_index& x, - const sequenced_index& y) -{ - return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); -} - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator!=( - const sequenced_index& x, - const sequenced_index& y) -{ - return !(x==y); -} - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator>( - const sequenced_index& x, - const sequenced_index& y) -{ - return y -bool operator>=( - const sequenced_index& x, - const sequenced_index& y) -{ - return !(x -bool operator<=( - const sequenced_index& x, - const sequenced_index& y) -{ - return !(x>y); -} - -/* specialized algorithms */ - -template -void swap( - sequenced_index& x, - sequenced_index& y) -{ - x.swap(y); -} - -} /* namespace multi_index::detail */ - -/* sequenced index specifier */ - -template -struct sequenced -{ - BOOST_STATIC_ASSERT(detail::is_tag::value); - - template - struct node_class - { - typedef detail::sequenced_index_node type; - }; - - template - struct index_class - { - typedef detail::sequenced_index type; - }; -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -/* Boost.Foreach compatibility */ - -template -inline boost::mpl::true_* boost_foreach_is_noncopyable( - boost::multi_index::detail::sequenced_index*&, - boost_foreach_argument_dependent_lookup_hack) -{ - return 0; -} - -#undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT -#undef BOOST_MULTI_INDEX_SEQ_INDEX_CHECK_INVARIANT_OF - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index_fwd.hpp deleted file mode 100644 index a019f2a6d2f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/sequenced_index_fwd.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_SEQUENCED_INDEX_FWD_HPP -#define BOOST_MULTI_INDEX_SEQUENCED_INDEX_FWD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include - -namespace boost{ - -namespace multi_index{ - -namespace detail{ - -template -class sequenced_index; - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator==( - const sequenced_index& x, - const sequenced_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator<( - const sequenced_index& x, - const sequenced_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator!=( - const sequenced_index& x, - const sequenced_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator>( - const sequenced_index& x, - const sequenced_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator>=( - const sequenced_index& x, - const sequenced_index& y); - -template< - typename SuperMeta1,typename TagList1, - typename SuperMeta2,typename TagList2 -> -bool operator<=( - const sequenced_index& x, - const sequenced_index& y); - -template -void swap( - sequenced_index& x, - sequenced_index& y); - -} /* namespace multi_index::detail */ - -/* index specifiers */ - -template > -struct sequenced; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index/tag.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index/tag.hpp deleted file mode 100644 index ce51f8241ee..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index/tag.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_TAG_HPP -#define BOOST_MULTI_INDEX_TAG_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* A wrapper of mpl::vector used to hide MPL from the user. - * tag contains types used as tag names for indices in get() functions. - */ - -/* This user_definable macro limits the number of elements of a tag; - * useful for shortening resulting symbol names (MSVC++ 6.0, for instance, - * has problems coping with very long symbol names.) - */ - -#if !defined(BOOST_MULTI_INDEX_LIMIT_TAG_SIZE) -#define BOOST_MULTI_INDEX_LIMIT_TAG_SIZE BOOST_MPL_LIMIT_VECTOR_SIZE -#endif - -#if BOOST_MULTI_INDEX_LIMIT_TAG_SIZE -struct is_tag -{ - BOOST_STATIC_CONSTANT(bool,value=(is_base_and_derived::value)); -}; - -} /* namespace multi_index::detail */ - -template< - BOOST_PP_ENUM_BINARY_PARAMS( - BOOST_MULTI_INDEX_TAG_SIZE, - typename T, - =mpl::na BOOST_PP_INTERCEPT) -> -struct tag:private detail::tag_marker -{ - /* The mpl::transform pass produces shorter symbols (without - * trailing mpl::na's.) - */ - - typedef typename mpl::transform< - mpl::vector, - mpl::identity - >::type type; - - BOOST_STATIC_ASSERT(detail::no_duplicate_tags::value); -}; - -} /* namespace multi_index */ - -} /* namespace boost */ - -#undef BOOST_MULTI_INDEX_TAG_SIZE - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index_container.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index_container.hpp deleted file mode 100644 index 9993a8dfa10..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index_container.hpp +++ /dev/null @@ -1,1362 +0,0 @@ -/* Multiply indexed container. - * - * Copyright 2003-2014 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_HPP -#define BOOST_MULTI_INDEX_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) -#include -#endif - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -#include -#include -#include -#include -#include -#include -#include -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) -#include -#define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x) \ - detail::scope_guard BOOST_JOIN(check_invariant_,__LINE__)= \ - detail::make_obj_guard(x,&multi_index_container::check_invariant_); \ - BOOST_JOIN(check_invariant_,__LINE__).touch(); -#define BOOST_MULTI_INDEX_CHECK_INVARIANT \ - BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(*this) -#else -#define BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x) -#define BOOST_MULTI_INDEX_CHECK_INVARIANT -#endif - -namespace boost{ - -namespace multi_index{ - -#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500)) -#pragma warning(push) -#pragma warning(disable:4522) /* spurious warning on multiple operator=()'s */ -#endif - -template -class multi_index_container: - private ::boost::base_from_member< - typename boost::detail::allocator::rebind_to< - Allocator, - typename detail::multi_index_node_type< - Value,IndexSpecifierList,Allocator>::type - >::type>, - BOOST_MULTI_INDEX_PRIVATE_IF_MEMBER_TEMPLATE_FRIENDS detail::header_holder< - typename boost::detail::allocator::rebind_to< - Allocator, - typename detail::multi_index_node_type< - Value,IndexSpecifierList,Allocator>::type - >::type::pointer, - multi_index_container >, - public detail::multi_index_base_type< - Value,IndexSpecifierList,Allocator>::type -{ -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -/* The "ISO C++ Template Parser" option in CW8.3 has a problem with the - * lifetime of const references bound to temporaries --precisely what - * scopeguards are. - */ - -#pragma parse_mfunc_templ off -#endif - -private: - BOOST_COPYABLE_AND_MOVABLE(multi_index_container) - -#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) - template friend class detail::index_base; - template friend struct detail::header_holder; - template friend struct detail::converter; -#endif - - typedef typename detail::multi_index_base_type< - Value,IndexSpecifierList,Allocator>::type super; - typedef typename - boost::detail::allocator::rebind_to< - Allocator, - typename super::node_type - >::type node_allocator; - typedef ::boost::base_from_member< - node_allocator> bfm_allocator; - typedef detail::header_holder< - typename node_allocator::pointer, - multi_index_container> bfm_header; - - -public: - /* All types are inherited from super, a few are explicitly - * brought forward here to save us some typename's. - */ - - typedef typename super::ctor_args_list ctor_args_list; - typedef IndexSpecifierList index_specifier_type_list; - - typedef typename super::index_type_list index_type_list; - - typedef typename super::iterator_type_list iterator_type_list; - typedef typename super::const_iterator_type_list const_iterator_type_list; - typedef typename super::value_type value_type; - typedef typename super::final_allocator_type allocator_type; - typedef typename super::iterator iterator; - typedef typename super::const_iterator const_iterator; - - BOOST_STATIC_ASSERT( - detail::no_duplicate_tags_in_index_list::value); - - /* global project() needs to see this publicly */ - - typedef typename super::node_type node_type; - - /* construct/copy/destroy */ - - explicit multi_index_container( - -#if BOOST_WORKAROUND(__IBMCPP__,<=600) - /* VisualAge seems to have an ETI issue with the default values - * for arguments args_list and al. - */ - - const ctor_args_list& args_list= - typename mpl::identity::type:: - ctor_args_list(), - const allocator_type& al= - typename mpl::identity::type:: - allocator_type()): -#else - const ctor_args_list& args_list=ctor_args_list(), - const allocator_type& al=allocator_type()): -#endif - - bfm_allocator(al), - super(args_list,bfm_allocator::member), - node_count(0) - { - BOOST_MULTI_INDEX_CHECK_INVARIANT; - } - - explicit multi_index_container(const allocator_type& al): - bfm_allocator(al), - super(ctor_args_list(),bfm_allocator::member), - node_count(0) - { - BOOST_MULTI_INDEX_CHECK_INVARIANT; - } - - template - multi_index_container( - InputIterator first,InputIterator last, - -#if BOOST_WORKAROUND(__IBMCPP__,<=600) - /* VisualAge seems to have an ETI issue with the default values - * for arguments args_list and al. - */ - - const ctor_args_list& args_list= - typename mpl::identity::type:: - ctor_args_list(), - const allocator_type& al= - typename mpl::identity::type:: - allocator_type()): -#else - const ctor_args_list& args_list=ctor_args_list(), - const allocator_type& al=allocator_type()): -#endif - - bfm_allocator(al), - super(args_list,bfm_allocator::member), - node_count(0) - { - BOOST_MULTI_INDEX_CHECK_INVARIANT; - BOOST_TRY{ - iterator hint=super::end(); - for(;first!=last;++first){ - hint=super::make_iterator( - insert_ref_(*first,hint.get_node()).first); - ++hint; - } - } - BOOST_CATCH(...){ - clear_(); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - multi_index_container( - std::initializer_list list, - const ctor_args_list& args_list=ctor_args_list(), - const allocator_type& al=allocator_type()): - bfm_allocator(al), - super(args_list,bfm_allocator::member), - node_count(0) - { - BOOST_MULTI_INDEX_CHECK_INVARIANT; - BOOST_TRY{ - typedef const Value* init_iterator; - - iterator hint=super::end(); - for(init_iterator first=list.begin(),last=list.end(); - first!=last;++first){ - hint=super::make_iterator(insert_(*first,hint.get_node()).first); - ++hint; - } - } - BOOST_CATCH(...){ - clear_(); - BOOST_RETHROW; - } - BOOST_CATCH_END - } -#endif - - multi_index_container( - const multi_index_container& x): - bfm_allocator(x.bfm_allocator::member), - bfm_header(), - super(x), - node_count(0) - { - copy_map_type map(bfm_allocator::member,x.size(),x.header(),header()); - for(const_iterator it=x.begin(),it_end=x.end();it!=it_end;++it){ - map.clone(it.get_node()); - } - super::copy_(x,map); - map.release(); - node_count=x.size(); - - /* Not until this point are the indices required to be consistent, - * hence the position of the invariant checker. - */ - - BOOST_MULTI_INDEX_CHECK_INVARIANT; - } - - multi_index_container(BOOST_RV_REF(multi_index_container) x): - bfm_allocator(x.bfm_allocator::member), - bfm_header(), - super(x,detail::do_not_copy_elements_tag()), - node_count(0) - { - BOOST_MULTI_INDEX_CHECK_INVARIANT; - BOOST_MULTI_INDEX_CHECK_INVARIANT_OF(x); - swap_elements_(x); - } - - ~multi_index_container() - { - delete_all_nodes_(); - } - -#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - /* As per http://www.boost.org/doc/html/move/emulation_limitations.html - * #move.emulation_limitations.assignment_operator - */ - - multi_index_container& operator=( - const multi_index_container& x) - { - multi_index_container y(x); - this->swap(y); - return *this; - } -#endif - - multi_index_container& operator=( - BOOST_COPY_ASSIGN_REF(multi_index_container) x) - { - multi_index_container y(x); - this->swap(y); - return *this; - } - - multi_index_container& operator=( - BOOST_RV_REF(multi_index_container) x) - { - this->swap(x); - return *this; - } - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - multi_index_container& operator=( - std::initializer_list list) - { - BOOST_MULTI_INDEX_CHECK_INVARIANT; - typedef const Value* init_iterator; - - multi_index_container x(*this,detail::do_not_copy_elements_tag()); - iterator hint=x.end(); - for(init_iterator first=list.begin(),last=list.end(); - first!=last;++first){ - hint=x.make_iterator(x.insert_(*first,hint.get_node()).first); - ++hint; - } - x.swap_elements_(*this); - return*this; - } -#endif - - allocator_type get_allocator()const BOOST_NOEXCEPT - { - return allocator_type(bfm_allocator::member); - } - - /* retrieval of indices by number */ - -#if !defined(BOOST_NO_MEMBER_TEMPLATES) - template - struct nth_index - { - BOOST_STATIC_ASSERT(N>=0&&N::type::value); - typedef typename mpl::at_c::type type; - }; - - template - typename nth_index::type& get()BOOST_NOEXCEPT - { - BOOST_STATIC_ASSERT(N>=0&&N::type::value); - return *this; - } - - template - const typename nth_index::type& get()const BOOST_NOEXCEPT - { - BOOST_STATIC_ASSERT(N>=0&&N::type::value); - return *this; - } -#endif - - /* retrieval of indices by tag */ - -#if !defined(BOOST_NO_MEMBER_TEMPLATES) - template - struct index - { - typedef typename mpl::find_if< - index_type_list, - detail::has_tag - >::type iter; - - BOOST_STATIC_CONSTANT( - bool,index_found=!(is_same::type >::value)); - BOOST_STATIC_ASSERT(index_found); - - typedef typename mpl::deref::type type; - }; - - template - typename index::type& get()BOOST_NOEXCEPT - { - return *this; - } - - template - const typename index::type& get()const BOOST_NOEXCEPT - { - return *this; - } -#endif - - /* projection of iterators by number */ - -#if !defined(BOOST_NO_MEMBER_TEMPLATES) - template - struct nth_index_iterator - { - typedef typename nth_index::type::iterator type; - }; - - template - struct nth_index_const_iterator - { - typedef typename nth_index::type::const_iterator type; - }; - - template - typename nth_index_iterator::type project(IteratorType it) - { - typedef typename nth_index::type index_type; - -#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ - BOOST_STATIC_ASSERT( - (mpl::contains::value)); -#endif - - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); - BOOST_MULTI_INDEX_CHECK_IS_OWNER( - it,static_cast(*this)); - - return index_type::make_iterator(static_cast(it.get_node())); - } - - template - typename nth_index_const_iterator::type project(IteratorType it)const - { - typedef typename nth_index::type index_type; - -#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ - BOOST_STATIC_ASSERT(( - mpl::contains::value|| - mpl::contains::value)); -#endif - - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); - BOOST_MULTI_INDEX_CHECK_IS_OWNER( - it,static_cast(*this)); - return index_type::make_iterator(static_cast(it.get_node())); - } -#endif - - /* projection of iterators by tag */ - -#if !defined(BOOST_NO_MEMBER_TEMPLATES) - template - struct index_iterator - { - typedef typename index::type::iterator type; - }; - - template - struct index_const_iterator - { - typedef typename index::type::const_iterator type; - }; - - template - typename index_iterator::type project(IteratorType it) - { - typedef typename index::type index_type; - -#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ - BOOST_STATIC_ASSERT( - (mpl::contains::value)); -#endif - - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); - BOOST_MULTI_INDEX_CHECK_IS_OWNER( - it,static_cast(*this)); - return index_type::make_iterator(static_cast(it.get_node())); - } - - template - typename index_const_iterator::type project(IteratorType it)const - { - typedef typename index::type index_type; - -#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* fails in Sun C++ 5.7 */ - BOOST_STATIC_ASSERT(( - mpl::contains::value|| - mpl::contains::value)); -#endif - - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); - BOOST_MULTI_INDEX_CHECK_IS_OWNER( - it,static_cast(*this)); - return index_type::make_iterator(static_cast(it.get_node())); - } -#endif - -BOOST_MULTI_INDEX_PROTECTED_IF_MEMBER_TEMPLATE_FRIENDS: - typedef typename super::copy_map_type copy_map_type; - -#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) - multi_index_container( - const multi_index_container& x, - detail::do_not_copy_elements_tag): - bfm_allocator(x.bfm_allocator::member), - bfm_header(), - super(x,detail::do_not_copy_elements_tag()), - node_count(0) - { - BOOST_MULTI_INDEX_CHECK_INVARIANT; - } -#endif - - node_type* header()const - { - return &*bfm_header::member; - } - - node_type* allocate_node() - { - return &*bfm_allocator::member.allocate(1); - } - - void deallocate_node(node_type* x) - { - typedef typename node_allocator::pointer node_pointer; - bfm_allocator::member.deallocate(static_cast(x),1); - } - - bool empty_()const - { - return node_count==0; - } - - std::size_t size_()const - { - return node_count; - } - - std::size_t max_size_()const - { - return static_cast(-1); - } - - template - std::pair insert_(const Value& v,Variant variant) - { - node_type* x=0; - node_type* res=super::insert_(v,x,variant); - if(res==x){ - ++node_count; - return std::pair(res,true); - } - else{ - return std::pair(res,false); - } - } - - std::pair insert_(const Value& v) - { - return insert_(v,detail::lvalue_tag()); - } - - std::pair insert_rv_(const Value& v) - { - return insert_(v,detail::rvalue_tag()); - } - - template - std::pair insert_ref_(T& t) - { - node_type* x=allocate_node(); - BOOST_TRY{ - new(&x->value()) value_type(t); - BOOST_TRY{ - node_type* res=super::insert_(x->value(),x,detail::emplaced_tag()); - if(res==x){ - ++node_count; - return std::pair(res,true); - } - else{ - boost::detail::allocator::destroy(&x->value()); - deallocate_node(x); - return std::pair(res,false); - } - } - BOOST_CATCH(...){ - boost::detail::allocator::destroy(&x->value()); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - BOOST_CATCH(...){ - deallocate_node(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - std::pair insert_ref_(const value_type& x) - { - return insert_(x); - } - - std::pair insert_ref_(value_type& x) - { - return insert_(x); - } - - template - std::pair emplace_( - BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - node_type* x=allocate_node(); - BOOST_TRY{ - detail::vartempl_placement_new( - &x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - BOOST_TRY{ - node_type* res=super::insert_(x->value(),x,detail::emplaced_tag()); - if(res==x){ - ++node_count; - return std::pair(res,true); - } - else{ - boost::detail::allocator::destroy(&x->value()); - deallocate_node(x); - return std::pair(res,false); - } - } - BOOST_CATCH(...){ - boost::detail::allocator::destroy(&x->value()); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - BOOST_CATCH(...){ - deallocate_node(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - template - std::pair insert_( - const Value& v,node_type* position,Variant variant) - { - node_type* x=0; - node_type* res=super::insert_(v,position,x,variant); - if(res==x){ - ++node_count; - return std::pair(res,true); - } - else{ - return std::pair(res,false); - } - } - - std::pair insert_(const Value& v,node_type* position) - { - return insert_(v,position,detail::lvalue_tag()); - } - - std::pair insert_rv_(const Value& v,node_type* position) - { - return insert_(v,position,detail::rvalue_tag()); - } - - template - std::pair insert_ref_( - T& t,node_type* position) - { - node_type* x=allocate_node(); - BOOST_TRY{ - new(&x->value()) value_type(t); - BOOST_TRY{ - node_type* res=super::insert_( - x->value(),position,x,detail::emplaced_tag()); - if(res==x){ - ++node_count; - return std::pair(res,true); - } - else{ - boost::detail::allocator::destroy(&x->value()); - deallocate_node(x); - return std::pair(res,false); - } - } - BOOST_CATCH(...){ - boost::detail::allocator::destroy(&x->value()); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - BOOST_CATCH(...){ - deallocate_node(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - std::pair insert_ref_( - const value_type& x,node_type* position) - { - return insert_(x,position); - } - - std::pair insert_ref_( - value_type& x,node_type* position) - { - return insert_(x,position); - } - - template - std::pair emplace_hint_( - node_type* position, - BOOST_MULTI_INDEX_FUNCTION_PARAM_PACK) - { - node_type* x=allocate_node(); - BOOST_TRY{ - detail::vartempl_placement_new( - &x->value(),BOOST_MULTI_INDEX_FORWARD_PARAM_PACK); - BOOST_TRY{ - node_type* res=super::insert_( - x->value(),position,x,detail::emplaced_tag()); - if(res==x){ - ++node_count; - return std::pair(res,true); - } - else{ - boost::detail::allocator::destroy(&x->value()); - deallocate_node(x); - return std::pair(res,false); - } - } - BOOST_CATCH(...){ - boost::detail::allocator::destroy(&x->value()); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - BOOST_CATCH(...){ - deallocate_node(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - void erase_(node_type* x) - { - --node_count; - super::erase_(x); - deallocate_node(x); - } - - void delete_node_(node_type* x) - { - super::delete_node_(x); - deallocate_node(x); - } - - void delete_all_nodes_() - { - super::delete_all_nodes_(); - } - - void clear_() - { - delete_all_nodes_(); - super::clear_(); - node_count=0; - } - - void swap_(multi_index_container& x) - { - if(bfm_allocator::member!=x.bfm_allocator::member){ - detail::adl_swap(bfm_allocator::member,x.bfm_allocator::member); - } - std::swap(bfm_header::member,x.bfm_header::member); - super::swap_(x); - std::swap(node_count,x.node_count); - } - - void swap_elements_( - multi_index_container& x) - { - std::swap(bfm_header::member,x.bfm_header::member); - super::swap_elements_(x); - std::swap(node_count,x.node_count); - } - - bool replace_(const Value& k,node_type* x) - { - return super::replace_(k,x,detail::lvalue_tag()); - } - - bool replace_rv_(const Value& k,node_type* x) - { - return super::replace_(k,x,detail::rvalue_tag()); - } - - template - bool modify_(Modifier& mod,node_type* x) - { - mod(const_cast(x->value())); - - BOOST_TRY{ - if(!super::modify_(x)){ - deallocate_node(x); - --node_count; - return false; - } - else return true; - } - BOOST_CATCH(...){ - deallocate_node(x); - --node_count; - BOOST_RETHROW; - } - BOOST_CATCH_END - } - - template - bool modify_(Modifier& mod,Rollback& back_,node_type* x) - { - mod(const_cast(x->value())); - - bool b; - BOOST_TRY{ - b=super::modify_rollback_(x); - } - BOOST_CATCH(...){ - BOOST_TRY{ - back_(const_cast(x->value())); - BOOST_RETHROW; - } - BOOST_CATCH(...){ - this->erase_(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - BOOST_CATCH_END - - BOOST_TRY{ - if(!b){ - back_(const_cast(x->value())); - return false; - } - else return true; - } - BOOST_CATCH(...){ - this->erase_(x); - BOOST_RETHROW; - } - BOOST_CATCH_END - } - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) - /* serialization */ - - friend class boost::serialization::access; - - BOOST_SERIALIZATION_SPLIT_MEMBER() - - typedef typename super::index_saver_type index_saver_type; - typedef typename super::index_loader_type index_loader_type; - - template - void save(Archive& ar,const unsigned int version)const - { - const serialization::collection_size_type s(size_()); - const detail::serialization_version value_version; - ar< - void load(Archive& ar,const unsigned int version) - { - BOOST_MULTI_INDEX_CHECK_INVARIANT; - - clear_(); - serialization::collection_size_type s; - detail::serialization_version value_version; - if(version<1){ - std::size_t sz; - ar>>serialization::make_nvp("count",sz); - s=static_cast(sz); - } - else{ - ar>>serialization::make_nvp("count",s); - } - if(version<2){ - value_version=0; - } - else{ - ar>>serialization::make_nvp("value_version",value_version); - } - - index_loader_type lm(bfm_allocator::member,s); - - for(std::size_t n=0;n value("item",ar,value_version); - std::pair p=insert_( - value.get(),super::end().get_node()); - if(!p.second)throw_exception( - archive::archive_exception( - archive::archive_exception::other_exception)); - ar.reset_object_address(&p.first->value(),&value.get()); - lm.add(p.first,ar,version); - } - lm.add_track(header(),ar,version); - - super::load_(ar,version,lm); - } -#endif - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING) - /* invariant stuff */ - - bool invariant_()const - { - return super::invariant_(); - } - - void check_invariant_()const - { - BOOST_MULTI_INDEX_INVARIANT_ASSERT(invariant_()); - } -#endif - -private: - std::size_t node_count; - -#if defined(BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING)&&\ - BOOST_WORKAROUND(__MWERKS__,<=0x3003) -#pragma parse_mfunc_templ reset -#endif -}; - -#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500)) -#pragma warning(pop) /* C4522 */ -#endif - -/* retrieval of indices by number */ - -template -struct nth_index -{ - BOOST_STATIC_CONSTANT( - int, - M=mpl::size::type::value); - BOOST_STATIC_ASSERT(N>=0&&N::type type; -}; - -template -typename nth_index< - multi_index_container,N>::type& -get( - multi_index_container& m)BOOST_NOEXCEPT -{ - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> multi_index_type; - typedef typename nth_index< - multi_index_container< - Value,IndexSpecifierList,Allocator>, - N - >::type index_type; - - BOOST_STATIC_ASSERT(N>=0&& - N< - mpl::size< - BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list - >::type::value); - - return detail::converter::index(m); -} - -template -const typename nth_index< - multi_index_container,N>::type& -get( - const multi_index_container& m -)BOOST_NOEXCEPT -{ - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> multi_index_type; - typedef typename nth_index< - multi_index_container< - Value,IndexSpecifierList,Allocator>, - N - >::type index_type; - - BOOST_STATIC_ASSERT(N>=0&& - N< - mpl::size< - BOOST_DEDUCED_TYPENAME multi_index_type::index_type_list - >::type::value); - - return detail::converter::index(m); -} - -/* retrieval of indices by tag */ - -template -struct index -{ - typedef typename MultiIndexContainer::index_type_list index_type_list; - - typedef typename mpl::find_if< - index_type_list, - detail::has_tag - >::type iter; - - BOOST_STATIC_CONSTANT( - bool,index_found=!(is_same::type >::value)); - BOOST_STATIC_ASSERT(index_found); - - typedef typename mpl::deref::type type; -}; - -template< - typename Tag,typename Value,typename IndexSpecifierList,typename Allocator -> -typename ::boost::multi_index::index< - multi_index_container,Tag>::type& -get( - multi_index_container& m)BOOST_NOEXCEPT -{ - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> multi_index_type; - typedef typename ::boost::multi_index::index< - multi_index_container< - Value,IndexSpecifierList,Allocator>, - Tag - >::type index_type; - - return detail::converter::index(m); -} - -template< - typename Tag,typename Value,typename IndexSpecifierList,typename Allocator -> -const typename ::boost::multi_index::index< - multi_index_container,Tag>::type& -get( - const multi_index_container& m -)BOOST_NOEXCEPT -{ - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> multi_index_type; - typedef typename ::boost::multi_index::index< - multi_index_container< - Value,IndexSpecifierList,Allocator>, - Tag - >::type index_type; - - return detail::converter::index(m); -} - -/* projection of iterators by number */ - -template -struct nth_index_iterator -{ - typedef typename nth_index::type::iterator type; -}; - -template -struct nth_index_const_iterator -{ - typedef typename nth_index::type::const_iterator type; -}; - -template< - int N,typename IteratorType, - typename Value,typename IndexSpecifierList,typename Allocator> -typename nth_index_iterator< - multi_index_container,N>::type -project( - multi_index_container& m, - IteratorType it) -{ - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> multi_index_type; - typedef typename nth_index::type index_type; - -#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */ - BOOST_STATIC_ASSERT(( - mpl::contains< - BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list, - IteratorType>::value)); -#endif - - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef detail::converter< - multi_index_type, - BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter; - BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m)); -#endif - - return detail::converter::iterator( - m,static_cast(it.get_node())); -} - -template< - int N,typename IteratorType, - typename Value,typename IndexSpecifierList,typename Allocator> -typename nth_index_const_iterator< - multi_index_container,N>::type -project( - const multi_index_container& m, - IteratorType it) -{ - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> multi_index_type; - typedef typename nth_index::type index_type; - -#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */ - BOOST_STATIC_ASSERT(( - mpl::contains< - BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list, - IteratorType>::value|| - mpl::contains< - BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list, - IteratorType>::value)); -#endif - - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef detail::converter< - multi_index_type, - BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter; - BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m)); -#endif - - return detail::converter::const_iterator( - m,static_cast(it.get_node())); -} - -/* projection of iterators by tag */ - -template -struct index_iterator -{ - typedef typename ::boost::multi_index::index< - MultiIndexContainer,Tag>::type::iterator type; -}; - -template -struct index_const_iterator -{ - typedef typename ::boost::multi_index::index< - MultiIndexContainer,Tag>::type::const_iterator type; -}; - -template< - typename Tag,typename IteratorType, - typename Value,typename IndexSpecifierList,typename Allocator> -typename index_iterator< - multi_index_container,Tag>::type -project( - multi_index_container& m, - IteratorType it) -{ - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> multi_index_type; - typedef typename ::boost::multi_index::index< - multi_index_type,Tag>::type index_type; - -#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */ - BOOST_STATIC_ASSERT(( - mpl::contains< - BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list, - IteratorType>::value)); -#endif - - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef detail::converter< - multi_index_type, - BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter; - BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m)); -#endif - - return detail::converter::iterator( - m,static_cast(it.get_node())); -} - -template< - typename Tag,typename IteratorType, - typename Value,typename IndexSpecifierList,typename Allocator> -typename index_const_iterator< - multi_index_container,Tag>::type -project( - const multi_index_container& m, - IteratorType it) -{ - typedef multi_index_container< - Value,IndexSpecifierList,Allocator> multi_index_type; - typedef typename ::boost::multi_index::index< - multi_index_type,Tag>::type index_type; - -#if !defined(__SUNPRO_CC)||!(__SUNPRO_CC<0x580) /* Sun C++ 5.7 fails */ - BOOST_STATIC_ASSERT(( - mpl::contains< - BOOST_DEDUCED_TYPENAME multi_index_type::iterator_type_list, - IteratorType>::value|| - mpl::contains< - BOOST_DEDUCED_TYPENAME multi_index_type::const_iterator_type_list, - IteratorType>::value)); -#endif - - BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(it); - -#if defined(BOOST_MULTI_INDEX_ENABLE_SAFE_MODE) - typedef detail::converter< - multi_index_type, - BOOST_DEDUCED_TYPENAME IteratorType::container_type> converter; - BOOST_MULTI_INDEX_CHECK_IS_OWNER(it,converter::index(m)); -#endif - - return detail::converter::const_iterator( - m,static_cast(it.get_node())); -} - -/* Comparison. Simple forward to first index. */ - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator==( - const multi_index_container& x, - const multi_index_container& y) -{ - return get<0>(x)==get<0>(y); -} - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator<( - const multi_index_container& x, - const multi_index_container& y) -{ - return get<0>(x)(y); -} - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator!=( - const multi_index_container& x, - const multi_index_container& y) -{ - return get<0>(x)!=get<0>(y); -} - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator>( - const multi_index_container& x, - const multi_index_container& y) -{ - return get<0>(x)>get<0>(y); -} - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator>=( - const multi_index_container& x, - const multi_index_container& y) -{ - return get<0>(x)>=get<0>(y); -} - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator<=( - const multi_index_container& x, - const multi_index_container& y) -{ - return get<0>(x)<=get<0>(y); -} - -/* specialized algorithms */ - -template -void swap( - multi_index_container& x, - multi_index_container& y) -{ - x.swap(y); -} - -} /* namespace multi_index */ - -#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) -/* class version = 1 : we now serialize the size through - * boost::serialization::collection_size_type. - * class version = 2 : proper use of {save|load}_construct_data. - */ - -namespace serialization { -template -struct version< - boost::multi_index_container -> -{ - BOOST_STATIC_CONSTANT(int,value=2); -}; -} /* namespace serialization */ -#endif - -/* Associated global functions are promoted to namespace boost, except - * comparison operators and swap, which are meant to be Koenig looked-up. - */ - -using multi_index::get; -using multi_index::project; - -} /* namespace boost */ - -#undef BOOST_MULTI_INDEX_CHECK_INVARIANT -#undef BOOST_MULTI_INDEX_CHECK_INVARIANT_OF - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/multi_index_container_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/multi_index_container_fwd.hpp deleted file mode 100644 index b35acad407a..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/multi_index_container_fwd.hpp +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright 2003-2013 Joaquin M Lopez Munoz. - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE_1_0.txt or copy at - * http://www.boost.org/LICENSE_1_0.txt) - * - * See http://www.boost.org/libs/multi_index for library home page. - */ - -#ifndef BOOST_MULTI_INDEX_FWD_HPP -#define BOOST_MULTI_INDEX_FWD_HPP - -#if defined(_MSC_VER) -#pragma once -#endif - -#include /* keep it first to prevent nasty warns in MSVC */ -#include -#include -#include -#include - -namespace boost{ - -namespace multi_index{ - -/* Default value for IndexSpecifierList specifies a container - * equivalent to std::set. - */ - -template< - typename Value, - typename IndexSpecifierList=indexed_by > >, - typename Allocator=std::allocator > -class multi_index_container; - -template -struct nth_index; - -template -struct index; - -template -struct nth_index_iterator; - -template -struct nth_index_const_iterator; - -template -struct index_iterator; - -template -struct index_const_iterator; - -/* get and project functions not fwd declared due to problems - * with dependent typenames - */ - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator==( - const multi_index_container& x, - const multi_index_container& y); - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator<( - const multi_index_container& x, - const multi_index_container& y); - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator!=( - const multi_index_container& x, - const multi_index_container& y); - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator>( - const multi_index_container& x, - const multi_index_container& y); - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator>=( - const multi_index_container& x, - const multi_index_container& y); - -template< - typename Value1,typename IndexSpecifierList1,typename Allocator1, - typename Value2,typename IndexSpecifierList2,typename Allocator2 -> -bool operator<=( - const multi_index_container& x, - const multi_index_container& y); - -template -void swap( - multi_index_container& x, - multi_index_container& y); - -} /* namespace multi_index */ - -/* multi_index_container, being the main type of this library, is promoted to - * namespace boost. - */ - -using multi_index::multi_index_container; - -} /* namespace boost */ - -#endif diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/access.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/access.hpp deleted file mode 100644 index f6581accc91..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/access.hpp +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ACCESS_HPP -#define BOOST_SERIALIZATION_ACCESS_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// access.hpp: interface for serialization system. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -namespace boost { - -namespace archive { -namespace detail { - template - class iserializer; - template - class oserializer; -} // namespace detail -} // namespace archive - -namespace serialization { - -// forward declarations -template -inline void serialize_adl(Archive &, T &, const unsigned int); -namespace detail { - template - struct member_saver; - template - struct member_loader; -} // namespace detail - -// use an "accessor class so that we can use: -// "friend class boost::serialization::access;" -// in any serialized class to permit clean, safe access to private class members -// by the serialization system - -class access { -public: - // grant access to "real" serialization defaults -#ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -public: -#else - template - friend struct detail::member_saver; - template - friend struct detail::member_loader; - template - friend class archive::detail::iserializer; - template - friend class archive::detail::oserializer; - template - friend inline void serialize( - Archive & ar, - T & t, - const unsigned int file_version - ); - template - friend inline void save_construct_data( - Archive & ar, - const T * t, - const unsigned int file_version - ); - template - friend inline void load_construct_data( - Archive & ar, - T * t, - const unsigned int file_version - ); -#endif - - // pass calls to users's class implementation - template - static void member_save( - Archive & ar, - //const T & t, - T & t, - const unsigned int file_version - ){ - t.save(ar, file_version); - } - template - static void member_load( - Archive & ar, - T & t, - const unsigned int file_version - ){ - t.load(ar, file_version); - } - template - static void serialize( - Archive & ar, - T & t, - const unsigned int file_version - ){ - // note: if you get a compile time error here with a - // message something like: - // cannot convert parameter 1 from to - // a likely possible cause is that the class T contains a - // serialize function - but that serialize function isn't - // a template and corresponds to a file type different than - // the class Archive. To resolve this, don't include an - // archive type other than that for which the serialization - // function is defined!!! - t.serialize(ar, file_version); - } - template - static void destroy( const T * t) // const appropriate here? - { - // the const business is an MSVC 6.0 hack that should be - // benign on everything else - delete const_cast(t); - } - template - static void construct(T * t){ - // default is inplace invocation of default constructor - // Note the :: before the placement new. Required if the - // class doesn't have a class-specific placement new defined. - ::new(t)T; - } - template - static T & cast_reference(U & u){ - return static_cast(u); - } - template - static T * cast_pointer(U * u){ - return static_cast(u); - } -}; - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_ACCESS_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_map.hpp deleted file mode 100644 index ccf806b1813..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_map.hpp +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_MAP_HPP -#define BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_MAP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization/unordered_map.hpp: -// serialization for stl unordered_map templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2014 Jim Bell -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { -namespace stl { - -// map input -template -struct archive_input_unordered_map -{ - inline void operator()( - Archive &ar, - Container &s, - const unsigned int v - ){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, v); - ar >> boost::serialization::make_nvp("item", t.reference()); - std::pair result = - s.insert(boost::move(t.reference())); - // note: the following presumes that the map::value_type was NOT tracked - // in the archive. This is the usual case, but here there is no way - // to determine that. - if(result.second){ - ar.reset_object_address( - & (result.first->second), - & t.reference().second - ); - } - } -}; - -// multimap input -template -struct archive_input_unordered_multimap -{ - inline void operator()( - Archive &ar, - Container &s, - const unsigned int v - ){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, v); - ar >> boost::serialization::make_nvp("item", t.reference()); - typename Container::const_iterator result = - s.insert(t.reference()); - // note: the following presumes that the map::value_type was NOT tracked - // in the archive. This is the usual case, but here there is no way - // to determine that. - ar.reset_object_address( - & result->second, - & t.reference() - ); - } -}; - -} // stl -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_set.hpp deleted file mode 100644 index 7f0003cc6a4..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/archive_input_unordered_set.hpp +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_SET_HPP -#define BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_SET_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// archive_input_unordered_set.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2014 Jim Bell -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -namespace stl { - -// unordered_set input -template -struct archive_input_unordered_set -{ - inline void operator()( - Archive &ar, - Container &s, - const unsigned int v - ){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, v); - // borland fails silently w/o full namespace - ar >> boost::serialization::make_nvp("item", t.reference()); - std::pair result = - s.insert(boost::move(t.reference())); - if(result.second) - ar.reset_object_address(& (* result.first), & t.reference()); - } -}; - -// unordered_multiset input -template -struct archive_input_unordered_multiset -{ - inline void operator()( - Archive &ar, - Container &s, - const unsigned int v - ){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, v); - ar >> boost::serialization::make_nvp("item", t.reference()); - typename Container::const_iterator result = - s.insert(boost::move(t.reference())); - ar.reset_object_address(& (* result), & t.reference()); - } -}; - -} // stl -} // serialization -} // boost - -#endif // BOOST_SERIALIZATION_ARCHIVE_INPUT_UNORDERED_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/array.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/array.hpp deleted file mode 100644 index 612d1a61985..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/array.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ARRAY_HPP -#define BOOST_SERIALIZATION_ARRAY_HPP - -// (C) Copyright 2005 Matthias Troyer and Dave Abrahams -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// for serialization of . If not supported by the standard -// library - this file becomes empty. This is to avoid breaking backward -// compatibiliy for applications which used this header to support -// serialization of native arrays. Code to serialize native arrays is -// now always include by default. RR - -#include // msvc 6.0 needs this for warning suppression - -#if defined(BOOST_NO_STDC_NAMESPACE) - -#include -#include // std::size_t -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include - -#ifndef BOOST_NO_CXX11_HDR_ARRAY - -#include -#include - -namespace boost { namespace serialization { - -template -void serialize(Archive& ar, std::array& a, const unsigned int /* version */) -{ - ar & boost::serialization::make_nvp( - "elems", - *static_cast(static_cast(a.data())) - ); - -} -} } // end namespace boost::serialization - -#endif // BOOST_NO_CXX11_HDR_ARRAY - -#endif //BOOST_SERIALIZATION_ARRAY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/array_optimization.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/array_optimization.hpp deleted file mode 100644 index 40dffba871a..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/array_optimization.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ARRAY_OPTIMIZATON_HPP -#define BOOST_SERIALIZATION_ARRAY_OPTIMIZATON_HPP - -// (C) Copyright 2005 Matthias Troyer and Dave Abrahams -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include // msvc 6.0 needs this for warning suppression - -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include -#include -#include - -namespace boost { namespace serialization { - -template -struct use_array_optimization : boost::mpl::always {}; - -} } // end namespace boost::serialization - -#define BOOST_SERIALIZATION_USE_ARRAY_OPTIMIZATION(Archive) \ -namespace boost { namespace serialization { \ -template <> struct use_array_optimization { \ - template \ - struct apply : boost::mpl::apply1::type \ - >::type {}; \ -}; }} - -#endif //BOOST_SERIALIZATION_ARRAY_OPTIMIZATON_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/array_wrapper.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/array_wrapper.hpp deleted file mode 100644 index adf436e15b4..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/array_wrapper.hpp +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ARRAY_WRAPPER_HPP -#define BOOST_SERIALIZATION_ARRAY_WRAPPER_HPP - -// (C) Copyright 2005 Matthias Troyer and Dave Abrahams -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -//#include - -#include // msvc 6.0 needs this for warning suppression - -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { namespace serialization { - -template -class array_wrapper : - public wrapper_traits > -{ -private: - array_wrapper & operator=(const array_wrapper & rhs); - // note: I would like to make the copy constructor private but this breaks - // make_array. So I make make_array a friend - template - friend const boost::serialization::array_wrapper make_array(Tx * t, S s); -public: - - array_wrapper(const array_wrapper & rhs) : - m_t(rhs.m_t), - m_element_count(rhs.m_element_count) - {} -public: - array_wrapper(T * t, std::size_t s) : - m_t(t), - m_element_count(s) - {} - - // default implementation - template - void serialize_optimized(Archive &ar, const unsigned int, mpl::false_ ) const - { - // default implemention does the loop - std::size_t c = count(); - T * t = address(); - while(0 < c--) - ar & boost::serialization::make_nvp("item", *t++); - } - - // optimized implementation - template - void serialize_optimized(Archive &ar, const unsigned int version, mpl::true_ ) - { - boost::serialization::split_member(ar, *this, version); - } - - // default implementation - template - void save(Archive &ar, const unsigned int version) const - { - ar.save_array(*this,version); - } - - // default implementation - template - void load(Archive &ar, const unsigned int version) - { - ar.load_array(*this,version); - } - - // default implementation - template - void serialize(Archive &ar, const unsigned int version) - { - typedef typename - boost::serialization::use_array_optimization::template apply< - typename remove_const< T >::type - >::type use_optimized; - serialize_optimized(ar,version,use_optimized()); - } - - T * address() const - { - return m_t; - } - - std::size_t count() const - { - return m_element_count; - } - -private: - T * const m_t; - const std::size_t m_element_count; -}; - -template -inline -const array_wrapper< T > make_array(T* t, S s){ - const array_wrapper< T > a(t, s); - return a; -} - -} } // end namespace boost::serialization - - -#endif //BOOST_SERIALIZATION_ARRAY_WRAPPER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/assume_abstract.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/assume_abstract.hpp deleted file mode 100644 index 632f9312f5f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/assume_abstract.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP -#define BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// assume_abstract_class.hpp: - -// (C) Copyright 2008 Robert Ramey -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// this is useful for compilers which don't support the boost::is_abstract - -#include -#include - -#ifndef BOOST_NO_IS_ABSTRACT - -// if there is an intrinsic is_abstract defined, we don't have to do anything -#define BOOST_SERIALIZATION_ASSUME_ABSTRACT(T) - -// but forward to the "official" is_abstract -namespace boost { -namespace serialization { - template - struct is_abstract : boost::is_abstract< T > {} ; -} // namespace serialization -} // namespace boost - -#else -// we have to "make" one - -namespace boost { -namespace serialization { - template - struct is_abstract : boost::false_type {}; -} // namespace serialization -} // namespace boost - -// define a macro to make explicit designation of this more transparent -#define BOOST_SERIALIZATION_ASSUME_ABSTRACT(T) \ -namespace boost { \ -namespace serialization { \ -template<> \ -struct is_abstract< T > : boost::true_type {}; \ -template<> \ -struct is_abstract< const T > : boost::true_type {}; \ -}} \ -/**/ - -#endif // BOOST_NO_IS_ABSTRACT - -#endif //BOOST_SERIALIZATION_ASSUME_ABSTRACT_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/base_object.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/base_object.hpp deleted file mode 100644 index 1a82cecd4b5..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/base_object.hpp +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef BOOST_SERIALIZATION_BASE_OBJECT_HPP -#define BOOST_SERIALIZATION_BASE_OBJECT_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// base_object.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// if no archive headers have been included this is a no op -// this is to permit BOOST_EXPORT etc to be included in a -// file declaration header - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -namespace detail -{ - // get the base type for a given derived type - // preserving the const-ness - template - struct base_cast - { - typedef typename - mpl::if_< - is_const, - const B, - B - >::type type; - BOOST_STATIC_ASSERT(is_const::value == is_const::value); - }; - - // only register void casts if the types are polymorphic - template - struct base_register - { - struct polymorphic { - static void const * invoke(){ - Base const * const b = 0; - Derived const * const d = 0; - return & void_cast_register(d, b); - } - }; - struct non_polymorphic { - static void const * invoke(){ - return 0; - } - }; - static void const * invoke(){ - typedef typename mpl::eval_if< - is_polymorphic, - mpl::identity, - mpl::identity - >::type type; - return type::invoke(); - } - }; - -} // namespace detail -template -typename detail::base_cast::type & -base_object(Derived &d) -{ - BOOST_STATIC_ASSERT(( is_base_and_derived::value)); - BOOST_STATIC_ASSERT(! is_pointer::value); - typedef typename detail::base_cast::type type; - detail::base_register::invoke(); - return access::cast_reference(d); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_BASE_OBJECT_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/binary_object.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/binary_object.hpp deleted file mode 100644 index 5c9038e5a9f..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/binary_object.hpp +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef BOOST_SERIALIZATION_BINARY_OBJECT_HPP -#define BOOST_SERIALIZATION_BINARY_OBJECT_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// nvp.hpp: interface for serialization system. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include // std::size_t -#include -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -struct binary_object : - public wrapper_traits > -{ - void const * m_t; - std::size_t m_size; - template - void save(Archive & ar, const unsigned int /* file_version */) const { - ar.save_binary(m_t, m_size); - } - template - void load(Archive & ar, const unsigned int /* file_version */) const { - ar.load_binary(const_cast(m_t), m_size); - } - BOOST_SERIALIZATION_SPLIT_MEMBER() - binary_object & operator=(const binary_object & rhs) { - m_t = rhs.m_t; - m_size = rhs.m_size; - return *this; - } - binary_object(const void * const t, std::size_t size) : - m_t(t), - m_size(size) - {} - binary_object(const binary_object & rhs) : - m_t(rhs.m_t), - m_size(rhs.m_size) - {} -}; - -// just a little helper to support the convention that all serialization -// wrappers follow the naming convention make_xxxxx -inline -const binary_object -make_binary_object(const void * t, std::size_t size){ - return binary_object(t, size); -} - -} // namespace serialization -} // boost - -#endif // BOOST_SERIALIZATION_BINARY_OBJECT_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/bitset.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/bitset.hpp deleted file mode 100644 index 78f9bd74336..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/bitset.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/*! - * \file bitset.hpp - * \brief Provides Boost.Serialization support for std::bitset - * \author Brian Ravnsgaard Riis - * \author Kenneth Riddile - * \date 16.09.2004, updated 04.03.2009 - * \copyright 2004 Brian Ravnsgaard Riis - * \license Boost Software License 1.0 - */ -#ifndef BOOST_SERIALIZATION_BITSET_HPP -#define BOOST_SERIALIZATION_BITSET_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -#include -#include // size_t - -#include -#include -#include -#include - -namespace boost{ -namespace serialization{ - -template -inline void save( - Archive & ar, - std::bitset const & t, - const unsigned int /* version */ -){ - const std::string bits = t.template to_string< - std::string::value_type, - std::string::traits_type, - std::string::allocator_type - >(); - ar << BOOST_SERIALIZATION_NVP( bits ); -} - -template -inline void load( - Archive & ar, - std::bitset & t, - const unsigned int /* version */ -){ - std::string bits; - ar >> BOOST_SERIALIZATION_NVP( bits ); - t = std::bitset(bits); -} - -template -inline void serialize( - Archive & ar, - std::bitset & t, - const unsigned int version -){ - boost::serialization::split_free( ar, t, version ); -} - -// don't track bitsets since that would trigger tracking -// all over the program - which probably would be a surprise. -// also, tracking would be hard to implement since, we're -// serialization a representation of the data rather than -// the data itself. -template -struct tracking_level > - : mpl::int_ {} ; - -} //serialization -} //boost - -#endif // BOOST_SERIALIZATION_BITSET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/boost_array.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/boost_array.hpp deleted file mode 100644 index d564ff15de0..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/boost_array.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ARRAY_HPP -#define BOOST_SERIALIZATION_ARRAY_HPP - -// (C) Copyright 2005 Matthias Troyer and Dave Abrahams -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -//#include - -#include // msvc 6.0 needs this for warning suppression - -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -#include -#include - -namespace boost { namespace serialization { -// implement serialization for boost::array -template -void serialize(Archive& ar, boost::array& a, const unsigned int /* version */) -{ - ar & boost::serialization::make_nvp("elems", a.elems); -} - -} } // end namespace boost::serialization - - -#endif //BOOST_SERIALIZATION_ARRAY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_map.hpp deleted file mode 100644 index 8913b31f9e6..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_map.hpp +++ /dev/null @@ -1,154 +0,0 @@ -#ifndef BOOST_SERIALIZATION_UNORDERED_MAP_HPP -#define BOOST_SERIALIZATION_UNORDERED_MAP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization/unordered_map.hpp: -// serialization for stl unordered_map templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2014 Jim Bell -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include - -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const boost::unordered_map &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::save_unordered_collection< - Archive, - boost::unordered_map - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - boost::unordered_map &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::load_unordered_collection< - Archive, - boost::unordered_map, - boost::serialization::stl::archive_input_unordered_map< - Archive, - boost::unordered_map - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - boost::unordered_map &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -// unordered_multimap -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const boost::unordered_multimap &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::save_unordered_collection< - Archive, - boost::unordered_multimap - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - boost::unordered_multimap< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::load_unordered_collection< - Archive, - boost::unordered_multimap, - boost::serialization::stl::archive_input_unordered_multimap< - Archive, - boost::unordered_multimap - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - boost::unordered_multimap &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_UNORDERED_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_set.hpp deleted file mode 100644 index 307c7819cbd..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/boost_unordered_set.hpp +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef BOOST_SERIALIZATION_BOOST_UNORDERED_SET_HPP -#define BOOST_SERIALIZATION_BOOST_UNORDERED_SET_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// unordered_set.hpp: serialization for boost unordered_set templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2014 Jim Bell -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include - -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const boost::unordered_set &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::save_unordered_collection< - Archive, - boost::unordered_set - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - boost::unordered_set &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::load_unordered_collection< - Archive, - boost::unordered_set, - boost::serialization::stl::archive_input_unordered_set< - Archive, - boost::unordered_set - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - boost::unordered_set &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -// unordered_multiset -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const boost::unordered_multiset &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::save_unordered_collection< - Archive, - boost::unordered_multiset - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - boost::unordered_multiset &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::load_unordered_collection< - Archive, - boost::unordered_multiset, - boost::serialization::stl::archive_input_unordered_multiset< - Archive, - boost::unordered_multiset - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - boost::unordered_multiset &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_BOOST_UNORDERED_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/collection_size_type.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/collection_size_type.hpp deleted file mode 100644 index 2dd8fa72584..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/collection_size_type.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef BOOST_SERIALIZATION_COLLECTION_SIZE_TYPE_HPP -#define BOOST_SERIALIZATION_COLLECTION_SIZE_TYPE_HPP - -// (C) Copyright 2005 Matthias Troyer -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include // size_t -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -//BOOST_STRONG_TYPEDEF(std::size_t, collection_size_type) - -class collection_size_type { -private: - typedef std::size_t base_type; - base_type t; -public: - collection_size_type(): t(0) {}; - explicit collection_size_type(const std::size_t & t_) : - t(t_) - {} - collection_size_type(const collection_size_type & t_) : - t(t_.t) - {} - collection_size_type & operator=(const collection_size_type & rhs){ - t = rhs.t; - return *this; - } - collection_size_type & operator=(const unsigned int & rhs){ - t = rhs; - return *this; - } - // used for text output - operator base_type () const { - return t; - } - // used for text input - operator base_type & () { - return t; - } - bool operator==(const collection_size_type & rhs) const { - return t == rhs.t; - } - bool operator<(const collection_size_type & rhs) const { - return t < rhs.t; - } -}; - - -} } // end namespace boost::serialization - -BOOST_CLASS_IMPLEMENTATION(collection_size_type, primitive_type) -BOOST_IS_BITWISE_SERIALIZABLE(collection_size_type) - -#endif //BOOST_SERIALIZATION_COLLECTION_SIZE_TYPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/collection_traits.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/collection_traits.hpp deleted file mode 100644 index 3ec9401eff0..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/collection_traits.hpp +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef BOOST_SERIALIZATION_COLLECTION_TRAITS_HPP -#define BOOST_SERIALIZATION_COLLECTION_TRAITS_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// collection_traits.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// This header assigns a level implemenation trait to a collection type -// for all primitives. It is needed so that archives which are meant to be -// portable don't write class information in the archive. Since, not all -// compiles recognize the same set of primitive types, the possibility -// exists for archives to be non-portable if class information for primitive -// types is included. This is addressed by the following macros. -#include -//#include -#include - -#include -#include -#include // ULONG_MAX -#include - -#define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(T, C) \ -template<> \ -struct implementation_level< C < T > > { \ - typedef mpl::integral_c_tag tag; \ - typedef mpl::int_ type; \ - BOOST_STATIC_CONSTANT(int, value = object_serializable); \ -}; \ -/**/ - -#if defined(BOOST_NO_CWCHAR) || defined(BOOST_NO_INTRINSIC_WCHAR_T) - #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C) -#else - #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(wchar_t, C) \ - /**/ -#endif - -#if defined(BOOST_HAS_LONG_LONG) - #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(boost::long_long_type, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(boost::ulong_long_type, C) \ - /**/ -#else - #define BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C) -#endif - -#define BOOST_SERIALIZATION_COLLECTION_TRAITS(C) \ - namespace boost { namespace serialization { \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(bool, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(char, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed char, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned char, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed int, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned int, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed long, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned long, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(float, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(double, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(unsigned short, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER(signed short, C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_INT64(C) \ - BOOST_SERIALIZATION_COLLECTION_TRAITS_HELPER_WCHAR(C) \ - } } \ - /**/ - -#endif // BOOST_SERIALIZATION_COLLECTION_TRAITS diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/collections_load_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/collections_load_imp.hpp deleted file mode 100644 index e042c0c130d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/collections_load_imp.hpp +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef BOOST_SERIALIZATION_COLLECTIONS_LOAD_IMP_HPP -#define BOOST_SERIALIZATION_COLLECTIONS_LOAD_IMP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -#if defined(_MSC_VER) && (_MSC_VER <= 1020) -# pragma warning (disable : 4786) // too long name, harmless warning -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// collections_load_imp.hpp: serialization for loading stl collections - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// helper function templates for serialization of collections - -#include -#include // size_t -#include // msvc 6.0 needs this for warning suppression -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost{ -namespace serialization { -namespace stl { - -////////////////////////////////////////////////////////////////////// -// implementation of serialization for STL containers -// - -template< - class Archive, - class T -> -typename boost::enable_if< - typename detail::is_default_constructible< - typename T::value_type - >, - void ->::type -collection_load_impl( - Archive & ar, - T & t, - collection_size_type count, - item_version_type /*item_version*/ -){ - t.resize(count); - typename T::iterator hint; - hint = t.begin(); - while(count-- > 0){ - ar >> boost::serialization::make_nvp("item", *hint++); - } -} - -template< - class Archive, - class T -> -typename boost::disable_if< - typename detail::is_default_constructible< - typename T::value_type - >, - void ->::type -collection_load_impl( - Archive & ar, - T & t, - collection_size_type count, - item_version_type item_version -){ - t.clear(); - while(count-- > 0){ - detail::stack_construct u(ar, item_version); - ar >> boost::serialization::make_nvp("item", u.reference()); - t.push_back(boost::move(u.reference())); - ar.reset_object_address(& t.back() , & u.reference()); - } -} - -} // namespace stl -} // namespace serialization -} // namespace boost - -#endif //BOOST_SERIALIZATION_COLLECTIONS_LOAD_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/collections_save_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/collections_save_imp.hpp deleted file mode 100644 index f3cabfcf3f5..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/collections_save_imp.hpp +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef BOOST_SERIALIZATION_COLLECTIONS_SAVE_IMP_HPP -#define BOOST_SERIALIZATION_COLLECTIONS_SAVE_IMP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// collections_save_imp.hpp: serialization for stl collections - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// helper function templates for serialization of collections - -#include -#include -#include -#include -#include -#include - -namespace boost{ -namespace serialization { -namespace stl { - -////////////////////////////////////////////////////////////////////// -// implementation of serialization for STL containers -// - -template -inline void save_collection( - Archive & ar, - const Container &s, - collection_size_type count) -{ - ar << BOOST_SERIALIZATION_NVP(count); - // record number of elements - const item_version_type item_version( - version::value - ); - #if 0 - boost::archive::library_version_type library_version( - ar.get_library_version() - ); - if(boost::archive::library_version_type(3) < library_version){ - ar << BOOST_SERIALIZATION_NVP(item_version); - } - #else - ar << BOOST_SERIALIZATION_NVP(item_version); - #endif - - typename Container::const_iterator it = s.begin(); - while(count-- > 0){ - // note borland emits a no-op without the explicit namespace - boost::serialization::save_construct_data_adl( - ar, - &(*it), - item_version - ); - ar << boost::serialization::make_nvp("item", *it++); - } -} - -template -inline void save_collection(Archive & ar, const Container &s) -{ - // record number of elements - collection_size_type count(s.size()); - save_collection(ar, s, count); -} - -} // namespace stl -} // namespace serialization -} // namespace boost - -#endif //BOOST_SERIALIZATION_COLLECTIONS_SAVE_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/complex.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/complex.hpp deleted file mode 100644 index b4ef44cf973..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/complex.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef BOOST_SERIALIZATION_COMPLEX_HPP -#define BOOST_SERIALIZATION_COMPLEX_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization/utility.hpp: -// serialization for stl utility templates - -// (C) Copyright 2007 Matthias Troyer . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -#include -#include -#include - -namespace boost { -namespace serialization { - -template -inline void serialize( - Archive & ar, - std::complex< T > & t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -template -inline void save( - Archive & ar, - std::complex< T > const & t, - const unsigned int /* file_version */ -){ - const T re = t.real(); - const T im = t.imag(); - ar << boost::serialization::make_nvp("real", re); - ar << boost::serialization::make_nvp("imag", im); -} - -template -inline void load( - Archive & ar, - std::complex< T >& t, - const unsigned int /* file_version */ -){ - T re; - T im; - ar >> boost::serialization::make_nvp("real", re); - ar >> boost::serialization::make_nvp("imag", im); - t = std::complex< T >(re,im); -} - -// specialization of serialization traits for complex -template -struct is_bitwise_serializable > - : public is_bitwise_serializable< T > {}; - -template -struct implementation_level > - : mpl::int_ {} ; - -// treat complex just like builtin arithmetic types for tracking -template -struct tracking_level > - : mpl::int_ {} ; - -} // serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_COMPLEX_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/config.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/config.hpp deleted file mode 100644 index ea8cb9239ed..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/config.hpp +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef BOOST_SERIALIZATION_CONFIG_HPP -#define BOOST_SERIALIZATION_CONFIG_HPP - -// config.hpp ---------------------------------------------// - -// (c) Copyright Robert Ramey 2004 -// Use, modification, and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See library home page at http://www.boost.org/libs/serialization - -//----------------------------------------------------------------------------// - -// This header implements separate compilation features as described in -// http://www.boost.org/more/separate_compilation.html - -#include -#include - -// note: this version incorporates the related code into the the -// the same library as BOOST_ARCHIVE. This could change some day in the -// future - -// if BOOST_SERIALIZATION_DECL is defined undefine it now: -#ifdef BOOST_SERIALIZATION_DECL - #undef BOOST_SERIALIZATION_DECL -#endif - -// we need to import/export our code only if the user has specifically -// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost -// libraries to be dynamically linked, or BOOST_SERIALIZATION_DYN_LINK -// if they want just this one to be dynamically liked: -#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) - #if !defined(BOOST_DYN_LINK) - #define BOOST_DYN_LINK - #endif - // export if this is our own source, otherwise import: - #if defined(BOOST_SERIALIZATION_SOURCE) - #define BOOST_SERIALIZATION_DECL BOOST_SYMBOL_EXPORT - #else - #define BOOST_SERIALIZATION_DECL BOOST_SYMBOL_IMPORT - #endif // defined(BOOST_SERIALIZATION_SOURCE) -#endif // defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) - -// if BOOST_SERIALIZATION_DECL isn't defined yet define it now: -#ifndef BOOST_SERIALIZATION_DECL - #define BOOST_SERIALIZATION_DECL -#endif - -// enable automatic library variant selection ------------------------------// - -#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) \ -&& !defined(BOOST_ARCHIVE_SOURCE) && !defined(BOOST_WARCHIVE_SOURCE) \ -&& !defined(BOOST_SERIALIZATION_SOURCE) - // - // Set the name of our library, this will get undef'ed by auto_link.hpp - // once it's done with it: - // - #define BOOST_LIB_NAME boost_serialization - // - // If we're importing code from a dll, then tell auto_link.hpp about it: - // - #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_SERIALIZATION_DYN_LINK) - # define BOOST_DYN_LINK - #endif - // - // And include the header that does the work: - // - #include - -#endif - -#endif // BOOST_SERIALIZATION_CONFIG_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/deque.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/deque.hpp deleted file mode 100644 index bba81364ce2..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/deque.hpp +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef BOOST_SERIALIZATION_DEQUE_HPP -#define BOOST_SERIALIZATION_DEQUE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// deque.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include - -#include - -#include -#include -#include - -namespace boost { -namespace serialization { - -template -inline void save( - Archive & ar, - const std::deque &t, - const unsigned int /* file_version */ -){ - boost::serialization::stl::save_collection< - Archive, std::deque - >(ar, t); -} - -template -inline void load( - Archive & ar, - std::deque &t, - const unsigned int /* file_version */ -){ - const boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - item_version_type item_version(0); - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - stl::collection_load_impl(ar, t, count, item_version); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::deque &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(std::deque) - -#endif // BOOST_SERIALIZATION_DEQUE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/is_default_constructible.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/is_default_constructible.hpp deleted file mode 100644 index 4d20b13bf3e..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/detail/is_default_constructible.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef BOOST_SERIALIZATION_DETAIL_IS_DEFAULT_CONSTRUCTIBLE_HPP -#define BOOST_SERIALIZATION_DETAIL_IS_DEFAULT_CONSTRUCTIBLE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// is_default_constructible.hpp: serialization for loading stl collections -// -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#if ! defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) - #include - namespace boost{ - namespace serialization { - namespace detail { - - template - struct is_default_constructible : public std::is_default_constructible {}; - - } // detail - } // serializaition - } // boost -#else - // we don't have standard library support for is_default_constructible - // so we fake it by using boost::has_trivial_construtor. But this is not - // actually correct because it's possible that a default constructor - // to be non trivial. So when using this, make sure you're not using your - // own definition of of T() but are using the actual default one! - #include - namespace boost{ - namespace serialization { - namespace detail { - - template - struct is_default_constructible : public boost::has_trivial_constructor {}; - - } // detail - } // serializaition - } // boost - -#endif - - -#endif // BOOST_SERIALIZATION_DETAIL_IS_DEFAULT_CONSTRUCTIBLE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_count_132.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_count_132.hpp deleted file mode 100644 index a5872557cf2..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_count_132.hpp +++ /dev/null @@ -1,551 +0,0 @@ -#ifndef BOOST_DETAIL_SHARED_COUNT_132_HPP_INCLUDED -#define BOOST_DETAIL_SHARED_COUNT_132_HPP_INCLUDED - -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) -# pragma once -#endif - -// -// detail/shared_count.hpp -// -// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// - -#include - -#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR) -# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible. -#endif - -#include -#include -#include - -#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) -#include -#endif - -#include // std::auto_ptr, std::allocator -#include // std::less -#include // std::exception -#include // std::bad_alloc -#include // std::type_info in get_deleter -#include // std::size_t - -#include // msvc 6.0 needs this for warning suppression -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif - -namespace boost_132 { - -// Debug hooks - -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - -void sp_scalar_constructor_hook(void * px, std::size_t size, void * pn); -void sp_array_constructor_hook(void * px); -void sp_scalar_destructor_hook(void * px, std::size_t size, void * pn); -void sp_array_destructor_hook(void * px); - -#endif - - -// The standard library that comes with Borland C++ 5.5.1 -// defines std::exception and its members as having C calling -// convention (-pc). When the definition of bad_weak_ptr -// is compiled with -ps, the compiler issues an error. -// Hence, the temporary #pragma option -pc below. The version -// check is deliberately conservative. - -class bad_weak_ptr: public std::exception -{ -public: - - virtual char const * what() const throw() - { - return "boost::bad_weak_ptr"; - } -}; - -namespace detail{ - -class sp_counted_base -{ -//private: - - typedef boost::detail::lightweight_mutex mutex_type; - -public: - - sp_counted_base(): use_count_(1), weak_count_(1) - { - } - - virtual ~sp_counted_base() // nothrow - { - } - - // dispose() is called when use_count_ drops to zero, to release - // the resources managed by *this. - - virtual void dispose() = 0; // nothrow - - // destruct() is called when weak_count_ drops to zero. - - virtual void destruct() // nothrow - { - delete this; - } - - virtual void * get_deleter(std::type_info const & ti) = 0; - - void add_ref_copy() - { -#if defined(BOOST_HAS_THREADS) - mutex_type::scoped_lock lock(mtx_); -#endif - ++use_count_; - } - - void add_ref_lock() - { -#if defined(BOOST_HAS_THREADS) - mutex_type::scoped_lock lock(mtx_); -#endif - if(use_count_ == 0) boost::serialization::throw_exception(bad_weak_ptr()); - ++use_count_; - } - - void release() // nothrow - { - { -#if defined(BOOST_HAS_THREADS) - mutex_type::scoped_lock lock(mtx_); -#endif - long new_use_count = --use_count_; - - if(new_use_count != 0) return; - } - - dispose(); - weak_release(); - } - - void weak_add_ref() // nothrow - { -#if defined(BOOST_HAS_THREADS) - mutex_type::scoped_lock lock(mtx_); -#endif - ++weak_count_; - } - - void weak_release() // nothrow - { - long new_weak_count; - - { -#if defined(BOOST_HAS_THREADS) - mutex_type::scoped_lock lock(mtx_); -#endif - new_weak_count = --weak_count_; - } - - if(new_weak_count == 0) - { - destruct(); - } - } - - long use_count() const // nothrow - { -#if defined(BOOST_HAS_THREADS) - mutex_type::scoped_lock lock(mtx_); -#endif - return use_count_; - } - -//private: -public: - sp_counted_base(sp_counted_base const &); - sp_counted_base & operator= (sp_counted_base const &); - - long use_count_; // #shared - long weak_count_; // #weak + (#shared != 0) - -#if defined(BOOST_HAS_THREADS) || defined(BOOST_LWM_WIN32) - mutable mutex_type mtx_; -#endif -}; - -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - -template void cbi_call_constructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &) -{ - boost::sp_scalar_constructor_hook(px, sizeof(T), pn); -} - -template void cbi_call_constructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &) -{ - boost::sp_array_constructor_hook(px); -} - -template void cbi_call_constructor_hook(sp_counted_base *, P const &, D const &, long) -{ -} - -template void cbi_call_destructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &) -{ - boost::sp_scalar_destructor_hook(px, sizeof(T), pn); -} - -template void cbi_call_destructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &) -{ - boost::sp_array_destructor_hook(px); -} - -template void cbi_call_destructor_hook(sp_counted_base *, P const &, D const &, long) -{ -} - -#endif - -// -// Borland's Codeguard trips up over the -Vx- option here: -// -#ifdef __CODEGUARD__ -# pragma option push -Vx- -#endif - -template class sp_counted_base_impl: public sp_counted_base -{ -//private: -public: - P ptr; // copy constructor must not throw - D del; // copy constructor must not throw - - sp_counted_base_impl(sp_counted_base_impl const &); - sp_counted_base_impl & operator= (sp_counted_base_impl const &); - - typedef sp_counted_base_impl this_type; - -public: - - // pre: initial_use_count <= initial_weak_count, d(p) must not throw - - sp_counted_base_impl(P p, D d): ptr(p), del(d) - { -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - detail::cbi_call_constructor_hook(this, p, d, 0); -#endif - } - - virtual void dispose() // nothrow - { -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - detail::cbi_call_destructor_hook(this, ptr, del, 0); -#endif - del(ptr); - } - - virtual void * get_deleter(std::type_info const & ti) - { - return ti == typeid(D)? &del: 0; - } - -#if defined(BOOST_SP_USE_STD_ALLOCATOR) - - void * operator new(std::size_t) - { - return std::allocator().allocate(1, static_cast(0)); - } - - void operator delete(void * p) - { - std::allocator().deallocate(static_cast(p), 1); - } - -#endif - -#if defined(BOOST_SP_USE_QUICK_ALLOCATOR) - - void * operator new(std::size_t) - { - return boost::detail::quick_allocator::alloc(); - } - - void operator delete(void * p) - { - boost::detail::quick_allocator::dealloc(p); - } - -#endif -}; - -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - -int const shared_count_id = 0x2C35F101; -int const weak_count_id = 0x298C38A4; - -#endif - -class weak_count; - -class shared_count -{ -//private: -public: - sp_counted_base * pi_; - -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - int id_; -#endif - - friend class weak_count; - -public: - - shared_count(): pi_(0) // nothrow -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(shared_count_id) -#endif - { - } - - template shared_count(P p, D d): pi_(0) -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(shared_count_id) -#endif - { -#ifndef BOOST_NO_EXCEPTIONS - - try - { - pi_ = new sp_counted_base_impl(p, d); - } - catch(...) - { - d(p); // delete p - throw; - } - -#else - - pi_ = new sp_counted_base_impl(p, d); - - if(pi_ == 0) - { - d(p); // delete p - boost::serialization::throw_exception(std::bad_alloc()); - } - -#endif - } - -#ifndef BOOST_NO_AUTO_PTR - - // auto_ptr is special cased to provide the strong guarantee - - template - explicit shared_count(std::auto_ptr & r): pi_( - new sp_counted_base_impl< - Y *, - boost::checked_deleter - >(r.get(), boost::checked_deleter())) -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(shared_count_id) -#endif - { - r.release(); - } - -#endif - - ~shared_count() // nothrow - { - if(pi_ != 0) pi_->release(); -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - id_ = 0; -#endif - } - - shared_count(shared_count const & r): pi_(r.pi_) // nothrow -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(shared_count_id) -#endif - { - if(pi_ != 0) pi_->add_ref_copy(); - } - - explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0 - - shared_count & operator= (shared_count const & r) // nothrow - { - sp_counted_base * tmp = r.pi_; - - if(tmp != pi_) - { - if(tmp != 0) tmp->add_ref_copy(); - if(pi_ != 0) pi_->release(); - pi_ = tmp; - } - - return *this; - } - - void swap(shared_count & r) // nothrow - { - sp_counted_base * tmp = r.pi_; - r.pi_ = pi_; - pi_ = tmp; - } - - long use_count() const // nothrow - { - return pi_ != 0? pi_->use_count(): 0; - } - - bool unique() const // nothrow - { - return use_count() == 1; - } - - friend inline bool operator==(shared_count const & a, shared_count const & b) - { - return a.pi_ == b.pi_; - } - - friend inline bool operator<(shared_count const & a, shared_count const & b) - { - return std::less()(a.pi_, b.pi_); - } - - void * get_deleter(std::type_info const & ti) const - { - return pi_? pi_->get_deleter(ti): 0; - } -}; - -#ifdef __CODEGUARD__ -# pragma option pop -#endif - - -class weak_count -{ -private: - - sp_counted_base * pi_; - -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - int id_; -#endif - - friend class shared_count; - -public: - - weak_count(): pi_(0) // nothrow -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(weak_count_id) -#endif - { - } - - weak_count(shared_count const & r): pi_(r.pi_) // nothrow -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(shared_count_id) -#endif - { - if(pi_ != 0) pi_->weak_add_ref(); - } - - weak_count(weak_count const & r): pi_(r.pi_) // nothrow -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(shared_count_id) -#endif - { - if(pi_ != 0) pi_->weak_add_ref(); - } - - ~weak_count() // nothrow - { - if(pi_ != 0) pi_->weak_release(); -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - id_ = 0; -#endif - } - - weak_count & operator= (shared_count const & r) // nothrow - { - sp_counted_base * tmp = r.pi_; - if(tmp != 0) tmp->weak_add_ref(); - if(pi_ != 0) pi_->weak_release(); - pi_ = tmp; - - return *this; - } - - weak_count & operator= (weak_count const & r) // nothrow - { - sp_counted_base * tmp = r.pi_; - if(tmp != 0) tmp->weak_add_ref(); - if(pi_ != 0) pi_->weak_release(); - pi_ = tmp; - - return *this; - } - - void swap(weak_count & r) // nothrow - { - sp_counted_base * tmp = r.pi_; - r.pi_ = pi_; - pi_ = tmp; - } - - long use_count() const // nothrow - { - return pi_ != 0? pi_->use_count(): 0; - } - - friend inline bool operator==(weak_count const & a, weak_count const & b) - { - return a.pi_ == b.pi_; - } - - friend inline bool operator<(weak_count const & a, weak_count const & b) - { - return std::less()(a.pi_, b.pi_); - } -}; - -inline shared_count::shared_count(weak_count const & r): pi_(r.pi_) -#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS) - , id_(shared_count_id) -#endif -{ - if(pi_ != 0) - { - pi_->add_ref_lock(); - } - else - { - boost::serialization::throw_exception(bad_weak_ptr()); - } -} - -} // namespace detail - -} // namespace boost - -BOOST_SERIALIZATION_ASSUME_ABSTRACT(boost_132::detail::sp_counted_base) - -#endif // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_132.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_132.hpp deleted file mode 100644 index ee98b7b9449..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_132.hpp +++ /dev/null @@ -1,443 +0,0 @@ -#ifndef BOOST_SHARED_PTR_132_HPP_INCLUDED -#define BOOST_SHARED_PTR_132_HPP_INCLUDED - -// -// shared_ptr.hpp -// -// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. -// Copyright (c) 2001, 2002, 2003 Peter Dimov -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation. -// - -#include // for broken compiler workarounds - -#if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) -#include -#else - -#include -#include -#include -#include - -#include -#include - -#include // for std::auto_ptr -#include // for std::swap -#include // for std::less -#include // for std::bad_cast -#include // for std::basic_ostream - -#ifdef BOOST_MSVC // moved here to work around VC++ compiler crash -# pragma warning(push) -# pragma warning(disable:4284) // odd return type for operator-> -#endif - -namespace boost_132 { - -template class weak_ptr; -template class enable_shared_from_this; - -namespace detail -{ - -struct static_cast_tag {}; -struct const_cast_tag {}; -struct dynamic_cast_tag {}; -struct polymorphic_cast_tag {}; - -template struct shared_ptr_traits -{ - typedef T & reference; -}; - -template<> struct shared_ptr_traits -{ - typedef void reference; -}; - -#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) - -template<> struct shared_ptr_traits -{ - typedef void reference; -}; - -template<> struct shared_ptr_traits -{ - typedef void reference; -}; - -template<> struct shared_ptr_traits -{ - typedef void reference; -}; - -#endif - -// enable_shared_from_this support - -template void sp_enable_shared_from_this( shared_count const & pn, enable_shared_from_this< T > const * pe, Y const * px ) -{ - if(pe != 0) pe->_internal_weak_this._internal_assign(const_cast(px), pn); -} - -inline void sp_enable_shared_from_this( shared_count const & /*pn*/, ... ) -{ -} - -} // namespace detail - - -// -// shared_ptr -// -// An enhanced relative of scoped_ptr with reference counted copy semantics. -// The object pointed to is deleted when the last shared_ptr pointing to it -// is destroyed or reset. -// - -template class shared_ptr -{ -private: - // Borland 5.5.1 specific workaround - typedef shared_ptr< T > this_type; - -public: - - typedef T element_type; - typedef T value_type; - typedef T * pointer; - typedef typename detail::shared_ptr_traits< T >::reference reference; - - shared_ptr(): px(0), pn() // never throws in 1.30+ - { - } - - template - explicit shared_ptr(Y * p): px(p), pn(p, boost::checked_deleter()) // Y must be complete - { - detail::sp_enable_shared_from_this( pn, p, p ); - } - - // - // Requirements: D's copy constructor must not throw - // - // shared_ptr will release p by calling d(p) - // - - template shared_ptr(Y * p, D d): px(p), pn(p, d) - { - detail::sp_enable_shared_from_this( pn, p, p ); - } - -// generated copy constructor, assignment, destructor are fine... - -// except that Borland C++ has a bug, and g++ with -Wsynth warns -#if defined(__GNUC__) - shared_ptr & operator=(shared_ptr const & r) // never throws - { - px = r.px; - pn = r.pn; // shared_count::op= doesn't throw - return *this; - } -#endif - - template - explicit shared_ptr(weak_ptr const & r): pn(r.pn) // may throw - { - // it is now safe to copy r.px, as pn(r.pn) did not throw - px = r.px; - } - - template - shared_ptr(shared_ptr const & r): px(r.px), pn(r.pn) // never throws - { - } - - template - shared_ptr(shared_ptr const & r, detail::static_cast_tag): px(static_cast(r.px)), pn(r.pn) - { - } - - template - shared_ptr(shared_ptr const & r, detail::const_cast_tag): px(const_cast(r.px)), pn(r.pn) - { - } - - template - shared_ptr(shared_ptr const & r, detail::dynamic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) - { - if(px == 0) // need to allocate new counter -- the cast failed - { - pn = detail::shared_count(); - } - } - - template - shared_ptr(shared_ptr const & r, detail::polymorphic_cast_tag): px(dynamic_cast(r.px)), pn(r.pn) - { - if(px == 0) - { - boost::serialization::throw_exception(std::bad_cast()); - } - } - -#ifndef BOOST_NO_AUTO_PTR - - template - explicit shared_ptr(std::auto_ptr & r): px(r.get()), pn() - { - Y * tmp = r.get(); - pn = detail::shared_count(r); - detail::sp_enable_shared_from_this( pn, tmp, tmp ); - } - -#endif - -#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200) - - template - shared_ptr & operator=(shared_ptr const & r) // never throws - { - px = r.px; - pn = r.pn; // shared_count::op= doesn't throw - return *this; - } - -#endif - -#ifndef BOOST_NO_AUTO_PTR - - template - shared_ptr & operator=(std::auto_ptr & r) - { - this_type(r).swap(*this); - return *this; - } - -#endif - - void reset() // never throws in 1.30+ - { - this_type().swap(*this); - } - - template void reset(Y * p) // Y must be complete - { - BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors - this_type(p).swap(*this); - } - - template void reset(Y * p, D d) - { - this_type(p, d).swap(*this); - } - - reference operator* () const // never throws - { - BOOST_ASSERT(px != 0); - return *px; - } - - T * operator-> () const // never throws - { - BOOST_ASSERT(px != 0); - return px; - } - - T * get() const // never throws - { - return px; - } - - // implicit conversion to "bool" - -#if defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x530) - - operator bool () const - { - return px != 0; - } - -#elif defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) - typedef T * (this_type::*unspecified_bool_type)() const; - - operator unspecified_bool_type() const // never throws - { - return px == 0? 0: &this_type::get; - } - -#else - - typedef T * this_type::*unspecified_bool_type; - - operator unspecified_bool_type() const // never throws - { - return px == 0? 0: &this_type::px; - } - -#endif - - // operator! is redundant, but some compilers need it - - bool operator! () const // never throws - { - return px == 0; - } - - bool unique() const // never throws - { - return pn.unique(); - } - - long use_count() const // never throws - { - return pn.use_count(); - } - - void swap(shared_ptr< T > & other) // never throws - { - std::swap(px, other.px); - pn.swap(other.pn); - } - - template bool _internal_less(shared_ptr const & rhs) const - { - return pn < rhs.pn; - } - - void * _internal_get_deleter(std::type_info const & ti) const - { - return pn.get_deleter(ti); - } - -// Tasteless as this may seem, making all members public allows member templates -// to work in the absence of member template friends. (Matthew Langston) - -#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS - -private: - - template friend class shared_ptr; - template friend class weak_ptr; - - -#endif -public: // for serialization - T * px; // contained pointer - detail::shared_count pn; // reference counter - -}; // shared_ptr - -template inline bool operator==(shared_ptr< T > const & a, shared_ptr const & b) -{ - return a.get() == b.get(); -} - -template inline bool operator!=(shared_ptr< T > const & a, shared_ptr const & b) -{ - return a.get() != b.get(); -} - -template inline bool operator<(shared_ptr< T > const & a, shared_ptr const & b) -{ - return a._internal_less(b); -} - -template inline void swap(shared_ptr< T > & a, shared_ptr< T > & b) -{ - a.swap(b); -} - -template shared_ptr< T > static_pointer_cast(shared_ptr const & r) -{ - return shared_ptr< T >(r, detail::static_cast_tag()); -} - -template shared_ptr< T > const_pointer_cast(shared_ptr const & r) -{ - return shared_ptr< T >(r, detail::const_cast_tag()); -} - -template shared_ptr< T > dynamic_pointer_cast(shared_ptr const & r) -{ - return shared_ptr< T >(r, detail::dynamic_cast_tag()); -} - -// shared_*_cast names are deprecated. Use *_pointer_cast instead. - -template shared_ptr< T > shared_static_cast(shared_ptr const & r) -{ - return shared_ptr< T >(r, detail::static_cast_tag()); -} - -template shared_ptr< T > shared_dynamic_cast(shared_ptr const & r) -{ - return shared_ptr< T >(r, detail::dynamic_cast_tag()); -} - -template shared_ptr< T > shared_polymorphic_cast(shared_ptr const & r) -{ - return shared_ptr< T >(r, detail::polymorphic_cast_tag()); -} - -template shared_ptr< T > shared_polymorphic_downcast(shared_ptr const & r) -{ - BOOST_ASSERT(dynamic_cast(r.get()) == r.get()); - return shared_static_cast< T >(r); -} - -// get_pointer() enables boost::mem_fn to recognize shared_ptr - -template inline T * get_pointer(shared_ptr< T > const & p) -{ - return p.get(); -} - -// operator<< - - -template std::basic_ostream & operator<< (std::basic_ostream & os, shared_ptr const & p) -{ - os << p.get(); - return os; -} - -// get_deleter (experimental) - -#if defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238) - -// g++ 2.9x doesn't allow static_cast(void *) -// apparently EDG 2.38 also doesn't accept it - -template D * get_deleter(shared_ptr< T > const & p) -{ - void const * q = p._internal_get_deleter(typeid(D)); - return const_cast(static_cast(q)); -} - -#else - -template D * get_deleter(shared_ptr< T > const & p) -{ - return static_cast(p._internal_get_deleter(typeid(D))); -} - -#endif - -} // namespace boost - -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif - -#endif // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) - -#endif // #ifndef BOOST_SHARED_PTR_132_HPP_INCLUDED diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_nmt_132.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_nmt_132.hpp deleted file mode 100644 index 490e7ddd3d0..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/detail/shared_ptr_nmt_132.hpp +++ /dev/null @@ -1,182 +0,0 @@ -#ifndef BOOST_DETAIL_SHARED_PTR_NMT_132_HPP_INCLUDED -#define BOOST_DETAIL_SHARED_PTR_NMT_132_HPP_INCLUDED - -// -// detail/shared_ptr_nmt.hpp - shared_ptr.hpp without member templates -// -// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. -// Copyright (c) 2001, 2002 Peter Dimov -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation. -// - -#include -#include -#include -#include - -#ifndef BOOST_NO_AUTO_PTR -# include // for std::auto_ptr -#endif - -#include // for std::swap -#include // for std::less -#include // for std::bad_alloc - -namespace boost -{ - -template class shared_ptr -{ -private: - - typedef detail::atomic_count count_type; - -public: - - typedef T element_type; - typedef T value_type; - - explicit shared_ptr(T * p = 0): px(p) - { -#ifndef BOOST_NO_EXCEPTIONS - - try // prevent leak if new throws - { - pn = new count_type(1); - } - catch(...) - { - boost::checked_delete(p); - throw; - } - -#else - - pn = new count_type(1); - - if(pn == 0) - { - boost::checked_delete(p); - boost::serialization::throw_exception(std::bad_alloc()); - } - -#endif - } - - ~shared_ptr() - { - if(--*pn == 0) - { - boost::checked_delete(px); - delete pn; - } - } - - shared_ptr(shared_ptr const & r): px(r.px) // never throws - { - pn = r.pn; - ++*pn; - } - - shared_ptr & operator=(shared_ptr const & r) - { - shared_ptr(r).swap(*this); - return *this; - } - -#ifndef BOOST_NO_AUTO_PTR - - explicit shared_ptr(std::auto_ptr< T > & r) - { - pn = new count_type(1); // may throw - px = r.release(); // fix: moved here to stop leak if new throws - } - - shared_ptr & operator=(std::auto_ptr< T > & r) - { - shared_ptr(r).swap(*this); - return *this; - } - -#endif - - void reset(T * p = 0) - { - BOOST_ASSERT(p == 0 || p != px); - shared_ptr(p).swap(*this); - } - - T & operator*() const // never throws - { - BOOST_ASSERT(px != 0); - return *px; - } - - T * operator->() const // never throws - { - BOOST_ASSERT(px != 0); - return px; - } - - T * get() const // never throws - { - return px; - } - - long use_count() const // never throws - { - return *pn; - } - - bool unique() const // never throws - { - return *pn == 1; - } - - void swap(shared_ptr< T > & other) // never throws - { - std::swap(px, other.px); - std::swap(pn, other.pn); - } - -private: - - T * px; // contained pointer - count_type * pn; // ptr to reference counter -}; - -template inline bool operator==(shared_ptr< T > const & a, shared_ptr const & b) -{ - return a.get() == b.get(); -} - -template inline bool operator!=(shared_ptr< T > const & a, shared_ptr const & b) -{ - return a.get() != b.get(); -} - -template inline bool operator<(shared_ptr< T > const & a, shared_ptr< T > const & b) -{ - return std::less()(a.get(), b.get()); -} - -template void swap(shared_ptr< T > & a, shared_ptr< T > & b) -{ - a.swap(b); -} - -// get_pointer() enables boost::mem_fn to recognize shared_ptr - -template inline T * get_pointer(shared_ptr< T > const & p) -{ - return p.get(); -} - -} // namespace boost - -#endif // #ifndef BOOST_DETAIL_SHARED_PTR_NMT_132_HPP_INCLUDED diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/detail/stack_constructor.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/detail/stack_constructor.hpp deleted file mode 100644 index ae14832c6db..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/detail/stack_constructor.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef BOOST_SERIALIZATION_DETAIL_STACK_CONSTRUCTOR_HPP -#define BOOST_SERIALIZATION_DETAIL_STACK_CONSTRUCTOR_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// stack_constructor.hpp: serialization for loading stl collections - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -namespace boost{ -namespace serialization { -namespace detail { - -// reserve space on stack for an object of type T without actually -// construction such an object -template -struct stack_allocate -{ - T * address() { - return static_cast(storage_.address()); - } - T & reference() { - return * address(); - } -private: - typedef typename boost::aligned_storage< - sizeof(T), - boost::alignment_of::value - > type; - type storage_; -}; - -// construct element on the stack -template -struct stack_construct : public stack_allocate -{ - stack_construct(Archive & ar, const unsigned int version){ - // note borland emits a no-op without the explicit namespace - boost::serialization::load_construct_data_adl( - ar, - this->address(), - version - ); - } - ~stack_construct(){ - this->address()->~T(); // undo load_construct_data above - } -}; - -} // detail -} // serializaition -} // boost - -#endif // BOOST_SERIALIZATION_DETAIL_STACH_CONSTRUCTOR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/ephemeral.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/ephemeral.hpp deleted file mode 100644 index 3a422c30a35..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/ephemeral.hpp +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef BOOST_SERIALIZATION_EPHEMERAL_HPP -#define BOOST_SERIALIZATION_EPHEMERAL_HPP - -// MS compatible compilers support -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// ephemeral_object.hpp: interface for serialization system. - -// (C) Copyright 2007 Matthias Troyer. -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template -struct ephemeral_object : - public wrapper_traits > -{ - explicit ephemeral_object(T& t) : - val(t) - {} - - T & value() const { - return val; - } - - const T & const_value() const { - return val; - } - - template - void serialize(Archive &ar, const unsigned int) const - { - ar & val; - } - -private: - T & val; -}; - -template -inline -const ephemeral_object ephemeral(const char * name, T & t){ - return ephemeral_object(name, t); -} - -} // seralization -} // boost - -#endif // BOOST_SERIALIZATION_EPHEMERAL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/export.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/export.hpp deleted file mode 100644 index 9eef440df42..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/export.hpp +++ /dev/null @@ -1,225 +0,0 @@ -#ifndef BOOST_SERIALIZATION_EXPORT_HPP -#define BOOST_SERIALIZATION_EXPORT_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// export.hpp: set traits of classes to be serialized - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// (C) Copyright 2006 David Abrahams - http://www.boost.org. -// implementation of class export functionality. This is an alternative to -// "forward declaration" method to provoke instantiation of derived classes -// that are to be serialized through pointers. - -#include -#include // NULL - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include // for guid_defined only -#include -#include -#include -#include - -#include - -#include - -namespace boost { -namespace archive { -namespace detail { - -class basic_pointer_iserializer; -class basic_pointer_oserializer; - -template -class pointer_iserializer; -template -class pointer_oserializer; - -template -struct export_impl -{ - static const basic_pointer_iserializer & - enable_load(mpl::true_){ - return boost::serialization::singleton< - pointer_iserializer - >::get_const_instance(); - } - - static const basic_pointer_oserializer & - enable_save(mpl::true_){ - return boost::serialization::singleton< - pointer_oserializer - >::get_const_instance(); - } - inline static void enable_load(mpl::false_) {} - inline static void enable_save(mpl::false_) {} -}; - -// On many platforms, naming a specialization of this template is -// enough to cause its argument to be instantiated. -template -struct instantiate_function {}; - -template -struct ptr_serialization_support -{ -# if defined(BOOST_MSVC) || defined(__SUNPRO_CC) - virtual BOOST_DLLEXPORT void instantiate() BOOST_USED; -# else - static BOOST_DLLEXPORT void instantiate() BOOST_USED; - typedef instantiate_function< - &ptr_serialization_support::instantiate - > x; -# endif -}; - -template -BOOST_DLLEXPORT void -ptr_serialization_support::instantiate() -{ - export_impl::enable_save( - typename Archive::is_saving() - ); - - export_impl::enable_load( - typename Archive::is_loading() - ); -} - -// Note INTENTIONAL usage of anonymous namespace in header. -// This was made this way so that export.hpp could be included -// in other headers. This is still under study. - -namespace extra_detail { - -template -struct guid_initializer -{ - void export_guid(mpl::false_) const { - // generates the statically-initialized objects whose constructors - // register the information allowing serialization of T objects - // through pointers to their base classes. - instantiate_ptr_serialization((T*)0, 0, adl_tag()); - } - void export_guid(mpl::true_) const { - } - guid_initializer const & export_guid() const { - BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); - // note: exporting an abstract base class will have no effect - // and cannot be used to instantitiate serialization code - // (one might be using this in a DLL to instantiate code) - //BOOST_STATIC_WARNING(! boost::serialization::is_abstract< T >::value); - export_guid(boost::serialization::is_abstract< T >()); - return *this; - } -}; - -template -struct init_guid; - -} // anonymous -} // namespace detail -} // namespace archive -} // namespace boost - -#define BOOST_CLASS_EXPORT_IMPLEMENT(T) \ - namespace boost { \ - namespace archive { \ - namespace detail { \ - namespace extra_detail { \ - template<> \ - struct init_guid< T > { \ - static guid_initializer< T > const & g; \ - }; \ - guid_initializer< T > const & init_guid< T >::g = \ - ::boost::serialization::singleton< \ - guid_initializer< T > \ - >::get_mutable_instance().export_guid(); \ - }}}} \ -/**/ - -#define BOOST_CLASS_EXPORT_KEY2(T, K) \ -namespace boost { \ -namespace serialization { \ -template<> \ -struct guid_defined< T > : boost::mpl::true_ {}; \ -template<> \ -inline const char * guid< T >(){ \ - return K; \ -} \ -} /* serialization */ \ -} /* boost */ \ -/**/ - -#define BOOST_CLASS_EXPORT_KEY(T) \ - BOOST_CLASS_EXPORT_KEY2(T, BOOST_PP_STRINGIZE(T)) \ -/**/ - -#define BOOST_CLASS_EXPORT_GUID(T, K) \ -BOOST_CLASS_EXPORT_KEY2(T, K) \ -BOOST_CLASS_EXPORT_IMPLEMENT(T) \ -/**/ - -#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) - -// CodeWarrior fails to construct static members of class templates -// when they are instantiated from within templates, so on that -// compiler we ask users to specifically register base/derived class -// relationships for exported classes. On all other compilers, use of -// this macro is entirely optional. -# define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived) \ -namespace { \ - static int BOOST_PP_CAT(boost_serialization_mwerks_init_, __LINE__) = \ - (::boost::archive::detail::instantiate_ptr_serialization((Derived*)0,0), 3); \ - static int BOOST_PP_CAT(boost_serialization_mwerks_init2_, __LINE__) = ( \ - ::boost::serialization::void_cast_register((Derived*)0,(Base*)0) \ - , 3); \ -} - -#else - -# define BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(Base,Derived) - -#endif - -// check for unnecessary export. T isn't polymorphic so there is no -// need to export it. -#define BOOST_CLASS_EXPORT_CHECK(T) \ - BOOST_STATIC_WARNING( \ - boost::is_polymorphic::value \ - ); \ - /**/ - -// the default exportable class identifier is the class name -// the default list of archives types for which code id generated -// are the originally included with this serialization system -#define BOOST_CLASS_EXPORT(T) \ - BOOST_CLASS_EXPORT_GUID( \ - T, \ - BOOST_PP_STRINGIZE(T) \ - ) \ - /**/ - -#endif // BOOST_SERIALIZATION_EXPORT_HPP - diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info.hpp deleted file mode 100644 index bb2a190d465..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info.hpp +++ /dev/null @@ -1,116 +0,0 @@ -#ifndef BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_HPP -#define BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// extended_type_info.hpp: interface for portable version of type_info - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// for now, extended type info is part of the serialization libraries -// this could change in the future. -#include -#include -#include // NULL -#include -#include -#include - -#include -#include // must be the last header -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4251 4231 4660 4275) -#endif - -#define BOOST_SERIALIZATION_MAX_KEY_SIZE 128 - -namespace boost { -namespace serialization { - -namespace void_cast_detail{ - class void_caster; -} - -class BOOST_SYMBOL_VISIBLE extended_type_info : - private boost::noncopyable -{ -private: - friend class boost::serialization::void_cast_detail::void_caster; - - // used to uniquely identify the type of class derived from this one - // so that different derivations of this class can be simultaneously - // included in implementation of sets and maps. - const unsigned int m_type_info_key; - virtual bool is_less_than(const extended_type_info & /*rhs*/) const = 0; - virtual bool is_equal(const extended_type_info & /*rhs*/) const = 0; - const char * m_key; - -protected: - BOOST_SERIALIZATION_DECL void key_unregister() const; - BOOST_SERIALIZATION_DECL void key_register() const; - // this class can't be used as is. It's just the - // common functionality for all type_info replacement - // systems. Hence, make these protected - BOOST_SERIALIZATION_DECL extended_type_info( - const unsigned int type_info_key, - const char * key - ); - virtual BOOST_SERIALIZATION_DECL ~extended_type_info(); -public: - const char * get_key() const { - return m_key; - } - virtual const char * get_debug_info() const = 0; - BOOST_SERIALIZATION_DECL bool operator<(const extended_type_info &rhs) const; - BOOST_SERIALIZATION_DECL bool operator==(const extended_type_info &rhs) const; - bool operator!=(const extended_type_info &rhs) const { - return !(operator==(rhs)); - } - // note explicit "export" of static function to work around - // gcc 4.5 mingw error - static BOOST_SERIALIZATION_DECL const extended_type_info * - find(const char *key); - // for plugins - virtual void * construct(unsigned int /*count*/ = 0, ...) const = 0; - virtual void destroy(void const * const /*p*/) const = 0; -}; - -template -struct guid_defined : boost::mpl::false_ {}; - -namespace ext { - template - struct guid_impl - { - static inline const char * call() - { - return NULL; - } - }; -} - -template -inline const char * guid(){ - return ext::guid_impl::call(); -} - -} // namespace serialization -} // namespace boost - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_no_rtti.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_no_rtti.hpp deleted file mode 100644 index aaa8b44459b..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_no_rtti.hpp +++ /dev/null @@ -1,182 +0,0 @@ -#ifndef BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP -#define BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -// extended_type_info_no_rtti.hpp: implementation for version that depends -// on runtime typing (rtti - typeid) but uses a user specified string -// as the portable class identifier. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. -#include - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -// hijack serialization access -#include - -#include // must be the last header -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4251 4231 4660 4275 4511 4512) -#endif - -namespace boost { -namespace serialization { -/////////////////////////////////////////////////////////////////////// -// define a special type_info that doesn't depend on rtti which is not -// available in all situations. - -namespace no_rtti_system { - -// common base class to share type_info_key. This is used to -// identify the method used to keep track of the extended type -class BOOST_SYMBOL_VISIBLE extended_type_info_no_rtti_0 : - public extended_type_info -{ -protected: - BOOST_SERIALIZATION_DECL extended_type_info_no_rtti_0(const char * key); - BOOST_SERIALIZATION_DECL ~extended_type_info_no_rtti_0(); -public: - virtual BOOST_SERIALIZATION_DECL bool - is_less_than(const boost::serialization::extended_type_info &rhs) const ; - virtual BOOST_SERIALIZATION_DECL bool - is_equal(const boost::serialization::extended_type_info &rhs) const ; -}; - -} // no_rtti_system - -template -class extended_type_info_no_rtti : - public no_rtti_system::extended_type_info_no_rtti_0, - public singleton > -{ - template - struct action { - struct defined { - static const char * invoke(){ - return guid< T >(); - } - }; - struct undefined { - // if your program traps here - you failed to - // export a guid for this type. the no_rtti - // system requires export for types serialized - // as pointers. - BOOST_STATIC_ASSERT(0 == sizeof(T)); - static const char * invoke(); - }; - static const char * invoke(){ - typedef - typename boost::mpl::if_c< - tf, - defined, - undefined - >::type type; - return type::invoke(); - } - }; -public: - extended_type_info_no_rtti() : - no_rtti_system::extended_type_info_no_rtti_0(get_key()) - { - key_register(); - } - ~extended_type_info_no_rtti(){ - key_unregister(); - } - const extended_type_info * - get_derived_extended_type_info(const T & t) const { - // find the type that corresponds to the most derived type. - // this implementation doesn't depend on typeid() but assumes - // that the specified type has a function of the following signature. - // A common implemention of such a function is to define as a virtual - // function. So if the is not a polymporphic type it's likely an error - BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); - const char * derived_key = t.get_key(); - BOOST_ASSERT(NULL != derived_key); - return boost::serialization::extended_type_info::find(derived_key); - } - const char * get_key() const{ - return action::value >::invoke(); - } - virtual const char * get_debug_info() const{ - return action::value >::invoke(); - } - virtual void * construct(unsigned int count, ...) const{ - // count up the arguments - std::va_list ap; - va_start(ap, count); - switch(count){ - case 0: - return factory::type, 0>(ap); - case 1: - return factory::type, 1>(ap); - case 2: - return factory::type, 2>(ap); - case 3: - return factory::type, 3>(ap); - case 4: - return factory::type, 4>(ap); - default: - BOOST_ASSERT(false); // too many arguments - // throw exception here? - return NULL; - } - } - virtual void destroy(void const * const p) const{ - boost::serialization::access::destroy( - static_cast(p) - ); - //delete static_cast(p) ; - } -}; - -} // namespace serialization -} // namespace boost - -/////////////////////////////////////////////////////////////////////////////// -// If no other implementation has been designated as default, -// use this one. To use this implementation as the default, specify it -// before any of the other headers. - -#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO - #define BOOST_SERIALIZATION_DEFAULT_TYPE_INFO - namespace boost { - namespace serialization { - template - struct extended_type_info_impl { - typedef typename - boost::serialization::extended_type_info_no_rtti< T > type; - }; - } // namespace serialization - } // namespace boost -#endif - -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_EXTENDED_TYPE_INFO_NO_RTTI_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_typeid.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_typeid.hpp deleted file mode 100644 index 8ee591b3169..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/extended_type_info_typeid.hpp +++ /dev/null @@ -1,167 +0,0 @@ -#ifndef BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_TYPEID_HPP -#define BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_TYPEID_HPP - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -// extended_type_info_typeid.hpp: implementation for version that depends -// on runtime typing (rtti - typeid) but uses a user specified string -// as the portable class identifier. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -// hijack serialization access -#include - -#include - -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4251 4231 4660 4275 4511 4512) -#endif - -namespace boost { -namespace serialization { -namespace typeid_system { - -class BOOST_SYMBOL_VISIBLE extended_type_info_typeid_0 : - public extended_type_info -{ - virtual const char * get_debug_info() const { - if(static_cast(0) == m_ti) - return static_cast(0); - return m_ti->name(); - } -protected: - const std::type_info * m_ti; - BOOST_SERIALIZATION_DECL extended_type_info_typeid_0(const char * key); - BOOST_SERIALIZATION_DECL ~extended_type_info_typeid_0(); - BOOST_SERIALIZATION_DECL void type_register(const std::type_info & ti); - BOOST_SERIALIZATION_DECL void type_unregister(); - BOOST_SERIALIZATION_DECL const extended_type_info * - get_extended_type_info(const std::type_info & ti) const; -public: - virtual BOOST_SERIALIZATION_DECL bool - is_less_than(const extended_type_info &rhs) const; - virtual BOOST_SERIALIZATION_DECL bool - is_equal(const extended_type_info &rhs) const; - const std::type_info & get_typeid() const { - return *m_ti; - } -}; - -} // typeid_system - -template -class extended_type_info_typeid : - public typeid_system::extended_type_info_typeid_0, - public singleton > -{ -public: - extended_type_info_typeid() : - typeid_system::extended_type_info_typeid_0( - boost::serialization::guid< T >() - ) - { - type_register(typeid(T)); - key_register(); - } - ~extended_type_info_typeid(){ - key_unregister(); - type_unregister(); - } - // get the eti record for the true type of this record - // relying upon standard type info implemenation (rtti) - const extended_type_info * - get_derived_extended_type_info(const T & t) const { - // note: this implementation - based on usage of typeid (rtti) - // only does something if the class has at least one virtual function. - BOOST_STATIC_WARNING(boost::is_polymorphic< T >::value); - return - typeid_system::extended_type_info_typeid_0::get_extended_type_info( - typeid(t) - ); - } - const char * get_key() const { - return boost::serialization::guid< T >(); - } - virtual void * construct(unsigned int count, ...) const{ - // count up the arguments - std::va_list ap; - va_start(ap, count); - switch(count){ - case 0: - return factory::type, 0>(ap); - case 1: - return factory::type, 1>(ap); - case 2: - return factory::type, 2>(ap); - case 3: - return factory::type, 3>(ap); - case 4: - return factory::type, 4>(ap); - default: - BOOST_ASSERT(false); // too many arguments - // throw exception here? - return NULL; - } - } - virtual void destroy(void const * const p) const { - boost::serialization::access::destroy( - static_cast(p) - ); - //delete static_cast(p); - } -}; - -} // namespace serialization -} // namespace boost - -/////////////////////////////////////////////////////////////////////////////// -// If no other implementation has been designated as default, -// use this one. To use this implementation as the default, specify it -// before any of the other headers. -#ifndef BOOST_SERIALIZATION_DEFAULT_TYPE_INFO - #define BOOST_SERIALIZATION_DEFAULT_TYPE_INFO - namespace boost { - namespace serialization { - template - struct extended_type_info_impl { - typedef typename - boost::serialization::extended_type_info_typeid< T > type; - }; - } // namespace serialization - } // namespace boost -#endif - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_SERIALIZATION_EXTENDED_TYPE_INFO_TYPEID_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/factory.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/factory.hpp deleted file mode 100644 index 2db7e7e36c3..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/factory.hpp +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef BOOST_SERIALIZATION_FACTORY_HPP -#define BOOST_SERIALIZATION_FACTORY_HPP - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -// factory.hpp: create an instance from an extended_type_info instance. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // valist -#include // NULL - -#include -#include -#include - -namespace std{ - #if defined(__LIBCOMO__) - using ::va_list; - #endif -} // namespace std - -namespace boost { -namespace serialization { - -// default implementation does nothing. -template -T * factory(std::va_list){ - BOOST_ASSERT(false); - // throw exception here? - return NULL; -} - -} // namespace serialization -} // namespace boost - -#define BOOST_SERIALIZATION_FACTORY(N, T, A0, A1, A2, A3) \ -namespace boost { \ -namespace serialization { \ - template<> \ - T * factory(std::va_list ap){ \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 0) \ - , A0 a0 = va_arg(ap, A0);, BOOST_PP_EMPTY()) \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 1) \ - , A1 a1 = va_arg(ap, A1);, BOOST_PP_EMPTY()) \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 2) \ - , A2 a2 = va_arg(ap, A2);, BOOST_PP_EMPTY()) \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 3) \ - , A3 a3 = va_arg(ap, A3);, BOOST_PP_EMPTY()) \ - return new T( \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 0) \ - , a0, BOOST_PP_EMPTY()) \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 1)) \ - , BOOST_PP_COMMA, BOOST_PP_EMPTY)() \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 1) \ - , a1, BOOST_PP_EMPTY()) \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 2)) \ - , BOOST_PP_COMMA, BOOST_PP_EMPTY)() \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 2) \ - , a2, BOOST_PP_EMPTY()) \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 3)) \ - , BOOST_PP_COMMA, BOOST_PP_EMPTY)() \ - BOOST_PP_IF(BOOST_PP_GREATER(N, 3) \ - , a3, BOOST_PP_EMPTY()) \ - ); \ - } \ -} \ -} /**/ - -#define BOOST_SERIALIZATION_FACTORY_4(T, A0, A1, A2, A3) \ - BOOST_SERIALIZATION_FACTORY(4, T, A0, A1, A2, A3) - -#define BOOST_SERIALIZATION_FACTORY_3(T, A0, A1, A2) \ - BOOST_SERIALIZATION_FACTORY(3, T, A0, A1, A2, 0) - -#define BOOST_SERIALIZATION_FACTORY_2(T, A0, A1) \ - BOOST_SERIALIZATION_FACTORY(2, T, A0, A1, 0, 0) - -#define BOOST_SERIALIZATION_FACTORY_1(T, A0) \ - BOOST_SERIALIZATION_FACTORY(1, T, A0, 0, 0, 0) - -#define BOOST_SERIALIZATION_FACTORY_0(T) \ -namespace boost { \ -namespace serialization { \ - template<> \ - T * factory(std::va_list){ \ - return new T(); \ - } \ -} \ -} \ -/**/ - -#endif // BOOST_SERIALIZATION_FACTORY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/force_include.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/force_include.hpp deleted file mode 100644 index 55ab79d0d58..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/force_include.hpp +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef BOOST_SERIALIZATION_FORCE_INCLUDE_HPP -#define BOOST_SERIALIZATION_FORCE_INCLUDE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// force_include.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -// the following help macro is to guarentee that certain coded -// is not removed by over-eager linker optimiser. In certain cases -// we create static objects must be created but are actually never -// referenced - creation has a side-effect such as global registration -// which is important to us. We make an effort to refer these objects -// so that a smart linker won't remove them as being unreferenced. -// In microsoft compilers, inlining the code that does the referring -// means the code gets lost and the static object is not included -// in the library and hence never registered. This manifests itself -// in an ungraceful crash at runtime when (and only when) built in -// release mode. - -#if defined(BOOST_HAS_DECLSPEC) && !defined(__COMO__) -# define BOOST_DLLEXPORT __declspec(dllexport) -#elif ! defined(_WIN32) && ! defined(_WIN64) -# if defined(__MWERKS__) -# define BOOST_DLLEXPORT __declspec(dllexport) -# elif defined(__GNUC__) && (__GNUC__ >= 3) -# define BOOST_USED __attribute__ ((__used__)) -# elif defined(__IBMCPP__) && (__IBMCPP__ >= 1110) -# define BOOST_USED __attribute__ ((__used__)) -# elif defined(__INTEL_COMPILER) && (BOOST_INTEL_CXX_VERSION >= 800) -# define BOOST_USED __attribute__ ((__used__)) -# endif -#endif - -#ifndef BOOST_USED -# define BOOST_USED -#endif - -#ifndef BOOST_DLLEXPORT -# define BOOST_DLLEXPORT -#endif - -#endif // BOOST_SERIALIZATION_FORCE_INCLUDE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/forward_list.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/forward_list.hpp deleted file mode 100644 index b8a3c20a6ea..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/forward_list.hpp +++ /dev/null @@ -1,124 +0,0 @@ -#ifndef BOOST_SERIALIZATION_FORWARD_LIST_HPP -#define BOOST_SERIALIZATION_FORWARD_LIST_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// forward_list.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include // distance - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template -inline void save( - Archive & ar, - const std::forward_list &t, - const unsigned int /*file_version*/ -){ - const collection_size_type count(std::distance(t.cbegin(), t.cend())); - boost::serialization::stl::save_collection< - Archive, - std::forward_list - >(ar, t, count); -} - -namespace stl { - -template< - class Archive, - class T, - class Allocator -> -typename boost::disable_if< - typename detail::is_default_constructible< - typename std::forward_list::value_type - >, - void ->::type -collection_load_impl( - Archive & ar, - std::forward_list &t, - collection_size_type count, - item_version_type item_version -){ - t.clear(); - boost::serialization::detail::stack_construct u(ar, item_version); - ar >> boost::serialization::make_nvp("item", u.reference()); - t.push_front(boost::move(u.reference())); - typename std::forward_list::iterator last; - last = t.begin(); - ar.reset_object_address(&(*t.begin()) , & u.reference()); - while(--count > 0){ - detail::stack_construct u(ar, item_version); - ar >> boost::serialization::make_nvp("item", u.reference()); - last = t.insert_after(last, boost::move(u.reference())); - ar.reset_object_address(&(*last) , & u.reference()); - } -} - -} // stl - -template -inline void load( - Archive & ar, - std::forward_list &t, - const unsigned int /*file_version*/ -){ - const boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - item_version_type item_version(0); - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - stl::collection_load_impl(ar, t, count, item_version); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::forward_list &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(std::forward_list) - -#endif // BOOST_SERIALIZATION_FORWARD_LIST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_load_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_load_imp.hpp deleted file mode 100644 index 88def8f1aa4..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_load_imp.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef BOOST_SERIALIZATION_HASH_COLLECTIONS_LOAD_IMP_HPP -#define BOOST_SERIALIZATION_HASH_COLLECTIONS_LOAD_IMP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -# pragma warning (disable : 4786) // too long name, harmless warning -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// hash_collections_load_imp.hpp: serialization for loading stl collections - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// helper function templates for serialization of hashed collections -#include -#include -#include -#include -#include - -namespace boost{ -namespace serialization { -namespace stl { - -////////////////////////////////////////////////////////////////////// -// implementation of serialization for STL containers -// -template -inline void load_hash_collection(Archive & ar, Container &s) -{ - collection_size_type count; - collection_size_type bucket_count; - boost::serialization::item_version_type item_version(0); - boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - if(boost::archive::library_version_type(6) != library_version){ - ar >> BOOST_SERIALIZATION_NVP(count); - ar >> BOOST_SERIALIZATION_NVP(bucket_count); - } - else{ - // note: fixup for error in version 6. collection size was - // changed to size_t BUT for hashed collections it was implemented - // as an unsigned int. This should be a problem only on win64 machines - // but I'll leave it for everyone just in case. - unsigned int c; - unsigned int bc; - ar >> BOOST_SERIALIZATION_NVP(c); - count = c; - ar >> BOOST_SERIALIZATION_NVP(bc); - bucket_count = bc; - } - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - s.clear(); - #if ! defined(__MWERKS__) - s.resize(bucket_count); - #endif - InputFunction ifunc; - while(count-- > 0){ - ifunc(ar, s, item_version); - } -} - -} // namespace stl -} // namespace serialization -} // namespace boost - -#endif //BOOST_SERIALIZATION_HASH_COLLECTIONS_LOAD_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_save_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_save_imp.hpp deleted file mode 100644 index 65dfe83f16e..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/hash_collections_save_imp.hpp +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef BOOST_SERIALIZATION_HASH_COLLECTIONS_SAVE_IMP_HPP -#define BOOST_SERIALIZATION_HASH_COLLECTIONS_SAVE_IMP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// hash_collections_save_imp.hpp: serialization for stl collections - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// helper function templates for serialization of collections - -#include -#include -#include -#include -#include -#include - -namespace boost{ -namespace serialization { -namespace stl { - -////////////////////////////////////////////////////////////////////// -// implementation of serialization for STL containers -// - -template -inline void save_hash_collection(Archive & ar, const Container &s) -{ - collection_size_type count(s.size()); - const collection_size_type bucket_count(s.bucket_count()); - const item_version_type item_version( - version::value - ); - - #if 0 - /* should only be necessary to create archives of previous versions - * which is not currently supported. So for now comment this out - */ - boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - if(boost::archive::library_version_type(6) != library_version){ - ar << BOOST_SERIALIZATION_NVP(count); - ar << BOOST_SERIALIZATION_NVP(bucket_count); - } - else{ - // note: fixup for error in version 6. collection size was - // changed to size_t BUT for hashed collections it was implemented - // as an unsigned int. This should be a problem only on win64 machines - // but I'll leave it for everyone just in case. - const unsigned int c = count; - const unsigned int bc = bucket_count; - ar << BOOST_SERIALIZATION_NVP(c); - ar << BOOST_SERIALIZATION_NVP(bc); - } - if(boost::archive::library_version_type(3) < library_version){ - // record number of elements - // make sure the target type is registered so we can retrieve - // the version when we load - ar << BOOST_SERIALIZATION_NVP(item_version); - } - #else - ar << BOOST_SERIALIZATION_NVP(count); - ar << BOOST_SERIALIZATION_NVP(bucket_count); - ar << BOOST_SERIALIZATION_NVP(item_version); - #endif - - typename Container::const_iterator it = s.begin(); - while(count-- > 0){ - // note borland emits a no-op without the explicit namespace - boost::serialization::save_construct_data_adl( - ar, - &(*it), - boost::serialization::version< - typename Container::value_type - >::value - ); - ar << boost::serialization::make_nvp("item", *it++); - } -} - -} // namespace stl -} // namespace serialization -} // namespace boost - -#endif //BOOST_SERIALIZATION_HASH_COLLECTIONS_SAVE_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/hash_map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/hash_map.hpp deleted file mode 100644 index 22626db6838..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/hash_map.hpp +++ /dev/null @@ -1,232 +0,0 @@ -#ifndef BOOST_SERIALIZATION_HASH_MAP_HPP -#define BOOST_SERIALIZATION_HASH_MAP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization/hash_map.hpp: -// serialization for stl hash_map templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifdef BOOST_HAS_HASH -#include BOOST_HASH_MAP_HEADER - -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -namespace stl { - -// map input -template -struct archive_input_hash_map -{ - inline void operator()( - Archive &ar, - Container &s, - const unsigned int v - ){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, v); - // borland fails silently w/o full namespace - ar >> boost::serialization::make_nvp("item", t.reference()); - std::pair result = - s.insert(boost::move(t.reference())); - // note: the following presumes that the map::value_type was NOT tracked - // in the archive. This is the usual case, but here there is no way - // to determine that. - if(result.second){ - ar.reset_object_address( - & (result.first->second), - & t.reference().second - ); - } - } -}; - -// multimap input -template -struct archive_input_hash_multimap -{ - inline void operator()( - Archive &ar, - Container &s, - const unsigned int v - ){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, v); - // borland fails silently w/o full namespace - ar >> boost::serialization::make_nvp("item", t.reference()); - typename Container::const_iterator result - = s.insert(boost::move(t.reference())); - // note: the following presumes that the map::value_type was NOT tracked - // in the archive. This is the usual case, but here there is no way - // to determine that. - ar.reset_object_address( - & result->second, - & t.reference() - ); - } -}; - -} // stl - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const BOOST_STD_EXTENSION_NAMESPACE::hash_map< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::stl::save_hash_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_map< - Key, HashFcn, EqualKey, Allocator - > - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::hash_map< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::stl::load_hash_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_map< - Key, HashFcn, EqualKey, Allocator - >, - boost::serialization::stl::archive_input_hash_map< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_map< - Key, HashFcn, EqualKey, Allocator - > - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::hash_map< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -// hash_multimap -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::stl::save_hash_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< - Key, HashFcn, EqualKey, Allocator - > - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::stl::load_hash_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< - Key, HashFcn, EqualKey, Allocator - >, - boost::serialization::stl::archive_input_hash_multimap< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< - Key, HashFcn, EqualKey, Allocator - > - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::hash_multimap< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_HAS_HASH -#endif // BOOST_SERIALIZATION_HASH_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/hash_set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/hash_set.hpp deleted file mode 100644 index 0c72c18457e..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/hash_set.hpp +++ /dev/null @@ -1,222 +0,0 @@ -#ifndef BOOST_SERIALIZATION_HASH_SET_HPP -#define BOOST_SERIALIZATION_HASH_SET_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// hash_set.hpp: serialization for stl hash_set templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifdef BOOST_HAS_HASH -#include BOOST_HASH_SET_HEADER - -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -namespace stl { - -// hash_set input -template -struct archive_input_hash_set -{ - inline void operator()( - Archive &ar, - Container &s, - const unsigned int v - ){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, v); - // borland fails silently w/o full namespace - ar >> boost::serialization::make_nvp("item", t.reference()); - std::pair result = - s.insert(boost::move(t.reference())); - if(result.second) - ar.reset_object_address(& (* result.first), & t.reference()); - } -}; - -// hash_multiset input -template -struct archive_input_hash_multiset -{ - inline void operator()( - Archive &ar, - Container &s, - const unsigned int v - ){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, v); - // borland fails silently w/o full namespace - ar >> boost::serialization::make_nvp("item", t.reference()); - typename Container::const_iterator result - = s.insert(boost::move(t.reference())); - ar.reset_object_address(& (* result), & t.reference()); - } -}; - -} // stl - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const BOOST_STD_EXTENSION_NAMESPACE::hash_set< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::stl::save_hash_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_set< - Key, HashFcn, EqualKey, Allocator - > - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::hash_set< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::stl::load_hash_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_set< - Key, HashFcn, EqualKey, Allocator - >, - boost::serialization::stl::archive_input_hash_set< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_set< - Key, HashFcn, EqualKey, Allocator - > - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::hash_set< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -// hash_multiset -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::stl::save_hash_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< - Key, HashFcn, EqualKey, Allocator - > - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::stl::load_hash_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< - Key, HashFcn, EqualKey, Allocator - >, - boost::serialization::stl::archive_input_hash_multiset< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< - Key, HashFcn, EqualKey, Allocator - > - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::hash_multiset< - Key, HashFcn, EqualKey, Allocator - > & t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(BOOST_STD_EXTENSION_NAMESPACE::hash_set) -BOOST_SERIALIZATION_COLLECTION_TRAITS(BOOST_STD_EXTENSION_NAMESPACE::hash_multiset) - -#endif // BOOST_HAS_HASH -#endif // BOOST_SERIALIZATION_HASH_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/is_bitwise_serializable.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/is_bitwise_serializable.hpp deleted file mode 100644 index 7e24a2cb6d8..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/is_bitwise_serializable.hpp +++ /dev/null @@ -1,46 +0,0 @@ -// (C) Copyright 2007 Matthias Troyer - -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// Authors: Matthias Troyer - -/** @file is_bitwise_serializable.hpp - * - * This header provides a traits class for determining whether a class - * can be serialized (in a non-portable way) just by copying the bits. - */ - - -#ifndef BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP -#define BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -#include -#include - -namespace boost { -namespace serialization { - template - struct is_bitwise_serializable - : public is_arithmetic< T > - {}; -} // namespace serialization -} // namespace boost - - -// define a macro to make explicit designation of this more transparent -#define BOOST_IS_BITWISE_SERIALIZABLE(T) \ -namespace boost { \ -namespace serialization { \ -template<> \ -struct is_bitwise_serializable< T > : mpl::true_ {}; \ -}} \ -/**/ - -#endif //BOOST_SERIALIZATION_IS_BITWISE_SERIALIZABLE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/item_version_type.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/item_version_type.hpp deleted file mode 100644 index f3e5adac6f8..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/item_version_type.hpp +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef BOOST_SERIALIZATION_ITEM_VERSION_TYPE_HPP -#define BOOST_SERIALIZATION_ITEM_VERSION_TYPE_HPP - -// (C) Copyright 2010 Robert Ramey -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include // uint_least8_t -#include -#include -#include - -// fixes broken example build on x86_64-linux-gnu-gcc-4.6.0 -#include - -namespace boost { -namespace serialization { - -#if defined(_MSC_VER) -#pragma warning( push ) -#pragma warning( disable : 4244 4267 ) -#endif - -class item_version_type { -private: - typedef unsigned int base_type; - base_type t; -public: - // should be private - but MPI fails if it's not!!! - item_version_type(): t(0) {}; - explicit item_version_type(const unsigned int t_) : t(t_){ - BOOST_ASSERT(t_ <= boost::integer_traits::const_max); - } - item_version_type(const item_version_type & t_) : - t(t_.t) - {} - item_version_type & operator=(item_version_type rhs){ - t = rhs.t; - return *this; - } - // used for text output - operator base_type () const { - return t; - } - // used for text input - operator base_type & () { - return t; - } - bool operator==(const item_version_type & rhs) const { - return t == rhs.t; - } - bool operator<(const item_version_type & rhs) const { - return t < rhs.t; - } -}; - -#if defined(_MSC_VER) -#pragma warning( pop ) -#endif - -} } // end namespace boost::serialization - -BOOST_IS_BITWISE_SERIALIZABLE(item_version_type) - -BOOST_CLASS_IMPLEMENTATION(item_version_type, primitive_type) - -#endif //BOOST_SERIALIZATION_ITEM_VERSION_TYPE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/level.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/level.hpp deleted file mode 100644 index f6a84d10422..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/level.hpp +++ /dev/null @@ -1,116 +0,0 @@ -#ifndef BOOST_SERIALIZATION_LEVEL_HPP -#define BOOST_SERIALIZATION_LEVEL_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// level.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -namespace boost { -namespace serialization { - -struct basic_traits; - -// default serialization implementation level -template -struct implementation_level_impl { - template - struct traits_class_level { - typedef typename U::level type; - }; - - typedef mpl::integral_c_tag tag; - // note: at least one compiler complained w/o the full qualification - // on basic traits below - typedef - typename mpl::eval_if< - is_base_and_derived, - traits_class_level< T >, - //else - typename mpl::eval_if< - is_fundamental< T >, - mpl::int_, - //else - typename mpl::eval_if< - is_class< T >, - mpl::int_, - //else - typename mpl::eval_if< - is_array< T >, - mpl::int_, - //else - typename mpl::eval_if< - is_enum< T >, - mpl::int_, - //else - mpl::int_ - > - > - > - > - >::type type; - // vc 7.1 doesn't like enums here - BOOST_STATIC_CONSTANT(int, value = type::value); -}; - -template -struct implementation_level : - public implementation_level_impl -{ -}; - -template -inline bool operator>=(implementation_level< T > t, enum level_type l) -{ - return t.value >= (int)l; -} - -} // namespace serialization -} // namespace boost - -// specify the level of serialization implementation for the class -// require that class info saved when versioning is used -#define BOOST_CLASS_IMPLEMENTATION(T, E) \ - namespace boost { \ - namespace serialization { \ - template <> \ - struct implementation_level_impl< const T > \ - { \ - typedef mpl::integral_c_tag tag; \ - typedef mpl::int_< E > type; \ - BOOST_STATIC_CONSTANT( \ - int, \ - value = implementation_level_impl::type::value \ - ); \ - }; \ - } \ - } - /**/ - -#endif // BOOST_SERIALIZATION_LEVEL_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/level_enum.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/level_enum.hpp deleted file mode 100644 index baf64e04f31..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/level_enum.hpp +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef BOOST_SERIALIZATION_LEVEL_ENUM_HPP -#define BOOST_SERIALIZATION_LEVEL_ENUM_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// level_enum.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -namespace boost { -namespace serialization { - -// for each class used in the program, specify which level -// of serialization should be implemented - -// names for each level -enum level_type -{ - // Don't serialize this type. An attempt to do so should - // invoke a compile time assertion. - not_serializable = 0, - // write/read this type directly to the archive. In this case - // serialization code won't be called. This is the default - // case for fundamental types. It presumes a member function or - // template in the archive class that can handle this type. - // there is no runtime overhead associated reading/writing - // instances of this level - primitive_type = 1, - // Serialize the objects of this type using the objects "serialize" - // function or template. This permits values to be written/read - // to/from archives but includes no class or version information. - object_serializable = 2, - /////////////////////////////////////////////////////////////////// - // once an object is serialized at one of the above levels, the - // corresponding archives cannot be read if the implementation level - // for the archive object is changed. - /////////////////////////////////////////////////////////////////// - // Add class information to the archive. Class information includes - // implementation level, class version and class name if available - object_class_info = 3 -}; - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_LEVEL_ENUM_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/list.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/list.hpp deleted file mode 100644 index 5fdc114d7ed..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/list.hpp +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef BOOST_SERIALIZATION_LIST_HPP -#define BOOST_SERIALIZATION_LIST_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// list.hpp: serialization for stl list templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template -inline void save( - Archive & ar, - const std::list &t, - const unsigned int /* file_version */ -){ - boost::serialization::stl::save_collection< - Archive, - std::list - >(ar, t); -} - -template -inline void load( - Archive & ar, - std::list &t, - const unsigned int /* file_version */ -){ - const boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - item_version_type item_version(0); - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - stl::collection_load_impl(ar, t, count, item_version); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::list & t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(std::list) - -#endif // BOOST_SERIALIZATION_LIST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/map.hpp deleted file mode 100644 index 9209864c8cf..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/map.hpp +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef BOOST_SERIALIZATION_MAP_HPP -#define BOOST_SERIALIZATION_MAP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization/map.hpp: -// serialization for stl map templates - -// (C) Copyright 2002-2014 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// implementation of serialization for map and mult-map STL containers - -template -inline void load_map_collection(Archive & ar, Container &s) -{ - s.clear(); - const boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - item_version_type item_version(0); - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - typename Container::iterator hint; - hint = s.begin(); - while(count-- > 0){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, item_version); - ar >> boost::serialization::make_nvp("item", t.reference()); - typename Container::iterator result = - s.insert(hint, boost::move(t.reference())); - ar.reset_object_address(& (result->second), & t.reference().second); - hint = result; - ++hint; - } -} - -// map -template -inline void save( - Archive & ar, - const std::map &t, - const unsigned int /* file_version */ -){ - boost::serialization::stl::save_collection< - Archive, - std::map - >(ar, t); -} - -template -inline void load( - Archive & ar, - std::map &t, - const unsigned int /* file_version */ -){ - load_map_collection(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::map &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -// multimap -template -inline void save( - Archive & ar, - const std::multimap &t, - const unsigned int /* file_version */ -){ - boost::serialization::stl::save_collection< - Archive, - std::multimap - >(ar, t); -} - -template -inline void load( - Archive & ar, - std::multimap &t, - const unsigned int /* file_version */ -){ - load_map_collection(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::multimap &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/nvp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/nvp.hpp deleted file mode 100644 index 4e2297b3cc9..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/nvp.hpp +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef BOOST_SERIALIZATION_NVP_HPP -#define BOOST_SERIALIZATION_NVP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// nvp.hpp: interface for serialization system. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template -struct nvp : - public std::pair, - public wrapper_traits > -{ -//private: - nvp(const nvp & rhs) : - std::pair(rhs.first, rhs.second) - {} -public: - explicit nvp(const char * name_, T & t) : - // note: added _ to suppress useless gcc warning - std::pair(name_, & t) - {} - - const char * name() const { - return this->first; - } - T & value() const { - return *(this->second); - } - - const T & const_value() const { - return *(this->second); - } - - template - void save( - Archive & ar, - const unsigned int /* file_version */ - ) const { - ar.operator<<(const_value()); - } - template - void load( - Archive & ar, - const unsigned int /* file_version */ - ){ - ar.operator>>(value()); - } - BOOST_SERIALIZATION_SPLIT_MEMBER() -}; - -template -inline -const nvp< T > make_nvp(const char * name, T & t){ - return nvp< T >(name, t); -} - -// to maintain efficiency and portability, we want to assign -// specific serialization traits to all instances of this wrappers. -// we can't strait forward method below as it depends upon -// Partial Template Specialization and doing so would mean that wrappers -// wouldn't be treated the same on different platforms. This would -// break archive portability. Leave this here as reminder not to use it !!! - -template -struct implementation_level > -{ - typedef mpl::integral_c_tag tag; - typedef mpl::int_ type; - BOOST_STATIC_CONSTANT(int, value = implementation_level::type::value); -}; - -// nvp objects are generally created on the stack and are never tracked -template -struct tracking_level > -{ - typedef mpl::integral_c_tag tag; - typedef mpl::int_ type; - BOOST_STATIC_CONSTANT(int, value = tracking_level::type::value); -}; - -} // seralization -} // boost - -#include - -#define BOOST_SERIALIZATION_NVP(name) \ - boost::serialization::make_nvp(BOOST_PP_STRINGIZE(name), name) -/**/ - -#define BOOST_SERIALIZATION_BASE_OBJECT_NVP(name) \ - boost::serialization::make_nvp( \ - BOOST_PP_STRINGIZE(name), \ - boost::serialization::base_object(*this) \ - ) -/**/ - -#endif // BOOST_SERIALIZATION_NVP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/optional.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/optional.hpp deleted file mode 100644 index d6ff830a8c3..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/optional.hpp +++ /dev/null @@ -1,107 +0,0 @@ -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 - -// (C) Copyright 2002-4 Pavel Vozenilek . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// Provides non-intrusive serialization for boost::optional. - -#ifndef BOOST_SERIALIZATION_OPTIONAL_HPP_ -#define BOOST_SERIALIZATION_OPTIONAL_HPP_ - -#if defined(_MSC_VER) -# pragma once -#endif - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// function specializations must be defined in the appropriate -// namespace - boost::serialization -namespace boost { -namespace serialization { - -template -void save( - Archive & ar, - const boost::optional< T > & t, - const unsigned int /*version*/ -){ - // It is an inherent limitation to the serialization of optional.hpp - // that the underlying type must be either a pointer or must have a - // default constructor. It's possible that this could change sometime - // in the future, but for now, one will have to work around it. This can - // be done by serialization the optional as optional - #if ! defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) - BOOST_STATIC_ASSERT( - boost::serialization::detail::is_default_constructible::value - || boost::is_pointer::value - ); - #endif - const bool tflag = t.is_initialized(); - ar << boost::serialization::make_nvp("initialized", tflag); - if (tflag){ - ar << boost::serialization::make_nvp("value", *t); - } -} - -template -void load( - Archive & ar, - boost::optional< T > & t, - const unsigned int version -){ - bool tflag; - ar >> boost::serialization::make_nvp("initialized", tflag); - if(! tflag){ - t.reset(); - return; - } - - if(0 == version){ - boost::serialization::item_version_type item_version(0); - boost::archive::library_version_type library_version( - ar.get_library_version() - ); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - } - if(! t.is_initialized()) - t = T(); - ar >> boost::serialization::make_nvp("value", *t); -} - -template -void serialize( - Archive & ar, - boost::optional< T > & t, - const unsigned int version -){ - boost::serialization::split_free(ar, t, version); -} - -template -struct version > { - BOOST_STATIC_CONSTANT(int, value = 1); -}; - -} // serialization -} // boost - -#endif // BOOST_SERIALIZATION_OPTIONAL_HPP_ diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/priority_queue.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/priority_queue.hpp deleted file mode 100644 index 5b08ffd1e82..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/priority_queue.hpp +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef BOOST_SERIALIZATION_PRIORITY_QUEUE_HPP -#define BOOST_SERIALIZATION_PRIORITY_QUEUE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// priority_queue.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include - -// function specializations must be defined in the appropriate -// namespace - boost::serialization -#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) -#define STD _STLP_STD -#else -#define STD std -#endif - -namespace boost { -namespace serialization { -namespace detail{ - -template -struct priority_queue_save : public STD::priority_queue { - template - void operator()(Archive & ar, const unsigned int file_version) const { - save(ar, STD::priority_queue::c, file_version); - } -}; -template -struct priority_queue_load : public STD::priority_queue { - template - void operator()(Archive & ar, const unsigned int file_version) { - load(ar, STD::priority_queue::c, file_version); - } -}; - -} // detail - -template -inline void serialize( - Archive & ar, - std::priority_queue< T, Container, Compare> & t, - const unsigned int file_version -){ - typedef typename mpl::eval_if< - typename Archive::is_saving, - mpl::identity >, - mpl::identity > - >::type typex; - static_cast(t)(ar, file_version); -} - -} // namespace serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::priority_queue) - -#undef STD - -#endif // BOOST_SERIALIZATION_PRIORITY_QUEUE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/queue.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/queue.hpp deleted file mode 100644 index b22745215d9..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/queue.hpp +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef BOOST_SERIALIZATION_QUEUE_HPP -#define BOOST_SERIALIZATION_QUEUE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// queue.hpp - -// (C) Copyright 2014 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include - -// function specializations must be defined in the appropriate -// namespace - boost::serialization -#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) -#define STD _STLP_STD -#else -#define STD std -#endif - -namespace boost { -namespace serialization { -namespace detail { - -template -struct queue_save : public STD::queue { - template - void operator()(Archive & ar, const unsigned int file_version) const { - save(ar, STD::queue::c, file_version); - } -}; -template -struct queue_load : public STD::queue { - template - void operator()(Archive & ar, const unsigned int file_version) { - load(ar, STD::queue::c, file_version); - } -}; - -} // detail - -template -inline void serialize( - Archive & ar, - std::queue< T, C> & t, - const unsigned int file_version -){ - typedef typename mpl::eval_if< - typename Archive::is_saving, - mpl::identity >, - mpl::identity > - >::type typex; - static_cast(t)(ar, file_version); -} - -} // namespace serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::queue) - -#undef STD - -#endif // BOOST_SERIALIZATION_QUEUE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/scoped_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/scoped_ptr.hpp deleted file mode 100644 index 0d11f8436e0..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/scoped_ptr.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SCOPED_PTR_HPP_VP_2003_10_30 -#define BOOST_SERIALIZATION_SCOPED_PTR_HPP_VP_2003_10_30 - -#if defined(_MSC_VER) -# pragma once -#endif - -// Copyright (c) 2003 Vladimir Prus. -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// Provides non-intrusive serialization for boost::scoped_ptr -// Does not allow to serialize scoped_ptr's to builtin types. - -#include - -#include -#include -#include - -namespace boost { -namespace serialization { - - template - void save( - Archive & ar, - const boost::scoped_ptr< T > & t, - const unsigned int /* version */ - ){ - T* r = t.get(); - ar << boost::serialization::make_nvp("scoped_ptr", r); - } - - template - void load( - Archive & ar, - boost::scoped_ptr< T > & t, - const unsigned int /* version */ - ){ - T* r; - ar >> boost::serialization::make_nvp("scoped_ptr", r); - t.reset(r); - } - - template - void serialize( - Archive& ar, - boost::scoped_ptr< T >& t, - const unsigned int version - ){ - boost::serialization::split_free(ar, t, version); - } - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_SCOPED_PTR_HPP_VP_2003_10_30 diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/serialization.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/serialization.hpp deleted file mode 100644 index a4d04723c75..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/serialization.hpp +++ /dev/null @@ -1,154 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SERIALIZATION_HPP -#define BOOST_SERIALIZATION_SERIALIZATION_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -#if defined(_MSC_VER) -# pragma warning (disable : 4675) // suppress ADL warning -#endif - -#include -#include - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization.hpp: interface for serialization system. - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -////////////////////////////////////////////////////////////////////// -// public interface to serialization. - -///////////////////////////////////////////////////////////////////////////// -// layer 0 - intrusive verison -// declared and implemented for each user defined class to be serialized -// -// template -// serialize(Archive &ar, const unsigned int file_version){ -// ar & base_object(*this) & member1 & member2 ... ; -// } - -///////////////////////////////////////////////////////////////////////////// -// layer 1 - layer that routes member access through the access class. -// this is what permits us to grant access to private class member functions -// by specifying friend class boost::serialization::access - -#include - -///////////////////////////////////////////////////////////////////////////// -// layer 2 - default implementation of non-intrusive serialization. -// -// note the usage of function overloading to compensate that C++ does not -// currently support Partial Template Specialization for function templates -// We have declared the version number as "const unsigned long". -// Overriding templates for specific data types should declare the version -// number as "const unsigned int". Template matching will first be applied -// to functions with the same version types - that is the overloads. -// If there is no declared function prototype that matches, the second argument -// will be converted to "const unsigned long" and a match will be made with -// one of the default template functions below. - -namespace boost { -namespace serialization { - -BOOST_STRONG_TYPEDEF(unsigned int, version_type) - -// default implementation - call the member function "serialize" -template -inline void serialize( - Archive & ar, T & t, const unsigned int file_version -){ - access::serialize(ar, t, static_cast(file_version)); -} - -// save data required for construction -template -inline void save_construct_data( - Archive & /*ar*/, - const T * /*t*/, - const unsigned int /*file_version */ -){ - // default is to save no data because default constructor - // requires no arguments. -} - -// load data required for construction and invoke constructor in place -template -inline void load_construct_data( - Archive & /*ar*/, - T * t, - const unsigned int /*file_version*/ -){ - // default just uses the default constructor. going - // through access permits usage of otherwise private default - // constructor - access::construct(t); -} - -///////////////////////////////////////////////////////////////////////////// -// layer 3 - move call into serialization namespace so that ADL will function -// in the manner we desire. -// -// on compilers which don't implement ADL. only the current namespace -// i.e. boost::serialization will be searched. -// -// on compilers which DO implement ADL -// serialize overrides can be in any of the following -// -// 1) same namepace as Archive -// 2) same namespace as T -// 3) boost::serialization -// -// Due to Martin Ecker - -template -inline void serialize_adl( - Archive & ar, - T & t, - const unsigned int file_version -){ - // note usage of function overloading to delay final resolution - // until the point of instantiation. This works around the two-phase - // lookup "feature" which inhibits redefintion of a default function - // template implementation. Due to Robert Ramey - // - // Note that this trick generates problems for compiles which don't support - // PFTO, suppress it here. As far as we know, there are no compilers - // which fail to support PFTO while supporting two-phase lookup. - const version_type v(file_version); - serialize(ar, t, v); -} - -template -inline void save_construct_data_adl( - Archive & ar, - const T * t, - const unsigned int file_version -){ - // see above - const version_type v(file_version); - save_construct_data(ar, t, v); -} - -template -inline void load_construct_data_adl( - Archive & ar, - T * t, - const unsigned int file_version -){ - // see above comment - const version_type v(file_version); - load_construct_data(ar, t, v); -} - -} // namespace serialization -} // namespace boost - -#endif //BOOST_SERIALIZATION_SERIALIZATION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/set.hpp deleted file mode 100644 index 643906c5aac..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/set.hpp +++ /dev/null @@ -1,137 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SET_HPP -#define BOOST_SERIALIZATION_SET_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// set.hpp: serialization for stl set templates - -// (C) Copyright 2002-2014 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace boost { -namespace serialization { - -template -inline void load_set_collection(Archive & ar, Container &s) -{ - s.clear(); - const boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - item_version_type item_version(0); - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - typename Container::iterator hint; - hint = s.begin(); - while(count-- > 0){ - typedef typename Container::value_type type; - detail::stack_construct t(ar, item_version); - // borland fails silently w/o full namespace - ar >> boost::serialization::make_nvp("item", t.reference()); - typename Container::iterator result = - s.insert(hint, boost::move(t.reference())); - ar.reset_object_address(& (* result), & t.reference()); - hint = result; - } -} - -template -inline void save( - Archive & ar, - const std::set &t, - const unsigned int /* file_version */ -){ - boost::serialization::stl::save_collection< - Archive, std::set - >(ar, t); -} - -template -inline void load( - Archive & ar, - std::set &t, - const unsigned int /* file_version */ -){ - load_set_collection(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::set & t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -// multiset -template -inline void save( - Archive & ar, - const std::multiset &t, - const unsigned int /* file_version */ -){ - boost::serialization::stl::save_collection< - Archive, - std::multiset - >(ar, t); -} - -template -inline void load( - Archive & ar, - std::multiset &t, - const unsigned int /* file_version */ -){ - load_set_collection(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::multiset & t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(std::set) -BOOST_SERIALIZATION_COLLECTION_TRAITS(std::multiset) - -#endif // BOOST_SERIALIZATION_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr.hpp deleted file mode 100644 index 0d4c5ae6056..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr.hpp +++ /dev/null @@ -1,281 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SHARED_PTR_HPP -#define BOOST_SERIALIZATION_SHARED_PTR_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// shared_ptr.hpp: serialization for boost shared pointer - -// (C) Copyright 2004 Robert Ramey and Martin Ecker -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // NULL -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// boost:: shared_ptr serialization traits -// version 1 to distinguish from boost 1.32 version. Note: we can only do this -// for a template when the compiler supports partial template specialization - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - namespace boost { - namespace serialization{ - template - struct version< ::boost::shared_ptr< T > > { - typedef mpl::integral_c_tag tag; - #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) - typedef typename mpl::int_<1> type; - #else - typedef mpl::int_<1> type; - #endif - BOOST_STATIC_CONSTANT(int, value = type::value); - }; - // don't track shared pointers - template - struct tracking_level< ::boost::shared_ptr< T > > { - typedef mpl::integral_c_tag tag; - #if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206)) - typedef typename mpl::int_< ::boost::serialization::track_never> type; - #else - typedef mpl::int_< ::boost::serialization::track_never> type; - #endif - BOOST_STATIC_CONSTANT(int, value = type::value); - }; - }} - #define BOOST_SERIALIZATION_SHARED_PTR(T) -#else - // define macro to let users of these compilers do this - #define BOOST_SERIALIZATION_SHARED_PTR(T) \ - BOOST_CLASS_VERSION( \ - ::boost::shared_ptr< T >, \ - 1 \ - ) \ - BOOST_CLASS_TRACKING( \ - ::boost::shared_ptr< T >, \ - ::boost::serialization::track_never \ - ) \ - /**/ -#endif - -namespace boost { -namespace serialization{ - -struct null_deleter { - void operator()(void const *) const {} -}; - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization for boost::shared_ptr - -// Using a constant means that all shared pointers are held in the same set. -// Thus we detect handle multiple pointers to the same value instances -// in the archive. -void * const shared_ptr_helper_id = 0; - -template -inline void save( - Archive & ar, - const boost::shared_ptr< T > &t, - const unsigned int /* file_version */ -){ - // The most common cause of trapping here would be serializing - // something like shared_ptr. This occurs because int - // is never tracked by default. Wrap int in a trackable type - BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); - const T * t_ptr = t.get(); - ar << boost::serialization::make_nvp("px", t_ptr); -} - -#ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP -template -inline void load( - Archive & ar, - boost::shared_ptr< T > &t, - const unsigned int file_version -){ - // something like shared_ptr. This occurs because int - // is never tracked by default. Wrap int in a trackable type - BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); - T* r; - if(file_version < 1){ - ar.register_type(static_cast< - boost_132::detail::sp_counted_base_impl * - >(NULL)); - boost_132::shared_ptr< T > sp; - ar >> boost::serialization::make_nvp("px", sp.px); - ar >> boost::serialization::make_nvp("pn", sp.pn); - // got to keep the sps around so the sp.pns don't disappear - boost::serialization::shared_ptr_helper & h = - ar.template get_helper< shared_ptr_helper >( - shared_ptr_helper_id - ); - h.append(sp); - r = sp.get(); - } - else{ - ar >> boost::serialization::make_nvp("px", r); - } - shared_ptr_helper & h = - ar.template get_helper >( - shared_ptr_helper_id - ); - h.reset(t,r); -} -#else - -template -inline void load( - Archive & ar, - boost::shared_ptr< T > &t, - const unsigned int /*file_version*/ -){ - // The most common cause of trapping here would be serializing - // something like shared_ptr. This occurs because int - // is never tracked by default. Wrap int in a trackable type - BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); - T* r; - ar >> boost::serialization::make_nvp("px", r); - - boost::serialization::shared_ptr_helper & h = - ar.template get_helper >( - shared_ptr_helper_id - ); - h.reset(t,r); -} -#endif - -template -inline void serialize( - Archive & ar, - boost::shared_ptr< T > &t, - const unsigned int file_version -){ - // correct shared_ptr serialization depends upon object tracking - // being used. - BOOST_STATIC_ASSERT( - boost::serialization::tracking_level< T >::value - != boost::serialization::track_never - ); - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// std::shared_ptr serialization traits -// version 1 to distinguish from boost 1.32 version. Note: we can only do this -// for a template when the compiler supports partial template specialization - -#ifndef BOOST_NO_CXX11_SMART_PTR -#include - -// note: we presume that any compiler/library which supports C++11 -// std::pointers also supports template partial specialization -// trap here if such presumption were to turn out to wrong!!! -#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - BOOST_STATIC_ASSERT(false); -#endif - -namespace boost { -namespace serialization{ - template - struct version< ::std::shared_ptr< T > > { - typedef mpl::integral_c_tag tag; - typedef mpl::int_<1> type; - BOOST_STATIC_CONSTANT(int, value = type::value); - }; - // don't track shared pointers - template - struct tracking_level< ::std::shared_ptr< T > > { - typedef mpl::integral_c_tag tag; - typedef mpl::int_< ::boost::serialization::track_never> type; - BOOST_STATIC_CONSTANT(int, value = type::value); - }; -}} -// the following just keeps older programs from breaking -#define BOOST_SERIALIZATION_SHARED_PTR(T) - -namespace boost { -namespace serialization{ - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization for std::shared_ptr - -template -inline void save( - Archive & ar, - const std::shared_ptr< T > &t, - const unsigned int /* file_version */ -){ - // The most common cause of trapping here would be serializing - // something like shared_ptr. This occurs because int - // is never tracked by default. Wrap int in a trackable type - BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); - const T * t_ptr = t.get(); - ar << boost::serialization::make_nvp("px", t_ptr); -} - -template -inline void load( - Archive & ar, - std::shared_ptr< T > &t, - const unsigned int /*file_version*/ -){ - // The most common cause of trapping here would be serializing - // something like shared_ptr. This occurs because int - // is never tracked by default. Wrap int in a trackable type - BOOST_STATIC_ASSERT((tracking_level< T >::value != track_never)); - T* r; - ar >> boost::serialization::make_nvp("px", r); - //void (* const id)(Archive &, std::shared_ptr< T > &, const unsigned int) = & load; - boost::serialization::shared_ptr_helper & h = - ar.template get_helper< - shared_ptr_helper - >( - shared_ptr_helper_id - ); - h.reset(t,r); -} - -template -inline void serialize( - Archive & ar, - std::shared_ptr< T > &t, - const unsigned int file_version -){ - // correct shared_ptr serialization depends upon object tracking - // being used. - BOOST_STATIC_ASSERT( - boost::serialization::tracking_level< T >::value - != boost::serialization::track_never - ); - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_NO_CXX11_SMART_PTR - -#endif // BOOST_SERIALIZATION_SHARED_PTR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_132.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_132.hpp deleted file mode 100644 index 3dfaba4d69a..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_132.hpp +++ /dev/null @@ -1,222 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SHARED_PTR_132_HPP -#define BOOST_SERIALIZATION_SHARED_PTR_132_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// shared_ptr.hpp: serialization for boost shared pointer - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// note: totally unadvised hack to gain access to private variables -// in shared_ptr and shared_count. Unfortunately its the only way to -// do this without changing shared_ptr and shared_count -// the best we can do is to detect a conflict here -#include - -#include -#include // NULL - -#include -#include -#include -#include -#include - -// mark base class as an (uncreatable) base class -#include - -///////////////////////////////////////////////////////////// -// Maintain a couple of lists of loaded shared pointers of the old previous -// version (1.32) - -namespace boost_132 { -namespace serialization { -namespace detail { - -struct null_deleter { - void operator()(void const *) const {} -}; - -} // namespace detail -} // namespace serialization -} // namespace boost_132 - -///////////////////////////////////////////////////////////// -// sp_counted_base_impl serialization - -namespace boost { -namespace serialization { - -template -inline void serialize( - Archive & /* ar */, - boost_132::detail::sp_counted_base_impl & /* t */, - const unsigned int /*file_version*/ -){ - // register the relationship between each derived class - // its polymorphic base - boost::serialization::void_cast_register< - boost_132::detail::sp_counted_base_impl, - boost_132::detail::sp_counted_base - >( - static_cast *>(NULL), - static_cast(NULL) - ); -} - -template -inline void save_construct_data( - Archive & ar, - const - boost_132::detail::sp_counted_base_impl *t, - const unsigned int /* file_version */ -){ - // variables used for construction - ar << boost::serialization::make_nvp("ptr", t->ptr); -} - -template -inline void load_construct_data( - Archive & ar, - boost_132::detail::sp_counted_base_impl * t, - const unsigned int /* file_version */ -){ - P ptr_; - ar >> boost::serialization::make_nvp("ptr", ptr_); - // ::new(t)boost_132::detail::sp_counted_base_impl(ptr_, D()); - // placement - // note: the original ::new... above is replaced by the one here. This one - // creates all new objects with a null_deleter so that after the archive - // is finished loading and the shared_ptrs are destroyed - the underlying - // raw pointers are NOT deleted. This is necessary as they are used by the - // new system as well. - ::new(t)boost_132::detail::sp_counted_base_impl< - P, - boost_132::serialization::detail::null_deleter - >( - ptr_, boost_132::serialization::detail::null_deleter() - ); // placement new - // compensate for that fact that a new shared count always is - // initialized with one. the add_ref_copy below will increment it - // every time its serialized so without this adjustment - // the use and weak counts will be off by one. - t->use_count_ = 0; -} - -} // serialization -} // namespace boost - -///////////////////////////////////////////////////////////// -// shared_count serialization - -namespace boost { -namespace serialization { - -template -inline void save( - Archive & ar, - const boost_132::detail::shared_count &t, - const unsigned int /* file_version */ -){ - ar << boost::serialization::make_nvp("pi", t.pi_); -} - -template -inline void load( - Archive & ar, - boost_132::detail::shared_count &t, - const unsigned int /* file_version */ -){ - ar >> boost::serialization::make_nvp("pi", t.pi_); - if(NULL != t.pi_) - t.pi_->add_ref_copy(); -} - -} // serialization -} // namespace boost - -BOOST_SERIALIZATION_SPLIT_FREE(boost_132::detail::shared_count) - -///////////////////////////////////////////////////////////// -// implement serialization for shared_ptr< T > - -namespace boost { -namespace serialization { - -template -inline void save( - Archive & ar, - const boost_132::shared_ptr< T > &t, - const unsigned int /* file_version */ -){ - // only the raw pointer has to be saved - // the ref count is maintained automatically as shared pointers are loaded - ar.register_type(static_cast< - boost_132::detail::sp_counted_base_impl > * - >(NULL)); - ar << boost::serialization::make_nvp("px", t.px); - ar << boost::serialization::make_nvp("pn", t.pn); -} - -template -inline void load( - Archive & ar, - boost_132::shared_ptr< T > &t, - const unsigned int /* file_version */ -){ - // only the raw pointer has to be saved - // the ref count is maintained automatically as shared pointers are loaded - ar.register_type(static_cast< - boost_132::detail::sp_counted_base_impl > * - >(NULL)); - ar >> boost::serialization::make_nvp("px", t.px); - ar >> boost::serialization::make_nvp("pn", t.pn); -} - -template -inline void serialize( - Archive & ar, - boost_132::shared_ptr< T > &t, - const unsigned int file_version -){ - // correct shared_ptr serialization depends upon object tracking - // being used. - BOOST_STATIC_ASSERT( - boost::serialization::tracking_level< T >::value - != boost::serialization::track_never - ); - boost::serialization::split_free(ar, t, file_version); -} - -} // serialization -} // namespace boost - -// note: change below uses null_deleter -// This macro is used to export GUIDS for shared pointers to allow -// the serialization system to export them properly. David Tonge -#define BOOST_SHARED_POINTER_EXPORT_GUID(T, K) \ - typedef boost_132::detail::sp_counted_base_impl< \ - T *, \ - boost::checked_deleter< T > \ - > __shared_ptr_ ## T; \ - BOOST_CLASS_EXPORT_GUID(__shared_ptr_ ## T, "__shared_ptr_" K) \ - BOOST_CLASS_EXPORT_GUID(T, K) \ - /**/ - -#define BOOST_SHARED_POINTER_EXPORT(T) \ - BOOST_SHARED_POINTER_EXPORT_GUID( \ - T, \ - BOOST_PP_STRINGIZE(T) \ - ) \ - /**/ - -#endif // BOOST_SERIALIZATION_SHARED_PTR_132_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_helper.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_helper.hpp deleted file mode 100644 index 37c34d6b2c4..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/shared_ptr_helper.hpp +++ /dev/null @@ -1,209 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP -#define BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// shared_ptr_helper.hpp: serialization for boost shared pointern - -// (C) Copyright 2004-2009 Robert Ramey, Martin Ecker and Takatoshi Kondo -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include // NULL - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace boost_132 { - template class shared_ptr; -} -namespace boost { -namespace serialization { - -#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS -template class SPT > -void load( - Archive & ar, - SPT< class U > &t, - const unsigned int file_version -); -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// a common class for holding various types of shared pointers - -template class SPT> -class shared_ptr_helper { - typedef std::map< - const void *, // address of object - SPT // address shared ptr to single instance - > object_shared_pointer_map; - - // list of shared_pointers create accessable by raw pointer. This - // is used to "match up" shared pointers loaded at different - // points in the archive. Note, we delay construction until - // it is actually used since this is by default included as - // a "mix-in" even if shared_ptr isn't used. - object_shared_pointer_map * m_o_sp; - - struct null_deleter { - void operator()(void const *) const {} - }; - -#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) \ -|| defined(BOOST_MSVC) \ -|| defined(__SUNPRO_CC) -public: -#else - template - friend void boost::serialization::load( - Archive & ar, - SPT< U > &t, - const unsigned int file_version - ); -#endif - - #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP - // list of loaded pointers. This is used to be sure that the pointers - // stay around long enough to be "matched" with other pointers loaded - // by the same archive. These are created with a "null_deleter" so that - // when this list is destroyed - the underlaying raw pointers are not - // destroyed. This has to be done because the pointers are also held by - // new system which is disjoint from this set. This is implemented - // by a change in load_construct_data below. It makes this file suitable - // only for loading pointers into a 1.33 or later boost system. - std::list > * m_pointers_132; - void - append(const boost_132::shared_ptr & t){ - if(NULL == m_pointers_132) - m_pointers_132 = new std::list >; - m_pointers_132->push_back(t); - } - #endif - - struct non_polymorphic { - template - static const boost::serialization::extended_type_info * - get_object_type(U & ){ - return & boost::serialization::singleton< - typename - boost::serialization::type_info_implementation< U >::type - >::get_const_instance(); - } - }; - struct polymorphic { - template - static const boost::serialization::extended_type_info * - get_object_type(U & u){ - return boost::serialization::singleton< - typename - boost::serialization::type_info_implementation< U >::type - >::get_const_instance().get_derived_extended_type_info(u); - } - }; - -public: - template - void reset(SPT< T > & s, T * t){ - if(NULL == t){ - s.reset(); - return; - } - const boost::serialization::extended_type_info * this_type - = & boost::serialization::type_info_implementation< T >::type - ::get_const_instance(); - - // get pointer to the most derived object's eti. This is effectively - // the object type identifer - typedef typename mpl::if_< - is_polymorphic< T >, - polymorphic, - non_polymorphic - >::type type; - - const boost::serialization::extended_type_info * true_type - = type::get_object_type(*t); - - // note:if this exception is thrown, be sure that derived pointern - // is either registered or exported. - if(NULL == true_type) - boost::serialization::throw_exception( - boost::archive::archive_exception( - boost::archive::archive_exception::unregistered_class, - this_type->get_debug_info() - ) - ); - // get void pointer to the most derived type - // this uniquely identifies the object referred to - // oid = "object identifier" - const void * oid = void_downcast( - *true_type, - *this_type, - t - ); - if(NULL == oid) - boost::serialization::throw_exception( - boost::archive::archive_exception( - boost::archive::archive_exception::unregistered_cast, - true_type->get_debug_info(), - this_type->get_debug_info() - ) - ); - - // make tracking array if necessary - if(NULL == m_o_sp) - m_o_sp = new object_shared_pointer_map; - - typename object_shared_pointer_map::iterator i = m_o_sp->find(oid); - - // if it's a new object - if(i == m_o_sp->end()){ - s.reset(t); - std::pair result; - result = m_o_sp->insert(std::make_pair(oid, s)); - BOOST_ASSERT(result.second); - } - // if the object has already been seen - else{ - s = SPT(i->second, t); - } - } - - shared_ptr_helper() : - m_o_sp(NULL) - #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP - , m_pointers_132(NULL) - #endif - {} - virtual ~shared_ptr_helper(){ - if(NULL != m_o_sp) - delete m_o_sp; - #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP - if(NULL != m_pointers_132) - delete m_pointers_132; - #endif - } -}; - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_SHARED_PTR_HELPER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/singleton.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/singleton.hpp deleted file mode 100644 index b50afedbb92..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/singleton.hpp +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SINGLETON_HPP -#define BOOST_SERIALIZATION_SINGLETON_HPP - -/////////1/////////2///////// 3/////////4/////////5/////////6/////////7/////////8 -// singleton.hpp -// -// Copyright David Abrahams 2006. Original version -// -// Copyright Robert Ramey 2007. Changes made to permit -// application throughout the serialization library. -// -// Distributed under the Boost -// Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -// The intention here is to define a template which will convert -// any class into a singleton with the following features: -// -// a) initialized before first use. -// b) thread-safe for const access to the class -// c) non-locking -// -// In order to do this, -// a) Initialize dynamically when used. -// b) Require that all singletons be initialized before main -// is called or any entry point into the shared library is invoked. -// This guarentees no race condition for initialization. -// In debug mode, we assert that no non-const functions are called -// after main is invoked. -// - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -#include -#include -#include -#include - -#include -#include -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4511 4512) -#endif - -namespace boost { -namespace serialization { - -////////////////////////////////////////////////////////////////////// -// Provides a dynamically-initialized (singleton) instance of T in a -// way that avoids LNK1179 on vc6. See http://tinyurl.com/ljdp8 or -// http://lists.boost.org/Archives/boost/2006/05/105286.php for -// details. -// - -// singletons created by this code are guarenteed to be unique -// within the executable or shared library which creates them. -// This is sufficient and in fact ideal for the serialization library. -// The singleton is created when the module is loaded and destroyed -// when the module is unloaded. - -// This base class has two functions. - -// First it provides a module handle for each singleton indicating -// the executable or shared library in which it was created. This -// turns out to be necessary and sufficient to implement the tables -// used by serialization library. - -// Second, it provides a mechanism to detect when a non-const function -// is called after initialization. - -// make a singleton to lock/unlock all singletons for alteration. -// The intent is that all singletons created/used by this code -// are to be initialized before main is called. A test program -// can lock all the singletons when main is entereed. This any -// attempt to retieve a mutable instances while locked will -// generate a assertion if compiled for debug. - -// note usage of BOOST_DLLEXPORT. These functions are in danger of -// being eliminated by the optimizer when building an application in -// release mode. Usage of the macro is meant to signal the compiler/linker -// to avoid dropping these functions which seem to be unreferenced. -// This usage is not related to autolinking. - -class BOOST_SYMBOL_VISIBLE singleton_module : - public boost::noncopyable -{ -private: - BOOST_SERIALIZATION_DECL BOOST_DLLEXPORT static bool & get_lock() BOOST_USED; -public: - BOOST_DLLEXPORT static void lock(){ - get_lock() = true; - } - BOOST_DLLEXPORT static void unlock(){ - get_lock() = false; - } - BOOST_DLLEXPORT static bool is_locked(){ - return get_lock(); - } -}; - -template -class singleton : public singleton_module -{ -private: - static T & m_instance; - // include this to provoke instantiation at pre-execution time - static void use(T const *) {} - static T & get_instance() { - // use a wrapper so that types T with protected constructors - // can be used - class singleton_wrapper : public T {}; - static singleton_wrapper t; - // refer to instance, causing it to be instantiated (and - // initialized at startup on working compilers) - BOOST_ASSERT(! is_destroyed()); - // note that the following is absolutely essential. - // commenting out this statement will cause compilers to fail to - // construct the instance at pre-execution time. This would prevent - // our usage/implementation of "locking" and introduce uncertainty into - // the sequence of object initializaition. - use(& m_instance); - return static_cast(t); - } - static bool & get_is_destroyed(){ - static bool is_destroyed; - return is_destroyed; - } - -public: - BOOST_DLLEXPORT static T & get_mutable_instance(){ - BOOST_ASSERT(! is_locked()); - return get_instance(); - } - BOOST_DLLEXPORT static const T & get_const_instance(){ - return get_instance(); - } - BOOST_DLLEXPORT static bool is_destroyed(){ - return get_is_destroyed(); - } - BOOST_DLLEXPORT singleton(){ - get_is_destroyed() = false; - } - BOOST_DLLEXPORT ~singleton() { - get_is_destroyed() = true; - } -}; - -template -T & singleton< T >::m_instance = singleton< T >::get_instance(); - -} // namespace serialization -} // namespace boost - -#include // pops abi_suffix.hpp pragmas - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -#endif // BOOST_SERIALIZATION_SINGLETON_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/slist.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/slist.hpp deleted file mode 100644 index d9b971bc4f1..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/slist.hpp +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SLIST_HPP -#define BOOST_SERIALIZATION_SLIST_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// slist.hpp - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#ifdef BOOST_HAS_SLIST -#include BOOST_SLIST_HEADER - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template -inline void save( - Archive & ar, - const BOOST_STD_EXTENSION_NAMESPACE::slist &t, - const unsigned int file_version -){ - boost::serialization::stl::save_collection< - Archive, - BOOST_STD_EXTENSION_NAMESPACE::slist - >(ar, t); -} - -namespace stl { - -template< - class Archive, - class T, - class Allocator -> -typename boost::disable_if< - typename detail::is_default_constructible< - typename BOOST_STD_EXTENSION_NAMESPACE::slist::value_type - >, - void ->::type -collection_load_impl( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::slist &t, - collection_size_type count, - item_version_type item_version -){ - t.clear(); - boost::serialization::detail::stack_construct u(ar, item_version); - ar >> boost::serialization::make_nvp("item", u.reference()); - t.push_front(boost::move(u.reference())); - typename BOOST_STD_EXTENSION_NAMESPACE::slist::iterator last; - last = t.begin(); - ar.reset_object_address(&(*t.begin()) , & u.reference()); - while(--count > 0){ - detail::stack_construct u(ar, item_version); - ar >> boost::serialization::make_nvp("item", u.reference()); - last = t.insert_after(last, boost::move(u.reference())); - ar.reset_object_address(&(*last) , & u.reference()); - } -} - -} // stl - -template -inline void load( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::slist &t, - const unsigned int file_version -){ - const boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - item_version_type item_version(0); - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - if(detail::is_default_constructible()){ - t.resize(count); - typename BOOST_STD_EXTENSION_NAMESPACE::slist::iterator hint; - hint = t.begin(); - while(count-- > 0){ - ar >> boost::serialization::make_nvp("item", *hint++); - } - } - else{ - t.clear(); - boost::serialization::detail::stack_construct u(ar, item_version); - ar >> boost::serialization::make_nvp("item", u.reference()); - t.push_front(boost::move(u.reference())); - typename BOOST_STD_EXTENSION_NAMESPACE::slist::iterator last; - last = t.begin(); - ar.reset_object_address(&(*t.begin()) , & u.reference()); - while(--count > 0){ - detail::stack_construct u(ar, item_version); - ar >> boost::serialization::make_nvp("item", u.reference()); - last = t.insert_after(last, boost::move(u.reference())); - ar.reset_object_address(&(*last) , & u.reference()); - } - } -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - BOOST_STD_EXTENSION_NAMESPACE::slist &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(BOOST_STD_EXTENSION_NAMESPACE::slist) - -#endif // BOOST_HAS_SLIST -#endif // BOOST_SERIALIZATION_SLIST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/smart_cast.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/smart_cast.hpp deleted file mode 100644 index 563f36aa20b..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/smart_cast.hpp +++ /dev/null @@ -1,275 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SMART_CAST_HPP -#define BOOST_SERIALIZATION_SMART_CAST_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// smart_cast.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org/libs/serialization for updates, documentation, and revision history. - -// casting of pointers and references. - -// In casting between different C++ classes, there are a number of -// rules that have to be kept in mind in deciding whether to use -// static_cast or dynamic_cast. - -// a) dynamic casting can only be applied when one of the types is polymorphic -// Otherwise static_cast must be used. -// b) only dynamic casting can do runtime error checking -// use of static_cast is generally un checked even when compiled for debug -// c) static_cast would be considered faster than dynamic_cast. - -// If casting is applied to a template parameter, there is no apriori way -// to know which of the two casting methods will be permitted or convenient. - -// smart_cast uses C++ type_traits, and program debug mode to select the -// most convenient cast to use. - -#include -#include -#include // NULL - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace serialization { -namespace smart_cast_impl { - - template - struct reference { - - struct polymorphic { - - struct linear { - template - static T cast(U & u){ - return static_cast< T >(u); - } - }; - - struct cross { - template - static T cast(U & u){ - return dynamic_cast< T >(u); - } - }; - - template - static T cast(U & u){ - // if we're in debug mode - #if ! defined(NDEBUG) \ - || defined(__MWERKS__) - // do a checked dynamic cast - return cross::cast(u); - #else - // borland 5.51 chokes here so we can't use it - // note: if remove_reference isn't function for these types - // cross casting will be selected this will work but will - // not be the most efficient method. This will conflict with - // the original smart_cast motivation. - typedef typename mpl::eval_if< - typename mpl::and_< - mpl::not_::type, - U - > >, - mpl::not_::type - > > - >, - // borland chokes w/o full qualification here - mpl::identity, - mpl::identity - >::type typex; - // typex works around gcc 2.95 issue - return typex::cast(u); - #endif - } - }; - - struct non_polymorphic { - template - static T cast(U & u){ - return static_cast< T >(u); - } - }; - template - static T cast(U & u){ - typedef typename mpl::eval_if< - boost::is_polymorphic, - mpl::identity, - mpl::identity - >::type typex; - return typex::cast(u); - } - }; - - template - struct pointer { - - struct polymorphic { - // unfortunately, this below fails to work for virtual base - // classes. need has_virtual_base to do this. - // Subject for further study - #if 0 - struct linear { - template - static T cast(U * u){ - return static_cast< T >(u); - } - }; - - struct cross { - template - static T cast(U * u){ - T tmp = dynamic_cast< T >(u); - #ifndef NDEBUG - if ( tmp == 0 ) throw_exception(std::bad_cast()); - #endif - return tmp; - } - }; - - template - static T cast(U * u){ - typedef - typename mpl::eval_if< - typename mpl::and_< - mpl::not_::type, - U - > >, - mpl::not_::type - > > - >, - // borland chokes w/o full qualification here - mpl::identity, - mpl::identity - >::type typex; - return typex::cast(u); - } - #else - template - static T cast(U * u){ - T tmp = dynamic_cast< T >(u); - #ifndef NDEBUG - if ( tmp == 0 ) throw_exception(std::bad_cast()); - #endif - return tmp; - } - #endif - }; - - struct non_polymorphic { - template - static T cast(U * u){ - return static_cast< T >(u); - } - }; - - template - static T cast(U * u){ - typedef typename mpl::eval_if< - boost::is_polymorphic, - mpl::identity, - mpl::identity - >::type typex; - return typex::cast(u); - } - - }; - - template - struct void_pointer { - template - static TPtr cast(UPtr uptr){ - return static_cast(uptr); - } - }; - - template - struct error { - // if we get here, its because we are using one argument in the - // cast on a system which doesn't support partial template - // specialization - template - static T cast(U){ - BOOST_STATIC_ASSERT(sizeof(T)==0); - return * static_cast(NULL); - } - }; - -} // smart_cast_impl - -// this implements: -// smart_cast(Source * s) -// smart_cast(s) -// note that it will fail with -// smart_cast(s) -template -T smart_cast(U u) { - typedef - typename mpl::eval_if< - typename mpl::or_< - boost::is_same, - boost::is_same, - boost::is_same, - boost::is_same - >, - mpl::identity >, - // else - typename mpl::eval_if, - mpl::identity >, - // else - typename mpl::eval_if, - mpl::identity >, - // else - mpl::identity - > - > - > - >::type typex; - return typex::cast(u); -} - -// this implements: -// smart_cast_reference(Source & s) -template -T smart_cast_reference(U & u) { - return smart_cast_impl::reference< T >::cast(u); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_SMART_CAST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/split_free.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/split_free.hpp deleted file mode 100644 index 85e2f590fe4..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/split_free.hpp +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SPLIT_FREE_HPP -#define BOOST_SERIALIZATION_SPLIT_FREE_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// split_free.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include - -namespace boost { -namespace archive { - namespace detail { - template class interface_oarchive; - template class interface_iarchive; - } // namespace detail -} // namespace archive - -namespace serialization { - -//namespace detail { -template -struct free_saver { - static void invoke( - Archive & ar, - const T & t, - const unsigned int file_version - ){ - // use function overload (version_type) to workaround - // two-phase lookup issue - const version_type v(file_version); - save(ar, t, v); - } -}; -template -struct free_loader { - static void invoke( - Archive & ar, - T & t, - const unsigned int file_version - ){ - // use function overload (version_type) to workaround - // two-phase lookup issue - const version_type v(file_version); - load(ar, t, v); - } -}; -//} // namespace detail - -template -inline void split_free( - Archive & ar, - T & t, - const unsigned int file_version -){ - typedef typename mpl::eval_if< - typename Archive::is_saving, - mpl::identity >, - mpl::identity > - >::type typex; - typex::invoke(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#define BOOST_SERIALIZATION_SPLIT_FREE(T) \ -namespace boost { namespace serialization { \ -template \ -inline void serialize( \ - Archive & ar, \ - T & t, \ - const unsigned int file_version \ -){ \ - split_free(ar, t, file_version); \ -} \ -}} -/**/ - -#endif // BOOST_SERIALIZATION_SPLIT_FREE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/split_member.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/split_member.hpp deleted file mode 100644 index 5f32520559e..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/split_member.hpp +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef BOOST_SERIALIZATION_SPLIT_MEMBER_HPP -#define BOOST_SERIALIZATION_SPLIT_MEMBER_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// split_member.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include - -#include - -namespace boost { -namespace archive { - namespace detail { - template class interface_oarchive; - template class interface_iarchive; - } // namespace detail -} // namespace archive - -namespace serialization { -namespace detail { - - template - struct member_saver { - static void invoke( - Archive & ar, - const T & t, - const unsigned int file_version - ){ - access::member_save(ar, t, file_version); - } - }; - - template - struct member_loader { - static void invoke( - Archive & ar, - T & t, - const unsigned int file_version - ){ - access::member_load(ar, t, file_version); - } - }; - -} // detail - -template -inline void split_member( - Archive & ar, T & t, const unsigned int file_version -){ - typedef typename mpl::eval_if< - typename Archive::is_saving, - mpl::identity >, - mpl::identity > - >::type typex; - typex::invoke(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -// split member function serialize funcition into save/load -#define BOOST_SERIALIZATION_SPLIT_MEMBER() \ -template \ -void serialize( \ - Archive &ar, \ - const unsigned int file_version \ -){ \ - boost::serialization::split_member(ar, *this, file_version); \ -} \ -/**/ - -#endif // BOOST_SERIALIZATION_SPLIT_MEMBER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/stack.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/stack.hpp deleted file mode 100644 index 96f90fe8767..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/stack.hpp +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef BOOST_SERIALIZATION_STACK_HPP -#define BOOST_SERIALIZATION_STACK_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// stack.hpp - -// (C) Copyright 2014 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include - -// function specializations must be defined in the appropriate -// namespace - boost::serialization -#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) -#define STD _STLP_STD -#else -#define STD std -#endif - -namespace boost { -namespace serialization { -namespace detail{ - -template -struct stack_save : public STD::stack { - template - void operator()(Archive & ar, const unsigned int file_version) const { - save(ar, STD::stack::c, file_version); - } -}; -template -struct stack_load : public STD::stack { - template - void operator()(Archive & ar, const unsigned int file_version) { - load(ar, STD::stack::c, file_version); - } -}; - -} // detail - -template -inline void serialize( - Archive & ar, - std::stack< T, C> & t, - const unsigned int file_version -){ - typedef typename mpl::eval_if< - typename Archive::is_saving, - mpl::identity >, - mpl::identity > - >::type typex; - static_cast(t)(ar, file_version); -} - -} // namespace serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::stack) - -#undef STD - -#endif // BOOST_SERIALIZATION_DEQUE_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/state_saver.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/state_saver.hpp deleted file mode 100644 index 248b8d91556..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/state_saver.hpp +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef BOOST_SERIALIZATION_STATE_SAVER_HPP -#define BOOST_SERIALIZATION_STATE_SAVER_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// state_saver.hpp: - -// (C) Copyright 2003-4 Pavel Vozenilek and Robert Ramey - http://www.rrsd.com. -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org/libs/serialization for updates, documentation, and revision history. - -// Inspired by Daryle Walker's iostate_saver concept. This saves the original -// value of a variable when a state_saver is constructed and restores -// upon destruction. Useful for being sure that state is restored to -// variables upon exit from scope. - - -#include -#ifndef BOOST_NO_EXCEPTIONS - #include -#endif - -#include -#include -#include -#include - -#include -#include - -namespace boost { -namespace serialization { - -template -// T requirements: -// - POD or object semantic (cannot be reference, function, ...) -// - copy constructor -// - operator = (no-throw one preferred) -class state_saver : private boost::noncopyable -{ -private: - const T previous_value; - T & previous_ref; - - struct restore { - static void invoke(T & previous_ref, const T & previous_value){ - previous_ref = previous_value; // won't throw - } - }; - - struct restore_with_exception { - static void invoke(T & previous_ref, const T & previous_value){ - BOOST_TRY{ - previous_ref = previous_value; - } - BOOST_CATCH(::std::exception &) { - // we must ignore it - we are in destructor - } - BOOST_CATCH_END - } - }; - -public: - state_saver( - T & object - ) : - previous_value(object), - previous_ref(object) - {} - - ~state_saver() { - #ifndef BOOST_NO_EXCEPTIONS - typedef typename mpl::eval_if< - has_nothrow_copy< T >, - mpl::identity, - mpl::identity - >::type typex; - typex::invoke(previous_ref, previous_value); - #else - previous_ref = previous_value; - #endif - } - -}; // state_saver<> - -} // serialization -} // boost - -#endif //BOOST_SERIALIZATION_STATE_SAVER_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/static_warning.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/static_warning.hpp deleted file mode 100644 index 1d9238fc4d9..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/static_warning.hpp +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef BOOST_SERIALIZATION_STATIC_WARNING_HPP -#define BOOST_SERIALIZATION_STATIC_WARNING_HPP - -// (C) Copyright Robert Ramey 2003. Jonathan Turkanis 2004. -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org/libs/static_assert for documentation. - -/* - Revision history: - 15 June 2003 - Initial version. - 31 March 2004 - improved diagnostic messages and portability - (Jonathan Turkanis) - 03 April 2004 - works on VC6 at class and namespace scope - - ported to DigitalMars - - static warnings disabled by default; when enabled, - uses pragmas to enable required compiler warnings - on MSVC, Intel, Metrowerks and Borland 5.x. - (Jonathan Turkanis) - 30 May 2004 - tweaked for msvc 7.1 and gcc 3.3 - - static warnings ENabled by default; when enabled, - (Robert Ramey) -*/ - -#include - -// -// Implementation -// Makes use of the following warnings: -// 1. GCC prior to 3.3: division by zero. -// 2. BCC 6.0 preview: unreferenced local variable. -// 3. DigitalMars: returning address of local automatic variable. -// 4. VC6: class previously seen as struct (as in 'boost/mpl/print.hpp') -// 5. All others: deletion of pointer to incomplete type. -// -// The trick is to find code which produces warnings containing the name of -// a structure or variable. Details, with same numbering as above: -// 1. static_warning_impl::value is zero iff B is false, so diving an int -// by this value generates a warning iff B is false. -// 2. static_warning_impl::type has a constructor iff B is true, so an -// unreferenced variable of this type generates a warning iff B is false. -// 3. static_warning_impl::type overloads operator& to return a dynamically -// allocated int pointer only is B is true, so returning the address of an -// automatic variable of this type generates a warning iff B is fasle. -// 4. static_warning_impl::STATIC_WARNING is decalred as a struct iff B is -// false. -// 5. static_warning_impl::type is incomplete iff B is false, so deleting a -// pointer to this type generates a warning iff B is false. -// - -//------------------Enable selected warnings----------------------------------// - -// Enable the warnings relied on by BOOST_STATIC_WARNING, where possible. - -// 6. replaced implementation with one which depends solely on -// mpl::print<>. The previous one was found to fail for functions -// under recent versions of gcc and intel compilers - Robert Ramey - -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template -struct BOOST_SERIALIZATION_STATIC_WARNING_LINE{}; - -template -struct static_warning_test{ - typename boost::mpl::eval_if_c< - B, - boost::mpl::true_, - typename boost::mpl::identity< - boost::mpl::print< - BOOST_SERIALIZATION_STATIC_WARNING_LINE - > - > - >::type type; -}; - -template -struct BOOST_SERIALIZATION_SS {}; - -} // serialization -} // boost - -#define BOOST_SERIALIZATION_BSW(B, L) \ - typedef boost::serialization::BOOST_SERIALIZATION_SS< \ - sizeof( boost::serialization::static_warning_test< B, L > ) \ - > BOOST_JOIN(STATIC_WARNING_LINE, L) BOOST_ATTRIBUTE_UNUSED; -#define BOOST_STATIC_WARNING(B) BOOST_SERIALIZATION_BSW(B, __LINE__) - -#endif // BOOST_SERIALIZATION_STATIC_WARNING_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/string.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/string.hpp deleted file mode 100644 index 76e695d4f3c..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/string.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef BOOST_SERIALIZATION_STRING_HPP -#define BOOST_SERIALIZATION_STRING_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization/string.hpp: -// serialization for stl string templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include - -BOOST_CLASS_IMPLEMENTATION(std::string, boost::serialization::primitive_type) -#ifndef BOOST_NO_STD_WSTRING -BOOST_CLASS_IMPLEMENTATION(std::wstring, boost::serialization::primitive_type) -#endif - -#endif // BOOST_SERIALIZATION_STRING_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/strong_typedef.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/strong_typedef.hpp deleted file mode 100644 index fdd1b24c9cb..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/strong_typedef.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef BOOST_SERIALIZATION_STRONG_TYPEDEF_HPP -#define BOOST_SERIALIZATION_STRONG_TYPEDEF_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// strong_typedef.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2016 Ashish Sadanandan -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org/libs/serialization for updates, documentation, and revision history. - -// macro used to implement a strong typedef. strong typedef -// guarentees that two types are distinguised even though the -// share the same underlying implementation. typedef does not create -// a new type. BOOST_STRONG_TYPEDEF(T, D) creates a new type named D -// that operates as a type T. - -#include -#include -#include -#include -#include - -#define BOOST_STRONG_TYPEDEF(T, D) \ -struct D \ - : boost::totally_ordered1< D \ - , boost::totally_ordered2< D, T \ - > > \ -{ \ - T t; \ - explicit D(const T& t_) BOOST_NOEXCEPT_IF(boost::has_nothrow_copy_constructor::value) : t(t_) {} \ - D() BOOST_NOEXCEPT_IF(boost::has_nothrow_default_constructor::value) : t() {} \ - D(const D & t_) BOOST_NOEXCEPT_IF(boost::has_nothrow_copy_constructor::value) : t(t_.t) {} \ - D& operator=(const D& rhs) BOOST_NOEXCEPT_IF(boost::has_nothrow_assign::value) {t = rhs.t; return *this;} \ - D& operator=(const T& rhs) BOOST_NOEXCEPT_IF(boost::has_nothrow_assign::value) {t = rhs; return *this;} \ - operator const T&() const {return t;} \ - operator T&() {return t;} \ - bool operator==(const D& rhs) const {return t == rhs.t;} \ - bool operator<(const D& rhs) const {return t < rhs.t;} \ -}; - -#endif // BOOST_SERIALIZATION_STRONG_TYPEDEF_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/throw_exception.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/throw_exception.hpp deleted file mode 100644 index b67618adc92..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/throw_exception.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef BOOST_SERIALIZATION_THROW_EXCEPTION_HPP_INCLUDED -#define BOOST_SERIALIZATION_THROW_EXCEPTION_HPP_INCLUDED - -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) -# pragma once -#endif - -// boost/throw_exception.hpp -// -// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include - -#ifndef BOOST_NO_EXCEPTIONS -#include -#endif - -namespace boost { -namespace serialization { - -#ifdef BOOST_NO_EXCEPTIONS - -inline void throw_exception(std::exception const & e) { - ::boost::throw_exception(e); -} - -#else - -template inline void throw_exception(E const & e){ - throw e; -} - -#endif - -} // namespace serialization -} // namespace boost - -#endif // #ifndef BOOST_SERIALIZATION_THROW_EXCEPTION_HPP_INCLUDED diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/tracking.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/tracking.hpp deleted file mode 100644 index d5c79b8409d..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/tracking.hpp +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef BOOST_SERIALIZATION_TRACKING_HPP -#define BOOST_SERIALIZATION_TRACKING_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// tracking.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -struct basic_traits; - -// default tracking level -template -struct tracking_level_impl { - template - struct traits_class_tracking { - typedef typename U::tracking type; - }; - typedef mpl::integral_c_tag tag; - // note: at least one compiler complained w/o the full qualification - // on basic traits below - typedef - typename mpl::eval_if< - is_base_and_derived, - traits_class_tracking< T >, - //else - typename mpl::eval_if< - is_pointer< T >, - // pointers are not tracked by default - mpl::int_, - //else - typename mpl::eval_if< - // for primitives - typename mpl::equal_to< - implementation_level< T >, - mpl::int_ - >, - // is never - mpl::int_, - // otherwise its selective - mpl::int_ - > > >::type type; - BOOST_STATIC_CONSTANT(int, value = type::value); -}; - -template -struct tracking_level : - public tracking_level_impl -{ -}; - -template -inline bool operator>=(tracking_level< T > t, enum tracking_type l) -{ - return t.value >= (int)l; -} - -} // namespace serialization -} // namespace boost - - -// The STATIC_ASSERT is prevents one from setting tracking for a primitive type. -// This almost HAS to be an error. Doing this will effect serialization of all -// char's in your program which is almost certainly what you don't want to do. -// If you want to track all instances of a given primitive type, You'll have to -// wrap it in your own type so its not a primitive anymore. Then it will compile -// without problem. -#define BOOST_CLASS_TRACKING(T, E) \ -namespace boost { \ -namespace serialization { \ -template<> \ -struct tracking_level< T > \ -{ \ - typedef mpl::integral_c_tag tag; \ - typedef mpl::int_< E> type; \ - BOOST_STATIC_CONSTANT( \ - int, \ - value = tracking_level::type::value \ - ); \ - /* tracking for a class */ \ - BOOST_STATIC_ASSERT(( \ - mpl::greater< \ - /* that is a prmitive */ \ - implementation_level< T >, \ - mpl::int_ \ - >::value \ - )); \ -}; \ -}} - -#endif // BOOST_SERIALIZATION_TRACKING_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/tracking_enum.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/tracking_enum.hpp deleted file mode 100644 index 278051e1baf..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/tracking_enum.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef BOOST_SERIALIZATION_TRACKING_ENUM_HPP -#define BOOST_SERIALIZATION_TRACKING_ENUM_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// tracking_enum.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -namespace boost { -namespace serialization { - -// addresses of serialized objects may be tracked to avoid saving/loading -// redundant copies. This header defines a class trait that can be used -// to specify when objects should be tracked - -// names for each tracking level -enum tracking_type -{ - // never track this type - track_never = 0, - // track objects of this type if the object is serialized through a - // pointer. - track_selectively = 1, - // always track this type - track_always = 2 -}; - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_TRACKING_ENUM_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/traits.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/traits.hpp deleted file mode 100644 index 9e114fdd3df..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/traits.hpp +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef BOOST_SERIALIZATION_TRAITS_HPP -#define BOOST_SERIALIZATION_TRAITS_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// traits.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// This header is used to apply serialization traits to templates. The -// standard system can't be used for platforms which don't support -// Partial Templlate Specialization. - -// The motivation for this is the Name-Value Pair (NVP) template. -// it has to work the same on all platforms in order for archives -// to be portable accross platforms. - -#include -#include - -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -// common base class used to detect appended traits class -struct basic_traits {}; - -template -struct extended_type_info_impl; - -template< - class T, - int Level, - int Tracking, - unsigned int Version = 0, - class ETII = extended_type_info_impl< T >, - class Wrapper = mpl::false_ -> -struct traits : public basic_traits { - BOOST_STATIC_ASSERT(Version == 0 || Level >= object_class_info); - BOOST_STATIC_ASSERT(Tracking == track_never || Level >= object_serializable); - typedef typename mpl::int_ level; - typedef typename mpl::int_ tracking; - typedef typename mpl::int_ version; - typedef ETII type_info_implementation; - typedef Wrapper is_wrapper; -}; - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_TRAITS_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/type_info_implementation.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/type_info_implementation.hpp deleted file mode 100644 index 24637a8dbb3..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/type_info_implementation.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef BOOST_SERIALIZATION_TYPE_INFO_IMPLEMENTATION_HPP -#define BOOST_SERIALIZATION_TYPE_INFO_IMPLEMENTATION_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// type_info_implementation.hpp: interface for portable version of type_info - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - - -#include -#include - -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -// note that T and const T are folded into const T so that -// there is only one table entry per type -template -struct type_info_implementation { - template - struct traits_class_typeinfo_implementation { - typedef typename U::type_info_implementation::type type; - }; - // note: at least one compiler complained w/o the full qualification - // on basic traits below - typedef - typename mpl::eval_if< - is_base_and_derived, - traits_class_typeinfo_implementation< T >, - //else - mpl::identity< - typename extended_type_info_impl< T >::type - > - >::type type; -}; - -} // namespace serialization -} // namespace boost - -// define a macro to assign a particular derivation of extended_type_info -// to a specified a class. -#define BOOST_CLASS_TYPE_INFO(T, ETI) \ -namespace boost { \ -namespace serialization { \ -template<> \ -struct type_info_implementation< T > { \ - typedef ETI type; \ -}; \ -template<> \ -struct type_info_implementation< const T > { \ - typedef ETI type; \ -}; \ -} \ -} \ -/**/ - -#endif /// BOOST_SERIALIZATION_TYPE_INFO_IMPLEMENTATION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unique_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unique_ptr.hpp deleted file mode 100644 index 8d8703ef4f7..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/unique_ptr.hpp +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef BOOST_SERIALIZATION_UNIQUE_PTR_HPP -#define BOOST_SERIALIZATION_UNIQUE_PTR_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// unique_ptr.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. -#include -#include -#include - -namespace boost { -namespace serialization { - -///////////////////////////////////////////////////////////// -// implement serialization for unique_ptr< T > -// note: this must be added to the boost namespace in order to -// be called by the library -template -inline void save( - Archive & ar, - const std::unique_ptr< T > &t, - const unsigned int /*file_version*/ -){ - // only the raw pointer has to be saved - // the ref count is rebuilt automatically on load - const T * const tx = t.get(); - ar << BOOST_SERIALIZATION_NVP(tx); -} - -template -inline void load( - Archive & ar, - std::unique_ptr< T > &t, - const unsigned int /*file_version*/ -){ - T *tx; - ar >> BOOST_SERIALIZATION_NVP(tx); - // note that the reset automagically maintains the reference count - t.reset(tx); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::unique_ptr< T > &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - - -#endif // BOOST_SERIALIZATION_UNIQUE_PTR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_load_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_load_imp.hpp deleted file mode 100644 index d56a423d180..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_load_imp.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_LOAD_IMP_HPP -#define BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_LOAD_IMP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -# pragma warning (disable : 4786) // too long name, harmless warning -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// unordered_collections_load_imp.hpp: serialization for loading stl collections - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2014 Jim Bell -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// helper function templates for serialization of collections - -#include -#include // size_t -#include // msvc 6.0 needs this for warning suppression -#if defined(BOOST_NO_STDC_NAMESPACE) -namespace std{ - using ::size_t; -} // namespace std -#endif -#include - -#include -#include -#include -#include -#include - -namespace boost{ -namespace serialization { -namespace stl { - -////////////////////////////////////////////////////////////////////// -// implementation of serialization for STL containers -// -template -inline void load_unordered_collection(Archive & ar, Container &s) -{ - collection_size_type count; - collection_size_type bucket_count; - boost::serialization::item_version_type item_version(0); - boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - ar >> BOOST_SERIALIZATION_NVP(count); - ar >> BOOST_SERIALIZATION_NVP(bucket_count); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - s.clear(); - s.rehash(bucket_count); - InputFunction ifunc; - while(count-- > 0){ - ifunc(ar, s, item_version); - } -} - -} // namespace stl -} // namespace serialization -} // namespace boost - -#endif //BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_LOAD_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_save_imp.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_save_imp.hpp deleted file mode 100644 index 56746ebeaa3..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_collections_save_imp.hpp +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_SAVE_IMP_HPP -#define BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_SAVE_IMP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// hash_collections_save_imp.hpp: serialization for stl collections - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2014 Jim Bell -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -// helper function templates for serialization of collections - -#include -#include -#include -#include -#include -#include - -namespace boost{ -namespace serialization { -namespace stl { - -////////////////////////////////////////////////////////////////////// -// implementation of serialization for STL containers -// - -template -inline void save_unordered_collection(Archive & ar, const Container &s) -{ - collection_size_type count(s.size()); - const collection_size_type bucket_count(s.bucket_count()); - const item_version_type item_version( - version::value - ); - - #if 0 - /* should only be necessary to create archives of previous versions - * which is not currently supported. So for now comment this out - */ - boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - ar << BOOST_SERIALIZATION_NVP(count); - ar << BOOST_SERIALIZATION_NVP(bucket_count); - if(boost::archive::library_version_type(3) < library_version){ - // record number of elements - // make sure the target type is registered so we can retrieve - // the version when we load - ar << BOOST_SERIALIZATION_NVP(item_version); - } - #else - ar << BOOST_SERIALIZATION_NVP(count); - ar << BOOST_SERIALIZATION_NVP(bucket_count); - ar << BOOST_SERIALIZATION_NVP(item_version); - #endif - - typename Container::const_iterator it = s.begin(); - while(count-- > 0){ - // note borland emits a no-op without the explicit namespace - boost::serialization::save_construct_data_adl( - ar, - &(*it), - boost::serialization::version< - typename Container::value_type - >::value - ); - ar << boost::serialization::make_nvp("item", *it++); - } -} - -} // namespace stl -} // namespace serialization -} // namespace boost - -#endif //BOOST_SERIALIZATION_UNORDERED_COLLECTIONS_SAVE_IMP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_map.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_map.hpp deleted file mode 100644 index 4fdbddd7b65..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_map.hpp +++ /dev/null @@ -1,160 +0,0 @@ -#ifndef BOOST_SERIALIZATION_UNORDERED_MAP_HPP -#define BOOST_SERIALIZATION_UNORDERED_MAP_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization/unordered_map.hpp: -// serialization for stl unordered_map templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2014 Jim Bell -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include - -#include -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const std::unordered_map &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::save_unordered_collection< - Archive, - std::unordered_map - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - std::unordered_map &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::load_unordered_collection< - Archive, - std::unordered_map, - boost::serialization::stl::archive_input_unordered_map< - Archive, - std::unordered_map - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - std::unordered_map &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -// unordered_multimap -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const std::unordered_multimap< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::save_unordered_collection< - Archive, - std::unordered_multimap - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - std::unordered_multimap< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::load_unordered_collection< - Archive, - std::unordered_multimap< - Key, HashFcn, EqualKey, Allocator - >, - boost::serialization::stl::archive_input_unordered_multimap< - Archive, - std::unordered_multimap - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - std::unordered_multimap< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_UNORDERED_MAP_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_set.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/unordered_set.hpp deleted file mode 100644 index adfee609cbe..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/unordered_set.hpp +++ /dev/null @@ -1,162 +0,0 @@ -#ifndef BOOST_SERIALIZATION_UNORDERED_SET_HPP -#define BOOST_SERIALIZATION_UNORDERED_SET_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// unordered_set.hpp: serialization for stl unordered_set templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// (C) Copyright 2014 Jim Bell -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include - -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const std::unordered_set< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::save_unordered_collection< - Archive, - std::unordered_set - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - std::unordered_set< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::load_unordered_collection< - Archive, - std::unordered_set, - stl::archive_input_unordered_set< - Archive, - std::unordered_set< - Key, HashFcn, EqualKey, Allocator - > - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - std::unordered_set< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int file_version -){ - split_free(ar, t, file_version); -} - -// unordered_multiset -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void save( - Archive & ar, - const std::unordered_multiset< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int /*file_version*/ -){ - stl::save_unordered_collection< - Archive, - std::unordered_multiset - >(ar, t); -} - -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void load( - Archive & ar, - std::unordered_multiset< - Key, HashFcn, EqualKey, Allocator - > &t, - const unsigned int /*file_version*/ -){ - boost::serialization::stl::load_unordered_collection< - Archive, - std::unordered_multiset, - boost::serialization::stl::archive_input_unordered_multiset< - Archive, - std::unordered_multiset - > - >(ar, t); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template< - class Archive, - class Key, - class HashFcn, - class EqualKey, - class Allocator -> -inline void serialize( - Archive & ar, - std::unordered_multiset &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_UNORDERED_SET_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/utility.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/utility.hpp deleted file mode 100644 index 4867a4a12d2..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/utility.hpp +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef BOOST_SERIALIZATION_UTILITY_HPP -#define BOOST_SERIALIZATION_UTILITY_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// serialization/utility.hpp: -// serialization for stl utility templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -#include -#include -#include -#include - -namespace boost { -namespace serialization { - -// pair -template -inline void serialize( - Archive & ar, - std::pair & p, - const unsigned int /* file_version */ -){ - // note: we remove any const-ness on the first argument. The reason is that - // for stl maps, the type saved is pair::type typef; - ar & boost::serialization::make_nvp("first", const_cast(p.first)); - ar & boost::serialization::make_nvp("second", p.second); -} - -/// specialization of is_bitwise_serializable for pairs -template -struct is_bitwise_serializable > - : public mpl::and_,is_bitwise_serializable > -{ -}; - -} // serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_UTILITY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/valarray.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/valarray.hpp deleted file mode 100644 index 9eece5c1737..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/valarray.hpp +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef BOOST_SERIALIZATION_VALARAY_HPP -#define BOOST_SERIALIZATION_VALARAY_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// valarray.hpp: serialization for stl vector templates - -// (C) Copyright 2005 Matthias Troyer . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -#include -#include -#include -#include -#include - -// function specializations must be defined in the appropriate -// namespace - boost::serialization -#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) -#define STD _STLP_STD -#else -#define STD std -#endif - -namespace boost { -namespace serialization { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// valarray< T > - -template -void save( Archive & ar, const STD::valarray &t, const unsigned int /*file_version*/ ) -{ - const collection_size_type count(t.size()); - ar << BOOST_SERIALIZATION_NVP(count); - if (t.size()){ - // explict template arguments to pass intel C++ compiler - ar << serialization::make_array( - static_cast(&t[0]), - count - ); - } -} - -template -void load( Archive & ar, STD::valarray &t, const unsigned int /*file_version*/ ) -{ - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - t.resize(count); - if (t.size()){ - // explict template arguments to pass intel C++ compiler - ar >> serialization::make_array( - static_cast(&t[0]), - count - ); - } -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( Archive & ar, STD::valarray & t, const unsigned int file_version) -{ - boost::serialization::split_free(ar, t, file_version); -} - -} } // end namespace boost::serialization - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(STD::valarray) -#undef STD - -#endif // BOOST_SERIALIZATION_VALARAY_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/variant.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/variant.hpp deleted file mode 100644 index dce6f3d49e7..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/variant.hpp +++ /dev/null @@ -1,158 +0,0 @@ -#ifndef BOOST_SERIALIZATION_VARIANT_HPP -#define BOOST_SERIALIZATION_VARIANT_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// variant.hpp - non-intrusive serialization of variant types -// -// copyright (c) 2005 -// troy d. straszheim -// http://www.resophonic.com -// -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// See http://www.boost.org for updates, documentation, and revision history. -// -// thanks to Robert Ramey, Peter Dimov, and Richard Crossley. -// - -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include - -#include -#include -#include - -namespace boost { -namespace serialization { - -template -struct variant_save_visitor : - boost::static_visitor<> -{ - variant_save_visitor(Archive& ar) : - m_ar(ar) - {} - template - void operator()(T const & value) const - { - m_ar << BOOST_SERIALIZATION_NVP(value); - } -private: - Archive & m_ar; -}; - -template -void save( - Archive & ar, - boost::variant const & v, - unsigned int /*version*/ -){ - int which = v.which(); - ar << BOOST_SERIALIZATION_NVP(which); - variant_save_visitor visitor(ar); - v.apply_visitor(visitor); -} - -template -struct variant_impl { - - struct load_null { - template - static void invoke( - Archive & /*ar*/, - int /*which*/, - V & /*v*/, - const unsigned int /*version*/ - ){} - }; - - struct load_impl { - template - static void invoke( - Archive & ar, - int which, - V & v, - const unsigned int version - ){ - if(which == 0){ - // note: A non-intrusive implementation (such as this one) - // necessary has to copy the value. This wouldn't be necessary - // with an implementation that de-serialized to the address of the - // aligned storage included in the variant. - typedef typename mpl::front::type head_type; - head_type value; - ar >> BOOST_SERIALIZATION_NVP(value); - v = value; - ar.reset_object_address(& boost::get(v), & value); - return; - } - typedef typename mpl::pop_front::type type; - variant_impl::load(ar, which - 1, v, version); - } - }; - - template - static void load( - Archive & ar, - int which, - V & v, - const unsigned int version - ){ - typedef typename mpl::eval_if, - mpl::identity, - mpl::identity - >::type typex; - typex::invoke(ar, which, v, version); - } - -}; - -template -void load( - Archive & ar, - boost::variant& v, - const unsigned int version -){ - int which; - typedef typename boost::variant::types types; - ar >> BOOST_SERIALIZATION_NVP(which); - if(which >= mpl::size::value) - // this might happen if a type was removed from the list of variant types - boost::serialization::throw_exception( - boost::archive::archive_exception( - boost::archive::archive_exception::unsupported_version - ) - ); - variant_impl::load(ar, which, v, version); -} - -template -inline void serialize( - Archive & ar, - boost::variant & v, - const unsigned int file_version -){ - split_free(ar,v,file_version); -} - -} // namespace serialization -} // namespace boost - -#endif //BOOST_SERIALIZATION_VARIANT_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/vector.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/vector.hpp deleted file mode 100644 index 9a114c00e20..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/vector.hpp +++ /dev/null @@ -1,233 +0,0 @@ -#ifndef BOOST_SERIALIZATION_VECTOR_HPP -#define BOOST_SERIALIZATION_VECTOR_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// vector.hpp: serialization for stl vector templates - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// fast array serialization (C) Copyright 2005 Matthias Troyer -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -// default is being compatible with version 1.34.1 files, not 1.35 files -#ifndef BOOST_SERIALIZATION_VECTOR_VERSIONED -#define BOOST_SERIALIZATION_VECTOR_VERSIONED(V) (V==4 || V==5) -#endif - -// function specializations must be defined in the appropriate -// namespace - boost::serialization -#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) -#define STD _STLP_STD -#else -#define STD std -#endif - -namespace boost { -namespace serialization { - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// vector< T > - -// the default versions - -template -inline void save( - Archive & ar, - const std::vector &t, - const unsigned int /* file_version */, - mpl::false_ -){ - boost::serialization::stl::save_collection >( - ar, t - ); -} - -template -inline void load( - Archive & ar, - std::vector &t, - const unsigned int /* file_version */, - mpl::false_ -){ - const boost::archive::library_version_type library_version( - ar.get_library_version() - ); - // retrieve number of elements - item_version_type item_version(0); - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - if(boost::archive::library_version_type(3) < library_version){ - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - t.reserve(count); - stl::collection_load_impl(ar, t, count, item_version); -} - -// the optimized versions - -template -inline void save( - Archive & ar, - const std::vector &t, - const unsigned int /* file_version */, - mpl::true_ -){ - const collection_size_type count(t.size()); - ar << BOOST_SERIALIZATION_NVP(count); - if (!t.empty()) - // explict template arguments to pass intel C++ compiler - ar << serialization::make_array( - static_cast(&t[0]), - count - ); -} - -template -inline void load( - Archive & ar, - std::vector &t, - const unsigned int /* file_version */, - mpl::true_ -){ - collection_size_type count(t.size()); - ar >> BOOST_SERIALIZATION_NVP(count); - t.resize(count); - unsigned int item_version=0; - if(BOOST_SERIALIZATION_VECTOR_VERSIONED(ar.get_library_version())) { - ar >> BOOST_SERIALIZATION_NVP(item_version); - } - if (!t.empty()) - // explict template arguments to pass intel C++ compiler - ar >> serialization::make_array( - static_cast(&t[0]), - count - ); - } - -// dispatch to either default or optimized versions - -template -inline void save( - Archive & ar, - const std::vector &t, - const unsigned int file_version -){ - typedef typename - boost::serialization::use_array_optimization::template apply< - typename remove_const::type - >::type use_optimized; - save(ar,t,file_version, use_optimized()); -} - -template -inline void load( - Archive & ar, - std::vector &t, - const unsigned int file_version -){ -#ifdef BOOST_SERIALIZATION_VECTOR_135_HPP - if (ar.get_library_version()==boost::archive::library_version_type(5)) - { - load(ar,t,file_version, boost::is_arithmetic()); - return; - } -#endif - typedef typename - boost::serialization::use_array_optimization::template apply< - typename remove_const::type - >::type use_optimized; - load(ar,t,file_version, use_optimized()); -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::vector & t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// vector -template -inline void save( - Archive & ar, - const std::vector &t, - const unsigned int /* file_version */ -){ - // record number of elements - collection_size_type count (t.size()); - ar << BOOST_SERIALIZATION_NVP(count); - std::vector::const_iterator it = t.begin(); - while(count-- > 0){ - bool tb = *it++; - ar << boost::serialization::make_nvp("item", tb); - } -} - -template -inline void load( - Archive & ar, - std::vector &t, - const unsigned int /* file_version */ -){ - // retrieve number of elements - collection_size_type count; - ar >> BOOST_SERIALIZATION_NVP(count); - t.resize(count); - for(collection_size_type i = collection_size_type(0); i < count; ++i){ - bool b; - ar >> boost::serialization::make_nvp("item", b); - t[i] = b; - } -} - -// split non-intrusive serialization function member into separate -// non intrusive save/load member functions -template -inline void serialize( - Archive & ar, - std::vector & t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // serialization -} // namespace boost - -#include - -BOOST_SERIALIZATION_COLLECTION_TRAITS(std::vector) -#undef STD - -#endif // BOOST_SERIALIZATION_VECTOR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/vector_135.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/vector_135.hpp deleted file mode 100644 index fd1a7393d1b..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/vector_135.hpp +++ /dev/null @@ -1,26 +0,0 @@ -////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// vector_135.hpp: serialization for stl vector templates for compatibility -// with release 1.35, which had a bug - -// (C) Copyright 2008 Matthias Troyer -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - - -#ifndef BOOST_SERIALIZATION_VECTOR_135_HPP -#define BOOST_SERIALIZATION_VECTOR_135_HPP - -#ifdef BOOST_SERIALIZATION_VECTOR_VERSIONED -#if BOOST_SERIALIZATION_VECTOR_VERSION != 4 -#error "Boost.Serialization cannot be compatible with both 1.35 and 1.36-1.40 files" -#endif -#else -#define BOOST_SERIALIZATION_VECTOR_VERSIONED(V) (V>4) -#endif - -#include - -#endif // BOOST_SERIALIZATION_VECTOR_135_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/version.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/version.hpp deleted file mode 100644 index 21a74d73daa..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/version.hpp +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef BOOST_SERIALIZATION_VERSION_HPP -#define BOOST_SERIALIZATION_VERSION_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// version.hpp: - -// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace serialization { - -struct basic_traits; - -// default version number is 0. Override with higher version -// when class definition changes. -template -struct version -{ - template - struct traits_class_version { - typedef typename U::version type; - }; - - typedef mpl::integral_c_tag tag; - // note: at least one compiler complained w/o the full qualification - // on basic traits below - typedef - typename mpl::eval_if< - is_base_and_derived, - traits_class_version< T >, - mpl::int_<0> - >::type type; - BOOST_STATIC_CONSTANT(int, value = version::type::value); -}; - -#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION -template -const int version::value; -#endif - -} // namespace serialization -} // namespace boost - -/* note: at first it seemed that this would be a good place to trap - * as an error an attempt to set a version # for a class which doesn't - * save its class information (including version #) in the archive. - * However, this imposes a requirement that the version be set after - * the implemention level which would be pretty confusing. If this - * is to be done, do this check in the input or output operators when - * ALL the serialization traits are available. Included the implementation - * here with this comment as a reminder not to do this! - */ -//#include -//#include - -#include -#include - -// specify the current version number for the class -// version numbers limited to 8 bits !!! -#define BOOST_CLASS_VERSION(T, N) \ -namespace boost { \ -namespace serialization { \ -template<> \ -struct version \ -{ \ - typedef mpl::int_ type; \ - typedef mpl::integral_c_tag tag; \ - BOOST_STATIC_CONSTANT(int, value = version::type::value); \ - BOOST_MPL_ASSERT(( \ - boost::mpl::less< \ - boost::mpl::int_, \ - boost::mpl::int_<256> \ - > \ - )); \ - /* \ - BOOST_MPL_ASSERT(( \ - mpl::equal_to< \ - :implementation_level, \ - mpl::int_ \ - >::value \ - )); \ - */ \ -}; \ -} \ -} - -#endif // BOOST_SERIALIZATION_VERSION_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/void_cast.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/void_cast.hpp deleted file mode 100644 index f1b38286115..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/void_cast.hpp +++ /dev/null @@ -1,298 +0,0 @@ -#ifndef BOOST_SERIALIZATION_VOID_CAST_HPP -#define BOOST_SERIALIZATION_VOID_CAST_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// void_cast.hpp: interface for run-time casting of void pointers. - -// (C) Copyright 2002-2009 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// gennadiy.rozental@tfn.com - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // for ptrdiff_t -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include // must be the last header - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4251 4231 4660 4275) -#endif - -namespace boost { -namespace serialization { - -class extended_type_info; - -// Given a void *, assume that it really points to an instance of one type -// and alter it so that it would point to an instance of a related type. -// Return the altered pointer. If there exists no sequence of casts that -// can transform from_type to to_type, return a NULL. - -BOOST_SERIALIZATION_DECL void const * -void_upcast( - extended_type_info const & derived, - extended_type_info const & base, - void const * const t -); - -inline void * -void_upcast( - extended_type_info const & derived, - extended_type_info const & base, - void * const t -){ - return const_cast(void_upcast( - derived, - base, - const_cast(t) - )); -} - -BOOST_SERIALIZATION_DECL void const * -void_downcast( - extended_type_info const & derived, - extended_type_info const & base, - void const * const t -); - -inline void * -void_downcast( - extended_type_info const & derived, - extended_type_info const & base, - void * const t -){ - return const_cast(void_downcast( - derived, - base, - const_cast(t) - )); -} - -namespace void_cast_detail { - -class BOOST_SYMBOL_VISIBLE void_caster : - private boost::noncopyable -{ - friend - BOOST_SERIALIZATION_DECL void const * - boost::serialization::void_upcast( - extended_type_info const & derived, - extended_type_info const & base, - void const * const - ); - friend - BOOST_SERIALIZATION_DECL void const * - boost::serialization::void_downcast( - extended_type_info const & derived, - extended_type_info const & base, - void const * const - ); -protected: - BOOST_SERIALIZATION_DECL void recursive_register(bool includes_virtual_base = false) const; - BOOST_SERIALIZATION_DECL void recursive_unregister() const; - virtual bool has_virtual_base() const = 0; -public: - // Data members - const extended_type_info * m_derived; - const extended_type_info * m_base; - /*const*/ std::ptrdiff_t m_difference; - void_caster const * const m_parent; - - // note that void_casters are keyed on value of - // member extended type info records - NOT their - // addresses. This is necessary in order for the - // void cast operations to work across dll and exe - // module boundries. - bool operator<(const void_caster & rhs) const; - - const void_caster & operator*(){ - return *this; - } - // each derived class must re-implement these; - virtual void const * upcast(void const * const t) const = 0; - virtual void const * downcast(void const * const t) const = 0; - // Constructor - void_caster( - extended_type_info const * derived, - extended_type_info const * base, - std::ptrdiff_t difference = 0, - void_caster const * const parent = 0 - ) : - m_derived(derived), - m_base(base), - m_difference(difference), - m_parent(parent) - {} - virtual ~void_caster(){} -}; - -#ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable : 4251 4231 4660 4275 4511 4512) -#endif - -template -class BOOST_SYMBOL_VISIBLE void_caster_primitive : - public void_caster -{ - virtual void const * downcast(void const * const t) const { - const Derived * d = - boost::serialization::smart_cast( - static_cast(t) - ); - return d; - } - virtual void const * upcast(void const * const t) const { - const Base * b = - boost::serialization::smart_cast( - static_cast(t) - ); - return b; - } - virtual bool has_virtual_base() const { - return false; - } -public: - void_caster_primitive(); - virtual ~void_caster_primitive(); -}; - -template -void_caster_primitive::void_caster_primitive() : - void_caster( - & type_info_implementation::type::get_const_instance(), - & type_info_implementation::type::get_const_instance(), - // note:I wanted to displace from 0 here, but at least one compiler - // treated 0 by not shifting it at all. - reinterpret_cast( - static_cast( - reinterpret_cast(8) - ) - ) - 8 - ) -{ - recursive_register(); -} - -template -void_caster_primitive::~void_caster_primitive(){ - recursive_unregister(); -} - -template -class BOOST_SYMBOL_VISIBLE void_caster_virtual_base : - public void_caster -{ - virtual bool has_virtual_base() const { - return true; - } -public: - virtual void const * downcast(void const * const t) const { - const Derived * d = - dynamic_cast( - static_cast(t) - ); - return d; - } - virtual void const * upcast(void const * const t) const { - const Base * b = - dynamic_cast( - static_cast(t) - ); - return b; - } - void_caster_virtual_base(); - virtual ~void_caster_virtual_base(); -}; - -#ifdef BOOST_MSVC -#pragma warning(pop) -#endif - -template -void_caster_virtual_base::void_caster_virtual_base() : - void_caster( - & (type_info_implementation::type::get_const_instance()), - & (type_info_implementation::type::get_const_instance()) - ) -{ - recursive_register(true); -} - -template -void_caster_virtual_base::~void_caster_virtual_base(){ - recursive_unregister(); -} - -template -struct BOOST_SYMBOL_VISIBLE void_caster_base : - public void_caster -{ - typedef - typename mpl::eval_if, - mpl::identity< - void_cast_detail::void_caster_virtual_base - > - ,// else - mpl::identity< - void_cast_detail::void_caster_primitive - > - >::type type; -}; - -} // void_cast_detail - -template -BOOST_DLLEXPORT -inline const void_cast_detail::void_caster & void_cast_register( - Derived const * /* dnull = NULL */, - Base const * /* bnull = NULL */ -){ - typedef - typename mpl::eval_if, - mpl::identity< - void_cast_detail::void_caster_virtual_base - > - ,// else - mpl::identity< - void_cast_detail::void_caster_primitive - > - >::type typex; - return singleton::get_const_instance(); -} - -template -class BOOST_SYMBOL_VISIBLE void_caster : - public void_cast_detail::void_caster_base::type -{ -}; - -} // namespace serialization -} // namespace boost - -#ifdef BOOST_MSVC -# pragma warning(pop) -#endif - -#include // pops abi_suffix.hpp pragmas - -#endif // BOOST_SERIALIZATION_VOID_CAST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/void_cast_fwd.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/void_cast_fwd.hpp deleted file mode 100644 index def61d52bb7..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/void_cast_fwd.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef BOOST_SERIALIZATION_VOID_CAST_FWD_HPP -#define BOOST_SERIALIZATION_VOID_CAST_FWD_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// void_cast_fwd.hpp: interface for run-time casting of void pointers. - -// (C) Copyright 2005 Robert Ramey - http://www.rrsd.com . -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// gennadiy.rozental@tfn.com - -// See http://www.boost.org for updates, documentation, and revision history. - -#include // NULL -#include - -namespace boost { -namespace serialization { -namespace void_cast_detail{ -class void_caster; -} // namespace void_cast_detail -template -BOOST_DLLEXPORT -inline const void_cast_detail::void_caster & void_cast_register( - const Derived * dnull = NULL, - const Base * bnull = NULL -) BOOST_USED; -} // namespace serialization -} // namespace boost - -#endif // BOOST_SERIALIZATION_VOID_CAST_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/weak_ptr.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/weak_ptr.hpp deleted file mode 100644 index 6952d24cb37..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/weak_ptr.hpp +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef BOOST_SERIALIZATION_WEAK_PTR_HPP -#define BOOST_SERIALIZATION_WEAK_PTR_HPP - -// MS compatible compilers support #pragma once -#if defined(_MSC_VER) -# pragma once -#endif - -/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 -// weak_ptr.hpp: serialization for boost weak pointer - -// (C) Copyright 2004 Robert Ramey and Martin Ecker -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org for updates, documentation, and revision history. - -#include -#include - -namespace boost { -namespace serialization{ - -template -inline void save( - Archive & ar, - const boost::weak_ptr< T > &t, - const unsigned int /* file_version */ -){ - const boost::shared_ptr< T > sp = t.lock(); - ar << boost::serialization::make_nvp("weak_ptr", sp); -} - -template -inline void load( - Archive & ar, - boost::weak_ptr< T > &t, - const unsigned int /* file_version */ -){ - boost::shared_ptr< T > sp; - ar >> boost::serialization::make_nvp("weak_ptr", sp); - t = sp; -} - -template -inline void serialize( - Archive & ar, - boost::weak_ptr< T > &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#ifndef BOOST_NO_CXX11_SMART_PTR -#include - -namespace boost { -namespace serialization{ - -template -inline void save( - Archive & ar, - const std::weak_ptr< T > &t, - const unsigned int /* file_version */ -){ - const std::shared_ptr< T > sp = t.lock(); - ar << boost::serialization::make_nvp("weak_ptr", sp); -} - -template -inline void load( - Archive & ar, - std::weak_ptr< T > &t, - const unsigned int /* file_version */ -){ - std::shared_ptr< T > sp; - ar >> boost::serialization::make_nvp("weak_ptr", sp); - t = sp; -} - -template -inline void serialize( - Archive & ar, - std::weak_ptr< T > &t, - const unsigned int file_version -){ - boost::serialization::split_free(ar, t, file_version); -} - -} // namespace serialization -} // namespace boost - -#endif // BOOST_NO_CXX11_SMART_PTR - -#endif // BOOST_SERIALIZATION_WEAK_PTR_HPP diff --git a/contrib/libboost/boost_1_65_0/boost/serialization/wrapper.hpp b/contrib/libboost/boost_1_65_0/boost/serialization/wrapper.hpp deleted file mode 100644 index 60d7910b17a..00000000000 --- a/contrib/libboost/boost_1_65_0/boost/serialization/wrapper.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef BOOST_SERIALIZATION_WRAPPER_HPP -#define BOOST_SERIALIZATION_WRAPPER_HPP - -// (C) Copyright 2005-2006 Matthias Troyer -// Use, modification and distribution is subject to the Boost Software -// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include -#include -#include -#include - -namespace boost { namespace serialization { - -/// the base class for serialization wrappers -/// -/// wrappers need to be treated differently at various places in the serialization library, -/// e.g. saving of non-const wrappers has to be possible. Since partial specialization -// is not supported by all compilers, we derive all wrappers from wrapper_traits. - -template< - class T, - int Level = object_serializable, - int Tracking = track_never, - unsigned int Version = 0, - class ETII = extended_type_info_impl< T > -> -struct wrapper_traits : - public traits -{}; - -template -struct is_wrapper_impl : - boost::mpl::eval_if< - boost::is_base_and_derived, - boost::mpl::true_, - boost::mpl::false_ - >::type -{}; - -template -struct is_wrapper { - typedef typename is_wrapper_impl::type type; -}; - -} // serialization -} // boost - -// A macro to define that a class is a wrapper -#define BOOST_CLASS_IS_WRAPPER(T) \ -namespace boost { \ -namespace serialization { \ -template<> \ -struct is_wrapper_impl : boost::mpl::true_ {}; \ -} \ -} \ -/**/ - -#endif //BOOST_SERIALIZATION_WRAPPER_HPP diff --git a/contrib/poco b/contrib/poco new file mode 160000 index 00000000000..29439cf7fa3 --- /dev/null +++ b/contrib/poco @@ -0,0 +1 @@ +Subproject commit 29439cf7fa32c1a2d62d925bb6d6a3f14668a4a2 diff --git a/contrib/zlib-ng b/contrib/zlib-ng new file mode 160000 index 00000000000..9173b89d467 --- /dev/null +++ b/contrib/zlib-ng @@ -0,0 +1 @@ +Subproject commit 9173b89d46799582d20a30578e0aa9788bc7d6e1 diff --git a/dbms/src/Storages/MergeTree/MergeTreeData.cpp b/dbms/src/Storages/MergeTree/MergeTreeData.cpp index b7ad890b47c..07b95dbb91a 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeData.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeData.cpp @@ -2266,8 +2266,6 @@ MergeTreeData::DataPartPtr MergeTreeData::getActiveContainingPart( { auto committed_parts_range = getDataPartsStateRange(state); - auto committed_parts_range = getDataPartsStateRange(DataPartState::Committed); - /// The part can be covered only by the previous or the next one in data_parts. auto it = data_parts_by_state_and_info.lower_bound(DataPartStateAndInfo{state, part_info}); @@ -2600,7 +2598,6 @@ MergeTreeData::getDetachedParts() const part.prefix = dir_name.substr(0, first_separator); } - return res; } From 03d659ea1abd57f8c908f3a2d3c83332f3cdd519 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Thu, 13 Jun 2019 12:41:40 -0400 Subject: [PATCH 0135/1165] * Sync with yandex/master so that the git diff yandex/master is empty --- .gitmodules | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.gitmodules b/.gitmodules index 336c2a892e2..0fda654f07c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ +[submodule "contrib/poco"] + path = contrib/poco + url = https://github.com/ClickHouse-Extras/poco [submodule "contrib/zstd"] path = contrib/zstd url = https://github.com/facebook/zstd.git @@ -10,6 +13,12 @@ [submodule "contrib/cctz"] path = contrib/cctz url = https://github.com/google/cctz.git +[submodule "contrib/zlib-ng"] + path = contrib/zlib-ng + url = https://github.com/ClickHouse-Extras/zlib-ng.git +[submodule "contrib/googletest"] + path = contrib/googletest + url = https://github.com/google/googletest.git [submodule "contrib/capnproto"] path = contrib/capnproto url = https://github.com/capnproto/capnproto.git From 6cca6d359dcb410ee30e9d30cf52e92819e2c265 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Thu, 13 Jun 2019 21:02:15 -0400 Subject: [PATCH 0136/1165] * Reverting changes to clickhouse-test as it seems to cause some tests to fail * Updating client.py to use CLICKHOUSE_BINARY env variable instead of CLICKHOUSE_CLIENT --- dbms/tests/clickhouse-test | 2 +- dbms/tests/queries/0_stateless/helpers/client.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/tests/clickhouse-test b/dbms/tests/clickhouse-test index 4ca549889d6..e64b04f2db5 100755 --- a/dbms/tests/clickhouse-test +++ b/dbms/tests/clickhouse-test @@ -258,7 +258,7 @@ def main(args): # Keep same default values as in queries/shell_config.sh os.environ.setdefault("CLICKHOUSE_BINARY", args.binary) - os.environ.setdefault("CLICKHOUSE_CLIENT", args.client) + #os.environ.setdefault("CLICKHOUSE_CLIENT", args.client) os.environ.setdefault("CLICKHOUSE_CONFIG", args.configserver) if args.configclient: os.environ.setdefault("CLICKHOUSE_CONFIG_CLIENT", args.configclient) diff --git a/dbms/tests/queries/0_stateless/helpers/client.py b/dbms/tests/queries/0_stateless/helpers/client.py index 59ea3d898ea..dec7eca7d78 100644 --- a/dbms/tests/queries/0_stateless/helpers/client.py +++ b/dbms/tests/queries/0_stateless/helpers/client.py @@ -12,7 +12,7 @@ end_of_block = r'.*\r\n.*\r\n' def client(command=None, name='', log=None): if command is None: - client = uexpect.spawn(os.environ.get('CLICKHOUSE_CLIENT')) + client = uexpect.spawn(os.environ.get('CLICKHOUSE_BINARY', 'clickhouse') + '-client') else: client = uexpect.spawn(command) client.eol('\r') From 13978c03f382ce44e404ecfe830bb62490aca02c Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Fri, 14 Jun 2019 10:06:15 -0400 Subject: [PATCH 0137/1165] * Fixing a bug in StorageLiveView.cpp in the getHeader() method when header block would not match blocks in the stream when Const column is present. * Updating 00963_temporary_live_view_watch_live_timeout.py and removed timeout=5 after WATCH query is aborted with Ctrl-C so that the default timeout of 20sec is used * Small style fixes in tests --- dbms/src/Storages/StorageLiveView.cpp | 25 ++++++++++++++----- .../0_stateless/00958_live_view_watch_live.py | 2 +- .../00960_live_view_watch_events_live.py | 2 +- .../00962_temporary_live_view_watch_live.py | 2 +- ..._temporary_live_view_watch_live_timeout.py | 4 +-- .../00964_live_view_watch_events_heartbeat.py | 2 +- .../00965_live_view_watch_heartbeat.py | 2 +- 7 files changed, 26 insertions(+), 13 deletions(-) diff --git a/dbms/src/Storages/StorageLiveView.cpp b/dbms/src/Storages/StorageLiveView.cpp index 77e95ac2e48..917d62baaa4 100644 --- a/dbms/src/Storages/StorageLiveView.cpp +++ b/dbms/src/Storages/StorageLiveView.cpp @@ -159,12 +159,25 @@ Block StorageLiveView::getHeader() const { if (!sample_block) { - auto storage = global_context.getTable(select_database_name, select_table_name); - sample_block = InterpreterSelectQuery(inner_query, global_context, storage).getSampleBlock(); - sample_block.insert({DataTypeUInt64().createColumnConst( - sample_block.rows(), 0)->convertToFullColumnIfConst(), - std::make_shared(), - "_version"}); + if (!(*blocks_ptr) || (*blocks_ptr)->empty()) + { + auto storage = global_context.getTable(select_database_name, select_table_name); + sample_block = InterpreterSelectQuery(inner_query, global_context, storage, SelectQueryOptions(QueryProcessingStage::Complete)).getSampleBlock(); + sample_block.insert({DataTypeUInt64().createColumnConst( + sample_block.rows(), 0)->convertToFullColumnIfConst(), + std::make_shared(), + "_version"}); + /// convert all columns to full columns + /// in case some of them are constant + for (size_t i = 0; i < sample_block.columns(); ++i) + { + sample_block.safeGetByPosition(i).column = sample_block.safeGetByPosition(i).column->convertToFullColumnIfConst(); + } + } + else + { + sample_block = (*blocks_ptr)->front().cloneEmpty(); + } } return sample_block; diff --git a/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py b/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py index cb6f1e95f7e..7cbea5fbff6 100755 --- a/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py +++ b/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py @@ -31,7 +31,7 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') client1.expect(r'21.*3' + end_of_block) # send Ctrl-C - os.kill(client1.process.pid,signal.SIGINT) + os.kill(client1.process.pid, signal.SIGINT) client1.expect(prompt) client1.send('DROP TABLE test.lv') client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py b/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py index 414f9c1ad96..becf0335600 100755 --- a/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py +++ b/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py @@ -31,7 +31,7 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') client1.expect('3.*2186dbea325ee4c56b67e9b792e993a3' + end_of_block) # send Ctrl-C - os.kill(client1.process.pid,signal.SIGINT) + os.kill(client1.process.pid, signal.SIGINT) client1.expect(prompt) client1.send('DROP TABLE test.lv') client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py b/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py index 1967284c38b..d4d35548d68 100755 --- a/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py +++ b/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py @@ -31,7 +31,7 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') client1.expect(r'21.*3' + end_of_block) # send Ctrl-C - os.kill(client1.process.pid,signal.SIGINT) + os.kill(client1.process.pid, signal.SIGINT) client1.expect(prompt) client1.send('DROP TABLE test.lv') client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py index 581363cd796..2008368f12e 100755 --- a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py +++ b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py @@ -35,8 +35,8 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client2.expect(prompt) client1.expect(r'21.*3' + end_of_block) # send Ctrl-C - os.kill(client1.process.pid,signal.SIGINT) - client1.expect(prompt, timeout=5) + os.kill(client1.process.pid, signal.SIGINT) + client1.expect(prompt) client1.send('SELECT sleep(1)') client1.expect(prompt) client1.send('DROP TABLE test.lv') diff --git a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py index b624e0b7080..3ced5f6f315 100755 --- a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py @@ -33,7 +33,7 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo # wait for heartbeat client1.expect('Progress: 2.00 rows.*\)') # send Ctrl-C - os.kill(client1.process.pid,signal.SIGINT) + os.kill(client1.process.pid, signal.SIGINT) client1.expect(prompt) client1.send('DROP TABLE test.lv') client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py b/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py index dfb46273f7c..b2bd84e0742 100755 --- a/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py @@ -34,7 +34,7 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo # wait for heartbeat client1.expect('Progress: 2.00 rows.*\)') # send Ctrl-C - os.kill(client1.process.pid,signal.SIGINT) + os.kill(client1.process.pid, signal.SIGINT) client1.expect(prompt) client1.send('DROP TABLE test.lv') client1.expect(prompt) From d6d0404c48af9cf56441a8def682e9fc47b3349b Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Fri, 14 Jun 2019 16:27:43 -0400 Subject: [PATCH 0138/1165] * Fixing bug in StorageLiveView.cpp getHeader() method that sometimes addressed invalid pointer when getHeader() method was called without holding the mutex --- dbms/src/Storages/StorageLiveView.cpp | 28 +++++++++++---------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/dbms/src/Storages/StorageLiveView.cpp b/dbms/src/Storages/StorageLiveView.cpp index 917d62baaa4..eecc7f6d1dc 100644 --- a/dbms/src/Storages/StorageLiveView.cpp +++ b/dbms/src/Storages/StorageLiveView.cpp @@ -159,24 +159,18 @@ Block StorageLiveView::getHeader() const { if (!sample_block) { - if (!(*blocks_ptr) || (*blocks_ptr)->empty()) + auto storage = global_context.getTable(select_database_name, select_table_name); + sample_block = InterpreterSelectQuery(inner_query, global_context, storage, + SelectQueryOptions(QueryProcessingStage::Complete)).getSampleBlock(); + sample_block.insert({DataTypeUInt64().createColumnConst( + sample_block.rows(), 0)->convertToFullColumnIfConst(), + std::make_shared(), + "_version"}); + /// convert all columns to full columns + /// in case some of them are constant + for (size_t i = 0; i < sample_block.columns(); ++i) { - auto storage = global_context.getTable(select_database_name, select_table_name); - sample_block = InterpreterSelectQuery(inner_query, global_context, storage, SelectQueryOptions(QueryProcessingStage::Complete)).getSampleBlock(); - sample_block.insert({DataTypeUInt64().createColumnConst( - sample_block.rows(), 0)->convertToFullColumnIfConst(), - std::make_shared(), - "_version"}); - /// convert all columns to full columns - /// in case some of them are constant - for (size_t i = 0; i < sample_block.columns(); ++i) - { - sample_block.safeGetByPosition(i).column = sample_block.safeGetByPosition(i).column->convertToFullColumnIfConst(); - } - } - else - { - sample_block = (*blocks_ptr)->front().cloneEmpty(); + sample_block.safeGetByPosition(i).column = sample_block.safeGetByPosition(i).column->convertToFullColumnIfConst(); } } From 282ff6bfda42c949b9d1a4921ad7f42435436526 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Fri, 14 Jun 2019 21:08:46 -0400 Subject: [PATCH 0139/1165] * Fixing a bug in writeIntoLiveView method where blocks->front() is called before checking if blocks vector is empty. --- dbms/src/Storages/StorageLiveView.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dbms/src/Storages/StorageLiveView.h b/dbms/src/Storages/StorageLiveView.h index 01dd82ff1fd..69410ec4e8b 100644 --- a/dbms/src/Storages/StorageLiveView.h +++ b/dbms/src/Storages/StorageLiveView.h @@ -202,7 +202,7 @@ public: } /// Need make new mergeable block structure match the other mergeable blocks - if (!mergeable_blocks->front()->empty() && !new_mergeable_blocks->empty()) + if (!mergeable_blocks->front()->empty()) { auto sample_block = mergeable_blocks->front()->front(); auto sample_new_block = new_mergeable_blocks->front(); @@ -237,6 +237,9 @@ public: blocks->push_back(this_block); } + if (blocks->empty()) + return; + auto sample_block = blocks->front().cloneEmpty(); BlockInputStreamPtr new_data = std::make_shared(std::make_shared(blocks), sample_block); From 103bf9d068eb047d2f1dc789401265b18fdbd13f Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Sat, 15 Jun 2019 23:34:28 -0400 Subject: [PATCH 0140/1165] * Updating tests as SHOW TABLES 'lv' does not return any tables as test database is not selected by default. --- .../queries/0_stateless/00952_live_view_create.reference | 1 - dbms/tests/queries/0_stateless/00952_live_view_create.sql | 2 -- .../0_stateless/00954_live_view_select_version.reference | 1 - .../queries/0_stateless/00954_live_view_select_version.sql | 2 -- .../00955_live_view_select_with_aggregation.reference | 1 - .../0_stateless/00955_live_view_select_with_aggregation.sql | 2 -- .../0_stateless/00956_live_view_watch_events.reference | 1 - .../queries/0_stateless/00956_live_view_watch_events.sql | 2 -- .../tests/queries/0_stateless/00957_live_view_watch.reference | 1 - dbms/tests/queries/0_stateless/00957_live_view_watch.sql | 2 -- .../0_stateless/00959_create_temporary_live_view.reference | 1 - .../0_stateless/00961_temporary_live_view_watch.reference | 1 - .../queries/0_stateless/00961_temporary_live_view_watch.sql | 2 -- ..._live_view_select_format_jsoneachrowwithprogress.reference | 1 - .../00968_live_view_select_format_jsoneachrowwithprogress.sql | 2 -- ...9_live_view_watch_format_jsoneachrowwithprogress.reference | 1 - .../00969_live_view_watch_format_jsoneachrowwithprogress.sql | 2 -- .../queries/0_stateless/00972_live_view_select_1.reference | 1 - dbms/tests/queries/0_stateless/00972_live_view_select_1.sql | 4 +++- .../queries/0_stateless/00973_live_view_select.reference | 1 - dbms/tests/queries/0_stateless/00973_live_view_select.sql | 2 -- 21 files changed, 3 insertions(+), 30 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00952_live_view_create.reference b/dbms/tests/queries/0_stateless/00952_live_view_create.reference index c39f21eaf5e..e69de29bb2d 100644 --- a/dbms/tests/queries/0_stateless/00952_live_view_create.reference +++ b/dbms/tests/queries/0_stateless/00952_live_view_create.reference @@ -1 +0,0 @@ -lv diff --git a/dbms/tests/queries/0_stateless/00952_live_view_create.sql b/dbms/tests/queries/0_stateless/00952_live_view_create.sql index 0b64ed3a876..1c929b15b00 100644 --- a/dbms/tests/queries/0_stateless/00952_live_view_create.sql +++ b/dbms/tests/queries/0_stateless/00952_live_view_create.sql @@ -3,7 +3,5 @@ DROP TABLE IF EXISTS test.mt; CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple(); CREATE LIVE VIEW test.lv AS SELECT * FROM test.mt; -SHOW TABLES LIKE 'lv'; - DROP TABLE test.lv; DROP TABLE test.mt; diff --git a/dbms/tests/queries/0_stateless/00954_live_view_select_version.reference b/dbms/tests/queries/0_stateless/00954_live_view_select_version.reference index 07b5ce41af1..453bd800469 100644 --- a/dbms/tests/queries/0_stateless/00954_live_view_select_version.reference +++ b/dbms/tests/queries/0_stateless/00954_live_view_select_version.reference @@ -1,4 +1,3 @@ -lv 1 1 2 1 3 1 diff --git a/dbms/tests/queries/0_stateless/00954_live_view_select_version.sql b/dbms/tests/queries/0_stateless/00954_live_view_select_version.sql index 569cf5b0ab2..5f3ab1f7546 100644 --- a/dbms/tests/queries/0_stateless/00954_live_view_select_version.sql +++ b/dbms/tests/queries/0_stateless/00954_live_view_select_version.sql @@ -4,8 +4,6 @@ DROP TABLE IF EXISTS test.mt; CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple(); CREATE LIVE VIEW test.lv AS SELECT * FROM test.mt; -SHOW TABLES LIKE 'lv'; - INSERT INTO test.mt VALUES (1),(2),(3); SELECT *,_version FROM test.lv; diff --git a/dbms/tests/queries/0_stateless/00955_live_view_select_with_aggregation.reference b/dbms/tests/queries/0_stateless/00955_live_view_select_with_aggregation.reference index cb865431ffd..6d50f0e9c3a 100644 --- a/dbms/tests/queries/0_stateless/00955_live_view_select_with_aggregation.reference +++ b/dbms/tests/queries/0_stateless/00955_live_view_select_with_aggregation.reference @@ -1,3 +1,2 @@ -lv 6 21 diff --git a/dbms/tests/queries/0_stateless/00955_live_view_select_with_aggregation.sql b/dbms/tests/queries/0_stateless/00955_live_view_select_with_aggregation.sql index cdac382cae2..3c11f855c9d 100644 --- a/dbms/tests/queries/0_stateless/00955_live_view_select_with_aggregation.sql +++ b/dbms/tests/queries/0_stateless/00955_live_view_select_with_aggregation.sql @@ -4,8 +4,6 @@ DROP TABLE IF EXISTS test.mt; CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple(); CREATE LIVE VIEW test.lv AS SELECT * FROM test.mt; -SHOW TABLES LIKE 'lv'; - INSERT INTO test.mt VALUES (1),(2),(3); SELECT sum(a) FROM test.lv; diff --git a/dbms/tests/queries/0_stateless/00956_live_view_watch_events.reference b/dbms/tests/queries/0_stateless/00956_live_view_watch_events.reference index b67c49182e9..57e3d59ecad 100644 --- a/dbms/tests/queries/0_stateless/00956_live_view_watch_events.reference +++ b/dbms/tests/queries/0_stateless/00956_live_view_watch_events.reference @@ -1,4 +1,3 @@ -lv 1 c9d39b11cce79112219a73aaa319b475 2 4cd0592103888d4682de9a32a23602e3 3 2186dbea325ee4c56b67e9b792e993a3 diff --git a/dbms/tests/queries/0_stateless/00956_live_view_watch_events.sql b/dbms/tests/queries/0_stateless/00956_live_view_watch_events.sql index 1dbc201bdca..a3b84e8d4c1 100644 --- a/dbms/tests/queries/0_stateless/00956_live_view_watch_events.sql +++ b/dbms/tests/queries/0_stateless/00956_live_view_watch_events.sql @@ -4,8 +4,6 @@ DROP TABLE IF EXISTS test.mt; CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple(); CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt; -SHOW TABLES LIKE 'lv'; - WATCH test.lv EVENTS LIMIT 0; INSERT INTO test.mt VALUES (1),(2),(3); diff --git a/dbms/tests/queries/0_stateless/00957_live_view_watch.reference b/dbms/tests/queries/0_stateless/00957_live_view_watch.reference index 65500578a69..6fbbedf1b21 100644 --- a/dbms/tests/queries/0_stateless/00957_live_view_watch.reference +++ b/dbms/tests/queries/0_stateless/00957_live_view_watch.reference @@ -1,4 +1,3 @@ -lv 0 1 6 2 21 3 diff --git a/dbms/tests/queries/0_stateless/00957_live_view_watch.sql b/dbms/tests/queries/0_stateless/00957_live_view_watch.sql index ac304fec0b9..abe4a6c32ae 100644 --- a/dbms/tests/queries/0_stateless/00957_live_view_watch.sql +++ b/dbms/tests/queries/0_stateless/00957_live_view_watch.sql @@ -4,8 +4,6 @@ DROP TABLE IF EXISTS test.mt; CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple(); CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt; -SHOW TABLES LIKE 'lv'; - WATCH test.lv LIMIT 0; INSERT INTO test.mt VALUES (1),(2),(3); diff --git a/dbms/tests/queries/0_stateless/00959_create_temporary_live_view.reference b/dbms/tests/queries/0_stateless/00959_create_temporary_live_view.reference index 49d86fc2fbf..7f9fcbb2e9c 100644 --- a/dbms/tests/queries/0_stateless/00959_create_temporary_live_view.reference +++ b/dbms/tests/queries/0_stateless/00959_create_temporary_live_view.reference @@ -1,4 +1,3 @@ temporary_live_view_timeout 5 live_view_heartbeat_interval 15 -lv 0 diff --git a/dbms/tests/queries/0_stateless/00961_temporary_live_view_watch.reference b/dbms/tests/queries/0_stateless/00961_temporary_live_view_watch.reference index 65500578a69..6fbbedf1b21 100644 --- a/dbms/tests/queries/0_stateless/00961_temporary_live_view_watch.reference +++ b/dbms/tests/queries/0_stateless/00961_temporary_live_view_watch.reference @@ -1,4 +1,3 @@ -lv 0 1 6 2 21 3 diff --git a/dbms/tests/queries/0_stateless/00961_temporary_live_view_watch.sql b/dbms/tests/queries/0_stateless/00961_temporary_live_view_watch.sql index eb99e054514..c3e2ab8d102 100644 --- a/dbms/tests/queries/0_stateless/00961_temporary_live_view_watch.sql +++ b/dbms/tests/queries/0_stateless/00961_temporary_live_view_watch.sql @@ -4,8 +4,6 @@ DROP TABLE IF EXISTS test.mt; CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple(); CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt; -SHOW TABLES LIKE 'lv'; - WATCH test.lv LIMIT 0; INSERT INTO test.mt VALUES (1),(2),(3); diff --git a/dbms/tests/queries/0_stateless/00968_live_view_select_format_jsoneachrowwithprogress.reference b/dbms/tests/queries/0_stateless/00968_live_view_select_format_jsoneachrowwithprogress.reference index 0f6a0405cda..5ae423d90d1 100644 --- a/dbms/tests/queries/0_stateless/00968_live_view_select_format_jsoneachrowwithprogress.reference +++ b/dbms/tests/queries/0_stateless/00968_live_view_select_format_jsoneachrowwithprogress.reference @@ -1,4 +1,3 @@ -lv {"row":{"a":1}} {"row":{"a":2}} {"row":{"a":3}} diff --git a/dbms/tests/queries/0_stateless/00968_live_view_select_format_jsoneachrowwithprogress.sql b/dbms/tests/queries/0_stateless/00968_live_view_select_format_jsoneachrowwithprogress.sql index 748d901b3bf..8c6f4197d54 100644 --- a/dbms/tests/queries/0_stateless/00968_live_view_select_format_jsoneachrowwithprogress.sql +++ b/dbms/tests/queries/0_stateless/00968_live_view_select_format_jsoneachrowwithprogress.sql @@ -4,8 +4,6 @@ DROP TABLE IF EXISTS test.mt; CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple(); CREATE LIVE VIEW test.lv AS SELECT * FROM test.mt; -SHOW TABLES LIKE 'lv'; - INSERT INTO test.mt VALUES (1),(2),(3); SELECT * FROM test.lv FORMAT JSONEachRowWithProgress; diff --git a/dbms/tests/queries/0_stateless/00969_live_view_watch_format_jsoneachrowwithprogress.reference b/dbms/tests/queries/0_stateless/00969_live_view_watch_format_jsoneachrowwithprogress.reference index 8510bebad77..287a1ced92d 100644 --- a/dbms/tests/queries/0_stateless/00969_live_view_watch_format_jsoneachrowwithprogress.reference +++ b/dbms/tests/queries/0_stateless/00969_live_view_watch_format_jsoneachrowwithprogress.reference @@ -1,4 +1,3 @@ -lv {"row":{"sum(a)":"0","_version":"1"}} {"progress":{"read_rows":"1","read_bytes":"16","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}} {"row":{"sum(a)":"6","_version":"2"}} diff --git a/dbms/tests/queries/0_stateless/00969_live_view_watch_format_jsoneachrowwithprogress.sql b/dbms/tests/queries/0_stateless/00969_live_view_watch_format_jsoneachrowwithprogress.sql index 9f2e0384dd8..725a4ad00ed 100644 --- a/dbms/tests/queries/0_stateless/00969_live_view_watch_format_jsoneachrowwithprogress.sql +++ b/dbms/tests/queries/0_stateless/00969_live_view_watch_format_jsoneachrowwithprogress.sql @@ -4,8 +4,6 @@ DROP TABLE IF EXISTS test.mt; CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple(); CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt; -SHOW TABLES LIKE 'lv'; - WATCH test.lv LIMIT 0 FORMAT JSONEachRowWithProgress; INSERT INTO test.mt VALUES (1),(2),(3); diff --git a/dbms/tests/queries/0_stateless/00972_live_view_select_1.reference b/dbms/tests/queries/0_stateless/00972_live_view_select_1.reference index f2f8c69d020..d00491fd7e5 100644 --- a/dbms/tests/queries/0_stateless/00972_live_view_select_1.reference +++ b/dbms/tests/queries/0_stateless/00972_live_view_select_1.reference @@ -1,2 +1 @@ -lv 1 diff --git a/dbms/tests/queries/0_stateless/00972_live_view_select_1.sql b/dbms/tests/queries/0_stateless/00972_live_view_select_1.sql index 01bfeb08fd5..661080b577b 100644 --- a/dbms/tests/queries/0_stateless/00972_live_view_select_1.sql +++ b/dbms/tests/queries/0_stateless/00972_live_view_select_1.sql @@ -1,5 +1,7 @@ DROP TABLE IF EXISTS test.lv; + CREATE LIVE VIEW test.lv AS SELECT 1; -SHOW TABLES LIKE 'lv'; + SELECT * FROM test.lv; + DROP TABLE test.lv; diff --git a/dbms/tests/queries/0_stateless/00973_live_view_select.reference b/dbms/tests/queries/0_stateless/00973_live_view_select.reference index 7beda18cd83..75236c0daf7 100644 --- a/dbms/tests/queries/0_stateless/00973_live_view_select.reference +++ b/dbms/tests/queries/0_stateless/00973_live_view_select.reference @@ -1,4 +1,3 @@ -lv 6 1 6 1 12 2 diff --git a/dbms/tests/queries/0_stateless/00973_live_view_select.sql b/dbms/tests/queries/0_stateless/00973_live_view_select.sql index 492fa265b7d..ff4a45ffcc1 100644 --- a/dbms/tests/queries/0_stateless/00973_live_view_select.sql +++ b/dbms/tests/queries/0_stateless/00973_live_view_select.sql @@ -4,8 +4,6 @@ DROP TABLE IF EXISTS test.mt; CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple(); CREATE LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt; -SHOW TABLES LIKE 'lv'; - INSERT INTO test.mt VALUES (1),(2),(3); SELECT *,_version FROM test.lv; From ea83a4cafa7199f6473db6b7fd35407af54e9cd0 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Sun, 16 Jun 2019 07:09:43 -0400 Subject: [PATCH 0141/1165] * Removing 'hash' column from WATCH [db.live_view] EVENTS query result as hash of the result are not usually provided in ClickHouse. This is also done to match the implementation of the SELECT query that only returns '_version' virtual column when using LIVE VIEW tables. --- dbms/src/DataStreams/LiveViewEventsBlockInputStream.h | 9 ++------- .../0_stateless/00956_live_view_watch_events.reference | 6 +++--- .../0_stateless/00960_live_view_watch_events_live.py | 4 ++-- .../00964_live_view_watch_events_heartbeat.py | 2 +- .../0_stateless/00966_live_view_watch_events_http.py | 4 ++-- .../00970_live_view_watch_events_http_heartbeat.py | 10 +++++----- 6 files changed, 15 insertions(+), 20 deletions(-) diff --git a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h index c7911074176..75e68b15d92 100644 --- a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h +++ b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h @@ -66,7 +66,7 @@ public: Block getHeader() const override { - return {ColumnWithTypeAndName(ColumnUInt64::create(), std::make_shared(), "version"), ColumnWithTypeAndName(ColumnString::create(), std::make_shared(), "hash")}; + return {ColumnWithTypeAndName(ColumnUInt64::create(), std::make_shared(), "version")}; } void refresh() @@ -106,12 +106,7 @@ public: ColumnWithTypeAndName( DataTypeUInt64().createColumnConst(1, blocks_metadata->version)->convertToFullColumnIfConst(), std::make_shared(), - "version"), - ColumnWithTypeAndName( - DataTypeString().createColumnConst(1, blocks_metadata->hash)->convertToFullColumnIfConst(), - std::make_shared(), - "hash"), - + "version") }; return res; } diff --git a/dbms/tests/queries/0_stateless/00956_live_view_watch_events.reference b/dbms/tests/queries/0_stateless/00956_live_view_watch_events.reference index 57e3d59ecad..01e79c32a8c 100644 --- a/dbms/tests/queries/0_stateless/00956_live_view_watch_events.reference +++ b/dbms/tests/queries/0_stateless/00956_live_view_watch_events.reference @@ -1,3 +1,3 @@ -1 c9d39b11cce79112219a73aaa319b475 -2 4cd0592103888d4682de9a32a23602e3 -3 2186dbea325ee4c56b67e9b792e993a3 +1 +2 +3 diff --git a/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py b/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py index becf0335600..44b8df185b1 100755 --- a/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py +++ b/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py @@ -27,9 +27,9 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client1.send('WATCH test.lv EVENTS') client1.expect('1.*' + end_of_block) client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') - client1.expect('2.*4cd0592103888d4682de9a32a23602e3' + end_of_block) + client1.expect('2.*' + end_of_block) client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') - client1.expect('3.*2186dbea325ee4c56b67e9b792e993a3' + end_of_block) + client1.expect('3.*' + end_of_block) # send Ctrl-C os.kill(client1.process.pid, signal.SIGINT) client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py index 3ced5f6f315..cecae7c5a72 100755 --- a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py @@ -28,7 +28,7 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client1.expect(prompt) client1.send('WATCH test.lv EVENTS') client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') - client1.expect('2.*4cd0592103888d4682de9a32a23602e3' + end_of_block) + client1.expect('2.*' + end_of_block) client1.expect('Progress: 2.00 rows.*\)') # wait for heartbeat client1.expect('Progress: 2.00 rows.*\)') diff --git a/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py b/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py index a1b6f2418ea..bb9d6152200 100755 --- a/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py +++ b/dbms/tests/queries/0_stateless/00966_live_view_watch_events_http.py @@ -26,10 +26,10 @@ with client(name='client1>', log=log) as client1: with http_client({'method':'GET', 'url': '/?query=WATCH%20test.lv%20EVENTS'}, name='client2>', log=log) as client2: - client2.expect('.*1\tc9d39b11cce79112219a73aaa319b475\n') + client2.expect('.*1\n') client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') client1.expect(prompt) - client2.expect('.*2\t.*\n') + client2.expect('.*2\n') client1.send('DROP TABLE test.lv') client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py b/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py index 29ea2142d5c..63628c4a76f 100755 --- a/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00970_live_view_watch_events_http_heartbeat.py @@ -26,16 +26,16 @@ with client(name='client1>', log=log) as client1: with http_client({'method':'GET', 'url': '/?live_view_heartbeat_interval=1&query=WATCH%20test.lv%20EVENTS%20FORMAT%20JSONEachRowWithProgress'}, name='client2>', log=log) as client2: - client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}\n', escape=True) - client2.expect('{"row":{"version":"1","hash":"c9d39b11cce79112219a73aaa319b475"}}', escape=True) - client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}', escape=True) + client2.expect('{"progress":{"read_rows":"1","read_bytes":"8","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}\n', escape=True) + client2.expect('{"row":{"version":"1"}', escape=True) + client2.expect('{"progress":{"read_rows":"1","read_bytes":"8","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}', escape=True) # heartbeat is provided by progress message - client2.expect('{"progress":{"read_rows":"1","read_bytes":"49","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}', escape=True) + client2.expect('{"progress":{"read_rows":"1","read_bytes":"8","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}}', escape=True) client1.send('INSERT INTO test.mt VALUES (1),(2),(3)') client1.expect(prompt) - client2.expect('{"row":{"version":"2","hash":"4cd0592103888d4682de9a32a23602e3"}}\n', escape=True) + client2.expect('{"row":{"version":"2"}}\n', escape=True) client1.send('DROP TABLE test.lv') client1.expect(prompt) From 8df3e48a7b997f423840af6ec1642f2699272ccd Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Mon, 17 Jun 2019 12:39:01 -0400 Subject: [PATCH 0142/1165] * Fixing bug in writeIntoLiveView method where mergeable blocks would always be reobtained after 64 inserts --- dbms/src/Storages/StorageLiveView.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dbms/src/Storages/StorageLiveView.h b/dbms/src/Storages/StorageLiveView.h index 69410ec4e8b..84a7ea80bca 100644 --- a/dbms/src/Storages/StorageLiveView.h +++ b/dbms/src/Storages/StorageLiveView.h @@ -141,6 +141,7 @@ public: std::shared_ptr getBlocksPtr() { return blocks_ptr; } BlocksPtrs getMergeableBlocks() { return mergeable_blocks; } + void setMergeableBlocks(BlocksPtrs blocks) { mergeable_blocks = blocks; } std::shared_ptr getActivePtr() { return active_ptr; } /// Read new data blocks that store query result @@ -193,12 +194,13 @@ public: { mergeable_blocks = std::make_shared>(); BlocksPtr base_mergeable_blocks = std::make_shared(); - InterpreterSelectQuery interpreter(live_view.getInnerQuery(), context, SelectQueryOptions(QueryProcessingStage::WithMergeableState), Names{}); + InterpreterSelectQuery interpreter(live_view.getInnerQuery(), context, SelectQueryOptions(QueryProcessingStage::WithMergeableState), Names()); auto view_mergeable_stream = std::make_shared( interpreter.execute().in); while (Block this_block = view_mergeable_stream->read()) base_mergeable_blocks->push_back(this_block); mergeable_blocks->push_back(base_mergeable_blocks); + live_view.setMergeableBlocks(mergeable_blocks); } /// Need make new mergeable block structure match the other mergeable blocks From a930713a24f68ec2183e35764083916ad9b3de0b Mon Sep 17 00:00:00 2001 From: FeehanG <51821376+FeehanG@users.noreply.github.com> Date: Sun, 23 Jun 2019 15:34:22 +0300 Subject: [PATCH 0143/1165] Update ext_dict_functions.md --- .../functions/ext_dict_functions.md | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/en/query_language/functions/ext_dict_functions.md b/docs/en/query_language/functions/ext_dict_functions.md index 017d941b9f6..2d96bef23fb 100644 --- a/docs/en/query_language/functions/ext_dict_functions.md +++ b/docs/en/query_language/functions/ext_dict_functions.md @@ -15,29 +15,29 @@ dictGetOrDefault('dict_name', 'attr_name', id_expr, default_value_expr) - `dict_name` — Name of the dictionary. [String literal](../syntax.md#syntax-string-literal). - `attr_name` — Name of the column of the dictionary. [String literal](../syntax.md#syntax-string-literal). -- `id_expr` — Key value. [Expression](../syntax.md#syntax-expressions) returning [UInt64](../../data_types/int_uint.md)-typed value or [Tuple](../../data_types/tuple.md) depending on the dictionary configuration. -- `default_value_expr` — Value which is returned if the dictionary doesn't contain a row with the `id_expr` key. [Expression](../syntax.md#syntax-expressions) returning the value of the data type configured for the `attr_name` attribute. +- `id_expr` — Key value. [Expression](../syntax.md#syntax-expressions) returns a [UInt64](../../data_types/int_uint.md) or [Tuple](../../data_types/tuple.md)-type value depending on the dictionary configuration. +- `default_value_expr` — Value returned if the dictionary doesn't contain a row with the `id_expr` key. [Expression](../syntax.md#syntax-expressions) returns the value in the data type configured for the `attr_name` attribute. **Returned value** -- If ClickHouse parses the attribute successfully with the [attribute's data type](../dicts/external_dicts_dict_structure.md#ext_dict_structure-attributes), functions return the value of the dictionary attribute that corresponds to `id_expr`. -- If there is no requested `id_expr` in the dictionary then: +- If ClickHouse parses the attribute successfully in the [attribute's data type](../dicts/external_dicts_dict_structure.md#ext_dict_structure-attributes), functions return the value of the dictionary attribute that corresponds to `id_expr`. +- If there is no requested `id_expr` in the dictionary, then: - - `dictGet` returns the content of the `` element which is specified for the attribute in the dictionary configuration. + - `dictGet` returns the content of the `` element specified for the attribute in the dictionary configuration. - `dictGetOrDefault` returns the value passed as the `default_value_expr` parameter. ClickHouse throws an exception if it cannot parse the value of the attribute or the value doesn't match the attribute data type. -**Example of Use** +**Example** -Create the text file `ext-dict-text.csv` with the following content: +Create a text file `ext-dict-text.csv` containing the following: ```text 1,1 2,2 ``` -The first column is `id`, the second column is `c1` +The first column is `id`, the second column is `c1`. Configure the external dictionary: @@ -93,7 +93,7 @@ LIMIT 3 ## dictHas -Checks whether the dictionary has the key. +Checks whether a key is present in a dictionary. ``` dictHas('dict_name', id) @@ -102,7 +102,7 @@ dictHas('dict_name', id) **Parameters** - `dict_name` — Name of the dictionary. [String literal](../syntax.md#syntax-string-literal). -- `id_expr` — Key value. [Expression](../syntax.md#syntax-expressions) returning [UInt64](../../data_types/int_uint.md)-typed value. +- `id_expr` — Key value. [Expression](../syntax.md#syntax-expressions) returns a [UInt64](../../data_types/int_uint.md)-type value. **Returned value** @@ -113,7 +113,7 @@ Type: `UInt8`. ## dictGetHierarchy -For the hierarchical dictionary, returns an array of dictionary keys starting from passed `id_expr` and continuing along the chain of parent elements. +For the hierarchical dictionary, returns an array of dictionary keys starting from the passed `id_expr` and continuing along the chain of parent elements. ``` dictGetHierarchy('dict_name', id) @@ -122,7 +122,7 @@ dictGetHierarchy('dict_name', id) **Parameters** - `dict_name` — Name of the dictionary. [String literal](../syntax.md#syntax-string-literal). -- `id_expr` — Key value. [Expression](../syntax.md#syntax-expressions) returning [UInt64](../../data_types/int_uint.md)-typed value. +- `id_expr` — Key value. [Expression](../syntax.md#syntax-expressions) returns a [UInt64](../../data_types/int_uint.md)-type value. **Returned value** @@ -139,8 +139,8 @@ Checks the ancestor of a key in the hierarchical dictionary. **Parameters** - `dict_name` — Name of the dictionary. [String literal](../syntax.md#syntax-string-literal). -- `child_id_expr` — Key that should be checked. [Expression](../syntax.md#syntax-expressions) returning [UInt64](../../data_types/int_uint.md)-typed value. -- `ancestor_id_expr` — Alleged ancestor of the `child_id_expr` key. [Expression](../syntax.md#syntax-expressions) returning [UInt64](../../data_types/int_uint.md)-typed value. +- `child_id_expr` — Key to be checked. [Expression](../syntax.md#syntax-expressions) returns a [UInt64](../../data_types/int_uint.md)-type value. +- `ancestor_id_expr` — Alleged ancestor of the `child_id_expr` key. [Expression](../syntax.md#syntax-expressions) returns a [UInt64](../../data_types/int_uint.md)-type value. **Returned value** @@ -151,7 +151,7 @@ Type: `UInt8`. ## Other functions {#ext_dict_functions-other} -ClickHouse supports the specialized functions that convert the dictionary attribute values to the strict data type independently of the configuration of the dictionary. +ClickHouse supports specialized functions that convert dictionary attribute values to a specific data type regardless of the dictionary configuration. Functions: @@ -163,7 +163,7 @@ Functions: - `dictGetUUID` - `dictGetString` -All these functions have the `OrDefault` modification. For example, `dictGetDateOrDefault`. +All these functions take the `OrDefault` modifier. For example, `dictGetDateOrDefault`. Syntax: @@ -176,17 +176,17 @@ dictGet[Type]OrDefault('dict_name', 'attr_name', id_expr, default_value_expr) - `dict_name` — Name of the dictionary. [String literal](../syntax.md#syntax-string-literal). - `attr_name` — Name of the column of the dictionary. [String literal](../syntax.md#syntax-string-literal). -- `id_expr` — Key value. [Expression](../syntax.md#syntax-expressions) returning [UInt64](../../data_types/int_uint.md)-typed value. -- `default_value_expr` — Value which is returned if the dictionary doesn't contain a row with the `id_expr` key. [Expression](../syntax.md#syntax-expressions) returning the value of the data type configured for the `attr_name` attribute. +- `id_expr` — Key value. [Expression](../syntax.md#syntax-expressions) returns a [UInt64](../../data_types/int_uint.md)-type value. +- `default_value_expr` — Value which is returned if the dictionary doesn't contain a row with the `id_expr` key. [Expression](../syntax.md#syntax-expressions) returns a value in the data type configured for the `attr_name` attribute. **Returned value** -- If ClickHouse parses the attribute successfully with the [attribute's data type](../dicts/external_dicts_dict_structure.md#ext_dict_structure-attributes), functions return the value of the dictionary attribute that corresponds to `id_expr`. +- If ClickHouse parses the attribute successfully in the [attribute's data type](../dicts/external_dicts_dict_structure.md#ext_dict_structure-attributes), functions return the value of the dictionary attribute that corresponds to `id_expr`. - If there is no requested `id_expr` in the dictionary then: - - `dictGet[Type]` returns the content of the `` element which is specified for the attribute in the dictionary configuration. + - `dictGet[Type]` returns the content of the `` element specified for the attribute in the dictionary configuration. - `dictGet[Type]OrDefault` returns the value passed as the `default_value_expr` parameter. -ClickHouse throws an exception, if it cannot parse the value of the attribute or the value doesn't match the attribute data type. +ClickHouse throws an exception if it cannot parse the value of the attribute or the value doesn't match the attribute data type. [Original article](https://clickhouse.yandex/docs/en/query_language/functions/ext_dict_functions/) From d87ed7f267becec342366b432613ef31932fb082 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Sun, 23 Jun 2019 09:51:29 -0400 Subject: [PATCH 0144/1165] * Adding max_live_view_insert_blocks_before_refresh setting with default value of 64 * Updating writeIntoLiveView method to use max_live_view_insert_blocks_before_refresh from global context instead of hard coded number * Adding squashing of the result blocks similar how it is done in materialized views * Fixing bug in writeIntoLiveView that caused incoming block to be processed twice when maximum number of insert blocks was reached --- dbms/src/Core/Settings.h | 3 +- dbms/src/Storages/StorageLiveView.cpp | 7 ++ dbms/src/Storages/StorageLiveView.h | 104 +++++++++--------- .../0_stateless/00958_live_view_watch_live.py | 6 + 4 files changed, 68 insertions(+), 52 deletions(-) diff --git a/dbms/src/Core/Settings.h b/dbms/src/Core/Settings.h index 5d29c50a9ac..0196e1e35ce 100644 --- a/dbms/src/Core/Settings.h +++ b/dbms/src/Core/Settings.h @@ -330,7 +330,8 @@ struct Settings : public SettingsCollection M(SettingSeconds, live_view_heartbeat_interval, DEFAULT_LIVE_VIEW_HEARTBEAT_INTERVAL_SEC, "The heartbeat interval in seconds to indicate live query is alive.") \ M(SettingSeconds, temporary_live_view_timeout, DEFAULT_TEMPORARY_LIVE_VIEW_TIMEOUT_SEC, "Timeout after which temporary live view is deleted.") \ M(SettingSeconds, temporary_live_channel_timeout, DEFAULT_TEMPORARY_LIVE_CHANNEL_TIMEOUT_SEC, "Timeout after which temporary live channel is deleted.") \ - M(SettingMilliseconds, alter_channel_wait_ms, DEFAULT_ALTER_LIVE_CHANNEL_WAIT_MS, "The wait time for alter channel request.") + M(SettingMilliseconds, alter_channel_wait_ms, DEFAULT_ALTER_LIVE_CHANNEL_WAIT_MS, "The wait time for alter channel request.") \ + M(SettingUInt64, max_live_view_insert_blocks_before_refresh, 64, "Limit maximum number of inserted blocks after which mergeable blocks are dropped and query is re-executed.") DECLARE_SETTINGS_COLLECTION(LIST_OF_SETTINGS) diff --git a/dbms/src/Storages/StorageLiveView.cpp b/dbms/src/Storages/StorageLiveView.cpp index eecc7f6d1dc..0eb31acf1ae 100644 --- a/dbms/src/Storages/StorageLiveView.cpp +++ b/dbms/src/Storages/StorageLiveView.cpp @@ -197,6 +197,13 @@ bool StorageLiveView::getNewBlocks() auto proxy_storage = ProxyStorage::createProxyStorage(global_context.getTable(select_database_name, select_table_name), {from}, QueryProcessingStage::WithMergeableState); InterpreterSelectQuery select(inner_query->clone(), global_context, proxy_storage, SelectQueryOptions(QueryProcessingStage::Complete)); BlockInputStreamPtr data = std::make_shared(select.execute().in); + + /// Squashing is needed here because the view query can generate a lot of blocks + /// even when only one block is inserted into the parent table (e.g. if the query is a GROUP BY + /// and two-level aggregation is triggered). + data = std::make_shared( + data, global_context.getSettingsRef().min_insert_block_size_rows, global_context.getSettingsRef().min_insert_block_size_bytes); + while (Block block = data->read()) { /// calculate hash before virtual column is added diff --git a/dbms/src/Storages/StorageLiveView.h b/dbms/src/Storages/StorageLiveView.h index 84a7ea80bca..3f2732647b3 100644 --- a/dbms/src/Storages/StorageLiveView.h +++ b/dbms/src/Storages/StorageLiveView.h @@ -17,6 +17,7 @@ limitations under the License. */ #include #include #include +#include #include #include #include @@ -166,10 +167,42 @@ public: } } + bool is_block_processed = false; BlockInputStreams from; - BlocksPtr blocks = std::make_shared(); BlocksPtrs mergeable_blocks; BlocksPtr new_mergeable_blocks = std::make_shared(); + + { + Poco::FastMutex::ScopedLock lock(live_view.mutex); + + mergeable_blocks = live_view.getMergeableBlocks(); + if (!mergeable_blocks || mergeable_blocks->size() >= context.getGlobalContext().getSettingsRef().max_live_view_insert_blocks_before_refresh) + { + mergeable_blocks = std::make_shared>(); + BlocksPtr base_mergeable_blocks = std::make_shared(); + InterpreterSelectQuery interpreter(live_view.getInnerQuery(), context, SelectQueryOptions(QueryProcessingStage::WithMergeableState), Names()); + auto view_mergeable_stream = std::make_shared( + interpreter.execute().in); + while (Block this_block = view_mergeable_stream->read()) + base_mergeable_blocks->push_back(this_block); + mergeable_blocks->push_back(base_mergeable_blocks); + live_view.setMergeableBlocks(mergeable_blocks); + + /// Create from streams + for (auto & blocks_ : *mergeable_blocks) + { + if (blocks_->empty()) + continue; + auto sample_block = blocks_->front().cloneEmpty(); + BlockInputStreamPtr stream = std::make_shared(std::make_shared(blocks_), sample_block); + from.push_back(std::move(stream)); + } + + is_block_processed = true; + } + } + + if (!is_block_processed) { auto parent_storage = context.getTable(live_view.getSelectDatabaseName(), live_view.getSelectTableName()); BlockInputStreams streams = {std::make_shared(block)}; @@ -181,52 +214,26 @@ public: select_block.execute().in); while (Block this_block = data_mergeable_stream->read()) new_mergeable_blocks->push_back(this_block); - } - if (new_mergeable_blocks->empty()) - return; + if (new_mergeable_blocks->empty()) + return; - { - Poco::FastMutex::ScopedLock lock(live_view.mutex); - - mergeable_blocks = live_view.getMergeableBlocks(); - if (!mergeable_blocks || mergeable_blocks->size() >= 64) { - mergeable_blocks = std::make_shared>(); - BlocksPtr base_mergeable_blocks = std::make_shared(); - InterpreterSelectQuery interpreter(live_view.getInnerQuery(), context, SelectQueryOptions(QueryProcessingStage::WithMergeableState), Names()); - auto view_mergeable_stream = std::make_shared( - interpreter.execute().in); - while (Block this_block = view_mergeable_stream->read()) - base_mergeable_blocks->push_back(this_block); - mergeable_blocks->push_back(base_mergeable_blocks); - live_view.setMergeableBlocks(mergeable_blocks); - } + Poco::FastMutex::ScopedLock lock(live_view.mutex); - /// Need make new mergeable block structure match the other mergeable blocks - if (!mergeable_blocks->front()->empty()) - { - auto sample_block = mergeable_blocks->front()->front(); - auto sample_new_block = new_mergeable_blocks->front(); - for (auto col : sample_new_block) + mergeable_blocks = live_view.getMergeableBlocks(); + mergeable_blocks->push_back(new_mergeable_blocks); + + /// Create from streams + for (auto & blocks_ : *mergeable_blocks) { - for (auto & new_block : *new_mergeable_blocks) - { - if (!sample_block.has(col.name)) - new_block.erase(col.name); - } + if (blocks_->empty()) + continue; + auto sample_block = blocks_->front().cloneEmpty(); + BlockInputStreamPtr stream = std::make_shared(std::make_shared(blocks_), sample_block); + from.push_back(std::move(stream)); } } - - mergeable_blocks->push_back(new_mergeable_blocks); - - /// Create from blocks streams - for (auto & blocks_ : *mergeable_blocks) - { - auto sample_block = mergeable_blocks->front()->front().cloneEmpty(); - BlockInputStreamPtr stream = std::make_shared(std::make_shared(blocks_), sample_block); - from.push_back(std::move(stream)); - } } auto parent_storage = context.getTable(live_view.getSelectDatabaseName(), live_view.getSelectTableName()); @@ -234,18 +241,13 @@ public: InterpreterSelectQuery select(live_view.getInnerQuery(), context, proxy_storage, QueryProcessingStage::Complete); BlockInputStreamPtr data = std::make_shared(select.execute().in); - while (Block this_block = data->read()) - { - blocks->push_back(this_block); - } + /// Squashing is needed here because the view query can generate a lot of blocks + /// even when only one block is inserted into the parent table (e.g. if the query is a GROUP BY + /// and two-level aggregation is triggered). + data = std::make_shared( + data, context.getGlobalContext().getSettingsRef().min_insert_block_size_rows, context.getGlobalContext().getSettingsRef().min_insert_block_size_bytes); - if (blocks->empty()) - return; - - auto sample_block = blocks->front().cloneEmpty(); - BlockInputStreamPtr new_data = std::make_shared(std::make_shared(blocks), sample_block); - - copyData(*new_data, *output); + copyData(*data, *output); } private: diff --git a/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py b/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py index 7cbea5fbff6..33cc9db3ccc 100755 --- a/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py +++ b/dbms/tests/queries/0_stateless/00958_live_view_watch_live.py @@ -28,8 +28,14 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client1.expect(r'0.*1' + end_of_block) client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') client1.expect(r'6.*2' + end_of_block) + client2.expect(prompt) client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') client1.expect(r'21.*3' + end_of_block) + client2.expect(prompt) + for i in range(1,129): + client2.send('INSERT INTO test.mt VALUES (1)') + client1.expect(r'%d.*%d' % (21+i, 3+i) + end_of_block) + client2.expect(prompt) # send Ctrl-C os.kill(client1.process.pid, signal.SIGINT) client1.expect(prompt) From 9873b046119be84e09b0901efc042bb3eade0a00 Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Tue, 25 Jun 2019 16:10:09 +0300 Subject: [PATCH 0145/1165] StringRef -> String (race cond) --- dbms/src/Parsers/ASTPartition.h | 2 +- dbms/src/Parsers/ParserPartition.cpp | 8 ++++---- dbms/src/Storages/MergeTree/MergeTreeData.cpp | 4 ++-- .../queries/0_stateless/00944_clear_index_in_partition.sh | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dbms/src/Parsers/ASTPartition.h b/dbms/src/Parsers/ASTPartition.h index d87206d7bb4..8a837a10451 100644 --- a/dbms/src/Parsers/ASTPartition.h +++ b/dbms/src/Parsers/ASTPartition.h @@ -12,7 +12,7 @@ class ASTPartition : public IAST { public: ASTPtr value; - StringRef fields_str; /// The extent of comma-separated partition expression fields without parentheses. + String fields_str; /// The extent of comma-separated partition expression fields without parentheses. size_t fields_count = 0; String id; diff --git a/dbms/src/Parsers/ParserPartition.cpp b/dbms/src/Parsers/ParserPartition.cpp index 6d2c259f8bf..4dc1f4cabf9 100644 --- a/dbms/src/Parsers/ParserPartition.cpp +++ b/dbms/src/Parsers/ParserPartition.cpp @@ -35,7 +35,7 @@ bool ParserPartition::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) return false; size_t fields_count; - StringRef fields_str; + String fields_str; const auto * tuple_ast = value->as(); if (tuple_ast && tuple_ast->name == "tuple") @@ -59,17 +59,17 @@ bool ParserPartition::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) if (right_paren->type != TokenType::ClosingRoundBracket) return false; - fields_str = StringRef(left_paren->end, right_paren->begin - left_paren->end); + fields_str = String(left_paren->end, right_paren->begin - left_paren->end); } else { fields_count = 1; - fields_str = StringRef(begin->begin, pos->begin - begin->begin); + fields_str = String(begin->begin, pos->begin - begin->begin); } partition->value = value; partition->children.push_back(value); - partition->fields_str = fields_str; + partition->fields_str = std::move(fields_str); partition->fields_count = fields_count; } diff --git a/dbms/src/Storages/MergeTree/MergeTreeData.cpp b/dbms/src/Storages/MergeTree/MergeTreeData.cpp index 894ee53e2da..f21e75eef75 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeData.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeData.cpp @@ -2492,7 +2492,7 @@ String MergeTreeData::getPartitionIDFromQuery(const ASTPtr & ast, const Context if (fields_count) { ReadBufferFromMemory left_paren_buf("(", 1); - ReadBufferFromMemory fields_buf(partition_ast.fields_str.data, partition_ast.fields_str.size); + ReadBufferFromMemory fields_buf(partition_ast.fields_str.data(), partition_ast.fields_str.size()); ReadBufferFromMemory right_paren_buf(")", 1); ConcatReadBuffer buf({&left_paren_buf, &fields_buf, &right_paren_buf}); @@ -2502,7 +2502,7 @@ String MergeTreeData::getPartitionIDFromQuery(const ASTPtr & ast, const Context RowReadExtension unused; if (!input_stream.read(columns, unused)) throw Exception( - "Could not parse partition value: `" + partition_ast.fields_str.toString() + "`", + "Could not parse partition value: `" + partition_ast.fields_str + "`", ErrorCodes::INVALID_PARTITION_VALUE); for (size_t i = 0; i < fields_count; ++i) diff --git a/dbms/tests/queries/0_stateless/00944_clear_index_in_partition.sh b/dbms/tests/queries/0_stateless/00944_clear_index_in_partition.sh index 5a179a8b20a..9047bbb3a72 100755 --- a/dbms/tests/queries/0_stateless/00944_clear_index_in_partition.sh +++ b/dbms/tests/queries/0_stateless/00944_clear_index_in_partition.sh @@ -48,4 +48,4 @@ $CLICKHOUSE_CLIENT --query="SELECT count() FROM test.minmax_idx WHERE i64 = 2;" $CLICKHOUSE_CLIENT --query="SELECT count() FROM test.minmax_idx WHERE i64 = 2 FORMAT JSON" | grep "rows_read" -#$CLICKHOUSE_CLIENT --query="DROP TABLE test.minmax_idx" +$CLICKHOUSE_CLIENT --query="DROP TABLE test.minmax_idx" From 8de1340f5123fa1060c1e1bc1c65d62a4ae682d2 Mon Sep 17 00:00:00 2001 From: Nikita Lapkov Date: Wed, 26 Jun 2019 11:10:07 +0000 Subject: [PATCH 0146/1165] update libunwind --- contrib/libunwind | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/libunwind b/contrib/libunwind index d18a43580cc..ec86b1c6a2c 160000 --- a/contrib/libunwind +++ b/contrib/libunwind @@ -1 +1 @@ -Subproject commit d18a43580cc201894c9ea9c7b90ca5237db841ed +Subproject commit ec86b1c6a2c6b8ba316f429db9a6d4122dd12710 From 882747fde6974dde412711a463bc64a62c2a9f9f Mon Sep 17 00:00:00 2001 From: proller Date: Fri, 28 Jun 2019 18:22:57 +0300 Subject: [PATCH 0147/1165] Fix building without submodules --- cmake/find_mimalloc.cmake | 3 ++- libs/libcommon/cmake/find_jemalloc.cmake | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cmake/find_mimalloc.cmake b/cmake/find_mimalloc.cmake index 9ee785e0753..45ebf90a204 100644 --- a/cmake/find_mimalloc.cmake +++ b/cmake/find_mimalloc.cmake @@ -3,7 +3,8 @@ if (OS_LINUX AND NOT SANITIZE AND NOT ARCH_ARM AND NOT ARCH_32 AND NOT ARCH_PPC6 endif () if (NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/mimalloc/include/mimalloc.h") - message (WARNING "submodule contrib/mimalloc is missing. to fix try run: \n git submodule update --init --recursive") + message (WARNING "submodule contrib/mimalloc is missing. to fix try run: \n git submodule update --init --recursive") + return () endif () if (ENABLE_MIMALLOC) diff --git a/libs/libcommon/cmake/find_jemalloc.cmake b/libs/libcommon/cmake/find_jemalloc.cmake index 3a1b14d9c33..0b1c80c8934 100644 --- a/libs/libcommon/cmake/find_jemalloc.cmake +++ b/libs/libcommon/cmake/find_jemalloc.cmake @@ -7,7 +7,7 @@ endif () option (ENABLE_JEMALLOC "Set to TRUE to use jemalloc" ${ENABLE_JEMALLOC_DEFAULT}) if (OS_LINUX AND NOT ARCH_ARM) option (USE_INTERNAL_JEMALLOC_LIBRARY "Set to FALSE to use system jemalloc library instead of bundled" ${NOT_UNBUNDLED}) -elseif () +else() option (USE_INTERNAL_JEMALLOC_LIBRARY "Set to FALSE to use system jemalloc library instead of bundled" OFF) endif() @@ -30,7 +30,7 @@ if (ENABLE_JEMALLOC) if (JEMALLOC_LIBRARIES) set (USE_JEMALLOC 1) - else () + elseif (NOT MISSING_INTERNAL_JEMALLOC_LIBRARY) message (FATAL_ERROR "ENABLE_JEMALLOC is set to true, but library was not found") endif () From b89c38f0f09697f40053965fef14c19ad307e9e1 Mon Sep 17 00:00:00 2001 From: proller Date: Fri, 28 Jun 2019 18:24:56 +0300 Subject: [PATCH 0148/1165] Fix more gcc9 warnings --- dbms/src/IO/ReadBufferAIO.cpp | 2 +- dbms/src/IO/WriteBufferAIO.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/IO/ReadBufferAIO.cpp b/dbms/src/IO/ReadBufferAIO.cpp index f47e04bff75..7aad9b1eebd 100644 --- a/dbms/src/IO/ReadBufferAIO.cpp +++ b/dbms/src/IO/ReadBufferAIO.cpp @@ -254,7 +254,7 @@ void ReadBufferAIO::prepare() /// Region of the disk from which we want to read data. const off_t region_begin = first_unread_pos_in_file; - if ((requested_byte_count > std::numeric_limits::max()) || + if ((static_cast(requested_byte_count) > std::numeric_limits::max()) || (first_unread_pos_in_file > (std::numeric_limits::max() - static_cast(requested_byte_count)))) throw Exception("An overflow occurred during file operation", ErrorCodes::LOGICAL_ERROR); diff --git a/dbms/src/IO/WriteBufferAIO.cpp b/dbms/src/IO/WriteBufferAIO.cpp index 2fe7da27809..e163124f418 100644 --- a/dbms/src/IO/WriteBufferAIO.cpp +++ b/dbms/src/IO/WriteBufferAIO.cpp @@ -274,7 +274,7 @@ void WriteBufferAIO::prepare() /// Region of the disk in which we want to write data. const off_t region_begin = pos_in_file; - if ((flush_buffer.offset() > std::numeric_limits::max()) || + if ((static_cast(flush_buffer.offset()) > std::numeric_limits::max()) || (pos_in_file > (std::numeric_limits::max() - static_cast(flush_buffer.offset())))) throw Exception("An overflow occurred during file operation", ErrorCodes::LOGICAL_ERROR); From a5e2a725d296d7b67ec6dba6062863aec4da1de2 Mon Sep 17 00:00:00 2001 From: proller Date: Fri, 28 Jun 2019 20:23:11 +0300 Subject: [PATCH 0149/1165] was wrong! ../dbms/src/IO/WriteBufferAIO.cpp:277:54: error: result of comparison 'ssize_t' (aka 'long') > 9223372036854775807 is always false [-Werror,-Wtautological-type-limit-compare] if ((static_cast(flush_buffer.offset()) > std::numeric_limits::max()) || ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- cmake/find_mimalloc.cmake | 2 +- dbms/src/IO/ReadBufferAIO.cpp | 2 +- dbms/src/IO/WriteBufferAIO.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/find_mimalloc.cmake b/cmake/find_mimalloc.cmake index 45ebf90a204..6e3f24625b6 100644 --- a/cmake/find_mimalloc.cmake +++ b/cmake/find_mimalloc.cmake @@ -4,7 +4,7 @@ endif () if (NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/mimalloc/include/mimalloc.h") message (WARNING "submodule contrib/mimalloc is missing. to fix try run: \n git submodule update --init --recursive") - return () + return() endif () if (ENABLE_MIMALLOC) diff --git a/dbms/src/IO/ReadBufferAIO.cpp b/dbms/src/IO/ReadBufferAIO.cpp index 7aad9b1eebd..f47e04bff75 100644 --- a/dbms/src/IO/ReadBufferAIO.cpp +++ b/dbms/src/IO/ReadBufferAIO.cpp @@ -254,7 +254,7 @@ void ReadBufferAIO::prepare() /// Region of the disk from which we want to read data. const off_t region_begin = first_unread_pos_in_file; - if ((static_cast(requested_byte_count) > std::numeric_limits::max()) || + if ((requested_byte_count > std::numeric_limits::max()) || (first_unread_pos_in_file > (std::numeric_limits::max() - static_cast(requested_byte_count)))) throw Exception("An overflow occurred during file operation", ErrorCodes::LOGICAL_ERROR); diff --git a/dbms/src/IO/WriteBufferAIO.cpp b/dbms/src/IO/WriteBufferAIO.cpp index e163124f418..2fe7da27809 100644 --- a/dbms/src/IO/WriteBufferAIO.cpp +++ b/dbms/src/IO/WriteBufferAIO.cpp @@ -274,7 +274,7 @@ void WriteBufferAIO::prepare() /// Region of the disk in which we want to write data. const off_t region_begin = pos_in_file; - if ((static_cast(flush_buffer.offset()) > std::numeric_limits::max()) || + if ((flush_buffer.offset() > std::numeric_limits::max()) || (pos_in_file > (std::numeric_limits::max() - static_cast(flush_buffer.offset())))) throw Exception("An overflow occurred during file operation", ErrorCodes::LOGICAL_ERROR); From a504baf0b32b7a3a5ea34b9a530f42d54e6d8d50 Mon Sep 17 00:00:00 2001 From: Danila Kutenin Date: Fri, 28 Jun 2019 20:33:47 +0300 Subject: [PATCH 0150/1165] mimalloc off MI_OVERRIDE --- contrib/mimalloc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/mimalloc b/contrib/mimalloc index b4ece3482f9..a787bdebce9 160000 --- a/contrib/mimalloc +++ b/contrib/mimalloc @@ -1 +1 @@ -Subproject commit b4ece3482f944b5d07d889cbaebaf9aa6c56cc03 +Subproject commit a787bdebce94bf3776dc0d1ad597917f479ab8d5 From 450b20ca89d2682adb0b82ab9857e040e6eb9876 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Mon, 1 Jul 2019 08:58:31 +0300 Subject: [PATCH 0151/1165] max_memory_usage support in MySQL wire protocol --- dbms/programs/server/MySQLHandler.cpp | 49 +-- dbms/programs/server/MySQLHandler.h | 8 +- dbms/src/Core/MySQLProtocol.cpp | 47 +-- dbms/src/Core/MySQLProtocol.h | 300 ++++++++++-------- .../Formats/MySQLWireBlockOutputStream.cpp | 4 +- dbms/src/IO/ReadHelpers.cpp | 26 ++ dbms/src/IO/ReadHelpers.h | 3 + dbms/src/IO/WriteHelpers.h | 10 + 8 files changed, 252 insertions(+), 195 deletions(-) diff --git a/dbms/programs/server/MySQLHandler.cpp b/dbms/programs/server/MySQLHandler.cpp index a935f13e82a..178778c0227 100644 --- a/dbms/programs/server/MySQLHandler.cpp +++ b/dbms/programs/server/MySQLHandler.cpp @@ -68,7 +68,8 @@ void MySQLHandler::run() LOG_TRACE(log, "Sent handshake"); - HandshakeResponse handshake_response = finishHandshake(); + HandshakeResponse handshake_response; + finishHandshake(handshake_response); connection_context.client_capabilities = handshake_response.capability_flags; if (handshake_response.max_packet_size) connection_context.max_packet_size = handshake_response.max_packet_size; @@ -104,7 +105,7 @@ void MySQLHandler::run() while (true) { packet_sender->resetSequenceId(); - String payload = packet_sender->receivePacketPayload(); + Vector payload = packet_sender->receivePacketPayload(); int command = payload[0]; LOG_DEBUG(log, "Received command: " << std::to_string(command) << ". Connection id: " << connection_id << "."); try @@ -114,13 +115,13 @@ void MySQLHandler::run() case COM_QUIT: return; case COM_INIT_DB: - comInitDB(payload); + comInitDB(std::move(payload)); break; case COM_QUERY: - comQuery(payload); + comQuery(std::move(payload)); break; case COM_FIELD_LIST: - comFieldList(payload); + comFieldList(std::move(payload)); break; case COM_PING: comPing(); @@ -151,9 +152,8 @@ void MySQLHandler::run() * Reading is performed from socket instead of ReadBuffer to prevent reading part of SSL handshake. * If we read it from socket, it will be impossible to start SSL connection using Poco. Size of SSLRequest packet payload is 32 bytes, thus we can read at most 36 bytes. */ -MySQLProtocol::HandshakeResponse MySQLHandler::finishHandshake() +void MySQLHandler::finishHandshake(MySQLProtocol::HandshakeResponse & packet) { - HandshakeResponse packet; size_t packet_size = PACKET_HEADER_SIZE + SSL_REQUEST_PAYLOAD_SIZE; /// Buffer for SSLRequest or part of HandshakeResponse. @@ -181,7 +181,10 @@ MySQLProtocol::HandshakeResponse MySQLHandler::finishHandshake() { read_bytes(packet_size); /// Reading rest SSLRequest. SSLRequest ssl_request; - ssl_request.readPayload(String(buf + PACKET_HEADER_SIZE, pos - PACKET_HEADER_SIZE)); + Vector payload; + WriteBufferFromVector buffer(payload); + buffer.write(buf + PACKET_HEADER_SIZE, pos - PACKET_HEADER_SIZE); + ssl_request.readPayload(std::move(payload)); connection_context.client_capabilities = ssl_request.capability_flags; connection_context.max_packet_size = ssl_request.max_packet_size ? ssl_request.max_packet_size : MAX_PACKET_LENGTH; secure_connection = true; @@ -197,13 +200,14 @@ MySQLProtocol::HandshakeResponse MySQLHandler::finishHandshake() { /// Reading rest of HandshakeResponse. packet_size = PACKET_HEADER_SIZE + payload_size; - WriteBufferFromOwnString buf_for_handshake_response; + Vector packet_data; + WriteBufferFromVector buf_for_handshake_response(packet_data); buf_for_handshake_response.write(buf, pos); copyData(*packet_sender->in, buf_for_handshake_response, packet_size - pos); - packet.readPayload(buf_for_handshake_response.str().substr(PACKET_HEADER_SIZE)); + Vector payload(Vector::const_iterator(packet_data.data() + PACKET_HEADER_SIZE), const_cast(packet_data).end()); + packet.readPayload(std::move(payload)); packet_sender->sequence_id++; } - return packet; } String MySQLHandler::generateScramble() @@ -319,18 +323,18 @@ void MySQLHandler::authenticate(const HandshakeResponse & handshake_response, co } } -void MySQLHandler::comInitDB(const String & payload) +void MySQLHandler::comInitDB(Vector && payload) { - String database = payload.substr(1); + String database(payload.data() + 1, payload.size() - 1); LOG_DEBUG(log, "Setting current database to " << database); connection_context.setCurrentDatabase(database); packet_sender->sendPacket(OK_Packet(0, client_capability_flags, 0, 0, 1), true); } -void MySQLHandler::comFieldList(const String & payload) +void MySQLHandler::comFieldList(Vector && payload) { ComFieldList packet; - packet.readPayload(payload); + packet.readPayload(std::move(payload)); String database = connection_context.getCurrentDatabase(); StoragePtr tablePtr = connection_context.getTable(database, packet.table); for (const NameAndTypePair & column: tablePtr->getColumns().getAll()) @@ -348,21 +352,26 @@ void MySQLHandler::comPing() packet_sender->sendPacket(OK_Packet(0x0, client_capability_flags, 0, 0, 0), true); } -void MySQLHandler::comQuery(const String & payload) +void MySQLHandler::comQuery(Vector && payload) { bool with_output = false; std::function set_content_type = [&with_output](const String &) -> void { with_output = true; }; - String query = payload.substr(1); + // MariaDB client starts session with that query + String select_version = "select @@version_comment limit 1"; // Translate query from MySQL to ClickHouse. // This is a temporary workaround until ClickHouse supports the syntax "@@var_name". - if (query == "select @@version_comment limit 1") // MariaDB client starts session with that query - query = "select ''"; + if (payload.size() > 1 && String(payload.data() + 1, payload.data() - 1) == select_version) + { + payload.clear(); + WriteBufferFromVector buffer(payload); + writeString(select_version, buffer); + } - ReadBufferFromString buf(query); + ReadBufferFromMemory buf(payload.data() + 1, payload.size() - 1); executeQuery(buf, *out, true, connection_context, set_content_type, nullptr); if (!with_output) packet_sender->sendPacket(OK_Packet(0x00, client_capability_flags, 0, 0, 0), true); diff --git a/dbms/programs/server/MySQLHandler.h b/dbms/programs/server/MySQLHandler.h index f55906f7428..f2161c7bd60 100644 --- a/dbms/programs/server/MySQLHandler.h +++ b/dbms/programs/server/MySQLHandler.h @@ -21,15 +21,15 @@ public: private: /// Enables SSL, if client requested. - MySQLProtocol::HandshakeResponse finishHandshake(); + void finishHandshake(MySQLProtocol::HandshakeResponse &); - void comQuery(const String & payload); + void comQuery(MySQLProtocol::Vector && payload); - void comFieldList(const String & payload); + void comFieldList(MySQLProtocol::Vector && payload); void comPing(); - void comInitDB(const String & payload); + void comInitDB(MySQLProtocol::Vector && payload); static String generateScramble(); diff --git a/dbms/src/Core/MySQLProtocol.cpp b/dbms/src/Core/MySQLProtocol.cpp index f727ae3df54..0e2766c8f9a 100644 --- a/dbms/src/Core/MySQLProtocol.cpp +++ b/dbms/src/Core/MySQLProtocol.cpp @@ -7,9 +7,7 @@ #include "MySQLProtocol.h" -namespace DB -{ -namespace MySQLProtocol +namespace DB::MySQLProtocol { void PacketSender::resetSequenceId() @@ -17,7 +15,7 @@ void PacketSender::resetSequenceId() sequence_id = 0; } -String PacketSender::packetToText(String payload) +String PacketSender::packetToText(const PODArray & payload) { String result; for (auto c : payload) @@ -28,11 +26,11 @@ String PacketSender::packetToText(String payload) return result; } -uint64_t readLengthEncodedNumber(std::istringstream & ss) +uint64_t readLengthEncodedNumber(ReadBuffer & ss) { char c; uint64_t buf = 0; - ss.get(c); + ss.readStrict(c); auto cc = static_cast(c); if (cc < 0xfc) { @@ -40,55 +38,40 @@ uint64_t readLengthEncodedNumber(std::istringstream & ss) } else if (cc < 0xfd) { - ss.read(reinterpret_cast(&buf), 2); + ss.readStrict(reinterpret_cast(&buf), 2); } else if (cc < 0xfe) { - ss.read(reinterpret_cast(&buf), 3); + ss.readStrict(reinterpret_cast(&buf), 3); } else { - ss.read(reinterpret_cast(&buf), 8); + ss.readStrict(reinterpret_cast(&buf), 8); } return buf; } -std::string writeLengthEncodedNumber(uint64_t x) +void writeLengthEncodedNumber(uint64_t x, WriteBuffer & buffer) { - std::string result; if (x < 251) { - result.append(1, static_cast(x)); + buffer.write(static_cast(x)); } else if (x < (1 << 16)) { - result.append(1, 0xfc); - result.append(reinterpret_cast(&x), 2); + buffer.write(0xfc); + buffer.write(reinterpret_cast(&x), 2); } else if (x < (1 << 24)) { - result.append(1, 0xfd); - result.append(reinterpret_cast(&x), 3); + buffer.write(0xfd); + buffer.write(reinterpret_cast(&x), 3); } else { - result.append(1, 0xfe); - result.append(reinterpret_cast(&x), 8); + buffer.write(0xfe); + buffer.write(reinterpret_cast(&x), 8); } - return result; -} - -void writeLengthEncodedString(std::string & payload, const std::string & s) -{ - payload.append(writeLengthEncodedNumber(s.length())); - payload.append(s); -} - -void writeNulTerminatedString(std::string & payload, const std::string & s) -{ - payload.append(s); - payload.append(1, 0); } } -} diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index 3d908971601..a4d03908bad 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -1,12 +1,17 @@ #pragma once +#include +#include #include #include #include +#include #include +#include #include #include #include +#include #include #include #include @@ -116,6 +121,27 @@ enum ColumnType }; +// For tracking memory of packets with String fields. +class PacketMemoryTracker +{ + Int64 allocated = 0; +public: + void alloc(Int64 size) + { + CurrentMemoryTracker::alloc(allocated); + allocated = size; + } + + ~PacketMemoryTracker() + { + CurrentMemoryTracker::free(allocated); + } +}; + + +using Vector = PODArray; + + class ProtocolError : public DB::Exception { public: @@ -126,7 +152,7 @@ public: class WritePacket { public: - virtual String getPayload() const = 0; + virtual void writePayload(WriteBuffer & buffer) const = 0; virtual ~WritePacket() = default; }; @@ -136,8 +162,8 @@ class ReadPacket { public: ReadPacket() = default; - ReadPacket(const ReadPacket &) = default; - virtual void readPayload(String payload) = 0; + ReadPacket(ReadPacket &&) = default; + virtual void readPayload(Vector && payload) = 0; virtual ~ReadPacket() = default; }; @@ -170,9 +196,10 @@ public: { } - String receivePacketPayload() + Vector receivePacketPayload() { - WriteBufferFromOwnString buf; + Vector result; + WriteBufferFromVector buf(result); size_t payload_length = 0; size_t packet_sequence_id = 0; @@ -202,23 +229,26 @@ public: copyData(*in, static_cast(buf), payload_length); } while (payload_length == max_packet_size); - return std::move(buf.str()); + return result; } void receivePacket(ReadPacket & packet) { - packet.readPayload(receivePacketPayload()); + auto payload = receivePacketPayload(); + packet.readPayload(std::move(payload)); } template void sendPacket(const T & packet, bool flush = false) { static_assert(std::is_base_of()); - String payload = packet.getPayload(); + Vector payload; + WriteBufferFromVector buffer(payload); + packet.writePayload(buffer); size_t pos = 0; do { - size_t payload_length = std::min(payload.length() - pos, max_packet_size); + size_t payload_length = std::min(payload.size() - pos, max_packet_size); out->write(reinterpret_cast(&payload_length), 3); out->write(reinterpret_cast(&sequence_id), 1); @@ -226,7 +256,7 @@ public: pos += payload_length; sequence_id++; - } while (pos < payload.length()); + } while (pos < payload.size()); if (flush) out->next(); @@ -235,19 +265,28 @@ public: /// Sets sequence-id to 0. Must be called before each command phase. void resetSequenceId(); -private: /// Converts packet to text. Is used for debug output. - static String packetToText(String payload); + static String packetToText(const Vector & payload); }; -uint64_t readLengthEncodedNumber(std::istringstream & ss); +uint64_t readLengthEncodedNumber(ReadBuffer & ss); -String writeLengthEncodedNumber(uint64_t x); +void writeLengthEncodedNumber(uint64_t x, WriteBuffer & buffer); -void writeLengthEncodedString(String & payload, const String & s); +template +void writeLengthEncodedString(const T & s, WriteBuffer & buffer) +{ + writeLengthEncodedNumber(s.size(), buffer); + buffer.write(s.data(), s.size()); +} -void writeNulTerminatedString(String & payload, const String & s); +template +void writeNulTerminatedString(const T & s, WriteBuffer & buffer) +{ + buffer.write(s.data(), s.size()); + buffer.write(0); +} class Handshake : public WritePacket @@ -267,27 +306,25 @@ public: , capability_flags(capability_flags) , character_set(CharacterSet::utf8_general_ci) , status_flags(0) - , auth_plugin_data(auth_plugin_data) + , auth_plugin_data(std::move(auth_plugin_data)) { } - String getPayload() const override + void writePayload(WriteBuffer & buffer) const override { - String result; - result.append(1, protocol_version); - writeNulTerminatedString(result, server_version); - result.append(reinterpret_cast(&connection_id), 4); - writeNulTerminatedString(result, auth_plugin_data.substr(0, AUTH_PLUGIN_DATA_PART_1_LENGTH)); - result.append(reinterpret_cast(&capability_flags), 2); - result.append(reinterpret_cast(&character_set), 1); - result.append(reinterpret_cast(&status_flags), 2); - result.append((reinterpret_cast(&capability_flags)) + 2, 2); - result.append(1, auth_plugin_data.size()); - result.append(10, 0x0); - result.append(auth_plugin_data.substr(AUTH_PLUGIN_DATA_PART_1_LENGTH, auth_plugin_data.size() - AUTH_PLUGIN_DATA_PART_1_LENGTH)); - result.append(Authentication::SHA256); - result.append(1, 0x0); - return result; + buffer.write(static_cast(protocol_version)); + writeNulTerminatedString(server_version, buffer); + buffer.write(reinterpret_cast(&connection_id), 4); + writeNulTerminatedString(auth_plugin_data.substr(0, AUTH_PLUGIN_DATA_PART_1_LENGTH), buffer); + buffer.write(reinterpret_cast(&capability_flags), 2); + buffer.write(reinterpret_cast(&character_set), 1); + buffer.write(reinterpret_cast(&status_flags), 2); + buffer.write((reinterpret_cast(&capability_flags)) + 2, 2); + buffer.write(static_cast(auth_plugin_data.size())); + writeChar(0x0, 10, buffer); + writeString(auth_plugin_data.substr(AUTH_PLUGIN_DATA_PART_1_LENGTH, auth_plugin_data.size() - AUTH_PLUGIN_DATA_PART_1_LENGTH), buffer); + writeString(Authentication::SHA256, buffer); + writeChar(0x0, 1, buffer); } }; @@ -298,67 +335,68 @@ public: uint32_t max_packet_size; uint8_t character_set; - void readPayload(String s) override + void readPayload(Vector && s) override { - std::istringstream ss(s); - ss.readsome(reinterpret_cast(&capability_flags), 4); - ss.readsome(reinterpret_cast(&max_packet_size), 4); - ss.readsome(reinterpret_cast(&character_set), 1); + ReadBufferFromMemory buffer(s.data(), s.size()); + buffer.readStrict(reinterpret_cast(&capability_flags), 4); + buffer.readStrict(reinterpret_cast(&max_packet_size), 4); + buffer.readStrict(reinterpret_cast(&character_set), 1); } }; class HandshakeResponse : public ReadPacket { public: - uint32_t capability_flags; - uint32_t max_packet_size; - uint8_t character_set; + uint32_t capability_flags = 0; + uint32_t max_packet_size = 0; + uint8_t character_set = 0; String username; String auth_response; String database; String auth_plugin_name; + PacketMemoryTracker tracker; HandshakeResponse() = default; - HandshakeResponse(const HandshakeResponse &) = default; - - void readPayload(String s) override + void readPayload(Vector && payload) override { - std::istringstream ss(s); + std::cerr << PacketSender::packetToText(payload) << std::endl; + tracker.alloc(payload.size()); + ReadBufferFromMemory buffer(payload.data(), payload.size()); - ss.readsome(reinterpret_cast(&capability_flags), 4); - ss.readsome(reinterpret_cast(&max_packet_size), 4); - ss.readsome(reinterpret_cast(&character_set), 1); - ss.ignore(23); + buffer.readStrict(reinterpret_cast(&capability_flags), 4); + buffer.readStrict(reinterpret_cast(&max_packet_size), 4); + buffer.readStrict(reinterpret_cast(&character_set), 1); + buffer.ignore(23); - std::getline(ss, username, static_cast(0x0)); + readNullTerminated(username, buffer); if (capability_flags & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA) { - auto len = readLengthEncodedNumber(ss); + auto len = readLengthEncodedNumber(buffer); auth_response.resize(len); - ss.read(auth_response.data(), static_cast(len)); + buffer.readStrict(auth_response.data(), len); } else if (capability_flags & CLIENT_SECURE_CONNECTION) { - uint8_t len; - ss.read(reinterpret_cast(&len), 1); - auth_response.resize(len); - ss.read(auth_response.data(), len); + char len; + buffer.readStrict(len); + auth_response.resize(static_cast(len)); + buffer.readStrict(auth_response.data(), len); } else { - std::getline(ss, auth_response, static_cast(0x0)); + readNullTerminated(auth_response, buffer); } if (capability_flags & CLIENT_CONNECT_WITH_DB) { - std::getline(ss, database, static_cast(0x0)); + readNullTerminated(database, buffer); } if (capability_flags & CLIENT_PLUGIN_AUTH) { - std::getline(ss, auth_plugin_name, static_cast(0x0)); + readNullTerminated(auth_plugin_name, buffer); } } }; @@ -373,13 +411,12 @@ public: { } - String getPayload() const override + void writePayload(WriteBuffer & buffer) const override { - String result; - result.append(1, 0xfe); - writeNulTerminatedString(result, plugin_name); - result.append(auth_plugin_data); - return result; + buffer.write(0xfe); + writeNulTerminatedString(plugin_name, buffer); + writeString(auth_plugin_data, buffer); + std::cerr << auth_plugin_data.size() << std::endl; } }; @@ -387,10 +424,12 @@ class AuthSwitchResponse : public ReadPacket { public: String value; + PacketMemoryTracker tracker; - void readPayload(String s) override + void readPayload(Vector && payload) override { - value = std::move(s); + tracker.alloc(payload.size()); + value.assign(payload.data(), payload.size()); } }; @@ -398,14 +437,12 @@ class AuthMoreData : public WritePacket { String data; public: - AuthMoreData(String data): data(std::move(data)) {} + explicit AuthMoreData(String data): data(std::move(data)) {} - String getPayload() const override + void writePayload(WriteBuffer & buffer) const override { - String result; - result.append(1, 0x01); - result.append(data); - return result; + buffer.write(0x01); + writeString(data, buffer); } }; @@ -413,15 +450,15 @@ public: class NullTerminatedString : public ReadPacket { public: - String value; + Vector value; - void readPayload(String s) override + void readPayload(Vector && payload) override { - if (s.length() == 0 || s.back() != 0) + if (payload.empty() || payload.back() != 0) { throw ProtocolError("String is not null terminated.", ErrorCodes::UNKNOWN_PACKET_FROM_CLIENT); } - value = s; + value = std::move(payload); value.pop_back(); } }; @@ -453,38 +490,36 @@ public: { } - String getPayload() const override + void writePayload(WriteBuffer & buffer) const override { - String result; - result.append(1, header); - result.append(writeLengthEncodedNumber(affected_rows)); - result.append(writeLengthEncodedNumber(0)); /// last insert-id + buffer.write(header); + writeLengthEncodedNumber(affected_rows, buffer); + writeLengthEncodedNumber(0, buffer); /// last insert-id if (capabilities & CLIENT_PROTOCOL_41) { - result.append(reinterpret_cast(&status_flags), 2); - result.append(reinterpret_cast(&warnings), 2); + buffer.write(reinterpret_cast(&status_flags), 2); + buffer.write(reinterpret_cast(&warnings), 2); } else if (capabilities & CLIENT_TRANSACTIONS) { - result.append(reinterpret_cast(&status_flags), 2); + buffer.write(reinterpret_cast(&status_flags), 2); } if (capabilities & CLIENT_SESSION_TRACK) { - result.append(writeLengthEncodedNumber(info.length())); - result.append(info); + writeLengthEncodedNumber(info.length(), buffer); + writeString(info, buffer); if (status_flags & SERVER_SESSION_STATE_CHANGED) { - result.append(writeLengthEncodedNumber(session_state_changes.length())); - result.append(session_state_changes); + writeLengthEncodedNumber(session_state_changes.length(), buffer); + writeString(session_state_changes, buffer); } } else { - result.append(info); + writeString(info, buffer); } - return result; } }; @@ -496,13 +531,11 @@ public: EOF_Packet(int warnings, int status_flags) : warnings(warnings), status_flags(status_flags) {} - String getPayload() const override + void writePayload(WriteBuffer & buffer) const override { - String result; - result.append(1, 0xfe); // EOF header - result.append(reinterpret_cast(&warnings), 2); - result.append(reinterpret_cast(&status_flags), 2); - return result; + buffer.write(0xfe); // EOF header + buffer.write(reinterpret_cast(&warnings), 2); + buffer.write(reinterpret_cast(&status_flags), 2); } }; @@ -517,15 +550,13 @@ public: { } - String getPayload() const override + void writePayload(WriteBuffer & buffer) const override { - String result; - result.append(1, 0xff); - result.append(reinterpret_cast(&error_code), 2); - result.append("#", 1); - result.append(sql_state.data(), sql_state.length()); - result.append(error_message.data(), std::min(error_message.length(), MYSQL_ERRMSG_SIZE)); - return result; + buffer.write(0xff); + buffer.write(reinterpret_cast(&error_code), 2); + buffer.write('#'); + buffer.write(sql_state.data(), sql_state.length()); + buffer.write(error_message.data(), std::min(error_message.length(), MYSQL_ERRMSG_SIZE)); } }; @@ -573,23 +604,21 @@ public: { } - String getPayload() const override + void writePayload(WriteBuffer & buffer) const override { - String result; - writeLengthEncodedString(result, "def"); /// always "def" - writeLengthEncodedString(result, ""); /// schema - writeLengthEncodedString(result, ""); /// table - writeLengthEncodedString(result, ""); /// org_table - writeLengthEncodedString(result, name); - writeLengthEncodedString(result, ""); /// org_name - result.append(writeLengthEncodedNumber(next_length)); - result.append(reinterpret_cast(&character_set), 2); - result.append(reinterpret_cast(&column_length), 4); - result.append(reinterpret_cast(&column_type), 1); - result.append(reinterpret_cast(&flags), 2); - result.append(reinterpret_cast(&decimals), 2); - result.append(2, 0x0); - return result; + writeLengthEncodedString(std::string("def"), buffer); /// always "def" + writeLengthEncodedString(schema, buffer); + writeLengthEncodedString(table, buffer); + writeLengthEncodedString(org_table, buffer); + writeLengthEncodedString(name, buffer); + writeLengthEncodedString(org_name, buffer); + writeLengthEncodedNumber(next_length, buffer); + buffer.write(reinterpret_cast(&character_set), 2); + buffer.write(reinterpret_cast(&column_length), 4); + buffer.write(reinterpret_cast(&column_type), 1); + buffer.write(reinterpret_cast(&flags), 2); + buffer.write(reinterpret_cast(&decimals), 2); + writeChar(0x0, 2, buffer); } }; @@ -598,12 +627,13 @@ class ComFieldList : public ReadPacket public: String table, field_wildcard; - void readPayload(String payload) + void readPayload(Vector && payload) override { - std::istringstream ss(payload); - ss.ignore(1); // command byte - std::getline(ss, table, static_cast(0x0)); - field_wildcard = payload.substr(table.length() + 2); // rest of the packet + ReadBufferFromMemory buffer(payload.data(), payload.size()); + buffer.ignore(1); // command byte + readNullTerminated(table, buffer); + field_wildcard.assign(payload.data() + table.size() + 2); + readStringUntilEOFInto(field_wildcard, buffer); } }; @@ -615,33 +645,29 @@ public: { } - String getPayload() const override + void writePayload(WriteBuffer & buffer) const override { - return writeLengthEncodedNumber(value); + writeLengthEncodedNumber(value, buffer); } }; class ResultsetRow : public WritePacket { - std::vector columns; + std::vector columns; public: ResultsetRow() { } - void appendColumn(String value) + void appendColumn(Vector value) { columns.emplace_back(std::move(value)); } - String getPayload() const override + void writePayload(WriteBuffer & buffer) const override { - String result; - for (const String & column : columns) - { - writeLengthEncodedString(result, column); - } - return result; + for (const Vector & column : columns) + writeLengthEncodedString(column, buffer); } }; diff --git a/dbms/src/Formats/MySQLWireBlockOutputStream.cpp b/dbms/src/Formats/MySQLWireBlockOutputStream.cpp index d587335c6fd..f70cfc2d4d9 100644 --- a/dbms/src/Formats/MySQLWireBlockOutputStream.cpp +++ b/dbms/src/Formats/MySQLWireBlockOutputStream.cpp @@ -45,8 +45,8 @@ void MySQLWireBlockOutputStream::write(const Block & block) ResultsetRow row_packet; for (const ColumnWithTypeAndName & column : block) { - String column_value; - WriteBufferFromString ostr(column_value); + Vector column_value; + WriteBufferFromVector ostr(column_value); column.type->serializeAsText(*column.column.get(), i, ostr, format_settings); ostr.finish(); diff --git a/dbms/src/IO/ReadHelpers.cpp b/dbms/src/IO/ReadHelpers.cpp index d686f56deef..28001cb74d0 100644 --- a/dbms/src/IO/ReadHelpers.cpp +++ b/dbms/src/IO/ReadHelpers.cpp @@ -173,6 +173,12 @@ inline void appendToStringOrVector(PaddedPODArray & s, ReadBuffer & rb, c s.insert(rb.position(), end); } +template <> +inline void appendToStringOrVector(PODArray & s, ReadBuffer & rb, const char * end) +{ + s.insert(rb.position(), end); +} + template void readStringInto(Vector & s, ReadBuffer & buf) { @@ -188,6 +194,26 @@ void readStringInto(Vector & s, ReadBuffer & buf) } } +template +void readNullTerminated(Vector & s, ReadBuffer & buf) +{ + while (!buf.eof()) + { + char * next_pos = find_first_symbols<'\0'>(buf.position(), buf.buffer().end()); + + appendToStringOrVector(s, buf, next_pos); + + buf.position() = next_pos; + + if (buf.hasPendingData()) + break; + } + buf.ignore(); +} + +template void readNullTerminated>(PODArray & s, ReadBuffer & buf); +template void readNullTerminated(String & s, ReadBuffer & buf); + void readString(String & s, ReadBuffer & buf) { s.clear(); diff --git a/dbms/src/IO/ReadHelpers.h b/dbms/src/IO/ReadHelpers.h index a24c1b4546c..7f8d822c1fe 100644 --- a/dbms/src/IO/ReadHelpers.h +++ b/dbms/src/IO/ReadHelpers.h @@ -425,6 +425,9 @@ void readCSVString(String & s, ReadBuffer & buf, const FormatSettings::CSV & set template void readStringInto(Vector & s, ReadBuffer & buf); +template +void readNullTerminated(Vector & s, ReadBuffer & buf); + template void readEscapedStringInto(Vector & s, ReadBuffer & buf); diff --git a/dbms/src/IO/WriteHelpers.h b/dbms/src/IO/WriteHelpers.h index b494f863421..3945ed3965c 100644 --- a/dbms/src/IO/WriteHelpers.h +++ b/dbms/src/IO/WriteHelpers.h @@ -47,6 +47,16 @@ inline void writeChar(char x, WriteBuffer & buf) ++buf.position(); } +inline void writeChar(char c, size_t n, WriteBuffer & buf) +{ + while (n) { + buf.nextIfAtEnd(); + size_t count = std::min(n, buf.available()); + memset(buf.position(), c, count); + n -= count; + buf.position() += buf.available(); + } +} /// Write POD-type in native format. It's recommended to use only with packed (dense) data types. template From dc6e6eaca79d3cc988e1abbd4a4fc07f0c4f3fb6 Mon Sep 17 00:00:00 2001 From: Nikita Lapkov Date: Thu, 4 Jul 2019 22:16:04 +0000 Subject: [PATCH 0152/1165] fix submodules --- contrib/boost | 2 +- contrib/librdkafka | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/boost b/contrib/boost index 471ea208abb..830e51edb59 160000 --- a/contrib/boost +++ b/contrib/boost @@ -1 +1 @@ -Subproject commit 471ea208abb92a5cba7d3a08a819bb728f27e95f +Subproject commit 830e51edb59c4f37a8638138581e1e56c29ac44f diff --git a/contrib/librdkafka b/contrib/librdkafka index 8695b9d63ac..8681f884020 160000 --- a/contrib/librdkafka +++ b/contrib/librdkafka @@ -1 +1 @@ -Subproject commit 8695b9d63ac0fe1b891b511d5b36302ffc84d4e2 +Subproject commit 8681f884020e880a4c6cda3cfc672f0669e1f38e From b8585a5630fa6540c534cfada15c554e214e0ba7 Mon Sep 17 00:00:00 2001 From: Nikita Lapkov Date: Fri, 5 Jul 2019 13:48:47 +0000 Subject: [PATCH 0153/1165] refactor and comments --- dbms/programs/server/config.xml | 2 + dbms/src/Common/QueryProfiler.cpp | 7 -- dbms/src/Common/QueryProfiler.h | 36 ++++++--- dbms/src/Common/ShellCommand.cpp | 20 ++--- dbms/src/Common/ThreadStatus.h | 2 - dbms/src/Core/Settings.h | 4 +- dbms/src/Functions/FunctionsIntrospection.h | 13 +-- dbms/src/Interpreters/Context.cpp | 2 +- dbms/src/Interpreters/ThreadStatusExt.cpp | 13 --- dbms/src/Interpreters/TraceCollector.cpp | 87 ++++++++++++--------- dbms/src/Interpreters/TraceCollector.h | 30 ++++--- dbms/src/Interpreters/TraceLog.cpp | 8 +- dbms/src/Interpreters/TraceLog.h | 2 +- libs/libcommon/CMakeLists.txt | 6 +- libs/libcommon/cmake/find_unwind.cmake | 52 ------------ libs/libcommon/include/common/Pipe.h | 6 +- libs/libcommon/include/common/Sleep.h | 2 - libs/libcommon/include/common/StackTrace.h | 9 ++- libs/libcommon/src/Sleep.cpp | 11 +++ libs/libcommon/src/StackTrace.cpp | 6 -- libs/libdaemon/src/BaseDaemon.cpp | 3 - 21 files changed, 141 insertions(+), 180 deletions(-) delete mode 100644 libs/libcommon/cmake/find_unwind.cmake diff --git a/dbms/programs/server/config.xml b/dbms/programs/server/config.xml index 18ccbc5820c..e78e3c255f7 100644 --- a/dbms/programs/server/config.xml +++ b/dbms/programs/server/config.xml @@ -294,6 +294,8 @@ 7500 + system trace_log
diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index 514a4f359f9..ce0ddef094f 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -5,11 +5,4 @@ namespace DB LazyPipe trace_pipe; -void CloseQueryTraceStream() -{ - DB::WriteBufferFromFileDescriptor out(trace_pipe.fds_rw[1]); - DB::writeIntBinary(true, out); - out.next(); -} - } diff --git a/dbms/src/Common/QueryProfiler.h b/dbms/src/Common/QueryProfiler.h index a4a55cc36a6..236a4907a15 100644 --- a/dbms/src/Common/QueryProfiler.h +++ b/dbms/src/Common/QueryProfiler.h @@ -27,28 +27,31 @@ enum class TimerType : UInt8 Cpu, }; -void CloseQueryTraceStream(); - namespace { + /// Normally query_id is a UUID (string with a fixed length) but user can provide custom query_id. + /// Thus upper bound on query_id length should be introduced to avoid buffer overflow in signal handler. + constexpr UInt32 QUERY_ID_MAX_LEN = 1024; + void writeTraceInfo(TimerType timer_type, int /* sig */, siginfo_t * /* info */, void * context) { - char buffer[DBMS_DEFAULT_BUFFER_SIZE]; - DB::WriteBufferFromFileDescriptor out( - /* fd */ trace_pipe.fds_rw[1], - /* buf_size */ DBMS_DEFAULT_BUFFER_SIZE, - /* existing_memory */ buffer - ); + constexpr UInt32 buf_size = sizeof(char) + // TraceCollector stop flag + 8 * sizeof(char) + // maximum VarUInt length for string size + QUERY_ID_MAX_LEN * sizeof(char) + // maximum query_id length + sizeof(StackTrace) + // collected stack trace + sizeof(TimerType); // timer type + char buffer[buf_size]; + DB::WriteBufferFromFileDescriptor out(trace_pipe.fds_rw[1], buf_size, buffer); const std::string & query_id = CurrentThread::getQueryId(); const auto signal_context = *reinterpret_cast(context); const StackTrace stack_trace(signal_context); - DB::writeIntBinary(false, out); + DB::writeChar(false, out); DB::writeStringBinary(query_id, out); DB::writePODBinary(stack_trace, out); - DB::writeIntBinary(timer_type, out); + DB::writePODBinary(timer_type, out); out.next(); } @@ -56,6 +59,17 @@ namespace } +/** + * Query profiler implementation for selected thread. + * + * This class installs timer and signal handler on creation to: + * 1. periodically pause given thread + * 2. collect thread's current stack trace + * 3. write collected stack trace to trace_pipe for TraceCollector + * + * Desctructor tries to unset timer and restore previous signal handler. + * Note that signal handler implementation is defined by template parameter. See QueryProfilerReal and QueryProfilerCpu. + */ template class QueryProfilerBase { @@ -112,6 +126,7 @@ private: struct sigaction * previous_handler = nullptr; }; +/// Query profiler with timer based on real clock class QueryProfilerReal : public QueryProfilerBase { public: @@ -125,6 +140,7 @@ public: } }; +/// Query profiler with timer based on CPU clock class QueryProfilerCpu : public QueryProfilerBase { public: diff --git a/dbms/src/Common/ShellCommand.cpp b/dbms/src/Common/ShellCommand.cpp index cb7f8c21bf6..66dbab35a20 100644 --- a/dbms/src/Common/ShellCommand.cpp +++ b/dbms/src/Common/ShellCommand.cpp @@ -10,6 +10,17 @@ #include #include +namespace +{ + /// By these return codes from the child process, we learn (for sure) about errors when creating it. + enum class ReturnCodes : int + { + CANNOT_DUP_STDIN = 0x55555555, /// The value is not important, but it is chosen so that it's rare to conflict with the program return code. + CANNOT_DUP_STDOUT = 0x55555556, + CANNOT_DUP_STDERR = 0x55555557, + CANNOT_EXEC = 0x55555558, + }; +} namespace DB { @@ -23,15 +34,6 @@ namespace ErrorCodes extern const int CANNOT_CREATE_CHILD_PROCESS; } -/// By these return codes from the child process, we learn (for sure) about errors when creating it. -enum class ReturnCodes : int -{ - CANNOT_DUP_STDIN = 0x55555555, /// The value is not important, but it is chosen so that it's rare to conflict with the program return code. - CANNOT_DUP_STDOUT = 0x55555556, - CANNOT_DUP_STDERR = 0x55555557, - CANNOT_EXEC = 0x55555558, -}; - ShellCommand::ShellCommand(pid_t pid, int in_fd, int out_fd, int err_fd, bool terminate_in_destructor_) : pid(pid) , terminate_in_destructor(terminate_in_destructor_) diff --git a/dbms/src/Common/ThreadStatus.h b/dbms/src/Common/ThreadStatus.h index 39564dcacfe..19935684796 100644 --- a/dbms/src/Common/ThreadStatus.h +++ b/dbms/src/Common/ThreadStatus.h @@ -11,7 +11,6 @@ #include #include #include -#include namespace Poco @@ -176,7 +175,6 @@ protected: size_t queries_started = 0; // CPU and Real time query profilers - bool has_query_profiler = false; std::unique_ptr query_profiler_real; std::unique_ptr query_profiler_cpu; diff --git a/dbms/src/Core/Settings.h b/dbms/src/Core/Settings.h index 01de5a7428f..dd01bfb1124 100644 --- a/dbms/src/Core/Settings.h +++ b/dbms/src/Core/Settings.h @@ -218,8 +218,8 @@ struct Settings : public SettingsCollection M(SettingBool, empty_result_for_aggregation_by_empty_set, false, "Return empty result when aggregating without keys on empty set.") \ M(SettingBool, allow_distributed_ddl, true, "If it is set to true, then a user is allowed to executed distributed DDL queries.") \ M(SettingUInt64, odbc_max_field_size, 1024, "Max size of filed can be read from ODBC dictionary. Long strings are truncated.") \ - M(SettingUInt64, query_profiler_real_time_period, 500000000, "Period for real clock timer of query profiler (in nanoseconds).") \ - M(SettingUInt64, query_profiler_cpu_time_period, 500000000, "Period for CPU clock timer of query profiler (in nanoseconds).") \ + M(SettingUInt64, query_profiler_real_time_period, 500000000, "Period for real clock timer of query profiler (in nanoseconds). Set 0 value to turn off real clock query profiler") \ + M(SettingUInt64, query_profiler_cpu_time_period, 500000000, "Period for CPU clock timer of query profiler (in nanoseconds). Set 0 value to turn off CPU clock query profiler") \ \ \ /** Limits during query execution are part of the settings. \ diff --git a/dbms/src/Functions/FunctionsIntrospection.h b/dbms/src/Functions/FunctionsIntrospection.h index 0252f2b4c8f..d7ca1d37efa 100644 --- a/dbms/src/Functions/FunctionsIntrospection.h +++ b/dbms/src/Functions/FunctionsIntrospection.h @@ -84,17 +84,20 @@ public: auto result_column = ColumnString::create(); - size_t pos = 0; + StackTrace::Frames frames; + size_t current_offset = 0; for (size_t i = 0; i < offsets.size(); ++i) { - std::vector frames; - for (; pos < offsets[i]; ++pos) + size_t current_size = 0; + for (; current_size < frames.size() && current_offset + current_size < offsets[i]; ++current_size) { - frames.push_back(reinterpret_cast(data[pos])); + frames[current_size] = reinterpret_cast(data[current_offset + current_size]); } - std::string backtrace = StackTrace(frames).toString(); + std::string backtrace = StackTrace(frames.begin(), frames.begin() + current_size).toString(); result_column->insertDataWithTerminatingZero(backtrace.c_str(), backtrace.length() + 1); + + current_offset = offsets[i]; } block.getByPosition(result).column = std::move(result_column); diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index 65e74dfd6de..cb7dfd9b053 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -295,7 +295,7 @@ struct ContextShared if (trace_collector != nullptr) { /// Stop trace collector - CloseQueryTraceStream(); + NotifyTraceCollectorToStop(); trace_collector_thread.join(); /// Close trace pipe - definitely nobody needs to write there after diff --git a/dbms/src/Interpreters/ThreadStatusExt.cpp b/dbms/src/Interpreters/ThreadStatusExt.cpp index 5e88458caff..f2d053d776d 100644 --- a/dbms/src/Interpreters/ThreadStatusExt.cpp +++ b/dbms/src/Interpreters/ThreadStatusExt.cpp @@ -11,12 +11,6 @@ #include #include -#include -#include -#include -#include -#include - /// Implement some methods of ThreadStatus and CurrentThread here to avoid extra linking dependencies in clickhouse_common_io /// TODO It doesn't make sense. @@ -156,19 +150,12 @@ void ThreadStatus::initQueryProfiler() /* thread_id */ os_thread_id, /* period */ static_cast(settings.query_profiler_cpu_time_period) ); - - has_query_profiler = true; } void ThreadStatus::finalizeQueryProfiler() { - if (!has_query_profiler) - return; - query_profiler_real.reset(nullptr); query_profiler_cpu.reset(nullptr); - - has_query_profiler = false; } void ThreadStatus::detachQuery(bool exit_if_already_detached, bool thread_exits) diff --git a/dbms/src/Interpreters/TraceCollector.cpp b/dbms/src/Interpreters/TraceCollector.cpp index c2054d6c373..671b77eee83 100644 --- a/dbms/src/Interpreters/TraceCollector.cpp +++ b/dbms/src/Interpreters/TraceCollector.cpp @@ -1,6 +1,7 @@ #include "TraceCollector.h" -#include +#include +#include #include #include #include @@ -9,50 +10,62 @@ #include #include -namespace DB +using namespace DB; + +/** + * Sends TraceCollector stop message + * + * Each sequence of data for TraceCollector thread starts with a boolean flag. + * If this flag is true, TraceCollector must stop reading trace_pipe and exit. + * This function sends flag with a true value to stop TraceCollector gracefully. + * + * NOTE: TraceCollector will NOT stop immediately as there may be some data left in the pipe + * before stop message. + */ +void DB::NotifyTraceCollectorToStop() { + WriteBufferFromFileDescriptor out(trace_pipe.fds_rw[1]); + writeIntBinary(true, out); + out.next(); +} - TraceCollector::TraceCollector(std::shared_ptr trace_log) - : log(&Logger::get("TraceCollector")) - , trace_log(trace_log) +TraceCollector::TraceCollector(std::shared_ptr trace_log) + : log(&Poco::Logger::get("TraceCollector")) + , trace_log(trace_log) +{ + if (trace_log == nullptr) + throw Poco::Exception("Invalid trace log pointer passed"); +} + +void TraceCollector::run() +{ + ReadBufferFromFileDescriptor in(trace_pipe.fds_rw[0]); + + while (true) { - } + char is_last; + readChar(is_last, in); + if (is_last) + break; - void TraceCollector::run() - { - DB::ReadBufferFromFileDescriptor in(trace_pipe.fds_rw[0]); + std::string query_id; + StackTrace stack_trace(NoCapture{}); + TimerType timer_type; - while (true) - { - SleepForMicroseconds(1); + readStringBinary(query_id, in); + readPODBinary(stack_trace, in); + readPODBinary(timer_type, in); - bool is_last; - DB::readIntBinary(is_last, in); - if (is_last) - break; + const auto size = stack_trace.getSize(); + const auto& frames = stack_trace.getFrames(); - std::string query_id; - StackTrace stack_trace(NoCapture{}); - TimerType timer_type; + Array trace; + trace.reserve(size); + for (size_t i = 0; i < size; i++) + trace.emplace_back(UInt64(reinterpret_cast(frames[i]))); - DB::readStringBinary(query_id, in); - DB::readPODBinary(stack_trace, in); - DB::readIntBinary(timer_type, in); + TraceLogElement element{std::time(nullptr), timer_type, query_id, trace}; - if (trace_log != nullptr) - { - const auto size = stack_trace.getSize(); - const auto& frames = stack_trace.getFrames(); - - std::vector trace; - trace.reserve(size); - for (size_t i = 0; i < size; i++) - trace.push_back(reinterpret_cast(frames[i])); - - TraceLogElement element{std::time(nullptr), timer_type, query_id, trace}; - - trace_log->add(element); - } - } + trace_log->add(element); } } diff --git a/dbms/src/Interpreters/TraceCollector.h b/dbms/src/Interpreters/TraceCollector.h index 0e70873d91d..43a712a9816 100644 --- a/dbms/src/Interpreters/TraceCollector.h +++ b/dbms/src/Interpreters/TraceCollector.h @@ -1,24 +1,28 @@ #pragma once -#include #include -#include -#include #include +namespace Poco +{ + class Logger; +} + namespace DB { - using Poco::Logger; - class TraceCollector : public Poco::Runnable - { - private: - Logger * log; - std::shared_ptr trace_log; +void NotifyTraceCollectorToStop(); - public: - TraceCollector(std::shared_ptr trace_log); +class TraceCollector : public Poco::Runnable +{ +private: + Poco::Logger * log; + std::shared_ptr trace_log; + +public: + TraceCollector(std::shared_ptr trace_log); + + void run() override; +}; - void run() override; - }; } diff --git a/dbms/src/Interpreters/TraceLog.cpp b/dbms/src/Interpreters/TraceLog.cpp index 0661fbb8da0..c5583476e99 100644 --- a/dbms/src/Interpreters/TraceLog.cpp +++ b/dbms/src/Interpreters/TraceLog.cpp @@ -36,13 +36,7 @@ void TraceLogElement::appendToBlock(Block &block) const columns[i++]->insert(event_time); columns[i++]->insert(static_cast(timer_type)); columns[i++]->insertData(query_id.data(), query_id.size()); - { - Array trace_array; - trace_array.reserve(trace.size()); - for (const UInt32 trace_address : trace) - trace_array.emplace_back(UInt64(trace_address)); - columns[i++]->insert(trace_array); - } + columns[i++]->insert(trace); block.setColumns(std::move(columns)); } diff --git a/dbms/src/Interpreters/TraceLog.h b/dbms/src/Interpreters/TraceLog.h index bfff8c425d3..d5b38b69440 100644 --- a/dbms/src/Interpreters/TraceLog.h +++ b/dbms/src/Interpreters/TraceLog.h @@ -17,7 +17,7 @@ struct TraceLogElement time_t event_time{}; TimerType timer_type; String query_id{}; - std::vector trace{}; + Array trace{}; static std::string name() { return "TraceLog"; } static Block createBlock(); diff --git a/libs/libcommon/CMakeLists.txt b/libs/libcommon/CMakeLists.txt index a2d641921b4..7469aabceec 100644 --- a/libs/libcommon/CMakeLists.txt +++ b/libs/libcommon/CMakeLists.txt @@ -63,8 +63,7 @@ add_library (common include/ext/unlock_guard.h include/ext/singleton.h - ${CONFIG_COMMON} -) + ${CONFIG_COMMON}) if (USE_UNWIND) target_compile_definitions (common PRIVATE USE_UNWIND=1) @@ -133,8 +132,7 @@ target_link_libraries (common PRIVATE ${MALLOC_LIBRARIES} Threads::Threads - ${MEMCPY_LIBRARIES} -) + ${MEMCPY_LIBRARIES}) if (RT_LIBRARY) target_link_libraries (common PRIVATE ${RT_LIBRARY}) diff --git a/libs/libcommon/cmake/find_unwind.cmake b/libs/libcommon/cmake/find_unwind.cmake deleted file mode 100644 index 876bc7298e8..00000000000 --- a/libs/libcommon/cmake/find_unwind.cmake +++ /dev/null @@ -1,52 +0,0 @@ -include (CMakePushCheckState) -cmake_push_check_state () - -option (ENABLE_UNWIND "Enable libunwind (better stacktraces)" ON) - -if (ENABLE_UNWIND) - -if (CMAKE_SYSTEM MATCHES "Linux" AND NOT ARCH_ARM AND NOT ARCH_32) - option (USE_INTERNAL_UNWIND_LIBRARY "Set to FALSE to use system unwind library instead of bundled" ${NOT_UNBUNDLED}) -else () - option (USE_INTERNAL_UNWIND_LIBRARY "Set to FALSE to use system unwind library instead of bundled" OFF) -endif () - -if (NOT USE_INTERNAL_UNWIND_LIBRARY) - find_library (UNWIND_LIBRARY unwind) - find_path (UNWIND_INCLUDE_DIR NAMES unwind.h PATHS ${UNWIND_INCLUDE_PATHS}) - - include (CheckCXXSourceCompiles) - set(CMAKE_REQUIRED_INCLUDES ${UNWIND_INCLUDE_DIR}) - set(CMAKE_REQUIRED_LIBRARIES ${UNWIND_LIBRARY}) - check_cxx_source_compiles(" - #include - #define UNW_LOCAL_ONLY - #include - int main () { - ucontext_t context; - unw_cursor_t cursor; - unw_init_local2(&cursor, &context, UNW_INIT_SIGNAL_FRAME); - return 0; - } - " HAVE_UNW_INIT_LOCAL2) - if (NOT HAVE_UNW_INIT_LOCAL2) - set(UNWIND_LIBRARY "") - set(UNWIND_INCLUDE_DIR "") - endif () - -endif () - -if (UNWIND_LIBRARY AND UNWIND_INCLUDE_DIR) - set (USE_UNWIND 1) -elseif (CMAKE_SYSTEM MATCHES "Linux" AND NOT ARCH_ARM AND NOT ARCH_32) - set (USE_INTERNAL_UNWIND_LIBRARY 1) - set (UNWIND_INCLUDE_DIR "${ClickHouse_SOURCE_DIR}/contrib/libunwind/include") - set (UNWIND_LIBRARY unwind) - set (USE_UNWIND 1) -endif () - -endif () - -message (STATUS "Using unwind=${USE_UNWIND}: ${UNWIND_INCLUDE_DIR} : ${UNWIND_LIBRARY}") - -cmake_pop_check_state () diff --git a/libs/libcommon/include/common/Pipe.h b/libs/libcommon/include/common/Pipe.h index 394db6d199c..3904099c9c2 100644 --- a/libs/libcommon/include/common/Pipe.h +++ b/libs/libcommon/include/common/Pipe.h @@ -1,11 +1,7 @@ #pragma once -#include -#include +#include #include -#include -#include -#include #include struct LazyPipe diff --git a/libs/libcommon/include/common/Sleep.h b/libs/libcommon/include/common/Sleep.h index f6c5fb8090b..7c5c955f723 100644 --- a/libs/libcommon/include/common/Sleep.h +++ b/libs/libcommon/include/common/Sleep.h @@ -1,8 +1,6 @@ #pragma once #include -#include -#include void SleepForNanoseconds(uint64_t nanoseconds); diff --git a/libs/libcommon/include/common/StackTrace.h b/libs/libcommon/include/common/StackTrace.h index 9c27ffdcc65..be3d6438386 100644 --- a/libs/libcommon/include/common/StackTrace.h +++ b/libs/libcommon/include/common/StackTrace.h @@ -35,7 +35,14 @@ public: StackTrace(NoCapture); /// Fills stack trace frames with provided sequence - StackTrace(const std::vector & source_frames); + template + StackTrace(Iterator it, Iterator end) + { + while (size < capacity && it != end) + { + frames[size++] = *(it++); + } + } size_t getSize() const; const Frames & getFrames() const; diff --git a/libs/libcommon/src/Sleep.cpp b/libs/libcommon/src/Sleep.cpp index 3a27b0080cd..13b03f2b95e 100644 --- a/libs/libcommon/src/Sleep.cpp +++ b/libs/libcommon/src/Sleep.cpp @@ -1,6 +1,17 @@ #include "common/Sleep.h" +#include +#include +/** + * Sleep with nanoseconds precision + * + * In case query profiler is turned on, all threads spawned for + * query execution are repeatedly interrupted by signals from timer. + * Functions for relative sleep (sleep(3), nanosleep(2), etc.) have + * problems in this setup and man page for nanosleep(2) suggests + * using absolute deadlines, for instance clock_nanosleep(2). + */ void SleepForNanoseconds(uint64_t nanoseconds) { const auto clock_type = CLOCK_REALTIME; diff --git a/libs/libcommon/src/StackTrace.cpp b/libs/libcommon/src/StackTrace.cpp index ea60626edf0..8aea884d004 100644 --- a/libs/libcommon/src/StackTrace.cpp +++ b/libs/libcommon/src/StackTrace.cpp @@ -195,12 +195,6 @@ StackTrace::StackTrace(NoCapture) { } -StackTrace::StackTrace(const std::vector & source_frames) -{ - for (size = 0; size < std::min(source_frames.size(), capacity); ++size) - frames[size] = source_frames[size]; -} - void StackTrace::tryCapture() { size = 0; diff --git a/libs/libdaemon/src/BaseDaemon.cpp b/libs/libdaemon/src/BaseDaemon.cpp index f5de0f0231a..1ba03168496 100644 --- a/libs/libdaemon/src/BaseDaemon.cpp +++ b/libs/libdaemon/src/BaseDaemon.cpp @@ -1,7 +1,4 @@ #include -#include -#include -#include #include #include #include From 6b7f5871569c482c81c932af2cecfd4c6cb567df Mon Sep 17 00:00:00 2001 From: Nikita Lapkov Date: Fri, 5 Jul 2019 14:16:20 +0000 Subject: [PATCH 0154/1165] cut large query_ids --- dbms/src/Common/QueryProfiler.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dbms/src/Common/QueryProfiler.h b/dbms/src/Common/QueryProfiler.h index 236a4907a15..81a3d564c3f 100644 --- a/dbms/src/Common/QueryProfiler.h +++ b/dbms/src/Common/QueryProfiler.h @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -10,7 +11,6 @@ #include #include - namespace Poco { class Logger; @@ -31,11 +31,11 @@ namespace { /// Normally query_id is a UUID (string with a fixed length) but user can provide custom query_id. /// Thus upper bound on query_id length should be introduced to avoid buffer overflow in signal handler. - constexpr UInt32 QUERY_ID_MAX_LEN = 1024; + constexpr size_t QUERY_ID_MAX_LEN = 1024; void writeTraceInfo(TimerType timer_type, int /* sig */, siginfo_t * /* info */, void * context) { - constexpr UInt32 buf_size = sizeof(char) + // TraceCollector stop flag + constexpr size_t buf_size = sizeof(char) + // TraceCollector stop flag 8 * sizeof(char) + // maximum VarUInt length for string size QUERY_ID_MAX_LEN * sizeof(char) + // maximum query_id length sizeof(StackTrace) + // collected stack trace @@ -44,12 +44,13 @@ namespace DB::WriteBufferFromFileDescriptor out(trace_pipe.fds_rw[1], buf_size, buffer); const std::string & query_id = CurrentThread::getQueryId(); + const StringRef cut_query_id(query_id.c_str(), std::min(query_id.size(), QUERY_ID_MAX_LEN)); const auto signal_context = *reinterpret_cast(context); const StackTrace stack_trace(signal_context); DB::writeChar(false, out); - DB::writeStringBinary(query_id, out); + DB::writeStringBinary(cut_query_id, out); DB::writePODBinary(stack_trace, out); DB::writePODBinary(timer_type, out); out.next(); From c7eaa30870500b1fd00be1289d344fb0fdaf62a0 Mon Sep 17 00:00:00 2001 From: Nikita Lapkov Date: Fri, 5 Jul 2019 21:02:02 +0000 Subject: [PATCH 0155/1165] update libunwind to RIP experiment --- contrib/libunwind | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/libunwind b/contrib/libunwind index ec86b1c6a2c..17a48fbfa79 160000 --- a/contrib/libunwind +++ b/contrib/libunwind @@ -1 +1 @@ -Subproject commit ec86b1c6a2c6b8ba316f429db9a6d4122dd12710 +Subproject commit 17a48fbfa7913ee889960a698516bd3ba51d63ee From 17e3542a5a70294d1c0014a94f91a186d8da70a8 Mon Sep 17 00:00:00 2001 From: Nikita Lapkov Date: Fri, 5 Jul 2019 22:35:09 +0000 Subject: [PATCH 0156/1165] refactor --- dbms/src/Common/QueryProfiler.h | 6 +++--- dbms/src/Interpreters/ThreadStatusExt.cpp | 15 ++++----------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/dbms/src/Common/QueryProfiler.h b/dbms/src/Common/QueryProfiler.h index 81a3d564c3f..eea1bb0374d 100644 --- a/dbms/src/Common/QueryProfiler.h +++ b/dbms/src/Common/QueryProfiler.h @@ -43,14 +43,14 @@ namespace char buffer[buf_size]; DB::WriteBufferFromFileDescriptor out(trace_pipe.fds_rw[1], buf_size, buffer); - const std::string & query_id = CurrentThread::getQueryId(); - const StringRef cut_query_id(query_id.c_str(), std::min(query_id.size(), QUERY_ID_MAX_LEN)); + StringRef query_id = CurrentThread::getQueryId(); + query_id.size = std::min(query_id.size, QUERY_ID_MAX_LEN); const auto signal_context = *reinterpret_cast(context); const StackTrace stack_trace(signal_context); DB::writeChar(false, out); - DB::writeStringBinary(cut_query_id, out); + DB::writeStringBinary(query_id, out); DB::writePODBinary(stack_trace, out); DB::writePODBinary(timer_type, out); out.next(); diff --git a/dbms/src/Interpreters/ThreadStatusExt.cpp b/dbms/src/Interpreters/ThreadStatusExt.cpp index a9596577f78..ddb7d9c27a7 100644 --- a/dbms/src/Interpreters/ThreadStatusExt.cpp +++ b/dbms/src/Interpreters/ThreadStatusExt.cpp @@ -6,10 +6,6 @@ #include #include #include -#include -#include -#include -#include /// Implement some methods of ThreadStatus and CurrentThread here to avoid extra linking dependencies in clickhouse_common_io /// TODO It doesn't make sense. @@ -32,15 +28,13 @@ void ThreadStatus::attachQueryContext(Context & query_context_) if (!thread_group->global_context) thread_group->global_context = global_context; } + + initQueryProfiler(); } StringRef ThreadStatus::getQueryId() const { - static const std::string empty = ""; - if (query_context) - return query_context->getClientInfo().current_query_id; - - return empty; + return query_id; } void CurrentThread::defaultThreadDeleter() @@ -102,7 +96,6 @@ void ThreadStatus::attachQuery(const ThreadGroupStatusPtr & thread_group_, bool } initPerformanceCounters(); - initQueryProfiler(); thread_state = ThreadState::AttachedToQuery; } @@ -134,7 +127,7 @@ void ThreadStatus::finalizePerformanceCounters() void ThreadStatus::initQueryProfiler() { if (!query_context) - return; + throw Exception("Can't init query profiler without query context", ErrorCodes::LOGICAL_ERROR); auto & settings = query_context->getSettingsRef(); From ef1d84b35a1eb07a6d0b0452f386f3edd6ead4e0 Mon Sep 17 00:00:00 2001 From: Nikita Lapkov Date: Sat, 6 Jul 2019 20:29:00 +0000 Subject: [PATCH 0157/1165] do not run trace collector without trace_log. do not run query profilers without trace collector. --- dbms/src/Interpreters/Context.cpp | 14 +++++++++++++- dbms/src/Interpreters/Context.h | 1 + dbms/src/Interpreters/ThreadStatusExt.cpp | 9 +++++---- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index 466d122ad82..451d05e7085 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -292,7 +292,7 @@ struct ContextShared ddl_worker.reset(); /// Trace collector is only initialized in server program - if (trace_collector != nullptr) + if (hasTraceCollector()) { /// Stop trace collector NotifyTraceCollectorToStop(); @@ -304,8 +304,15 @@ struct ContextShared } } + bool hasTraceCollector() { + return trace_collector != nullptr; + } + void initializeTraceCollector(std::shared_ptr trace_log) { + if (trace_log == nullptr) + return; + trace_pipe.open(); trace_collector.reset(new TraceCollector(trace_log)); trace_collector_thread.start(*trace_collector); @@ -1646,6 +1653,11 @@ void Context::initializeSystemLogs() shared->system_logs.emplace(*global_context, getConfigRef()); } +bool Context::hasTraceCollector() +{ + return shared->hasTraceCollector(); +} + void Context::initializeTraceCollector() { shared->initializeTraceCollector(getTraceLog()); diff --git a/dbms/src/Interpreters/Context.h b/dbms/src/Interpreters/Context.h index a17565a60bb..4f622a0eae1 100644 --- a/dbms/src/Interpreters/Context.h +++ b/dbms/src/Interpreters/Context.h @@ -416,6 +416,7 @@ public: void initializeSystemLogs(); void initializeTraceCollector(); + bool hasTraceCollector(); /// Nullptr if the query log is not ready for this moment. std::shared_ptr getQueryLog(); diff --git a/dbms/src/Interpreters/ThreadStatusExt.cpp b/dbms/src/Interpreters/ThreadStatusExt.cpp index ddb7d9c27a7..cc108f31820 100644 --- a/dbms/src/Interpreters/ThreadStatusExt.cpp +++ b/dbms/src/Interpreters/ThreadStatusExt.cpp @@ -126,8 +126,9 @@ void ThreadStatus::finalizePerformanceCounters() void ThreadStatus::initQueryProfiler() { - if (!query_context) - throw Exception("Can't init query profiler without query context", ErrorCodes::LOGICAL_ERROR); + /// query profilers are useless without trace collector + if (!global_context->hasTraceCollector()) + return; auto & settings = query_context->getSettingsRef(); @@ -146,8 +147,8 @@ void ThreadStatus::initQueryProfiler() void ThreadStatus::finalizeQueryProfiler() { - query_profiler_real.reset(nullptr); - query_profiler_cpu.reset(nullptr); + query_profiler_real.reset(); + query_profiler_cpu.reset(); } void ThreadStatus::detachQuery(bool exit_if_already_detached, bool thread_exits) From 3828684f7a9cf1a06f13eda1ab4dd6fba98161a9 Mon Sep 17 00:00:00 2001 From: Nikita Lapkov Date: Sat, 6 Jul 2019 20:42:03 +0000 Subject: [PATCH 0158/1165] style --- dbms/src/Interpreters/Context.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index 451d05e7085..407cb9366d1 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -304,7 +304,8 @@ struct ContextShared } } - bool hasTraceCollector() { + bool hasTraceCollector() + { return trace_collector != nullptr; } From 259a95a3da5ca6ad05d0cbc11f82682258f00576 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Sun, 7 Jul 2019 19:57:58 -0400 Subject: [PATCH 0159/1165] * Updates to fix issues after the merge --- dbms/src/Interpreters/ExternalLoader.cpp | 7 +++++++ dbms/src/Storages/IStorage.h | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/dbms/src/Interpreters/ExternalLoader.cpp b/dbms/src/Interpreters/ExternalLoader.cpp index 018565e0a2c..f00fa2bfa90 100644 --- a/dbms/src/Interpreters/ExternalLoader.cpp +++ b/dbms/src/Interpreters/ExternalLoader.cpp @@ -400,6 +400,10 @@ public: return count; } +#if !__clang__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif bool hasCurrentlyLoadedObjects() const { std::lock_guard lock{mutex}; @@ -408,6 +412,9 @@ public: return true; return false; } +#if !__clang__ +#pragma GCC diagnostic pop +#endif /// Starts loading of a specified object. void load(const String & name) diff --git a/dbms/src/Storages/IStorage.h b/dbms/src/Storages/IStorage.h index 8541def8753..b7358c3fc6e 100644 --- a/dbms/src/Storages/IStorage.h +++ b/dbms/src/Storages/IStorage.h @@ -84,7 +84,8 @@ public: public: /// thread-unsafe part. lockStructure must be acquired virtual const ColumnsDescription & getColumns() const; /// returns combined set of columns - + virtual void setColumns(ColumnsDescription columns_); /// sets only real columns, possibly overwrites virtual ones. + const IndicesDescription & getIndices() const; /// NOTE: these methods should include virtual columns, @@ -113,7 +114,6 @@ public: /// thread-unsafe part. lockStructure must be acquired void check(const Block & block, bool need_all = false) const; protected: /// still thread-unsafe part. - virtual void setColumns(ColumnsDescription columns_); /// sets only real columns, possibly overwrites virtual ones. void setIndices(IndicesDescription indices_); /// Returns whether the column is virtual - by default all columns are real. From a80af666adbcbeb173b5dd125a72439b55b92c25 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Tue, 9 Jul 2019 08:41:55 -0400 Subject: [PATCH 0160/1165] * Updates that incorporate comments from the review --- dbms/src/DataStreams/BlocksBlockInputStream.h | 6 +-- .../DataStreams/LiveViewBlockInputStream.h | 47 +++++++++---------- .../LiveViewEventsBlockInputStream.h | 46 ++++++++++-------- dbms/src/Storages/IStorage.h | 2 +- dbms/src/Storages/StorageLiveView.cpp | 13 +++-- dbms/src/Storages/StorageLiveView.h | 2 +- 6 files changed, 62 insertions(+), 54 deletions(-) diff --git a/dbms/src/DataStreams/BlocksBlockInputStream.h b/dbms/src/DataStreams/BlocksBlockInputStream.h index ad0d37da622..58a63e5b85e 100644 --- a/dbms/src/DataStreams/BlocksBlockInputStream.h +++ b/dbms/src/DataStreams/BlocksBlockInputStream.h @@ -23,8 +23,8 @@ class BlocksBlockInputStream : public IBlockInputStream { public: /// Acquires shared ownership of the blocks vector - BlocksBlockInputStream(std::shared_ptr blocks_ptr_, Block header) - : blocks_ptr(blocks_ptr_), it((*blocks_ptr_)->begin()), end((*blocks_ptr_)->end()), header(header) {} + BlocksBlockInputStream(const std::shared_ptr & blocks_ptr_, Block header) + : blocks(*blocks_ptr_), it((*blocks_ptr_)->begin()), end((*blocks_ptr_)->end()), header(std::move(header)) {} String getName() const override { return "Blocks"; } @@ -42,7 +42,7 @@ protected: } private: - std::shared_ptr blocks_ptr; + BlocksPtr blocks; Blocks::iterator it; const Blocks::iterator end; Block header; diff --git a/dbms/src/DataStreams/LiveViewBlockInputStream.h b/dbms/src/DataStreams/LiveViewBlockInputStream.h index e9bb599a1d6..89ac5e4f9f3 100644 --- a/dbms/src/DataStreams/LiveViewBlockInputStream.h +++ b/dbms/src/DataStreams/LiveViewBlockInputStream.h @@ -23,9 +23,10 @@ limitations under the License. */ namespace DB { -/** - */ - +/** Implements LIVE VIEW table WATCH input stream. + * Keeps stream alive by outputing blocks with no rows + * based on period specified by the heartbeat interval. + */ class LiveViewBlockInputStream : public IBlockInputStream { @@ -37,18 +38,17 @@ public: /// Start storage no users thread /// if we are the last active user if (!storage->is_dropped && blocks_ptr.use_count() < 3) - storage->startNoUsersThread(temporary_live_view_timeout); + storage->startNoUsersThread(temporary_live_view_timeout_sec); } - /// length default -2 because we want LIMIT to specify number of updates so that LIMIT 1 waits for 1 update - /// and LIMIT 0 just returns data without waiting for any updates + LiveViewBlockInputStream(std::shared_ptr storage_, std::shared_ptr blocks_ptr_, std::shared_ptr blocks_metadata_ptr_, std::shared_ptr active_ptr_, - int64_t length_, const UInt64 & heartbeat_interval_, - const UInt64 & temporary_live_view_timeout_) - : storage(storage_), blocks_ptr(blocks_ptr_), blocks_metadata_ptr(blocks_metadata_ptr_), active_ptr(active_ptr_), length(length_ + 1), heartbeat_interval(heartbeat_interval_ * 1000000), temporary_live_view_timeout(temporary_live_view_timeout_), - blocks_hash("") + const bool has_limit_, const UInt64 limit_, + const UInt64 heartbeat_interval_sec_, + const UInt64 temporary_live_view_timeout_sec_) + : storage(std::move(storage_)), blocks_ptr(std::move(blocks_ptr_)), blocks_metadata_ptr(std::move(blocks_metadata_ptr_)), active_ptr(std::move(active_ptr_)), has_limit(has_limit_), limit(limit_), heartbeat_interval_usec(heartbeat_interval_sec_ * 1000000), temporary_live_view_timeout_sec(temporary_live_view_timeout_sec_) { /// grab active pointer active = active_ptr.lock(); @@ -70,7 +70,7 @@ public: void refresh() { if (active && blocks && it == end) - it = blocks->begin(); + it = blocks->begin(); } void suspend() @@ -111,7 +111,7 @@ protected: { Block res; - if (length == 0) + if (has_limit && num_updates == (Int64)limit) { return { Block(), true }; } @@ -162,7 +162,7 @@ protected: while (true) { UInt64 timestamp_usec = static_cast(timestamp.epochMicroseconds()); - bool signaled = storage->condition.tryWait(storage->mutex, std::max(static_cast(0), heartbeat_interval - (timestamp_usec - last_event_timestamp)) / 1000); + bool signaled = storage->condition.tryWait(storage->mutex, std::max(static_cast(0), heartbeat_interval_usec - (timestamp_usec - last_event_timestamp_usec)) / 1000); if (isCancelled() || storage->is_dropped) { @@ -175,7 +175,7 @@ protected: else { // heartbeat - last_event_timestamp = static_cast(timestamp.epochMicroseconds()); + last_event_timestamp_usec = static_cast(timestamp.epochMicroseconds()); return { getHeader(), true }; } } @@ -191,11 +191,10 @@ protected: if (it == end) { end_of_blocks = false; - if (length > 0) - --length; + num_updates += 1; } - last_event_timestamp = static_cast(timestamp.epochMicroseconds()); + last_event_timestamp_usec = static_cast(timestamp.epochMicroseconds()); return { res, true }; } @@ -210,13 +209,13 @@ private: Blocks::iterator it; Blocks::iterator end; Blocks::iterator begin; - /// Length specifies number of updates to send, default -1 (no limit) - int64_t length; - bool end_of_blocks{0}; - UInt64 heartbeat_interval; - UInt64 temporary_live_view_timeout; - String blocks_hash; - UInt64 last_event_timestamp{0}; + const bool has_limit; + const UInt64 limit; + Int64 num_updates = -1; + bool end_of_blocks = false; + UInt64 heartbeat_interval_usec; + UInt64 temporary_live_view_timeout_sec; + UInt64 last_event_timestamp_usec = 0; Poco::Timestamp timestamp; }; diff --git a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h index 75e68b15d92..fa97ae2e7f5 100644 --- a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h +++ b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h @@ -27,9 +27,10 @@ limitations under the License. */ namespace DB { -/** - */ - +/** Implements LIVE VIEW table WATCH EVENTS input stream. + * Keeps stream alive by outputing blocks with no rows + * based on period specified by the heartbeat interval. + */ class LiveViewEventsBlockInputStream : public IBlockInputStream { @@ -41,13 +42,18 @@ public: /// Start storage no users thread /// if we are the last active user if (!storage->is_dropped && blocks_ptr.use_count() < 3) - storage->startNoUsersThread(temporary_live_view_timeout); + storage->startNoUsersThread(temporary_live_view_timeout_sec); } /// length default -2 because we want LIMIT to specify number of updates so that LIMIT 1 waits for 1 update /// and LIMIT 0 just returns data without waiting for any updates - LiveViewEventsBlockInputStream(std::shared_ptr storage_, std::shared_ptr blocks_ptr_, std::shared_ptr blocks_metadata_ptr_, std::shared_ptr active_ptr_, - int64_t length_, const UInt64 & heartbeat_interval_, const UInt64 & temporary_live_view_timeout_) - : storage(storage_), blocks_ptr(blocks_ptr_), blocks_metadata_ptr(blocks_metadata_ptr_), active_ptr(active_ptr_), length(length_ + 1), heartbeat_interval(heartbeat_interval_ * 1000000), temporary_live_view_timeout(temporary_live_view_timeout_) + LiveViewEventsBlockInputStream(std::shared_ptr storage_, + std::shared_ptr blocks_ptr_, + std::shared_ptr blocks_metadata_ptr_, + std::shared_ptr active_ptr_, + const bool has_limit_, const UInt64 limit_, + const UInt64 heartbeat_interval_sec_, + const UInt64 temporary_live_view_timeout_sec_) + : storage(std::move(storage_)), blocks_ptr(std::move(blocks_ptr_)), blocks_metadata_ptr(std::move(blocks_metadata_ptr_)), active_ptr(std::move(active_ptr_)), has_limit(has_limit_), limit(limit_), heartbeat_interval_usec(heartbeat_interval_sec_ * 1000000), temporary_live_view_timeout_sec(temporary_live_view_timeout_sec_) { /// grab active pointer active = active_ptr.lock(); @@ -72,7 +78,7 @@ public: void refresh() { if (active && blocks && it == end) - it = blocks->begin(); + it = blocks->begin(); } void suspend() @@ -124,7 +130,7 @@ protected: */ NonBlockingResult tryRead_(bool blocking) { - if (length == 0) + if (has_limit && num_updates == (Int64)limit) { return { Block(), true }; } @@ -177,7 +183,7 @@ protected: while (true) { UInt64 timestamp_usec = static_cast(timestamp.epochMicroseconds()); - bool signaled = storage->condition.tryWait(storage->mutex, std::max(static_cast(0), heartbeat_interval - (timestamp_usec - last_event_timestamp)) / 1000); + bool signaled = storage->condition.tryWait(storage->mutex, std::max(static_cast(0), heartbeat_interval_usec - (timestamp_usec - last_event_timestamp_usec)) / 1000); if (isCancelled() || storage->is_dropped) { @@ -190,7 +196,7 @@ protected: else { // repeat the event block as a heartbeat - last_event_timestamp = static_cast(timestamp.epochMicroseconds()); + last_event_timestamp_usec = static_cast(timestamp.epochMicroseconds()); return { getHeader(), true }; } } @@ -205,11 +211,10 @@ protected: if (it == end) { end_of_blocks = false; - if (length > 0) - --length; + num_updates += 1; } - last_event_timestamp = static_cast(timestamp.epochMicroseconds()); + last_event_timestamp_usec = static_cast(timestamp.epochMicroseconds()); return { getEventBlock(), true }; } @@ -225,12 +230,13 @@ private: Blocks::iterator it; Blocks::iterator end; Blocks::iterator begin; - /// Length specifies number of updates to send, default -1 (no limit) - int64_t length; - bool end_of_blocks{0}; - UInt64 heartbeat_interval; - UInt64 temporary_live_view_timeout; - UInt64 last_event_timestamp{0}; + const bool has_limit; + const UInt64 limit; + Int64 num_updates = -1; + bool end_of_blocks = false; + UInt64 heartbeat_interval_usec; + UInt64 temporary_live_view_timeout_sec; + UInt64 last_event_timestamp_usec = 0; Poco::Timestamp timestamp; }; diff --git a/dbms/src/Storages/IStorage.h b/dbms/src/Storages/IStorage.h index b7358c3fc6e..0d13a63a214 100644 --- a/dbms/src/Storages/IStorage.h +++ b/dbms/src/Storages/IStorage.h @@ -85,7 +85,7 @@ public: public: /// thread-unsafe part. lockStructure must be acquired virtual const ColumnsDescription & getColumns() const; /// returns combined set of columns virtual void setColumns(ColumnsDescription columns_); /// sets only real columns, possibly overwrites virtual ones. - + const IndicesDescription & getIndices() const; /// NOTE: these methods should include virtual columns, diff --git a/dbms/src/Storages/StorageLiveView.cpp b/dbms/src/Storages/StorageLiveView.cpp index 0eb31acf1ae..df7f8c896b3 100644 --- a/dbms/src/Storages/StorageLiveView.cpp +++ b/dbms/src/Storages/StorageLiveView.cpp @@ -407,15 +407,18 @@ BlockInputStreams StorageLiveView::watch( { ASTWatchQuery & query = typeid_cast(*query_info.query); - /// By default infinite stream of updates - int64_t length = -2; + bool has_limit = false; + UInt64 limit = 0; if (query.limit_length) - length = static_cast(safeGet(typeid_cast(*query.limit_length).value)); + { + has_limit = true; + limit = safeGet(typeid_cast(*query.limit_length).value); + } if (query.is_watch_events) { - auto reader = std::make_shared(std::static_pointer_cast(shared_from_this()), blocks_ptr, blocks_metadata_ptr, active_ptr, length, context.getSettingsRef().live_view_heartbeat_interval.totalSeconds(), + auto reader = std::make_shared(std::static_pointer_cast(shared_from_this()), blocks_ptr, blocks_metadata_ptr, active_ptr, has_limit, limit, context.getSettingsRef().live_view_heartbeat_interval.totalSeconds(), context.getSettingsRef().temporary_live_view_timeout.totalSeconds()); if (no_users_thread.joinable()) @@ -440,7 +443,7 @@ BlockInputStreams StorageLiveView::watch( } else { - auto reader = std::make_shared(std::static_pointer_cast(shared_from_this()), blocks_ptr, blocks_metadata_ptr, active_ptr, length, context.getSettingsRef().live_view_heartbeat_interval.totalSeconds(), + auto reader = std::make_shared(std::static_pointer_cast(shared_from_this()), blocks_ptr, blocks_metadata_ptr, active_ptr, has_limit, limit, context.getSettingsRef().live_view_heartbeat_interval.totalSeconds(), context.getSettingsRef().temporary_live_view_timeout.totalSeconds()); if (no_users_thread.joinable()) diff --git a/dbms/src/Storages/StorageLiveView.h b/dbms/src/Storages/StorageLiveView.h index 3f2732647b3..6bff9c2dc85 100644 --- a/dbms/src/Storages/StorageLiveView.h +++ b/dbms/src/Storages/StorageLiveView.h @@ -78,7 +78,7 @@ public: return blocks_ptr.use_count() > 1; } - /// Check we we have any active readers + /// Check we have any active readers /// must be called with mutex locked bool hasActiveUsers() { From c84fd80345d76f648e9c8f1463c9b4210d08c5be Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Tue, 9 Jul 2019 22:06:29 -0400 Subject: [PATCH 0161/1165] * Fixing clang build by converting old style cast (Int64) to static_cast. --- dbms/src/DataStreams/LiveViewBlockInputStream.h | 2 +- dbms/src/DataStreams/LiveViewEventsBlockInputStream.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/DataStreams/LiveViewBlockInputStream.h b/dbms/src/DataStreams/LiveViewBlockInputStream.h index 89ac5e4f9f3..b3756c9ff6d 100644 --- a/dbms/src/DataStreams/LiveViewBlockInputStream.h +++ b/dbms/src/DataStreams/LiveViewBlockInputStream.h @@ -111,7 +111,7 @@ protected: { Block res; - if (has_limit && num_updates == (Int64)limit) + if (has_limit && num_updates == static_cast(limit)) { return { Block(), true }; } diff --git a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h index fa97ae2e7f5..93fb6a76372 100644 --- a/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h +++ b/dbms/src/DataStreams/LiveViewEventsBlockInputStream.h @@ -130,7 +130,7 @@ protected: */ NonBlockingResult tryRead_(bool blocking) { - if (has_limit && num_updates == (Int64)limit) + if (has_limit && num_updates == static_cast(limit)) { return { Block(), true }; } From 9c5514135d689c77036850afed38f48f81ad0134 Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Tue, 9 Jul 2019 23:27:19 -0400 Subject: [PATCH 0162/1165] * Updating tests to send Ctrl-C instead of SIGINT signal to abort WATCH query * Updating client.py to start commands inside shell * Removing test code from uexpect.py --- .../00960_live_view_watch_events_live.py | 2 +- .../00962_temporary_live_view_watch_live.py | 2 +- ...3_temporary_live_view_watch_live_timeout.py | 2 +- .../00964_live_view_watch_events_heartbeat.py | 2 +- .../00965_live_view_watch_heartbeat.py | 2 +- .../0_stateless/00979_live_view_watch_live.py | 2 +- .../queries/0_stateless/helpers/client.py | 7 ++++--- .../queries/0_stateless/helpers/uexpect.py | 18 ------------------ 8 files changed, 10 insertions(+), 27 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py b/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py index 44b8df185b1..5f2d7c90da7 100755 --- a/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py +++ b/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py @@ -31,7 +31,7 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') client1.expect('3.*' + end_of_block) # send Ctrl-C - os.kill(client1.process.pid, signal.SIGINT) + client1.send('\x03', eol='') client1.expect(prompt) client1.send('DROP TABLE test.lv') client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py b/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py index d4d35548d68..d3c6e4cb6cf 100755 --- a/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py +++ b/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py @@ -31,7 +31,7 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') client1.expect(r'21.*3' + end_of_block) # send Ctrl-C - os.kill(client1.process.pid, signal.SIGINT) + client1.send('\x03', eol='') client1.expect(prompt) client1.send('DROP TABLE test.lv') client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py index 2008368f12e..28c1c027017 100755 --- a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py +++ b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py @@ -35,7 +35,7 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client2.expect(prompt) client1.expect(r'21.*3' + end_of_block) # send Ctrl-C - os.kill(client1.process.pid, signal.SIGINT) + client1.send('\x03', eol='') client1.expect(prompt) client1.send('SELECT sleep(1)') client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py index cecae7c5a72..5db6a6c13aa 100755 --- a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py @@ -33,7 +33,7 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo # wait for heartbeat client1.expect('Progress: 2.00 rows.*\)') # send Ctrl-C - os.kill(client1.process.pid, signal.SIGINT) + client1.send('\x03', eol='') client1.expect(prompt) client1.send('DROP TABLE test.lv') client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py b/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py index b2bd84e0742..f024f3f1008 100755 --- a/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py @@ -34,7 +34,7 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo # wait for heartbeat client1.expect('Progress: 2.00 rows.*\)') # send Ctrl-C - os.kill(client1.process.pid, signal.SIGINT) + client1.send('\x03', eol='') client1.expect(prompt) client1.send('DROP TABLE test.lv') client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/00979_live_view_watch_live.py b/dbms/tests/queries/0_stateless/00979_live_view_watch_live.py index 33cc9db3ccc..e5e44284959 100755 --- a/dbms/tests/queries/0_stateless/00979_live_view_watch_live.py +++ b/dbms/tests/queries/0_stateless/00979_live_view_watch_live.py @@ -37,7 +37,7 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client1.expect(r'%d.*%d' % (21+i, 3+i) + end_of_block) client2.expect(prompt) # send Ctrl-C - os.kill(client1.process.pid, signal.SIGINT) + client1.send('\x03', eol='') client1.expect(prompt) client1.send('DROP TABLE test.lv') client1.expect(prompt) diff --git a/dbms/tests/queries/0_stateless/helpers/client.py b/dbms/tests/queries/0_stateless/helpers/client.py index dec7eca7d78..b8f0dec46ad 100644 --- a/dbms/tests/queries/0_stateless/helpers/client.py +++ b/dbms/tests/queries/0_stateless/helpers/client.py @@ -11,11 +11,12 @@ prompt = ':\) ' end_of_block = r'.*\r\n.*\r\n' def client(command=None, name='', log=None): + client = uexpect.spawn(['/bin/bash','--noediting']) if command is None: - client = uexpect.spawn(os.environ.get('CLICKHOUSE_BINARY', 'clickhouse') + '-client') - else: - client = uexpect.spawn(command) + command = os.environ.get('CLICKHOUSE_BINARY', 'clickhouse') + '-client' client.eol('\r') client.logger(log, prefix=name) client.timeout(20) + client.expect('[#\$] ', timeout=2) + client.send(command) return client diff --git a/dbms/tests/queries/0_stateless/helpers/uexpect.py b/dbms/tests/queries/0_stateless/helpers/uexpect.py index 2f323cf6ca6..d65190e2b29 100644 --- a/dbms/tests/queries/0_stateless/helpers/uexpect.py +++ b/dbms/tests/queries/0_stateless/helpers/uexpect.py @@ -202,21 +202,3 @@ def reader(process, out, queue, kill_event): if e.errno == 5 and kill_event.is_set(): break raise - -if __name__ == '__main__': - io = spawn(['/bin/bash','--noediting']) - prompt = '\$ ' - io.logger(sys.stdout) - io.timeout(2) - io.eol('\r') - - io.expect(prompt) - io.send('clickhouse-client') - prompt = ':\) ' - io.expect(prompt) - io.send('SELECT 1') - io.expect(prompt) - io.send('SHOW TABLES') - io.expect('.*\r\n.*') - io.expect(prompt) - io.close() From 280025d5b4931205d3186d055ed69c2ccfe9685e Mon Sep 17 00:00:00 2001 From: Vitaliy Zakaznikov Date: Wed, 10 Jul 2019 08:22:31 -0400 Subject: [PATCH 0163/1165] * Updating live view tests to workaround an issue with clickhouse-client exiting when Ctrl-C is pressed during WATCH query execution instead of going to the client prompt. --- .../queries/0_stateless/00960_live_view_watch_events_live.py | 5 ++++- .../0_stateless/00962_temporary_live_view_watch_live.py | 5 ++++- .../00963_temporary_live_view_watch_live_timeout.py | 5 ++++- .../0_stateless/00964_live_view_watch_events_heartbeat.py | 5 ++++- .../queries/0_stateless/00965_live_view_watch_heartbeat.py | 5 ++++- dbms/tests/queries/0_stateless/00979_live_view_watch_live.py | 5 ++++- dbms/tests/queries/0_stateless/helpers/client.py | 1 + 7 files changed, 25 insertions(+), 6 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py b/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py index 5f2d7c90da7..b7fc3f4e3a6 100755 --- a/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py +++ b/dbms/tests/queries/0_stateless/00960_live_view_watch_events_live.py @@ -32,7 +32,10 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client1.expect('3.*' + end_of_block) # send Ctrl-C client1.send('\x03', eol='') - client1.expect(prompt) + match = client1.expect('(%s)|([#\$] )' % prompt) + if match.groups()[1]: + client1.send(client1.command) + client1.expect(prompt) client1.send('DROP TABLE test.lv') client1.expect(prompt) client1.send('DROP TABLE test.mt') diff --git a/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py b/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py index d3c6e4cb6cf..f27b1213c70 100755 --- a/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py +++ b/dbms/tests/queries/0_stateless/00962_temporary_live_view_watch_live.py @@ -32,7 +32,10 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client1.expect(r'21.*3' + end_of_block) # send Ctrl-C client1.send('\x03', eol='') - client1.expect(prompt) + match = client1.expect('(%s)|([#\$] )' % prompt) + if match.groups()[1]: + client1.send(client1.command) + client1.expect(prompt) client1.send('DROP TABLE test.lv') client1.expect(prompt) client1.send('DROP TABLE test.mt') diff --git a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py index 28c1c027017..df627c84e49 100755 --- a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py +++ b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py @@ -36,7 +36,10 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client1.expect(r'21.*3' + end_of_block) # send Ctrl-C client1.send('\x03', eol='') - client1.expect(prompt) + match = client1.expect('(%s)|([#\$] )' % prompt) + if match.groups()[1]: + client1.send(client1.command) + client1.expect(prompt) client1.send('SELECT sleep(1)') client1.expect(prompt) client1.send('DROP TABLE test.lv') diff --git a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py index 5db6a6c13aa..5664c0e6c6d 100755 --- a/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00964_live_view_watch_events_heartbeat.py @@ -34,7 +34,10 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client1.expect('Progress: 2.00 rows.*\)') # send Ctrl-C client1.send('\x03', eol='') - client1.expect(prompt) + match = client1.expect('(%s)|([#\$] )' % prompt) + if match.groups()[1]: + client1.send(client1.command) + client1.expect(prompt) client1.send('DROP TABLE test.lv') client1.expect(prompt) client1.send('DROP TABLE test.mt') diff --git a/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py b/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py index f024f3f1008..03e22175dff 100755 --- a/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py +++ b/dbms/tests/queries/0_stateless/00965_live_view_watch_heartbeat.py @@ -35,7 +35,10 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client1.expect('Progress: 2.00 rows.*\)') # send Ctrl-C client1.send('\x03', eol='') - client1.expect(prompt) + match = client1.expect('(%s)|([#\$] )' % prompt) + if match.groups()[1]: + client1.send(client1.command) + client1.expect(prompt) client1.send('DROP TABLE test.lv') client1.expect(prompt) client1.send('DROP TABLE test.mt') diff --git a/dbms/tests/queries/0_stateless/00979_live_view_watch_live.py b/dbms/tests/queries/0_stateless/00979_live_view_watch_live.py index e5e44284959..948e4c93662 100755 --- a/dbms/tests/queries/0_stateless/00979_live_view_watch_live.py +++ b/dbms/tests/queries/0_stateless/00979_live_view_watch_live.py @@ -38,7 +38,10 @@ with client(name='client1>', log=log) as client1, client(name='client2>', log=lo client2.expect(prompt) # send Ctrl-C client1.send('\x03', eol='') - client1.expect(prompt) + match = client1.expect('(%s)|([#\$] )' % prompt) + if match.groups()[1]: + client1.send(client1.command) + client1.expect(prompt) client1.send('DROP TABLE test.lv') client1.expect(prompt) client1.send('DROP TABLE test.mt') diff --git a/dbms/tests/queries/0_stateless/helpers/client.py b/dbms/tests/queries/0_stateless/helpers/client.py index b8f0dec46ad..de4da794805 100644 --- a/dbms/tests/queries/0_stateless/helpers/client.py +++ b/dbms/tests/queries/0_stateless/helpers/client.py @@ -14,6 +14,7 @@ def client(command=None, name='', log=None): client = uexpect.spawn(['/bin/bash','--noediting']) if command is None: command = os.environ.get('CLICKHOUSE_BINARY', 'clickhouse') + '-client' + client.command = command client.eol('\r') client.logger(log, prefix=name) client.timeout(20) From 9d540abc84ca2b8ba648b7dd78e5b6641b5b73d3 Mon Sep 17 00:00:00 2001 From: Nikita Lapkov Date: Wed, 10 Jul 2019 20:47:39 +0000 Subject: [PATCH 0164/1165] refactor --- dbms/programs/server/config.xml | 2 +- dbms/src/Common/CurrentThread.h | 8 +- dbms/src/Common/ErrorCodes.cpp | 3 + dbms/src/Common/QueryProfiler.cpp | 128 +++++++++++++++++- dbms/src/Common/QueryProfiler.h | 102 ++------------ dbms/src/Common/ThreadStatus.h | 5 +- dbms/src/Common/Throttler.h | 4 +- .../TraceCollector.cpp | 55 ++++++-- dbms/src/Common/TraceCollector.h | 32 +++++ dbms/src/Core/Settings.h | 4 +- dbms/src/DataStreams/IBlockInputStream.cpp | 4 +- dbms/src/Functions/sleep.h | 4 +- dbms/src/Interpreters/Context.cpp | 22 +-- dbms/src/Interpreters/Context.h | 1 - dbms/src/Interpreters/DDLWorker.cpp | 4 +- dbms/src/Interpreters/ThreadStatusExt.cpp | 22 +-- dbms/src/Interpreters/TraceCollector.h | 28 ---- libs/libcommon/CMakeLists.txt | 5 +- libs/libcommon/include/common/Pipe.h | 55 ++------ libs/libcommon/include/common/Sleep.h | 11 -- libs/libcommon/include/common/sleep.h | 16 +++ libs/libcommon/src/Pipe.cpp | 45 ++++++ libs/libcommon/src/{Sleep.cpp => sleep.cpp} | 22 +-- libs/libmysqlxx/src/Pool.cpp | 6 +- 24 files changed, 338 insertions(+), 250 deletions(-) rename dbms/src/{Interpreters => Common}/TraceCollector.cpp (65%) create mode 100644 dbms/src/Common/TraceCollector.h delete mode 100644 dbms/src/Interpreters/TraceCollector.h delete mode 100644 libs/libcommon/include/common/Sleep.h create mode 100644 libs/libcommon/include/common/sleep.h create mode 100644 libs/libcommon/src/Pipe.cpp rename libs/libcommon/src/{Sleep.cpp => sleep.cpp} (62%) diff --git a/dbms/programs/server/config.xml b/dbms/programs/server/config.xml index e78e3c255f7..a8f37a2cd78 100644 --- a/dbms/programs/server/config.xml +++ b/dbms/programs/server/config.xml @@ -295,7 +295,7 @@ + See query_profiler_real_time_period_ns and query_profiler_cpu_time_period_ns settings. --> system trace_log
diff --git a/dbms/src/Common/CurrentThread.h b/dbms/src/Common/CurrentThread.h index 3c248ad903f..8b15bc7c3e3 100644 --- a/dbms/src/Common/CurrentThread.h +++ b/dbms/src/Common/CurrentThread.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -70,7 +71,12 @@ public: static void finalizePerformanceCounters(); /// Returns a non-empty string if the thread is attached to a query - static StringRef getQueryId(); + static StringRef getQueryId() + { + if (unlikely(!current_thread)) + return {}; + return current_thread->getQueryId(); + } /// Non-master threads call this method in destructor automatically static void detachQuery(); diff --git a/dbms/src/Common/ErrorCodes.cpp b/dbms/src/Common/ErrorCodes.cpp index a3b788c230f..c472a336d73 100644 --- a/dbms/src/Common/ErrorCodes.cpp +++ b/dbms/src/Common/ErrorCodes.cpp @@ -434,6 +434,9 @@ namespace ErrorCodes extern const int BAD_QUERY_PARAMETER = 457; extern const int CANNOT_UNLINK = 458; extern const int CANNOT_SET_THREAD_PRIORITY = 459; + extern const int CANNOT_CREATE_TIMER = 460; + extern const int CANNOT_SET_TIMER_PERIOD = 461; + extern const int CANNOT_DELETE_TIMER = 462; extern const int KEEPER_EXCEPTION = 999; extern const int POCO_EXCEPTION = 1000; diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index ce0ddef094f..9832b64ee8b 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -1,8 +1,134 @@ #include "QueryProfiler.h" +#include +#include +#include +#include +#include +#include +#include +#include + namespace DB { -LazyPipe trace_pipe; +extern LazyPipe trace_pipe; + +namespace +{ + /// Normally query_id is a UUID (string with a fixed length) but user can provide custom query_id. + /// Thus upper bound on query_id length should be introduced to avoid buffer overflow in signal handler. + constexpr size_t QUERY_ID_MAX_LEN = 1024; + + void writeTraceInfo(TimerType timer_type, int /* sig */, siginfo_t * /* info */, void * context) + { + constexpr size_t buf_size = sizeof(char) + // TraceCollector stop flag + 8 * sizeof(char) + // maximum VarUInt length for string size + QUERY_ID_MAX_LEN * sizeof(char) + // maximum query_id length + sizeof(StackTrace) + // collected stack trace + sizeof(TimerType); // timer type + char buffer[buf_size]; + WriteBufferFromFileDescriptor out(trace_pipe.fds_rw[1], buf_size, buffer); + + StringRef query_id = CurrentThread::getQueryId(); + query_id.size = std::min(query_id.size, QUERY_ID_MAX_LEN); + + const auto signal_context = *reinterpret_cast(context); + const StackTrace stack_trace(signal_context); + + writeChar(false, out); + writeStringBinary(query_id, out); + writePODBinary(stack_trace, out); + writePODBinary(timer_type, out); + out.next(); + } + + const UInt32 TIMER_PRECISION = 1e9; +} + +namespace ErrorCodes +{ + extern const int CANNOT_MANIPULATE_SIGSET; + extern const int CANNOT_SET_SIGNAL_HANDLER; + extern const int CANNOT_CREATE_TIMER; + extern const int CANNOT_SET_TIMER_PERIOD; + extern const int CANNOT_DELETE_TIMER; +} + +template +QueryProfilerBase::QueryProfilerBase(const Int32 thread_id, const int clock_type, const UInt32 period, const int pause_signal) + : log(&Logger::get("QueryProfiler")) + , pause_signal(pause_signal) +{ + struct sigaction sa{}; + sa.sa_sigaction = ProfilerImpl::signalHandler; + sa.sa_flags = SA_SIGINFO | SA_RESTART; + + if (sigemptyset(&sa.sa_mask)) + throwFromErrno("Failed to clean signal mask for query profiler", ErrorCodes::CANNOT_MANIPULATE_SIGSET); + + if (sigaddset(&sa.sa_mask, pause_signal)) + throwFromErrno("Failed to add signal to mask for query profiler", ErrorCodes::CANNOT_MANIPULATE_SIGSET); + + if (sigaction(pause_signal, &sa, previous_handler)) + throwFromErrno("Failed to setup signal handler for query profiler", ErrorCodes::CANNOT_SET_SIGNAL_HANDLER); + + try + { + struct sigevent sev; + sev.sigev_notify = SIGEV_THREAD_ID; + sev.sigev_signo = pause_signal; + sev._sigev_un._tid = thread_id; + if (timer_create(clock_type, &sev, &timer_id)) + throwFromErrno("Failed to create thread timer", ErrorCodes::CANNOT_CREATE_TIMER); + + struct timespec interval{.tv_sec = period / TIMER_PRECISION, .tv_nsec = period % TIMER_PRECISION}; + struct itimerspec timer_spec = {.it_interval = interval, .it_value = interval}; + if (timer_settime(timer_id, 0, &timer_spec, nullptr)) + throwFromErrno("Failed to set thread timer period", ErrorCodes::CANNOT_SET_TIMER_PERIOD); + } + catch (...) + { + tryCleanup(); + throw; + } +} + +template +QueryProfilerBase::~QueryProfilerBase() +{ + tryCleanup(); +} + +template +void QueryProfilerBase::tryCleanup() +{ + if (timer_id != nullptr && timer_delete(timer_id)) + LOG_ERROR(log, "Failed to delete query profiler timer " + errnoToString(ErrorCodes::CANNOT_DELETE_TIMER)); + + if (previous_handler != nullptr && sigaction(pause_signal, previous_handler, nullptr)) + LOG_ERROR(log, "Failed to restore signal handler after query profiler " + errnoToString(ErrorCodes::CANNOT_SET_SIGNAL_HANDLER)); +} + +template class QueryProfilerBase; +template class QueryProfilerBase; + +QueryProfilerReal::QueryProfilerReal(const Int32 thread_id, const UInt32 period) + : QueryProfilerBase(thread_id, CLOCK_REALTIME, period, SIGUSR1) +{} + +void QueryProfilerReal::signalHandler(int sig, siginfo_t * info, void * context) +{ + writeTraceInfo(TimerType::Real, sig, info, context); +} + +QueryProfilerCpu::QueryProfilerCpu(const Int32 thread_id, const UInt32 period) + : QueryProfilerBase(thread_id, CLOCK_THREAD_CPUTIME_ID, period, SIGUSR2) +{} + +void QueryProfilerCpu::signalHandler(int sig, siginfo_t * info, void * context) +{ + writeTraceInfo(TimerType::Cpu, sig, info, context); +} } diff --git a/dbms/src/Common/QueryProfiler.h b/dbms/src/Common/QueryProfiler.h index eea1bb0374d..d4e92f25a17 100644 --- a/dbms/src/Common/QueryProfiler.h +++ b/dbms/src/Common/QueryProfiler.h @@ -1,12 +1,6 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include +#include #include #include @@ -19,47 +13,12 @@ namespace Poco namespace DB { -extern LazyPipe trace_pipe; - enum class TimerType : UInt8 { Real, Cpu, }; -namespace -{ - /// Normally query_id is a UUID (string with a fixed length) but user can provide custom query_id. - /// Thus upper bound on query_id length should be introduced to avoid buffer overflow in signal handler. - constexpr size_t QUERY_ID_MAX_LEN = 1024; - - void writeTraceInfo(TimerType timer_type, int /* sig */, siginfo_t * /* info */, void * context) - { - constexpr size_t buf_size = sizeof(char) + // TraceCollector stop flag - 8 * sizeof(char) + // maximum VarUInt length for string size - QUERY_ID_MAX_LEN * sizeof(char) + // maximum query_id length - sizeof(StackTrace) + // collected stack trace - sizeof(TimerType); // timer type - char buffer[buf_size]; - DB::WriteBufferFromFileDescriptor out(trace_pipe.fds_rw[1], buf_size, buffer); - - StringRef query_id = CurrentThread::getQueryId(); - query_id.size = std::min(query_id.size, QUERY_ID_MAX_LEN); - - const auto signal_context = *reinterpret_cast(context); - const StackTrace stack_trace(signal_context); - - DB::writeChar(false, out); - DB::writeStringBinary(query_id, out); - DB::writePODBinary(stack_trace, out); - DB::writePODBinary(timer_type, out); - out.next(); - } - - const UInt32 TIMER_PRECISION = 1e9; -} - - /** * Query profiler implementation for selected thread. * @@ -75,46 +34,13 @@ template class QueryProfilerBase { public: - QueryProfilerBase(const Int32 thread_id, const int clock_type, const UInt32 period, const int pause_signal = SIGALRM) - : log(&Logger::get("QueryProfiler")) - , pause_signal(pause_signal) - { - struct sigaction sa{}; - sa.sa_sigaction = ProfilerImpl::signalHandler; - sa.sa_flags = SA_SIGINFO | SA_RESTART; + QueryProfilerBase(const Int32 thread_id, const int clock_type, const UInt32 period, const int pause_signal = SIGALRM); - if (sigemptyset(&sa.sa_mask)) - throw Poco::Exception("Failed to clean signal mask for query profiler"); - - if (sigaddset(&sa.sa_mask, pause_signal)) - throw Poco::Exception("Failed to add signal to mask for query profiler"); - - if (sigaction(pause_signal, &sa, previous_handler)) - throw Poco::Exception("Failed to setup signal handler for query profiler"); - - struct sigevent sev; - sev.sigev_notify = SIGEV_THREAD_ID; - sev.sigev_signo = pause_signal; - sev._sigev_un._tid = thread_id; - if (timer_create(clock_type, &sev, &timer_id)) - throw Poco::Exception("Failed to create thread timer"); - - struct timespec interval{.tv_sec = period / TIMER_PRECISION, .tv_nsec = period % TIMER_PRECISION}; - struct itimerspec timer_spec = {.it_interval = interval, .it_value = interval}; - if (timer_settime(timer_id, 0, &timer_spec, nullptr)) - throw Poco::Exception("Failed to set thread timer"); - } - - ~QueryProfilerBase() - { - if (timer_delete(timer_id)) - LOG_ERROR(log, "Failed to delete query profiler timer"); - - if (sigaction(pause_signal, previous_handler, nullptr)) - LOG_ERROR(log, "Failed to restore signal handler after query profiler"); - } + ~QueryProfilerBase(); private: + void tryCleanup(); + Poco::Logger * log; /// Timer id from timer_create(2) @@ -131,28 +57,18 @@ private: class QueryProfilerReal : public QueryProfilerBase { public: - QueryProfilerReal(const Int32 thread_id, const UInt32 period) - : QueryProfilerBase(thread_id, CLOCK_REALTIME, period, SIGUSR1) - {} + QueryProfilerReal(const Int32 thread_id, const UInt32 period); - static void signalHandler(int sig, siginfo_t * info, void * context) - { - writeTraceInfo(TimerType::Real, sig, info, context); - } + static void signalHandler(int sig, siginfo_t * info, void * context); }; /// Query profiler with timer based on CPU clock class QueryProfilerCpu : public QueryProfilerBase { public: - QueryProfilerCpu(const Int32 thread_id, const UInt32 period) - : QueryProfilerBase(thread_id, CLOCK_THREAD_CPUTIME_ID, period, SIGUSR2) - {} + QueryProfilerCpu(const Int32 thread_id, const UInt32 period); - static void signalHandler(int sig, siginfo_t * info, void * context) - { - writeTraceInfo(TimerType::Cpu, sig, info, context); - } + static void signalHandler(int sig, siginfo_t * info, void * context); }; } diff --git a/dbms/src/Common/ThreadStatus.h b/dbms/src/Common/ThreadStatus.h index 87ddd32044c..0b737ccb6a7 100644 --- a/dbms/src/Common/ThreadStatus.h +++ b/dbms/src/Common/ThreadStatus.h @@ -119,7 +119,10 @@ public: return thread_state.load(std::memory_order_relaxed); } - StringRef getQueryId() const; + StringRef getQueryId() const + { + return query_id; + } /// Starts new query and create new thread group for it, current thread becomes master thread of the query void initializeQuery(); diff --git a/dbms/src/Common/Throttler.h b/dbms/src/Common/Throttler.h index 6fd5a7f16c0..3ad50215b9e 100644 --- a/dbms/src/Common/Throttler.h +++ b/dbms/src/Common/Throttler.h @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include @@ -77,7 +77,7 @@ public: if (desired_ns > elapsed_ns) { UInt64 sleep_ns = desired_ns - elapsed_ns; - SleepForNanoseconds(sleep_ns); + sleepForNanoseconds(sleep_ns); ProfileEvents::increment(ProfileEvents::ThrottlerSleepMicroseconds, sleep_ns / 1000UL); } diff --git a/dbms/src/Interpreters/TraceCollector.cpp b/dbms/src/Common/TraceCollector.cpp similarity index 65% rename from dbms/src/Interpreters/TraceCollector.cpp rename to dbms/src/Common/TraceCollector.cpp index 671b77eee83..293e4c38e97 100644 --- a/dbms/src/Interpreters/TraceCollector.cpp +++ b/dbms/src/Common/TraceCollector.cpp @@ -2,15 +2,50 @@ #include #include +#include #include #include #include #include +#include +#include #include -#include #include -using namespace DB; +namespace DB +{ + +LazyPipe trace_pipe; + +namespace ErrorCodes +{ + extern const int NULL_POINTER_DEREFERENCE; + extern const int THREAD_IS_NOT_JOINABLE; +} + +TraceCollector::TraceCollector(std::shared_ptr & trace_log) + : log(&Poco::Logger::get("TraceCollector")) + , trace_log(trace_log) +{ + if (trace_log == nullptr) + throw Exception("Invalid trace log pointer passed", ErrorCodes::NULL_POINTER_DEREFERENCE); + + trace_pipe.open(); + thread = ThreadFromGlobalPool(&TraceCollector::run, this); +} + +TraceCollector::~TraceCollector() +{ + if (!thread.joinable()) + LOG_ERROR(log, "TraceCollector thread is malformed and cannot be joined"); + else + { + TraceCollector::notifyToStop(); + thread.join(); + } + + trace_pipe.close(); +} /** * Sends TraceCollector stop message @@ -22,21 +57,13 @@ using namespace DB; * NOTE: TraceCollector will NOT stop immediately as there may be some data left in the pipe * before stop message. */ -void DB::NotifyTraceCollectorToStop() +void TraceCollector::notifyToStop() { WriteBufferFromFileDescriptor out(trace_pipe.fds_rw[1]); - writeIntBinary(true, out); + writeChar(true, out); out.next(); } -TraceCollector::TraceCollector(std::shared_ptr trace_log) - : log(&Poco::Logger::get("TraceCollector")) - , trace_log(trace_log) -{ - if (trace_log == nullptr) - throw Poco::Exception("Invalid trace log pointer passed"); -} - void TraceCollector::run() { ReadBufferFromFileDescriptor in(trace_pipe.fds_rw[0]); @@ -57,7 +84,7 @@ void TraceCollector::run() readPODBinary(timer_type, in); const auto size = stack_trace.getSize(); - const auto& frames = stack_trace.getFrames(); + const auto & frames = stack_trace.getFrames(); Array trace; trace.reserve(size); @@ -69,3 +96,5 @@ void TraceCollector::run() trace_log->add(element); } } + +} diff --git a/dbms/src/Common/TraceCollector.h b/dbms/src/Common/TraceCollector.h new file mode 100644 index 00000000000..7c07f48776f --- /dev/null +++ b/dbms/src/Common/TraceCollector.h @@ -0,0 +1,32 @@ +#pragma once + +#include + +namespace Poco +{ + class Logger; +} + +namespace DB +{ + +class TraceLog; + +class TraceCollector +{ +private: + Poco::Logger * log; + std::shared_ptr trace_log; + ThreadFromGlobalPool thread; + + void run(); + + static void notifyToStop(); + +public: + TraceCollector(std::shared_ptr & trace_log); + + ~TraceCollector(); +}; + +} diff --git a/dbms/src/Core/Settings.h b/dbms/src/Core/Settings.h index e718da6fa99..967615d6da1 100644 --- a/dbms/src/Core/Settings.h +++ b/dbms/src/Core/Settings.h @@ -220,8 +220,8 @@ struct Settings : public SettingsCollection M(SettingBool, empty_result_for_aggregation_by_empty_set, false, "Return empty result when aggregating without keys on empty set.") \ M(SettingBool, allow_distributed_ddl, true, "If it is set to true, then a user is allowed to executed distributed DDL queries.") \ M(SettingUInt64, odbc_max_field_size, 1024, "Max size of filed can be read from ODBC dictionary. Long strings are truncated.") \ - M(SettingUInt64, query_profiler_real_time_period, 500000000, "Period for real clock timer of query profiler (in nanoseconds). Set 0 value to turn off real clock query profiler") \ - M(SettingUInt64, query_profiler_cpu_time_period, 500000000, "Period for CPU clock timer of query profiler (in nanoseconds). Set 0 value to turn off CPU clock query profiler") \ + M(SettingUInt64, query_profiler_real_time_period_ns, 500000000, "Period for real clock timer of query profiler (in nanoseconds). Set 0 value to turn off real clock query profiler") \ + M(SettingUInt64, query_profiler_cpu_time_period_ns, 500000000, "Period for CPU clock timer of query profiler (in nanoseconds). Set 0 value to turn off CPU clock query profiler") \ \ \ /** Limits during query execution are part of the settings. \ diff --git a/dbms/src/DataStreams/IBlockInputStream.cpp b/dbms/src/DataStreams/IBlockInputStream.cpp index a2d52dfc36d..406a660879c 100644 --- a/dbms/src/DataStreams/IBlockInputStream.cpp +++ b/dbms/src/DataStreams/IBlockInputStream.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include namespace ProfileEvents { @@ -255,7 +255,7 @@ static void limitProgressingSpeed(size_t total_progress_size, size_t max_speed_i if (desired_microseconds > total_elapsed_microseconds) { UInt64 sleep_microseconds = desired_microseconds - total_elapsed_microseconds; - SleepForMicroseconds(sleep_microseconds); + sleepForMicroseconds(sleep_microseconds); ProfileEvents::increment(ProfileEvents::ThrottlerSleepMicroseconds, sleep_microseconds); } diff --git a/dbms/src/Functions/sleep.h b/dbms/src/Functions/sleep.h index ff7cb36786e..5e9732d59f4 100644 --- a/dbms/src/Functions/sleep.h +++ b/dbms/src/Functions/sleep.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include @@ -88,7 +88,7 @@ public: throw Exception("The maximum sleep time is 3 seconds. Requested: " + toString(seconds), ErrorCodes::TOO_SLOW); UInt64 microseconds = seconds * (variant == FunctionSleepVariant::PerBlock ? 1 : size) * 1e6; - SleepForMicroseconds(microseconds); + sleepForMicroseconds(microseconds); } /// convertToFullColumn needed, because otherwise (constant expression case) function will not get called on each block. diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index 407cb9366d1..bd2c03cb78a 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -54,8 +54,8 @@ #include #include #include +#include #include -#include "TraceCollector.h" namespace ProfileEvents @@ -155,8 +155,7 @@ struct ContextShared ActionLocksManagerPtr action_locks_manager; /// Set of storages' action lockers std::optional system_logs; /// Used to log queries and operations on parts - Poco::Thread trace_collector_thread; /// Thread collecting traces from threads executing queries - std::unique_ptr trace_collector; + std::unique_ptr trace_collector; /// Thread collecting traces from threads executing queries /// Named sessions. The user could specify session identifier to reuse settings and temporary tables in subsequent requests. @@ -291,17 +290,8 @@ struct ContextShared schedule_pool.reset(); ddl_worker.reset(); - /// Trace collector is only initialized in server program - if (hasTraceCollector()) - { - /// Stop trace collector - NotifyTraceCollectorToStop(); - trace_collector_thread.join(); - - /// Close trace pipe - definitely nobody needs to write there after - /// databases shutdown - trace_pipe.close(); - } + /// Stop trace collector if any + trace_collector.reset(); } bool hasTraceCollector() @@ -314,9 +304,7 @@ struct ContextShared if (trace_log == nullptr) return; - trace_pipe.open(); - trace_collector.reset(new TraceCollector(trace_log)); - trace_collector_thread.start(*trace_collector); + trace_collector = std::make_unique(trace_log); } private: diff --git a/dbms/src/Interpreters/Context.h b/dbms/src/Interpreters/Context.h index 4f622a0eae1..58745d97add 100644 --- a/dbms/src/Interpreters/Context.h +++ b/dbms/src/Interpreters/Context.h @@ -136,7 +136,6 @@ private: Context * session_context = nullptr; /// Session context or nullptr. Could be equal to this. Context * global_context = nullptr; /// Global context or nullptr. Could be equal to this. - UInt64 session_close_cycle = 0; bool session_is_used = false; diff --git a/dbms/src/Interpreters/DDLWorker.cpp b/dbms/src/Interpreters/DDLWorker.cpp index 4a3665f3d50..e445b7503ce 100644 --- a/dbms/src/Interpreters/DDLWorker.cpp +++ b/dbms/src/Interpreters/DDLWorker.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -953,7 +953,7 @@ void DDLWorker::runMainThread() tryLogCurrentException(__PRETTY_FUNCTION__); /// Avoid busy loop when ZooKeeper is not available. - SleepForSeconds(1); + sleepForSeconds(1); } } catch (...) diff --git a/dbms/src/Interpreters/ThreadStatusExt.cpp b/dbms/src/Interpreters/ThreadStatusExt.cpp index d0d1badc8ad..c4f1fa055b3 100644 --- a/dbms/src/Interpreters/ThreadStatusExt.cpp +++ b/dbms/src/Interpreters/ThreadStatusExt.cpp @@ -46,11 +46,6 @@ void ThreadStatus::attachQueryContext(Context & query_context_) initQueryProfiler(); } -StringRef ThreadStatus::getQueryId() const -{ - return query_id; -} - void CurrentThread::defaultThreadDeleter() { if (unlikely(!current_thread)) @@ -161,18 +156,18 @@ void ThreadStatus::initQueryProfiler() if (!global_context->hasTraceCollector()) return; - auto & settings = query_context->getSettingsRef(); + const auto & settings = query_context->getSettingsRef(); - if (settings.query_profiler_real_time_period > 0) + if (settings.query_profiler_real_time_period_ns > 0) query_profiler_real = std::make_unique( /* thread_id */ os_thread_id, - /* period */ static_cast(settings.query_profiler_real_time_period) + /* period */ static_cast(settings.query_profiler_real_time_period_ns) ); - if (settings.query_profiler_cpu_time_period > 0) + if (settings.query_profiler_cpu_time_period_ns > 0) query_profiler_cpu = std::make_unique( /* thread_id */ os_thread_id, - /* period */ static_cast(settings.query_profiler_cpu_time_period) + /* period */ static_cast(settings.query_profiler_cpu_time_period_ns) ); } @@ -291,13 +286,6 @@ void CurrentThread::attachToIfDetached(const ThreadGroupStatusPtr & thread_group current_thread->deleter = CurrentThread::defaultThreadDeleter; } -StringRef CurrentThread::getQueryId() -{ - if (unlikely(!current_thread)) - return {}; - return current_thread->getQueryId(); -} - void CurrentThread::attachQueryContext(Context & query_context) { if (unlikely(!current_thread)) diff --git a/dbms/src/Interpreters/TraceCollector.h b/dbms/src/Interpreters/TraceCollector.h deleted file mode 100644 index 43a712a9816..00000000000 --- a/dbms/src/Interpreters/TraceCollector.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -#include - -namespace Poco -{ - class Logger; -} - -namespace DB -{ - -void NotifyTraceCollectorToStop(); - -class TraceCollector : public Poco::Runnable -{ -private: - Poco::Logger * log; - std::shared_ptr trace_log; - -public: - TraceCollector(std::shared_ptr trace_log); - - void run() override; -}; - -} diff --git a/libs/libcommon/CMakeLists.txt b/libs/libcommon/CMakeLists.txt index 7469aabceec..eb77f43a37f 100644 --- a/libs/libcommon/CMakeLists.txt +++ b/libs/libcommon/CMakeLists.txt @@ -21,9 +21,10 @@ add_library (common src/demangle.cpp src/setTerminalEcho.cpp src/getThreadNumber.cpp - src/Sleep.cpp + src/sleep.cpp src/argsToConfig.cpp src/StackTrace.cpp + src/Pipe.cpp include/common/SimpleCache.h include/common/StackTrace.h @@ -48,7 +49,7 @@ add_library (common include/common/constexpr_helpers.h include/common/Pipe.h include/common/getThreadNumber.h - include/common/Sleep.h + include/common/sleep.h include/common/SimpleCache.h include/ext/bit_cast.h diff --git a/libs/libcommon/include/common/Pipe.h b/libs/libcommon/include/common/Pipe.h index 3904099c9c2..0137c3d97af 100644 --- a/libs/libcommon/include/common/Pipe.h +++ b/libs/libcommon/include/common/Pipe.h @@ -4,56 +4,31 @@ #include #include +/** + * Struct containing a pipe with lazy initialization. + * Use `open` and `close` methods to manipulate pipe and `fds_rw` field to access + * pipe's file descriptors. + */ struct LazyPipe { int fds_rw[2] = {-1, -1}; LazyPipe() = default; - virtual void open() - { - for (int &fd : fds_rw) - { - if (fd >= 0) - { - throw std::logic_error("Pipe is already opened"); - } - } + void open(); -#ifndef __APPLE__ - if (0 != pipe2(fds_rw, O_CLOEXEC)) - throw std::runtime_error("Cannot create pipe"); -#else - if (0 != pipe(fds_rw)) - throw std::runtime_error("Cannot create pipe"); - if (0 != fcntl(fds_rw[0], F_SETFD, FD_CLOEXEC)) - throw std::runtime_error("Cannot setup auto-close on exec for read end of pipe"); - if (0 != fcntl(fds_rw[1], F_SETFD, FD_CLOEXEC)) - throw std::runtime_error("Cannot setup auto-close on exec for write end of pipe"); -#endif - } - - virtual void close() { - for (int fd : fds_rw) - { - if (fd >= 0) - { - ::close(fd); - } - } - } + void close(); virtual ~LazyPipe() = default; }; -struct Pipe : public LazyPipe { - Pipe() - { - open(); - } +/** + * Struct which opens new pipe on creation and closes it on destruction. + * Use `fds_rw` field to access pipe's file descriptors. + */ +struct Pipe : public LazyPipe +{ + Pipe(); - ~Pipe() - { - close(); - } + ~Pipe(); }; diff --git a/libs/libcommon/include/common/Sleep.h b/libs/libcommon/include/common/Sleep.h deleted file mode 100644 index 7c5c955f723..00000000000 --- a/libs/libcommon/include/common/Sleep.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include - -void SleepForNanoseconds(uint64_t nanoseconds); - -void SleepForMicroseconds(uint64_t microseconds); - -void SleepForMilliseconds(uint64_t milliseconds); - -void SleepForSeconds(uint64_t seconds); diff --git a/libs/libcommon/include/common/sleep.h b/libs/libcommon/include/common/sleep.h new file mode 100644 index 00000000000..6ae99a4a57d --- /dev/null +++ b/libs/libcommon/include/common/sleep.h @@ -0,0 +1,16 @@ +#pragma once + +#include + +/** + * Sleep functions tolerant to signal interruptions (which can happen + * when query profiler is turned on for example) + */ + +void sleepForNanoseconds(uint64_t nanoseconds); + +void sleepForMicroseconds(uint64_t microseconds); + +void sleepForMilliseconds(uint64_t milliseconds); + +void sleepForSeconds(uint64_t seconds); diff --git a/libs/libcommon/src/Pipe.cpp b/libs/libcommon/src/Pipe.cpp new file mode 100644 index 00000000000..83268b76ea6 --- /dev/null +++ b/libs/libcommon/src/Pipe.cpp @@ -0,0 +1,45 @@ +#include "common/Pipe.h" + +void LazyPipe::open() +{ + for (int & fd : fds_rw) + { + if (fd >= 0) + { + throw std::logic_error("Pipe is already opened"); + } + } + +#ifndef __APPLE__ + if (0 != pipe2(fds_rw, O_CLOEXEC)) + throw std::runtime_error("Cannot create pipe"); +#else + if (0 != pipe(fds_rw)) + throw std::runtime_error("Cannot create pipe"); + if (0 != fcntl(fds_rw[0], F_SETFD, FD_CLOEXEC)) + throw std::runtime_error("Cannot setup auto-close on exec for read end of pipe"); + if (0 != fcntl(fds_rw[1], F_SETFD, FD_CLOEXEC)) + throw std::runtime_error("Cannot setup auto-close on exec for write end of pipe"); +#endif +} + +void LazyPipe::close() +{ + for (int fd : fds_rw) + { + if (fd >= 0) + { + ::close(fd); + } + } +} + +Pipe::Pipe() +{ + open(); +} + +Pipe::~Pipe() +{ + close(); +} diff --git a/libs/libcommon/src/Sleep.cpp b/libs/libcommon/src/sleep.cpp similarity index 62% rename from libs/libcommon/src/Sleep.cpp rename to libs/libcommon/src/sleep.cpp index 13b03f2b95e..710b387d62e 100644 --- a/libs/libcommon/src/Sleep.cpp +++ b/libs/libcommon/src/sleep.cpp @@ -1,10 +1,10 @@ -#include "common/Sleep.h" +#include "common/sleep.h" #include #include /** - * Sleep with nanoseconds precision + * Sleep with nanoseconds precision. Tolerant to signal interruptions * * In case query profiler is turned on, all threads spawned for * query execution are repeatedly interrupted by signals from timer. @@ -12,14 +12,14 @@ * problems in this setup and man page for nanosleep(2) suggests * using absolute deadlines, for instance clock_nanosleep(2). */ -void SleepForNanoseconds(uint64_t nanoseconds) +void sleepForNanoseconds(uint64_t nanoseconds) { - const auto clock_type = CLOCK_REALTIME; + constexpr auto clock_type = CLOCK_MONOTONIC; struct timespec current_time; clock_gettime(clock_type, ¤t_time); - const uint64_t resolution = 1'000'000'000; + constexpr uint64_t resolution = 1'000'000'000; struct timespec finish_time = current_time; finish_time.tv_nsec += nanoseconds % resolution; @@ -31,17 +31,17 @@ void SleepForNanoseconds(uint64_t nanoseconds) while (clock_nanosleep(clock_type, TIMER_ABSTIME, &finish_time, nullptr) == EINTR); } -void SleepForMicroseconds(uint64_t microseconds) +void sleepForMicroseconds(uint64_t microseconds) { - SleepForNanoseconds(microseconds * 1000); + sleepForNanoseconds(microseconds * 1000); } -void SleepForMilliseconds(uint64_t milliseconds) +void sleepForMilliseconds(uint64_t milliseconds) { - SleepForMicroseconds(milliseconds * 1000); + sleepForMicroseconds(milliseconds * 1000); } -void SleepForSeconds(uint64_t seconds) +void sleepForSeconds(uint64_t seconds) { - SleepForMilliseconds(seconds * 1000); + sleepForMilliseconds(seconds * 1000); } diff --git a/libs/libmysqlxx/src/Pool.cpp b/libs/libmysqlxx/src/Pool.cpp index 6e35a311b44..a17246e5d6d 100644 --- a/libs/libmysqlxx/src/Pool.cpp +++ b/libs/libmysqlxx/src/Pool.cpp @@ -8,7 +8,7 @@ #include -#include +#include #include #include @@ -135,7 +135,7 @@ Pool::Entry Pool::Get() } lock.unlock(); - SleepForSeconds(MYSQLXX_POOL_SLEEP_ON_CONNECT_FAIL); + sleepForSeconds(MYSQLXX_POOL_SLEEP_ON_CONNECT_FAIL); lock.lock(); } } @@ -195,7 +195,7 @@ void Pool::Entry::forceConnected() const if (first) first = false; else - SleepForSeconds(MYSQLXX_POOL_SLEEP_ON_CONNECT_FAIL); + sleepForSeconds(MYSQLXX_POOL_SLEEP_ON_CONNECT_FAIL); app.logger().information("MYSQL: Reconnecting to " + pool->description); data->conn.connect( From 9f3a5cb8f2046d5a6c481ae82d3af5f1e7813054 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Fri, 12 Jul 2019 07:50:01 +0300 Subject: [PATCH 0165/1165] DOCAPI-6889: RU translations for docs on external dicts functions. --- .../functions/ext_dict_functions.md | 20 +- .../dicts/external_dicts_dict_structure.md | 2 +- .../functions/ext_dict_functions.md | 199 ++++++++++++++++-- docs/ru/query_language/syntax.md | 2 +- 4 files changed, 189 insertions(+), 34 deletions(-) diff --git a/docs/en/query_language/functions/ext_dict_functions.md b/docs/en/query_language/functions/ext_dict_functions.md index 2d96bef23fb..cb033f14c24 100644 --- a/docs/en/query_language/functions/ext_dict_functions.md +++ b/docs/en/query_language/functions/ext_dict_functions.md @@ -15,8 +15,8 @@ dictGetOrDefault('dict_name', 'attr_name', id_expr, default_value_expr) - `dict_name` — Name of the dictionary. [String literal](../syntax.md#syntax-string-literal). - `attr_name` — Name of the column of the dictionary. [String literal](../syntax.md#syntax-string-literal). -- `id_expr` — Key value. [Expression](../syntax.md#syntax-expressions) returns a [UInt64](../../data_types/int_uint.md) or [Tuple](../../data_types/tuple.md)-type value depending on the dictionary configuration. -- `default_value_expr` — Value returned if the dictionary doesn't contain a row with the `id_expr` key. [Expression](../syntax.md#syntax-expressions) returns the value in the data type configured for the `attr_name` attribute. +- `id_expr` — Key value. [Expression](../syntax.md#syntax-expressions) returning a [UInt64](../../data_types/int_uint.md) or [Tuple](../../data_types/tuple.md)-type value depending on the dictionary configuration. +- `default_value_expr` — Value returned if the dictionary doesn't contain a row with the `id_expr` key. [Expression](../syntax.md#syntax-expressions) returning the value in the data type configured for the `attr_name` attribute. **Returned value** @@ -102,7 +102,7 @@ dictHas('dict_name', id) **Parameters** - `dict_name` — Name of the dictionary. [String literal](../syntax.md#syntax-string-literal). -- `id_expr` — Key value. [Expression](../syntax.md#syntax-expressions) returns a [UInt64](../../data_types/int_uint.md)-type value. +- `id_expr` — Key value. [Expression](../syntax.md#syntax-expressions) returning a [UInt64](../../data_types/int_uint.md)-type value. **Returned value** @@ -122,7 +122,7 @@ dictGetHierarchy('dict_name', id) **Parameters** - `dict_name` — Name of the dictionary. [String literal](../syntax.md#syntax-string-literal). -- `id_expr` — Key value. [Expression](../syntax.md#syntax-expressions) returns a [UInt64](../../data_types/int_uint.md)-type value. +- `id_expr` — Key value. [Expression](../syntax.md#syntax-expressions) returning a [UInt64](../../data_types/int_uint.md)-type value. **Returned value** @@ -134,13 +134,15 @@ Type: Array(UInt64). Checks the ancestor of a key in the hierarchical dictionary. -`dictIsIn ('dict_name', child_id_expr, ancestor_id_expr)` +``` +dictIsIn('dict_name', child_id_expr, ancestor_id_expr) +``` **Parameters** - `dict_name` — Name of the dictionary. [String literal](../syntax.md#syntax-string-literal). -- `child_id_expr` — Key to be checked. [Expression](../syntax.md#syntax-expressions) returns a [UInt64](../../data_types/int_uint.md)-type value. -- `ancestor_id_expr` — Alleged ancestor of the `child_id_expr` key. [Expression](../syntax.md#syntax-expressions) returns a [UInt64](../../data_types/int_uint.md)-type value. +- `child_id_expr` — Key to be checked. [Expression](../syntax.md#syntax-expressions) returning a [UInt64](../../data_types/int_uint.md)-type value. +- `ancestor_id_expr` — Alleged ancestor of the `child_id_expr` key. [Expression](../syntax.md#syntax-expressions) returning a [UInt64](../../data_types/int_uint.md)-type value. **Returned value** @@ -176,8 +178,8 @@ dictGet[Type]OrDefault('dict_name', 'attr_name', id_expr, default_value_expr) - `dict_name` — Name of the dictionary. [String literal](../syntax.md#syntax-string-literal). - `attr_name` — Name of the column of the dictionary. [String literal](../syntax.md#syntax-string-literal). -- `id_expr` — Key value. [Expression](../syntax.md#syntax-expressions) returns a [UInt64](../../data_types/int_uint.md)-type value. -- `default_value_expr` — Value which is returned if the dictionary doesn't contain a row with the `id_expr` key. [Expression](../syntax.md#syntax-expressions) returns a value in the data type configured for the `attr_name` attribute. +- `id_expr` — Key value. [Expression](../syntax.md#syntax-expressions) returning a [UInt64](../../data_types/int_uint.md)-type value. +- `default_value_expr` — Value which is returned if the dictionary doesn't contain a row with the `id_expr` key. [Expression](../syntax.md#syntax-expressions) returning a value in the data type configured for the `attr_name` attribute. **Returned value** diff --git a/docs/ru/query_language/dicts/external_dicts_dict_structure.md b/docs/ru/query_language/dicts/external_dicts_dict_structure.md index 50a2469358b..482f47d4a8f 100644 --- a/docs/ru/query_language/dicts/external_dicts_dict_structure.md +++ b/docs/ru/query_language/dicts/external_dicts_dict_structure.md @@ -84,7 +84,7 @@ ClickHouse поддерживает следующие виды ключей: При запросе в функции `dictGet*` в качестве ключа передаётся кортеж. Пример: `dictGetString('dict_name', 'attr_name', tuple('string for field1', num_for_field2))`. -## Атрибуты +## Атрибуты {#ext_dict_structure-attributes} Пример конфигурации: diff --git a/docs/ru/query_language/functions/ext_dict_functions.md b/docs/ru/query_language/functions/ext_dict_functions.md index 8901292aeb2..47e221d7e74 100644 --- a/docs/ru/query_language/functions/ext_dict_functions.md +++ b/docs/ru/query_language/functions/ext_dict_functions.md @@ -1,40 +1,193 @@ # Функции для работы с внешними словарями {#ext_dict_functions} -Информация о подключении и настройке внешних словарей смотрите в разделе [Внешние словари](../dicts/external_dicts.md). +Информацию о подключении и настройке внешних словарей смотрите в разделе [Внешние словари](../dicts/external_dicts.md). -## dictGetUInt8, dictGetUInt16, dictGetUInt32, dictGetUInt64 +## dictGet -## dictGetInt8, dictGetInt16, dictGetInt32, dictGetInt64 +Извлекает значение из внешнего словаря. -## dictGetFloat32, dictGetFloat64 +``` +dictGet('dict_name', 'attr_name', id_expr) +dictGetOrDefault('dict_name', 'attr_name', id_expr, default_value_expr) +``` -## dictGetDate, dictGetDateTime +**Параметры** -## dictGetUUID +- `dict_name` — имя словаря. [Строковый литерал](../syntax.md#syntax-string-literal). +- `attr_name` — имя столбца словаря. [Строковый литерал](../syntax.md#syntax-string-literal). +- `id_expr` — значение ключа словаря. [Выражение](../syntax.md#syntax-expressions), возвращающее значение типа [UInt64](../../data_types/int_uint.md) или [Tuple](../../data_types/tuple.md) в зависимости от конфигурации словаря. +- `default_value_expr` — значение, возвращаемое в том случае, когда словарь не содержит строки с заданным ключем `id_expr`. [Выражение](../syntax.md#syntax-expressions) возвращающее значение с типом данных, сконфигурированным для атрибута `attr_name`. -## dictGetString -`dictGetT('dict_name', 'attr_name', id)` -- получить из словаря dict_name значение атрибута attr_name по ключу id. -`dict_name` и `attr_name` - константные строки. -`id` должен иметь тип UInt64. -Если ключа `id` нет в словаре - вернуть значение по умолчанию, заданное в описании словаря. +**Возвращаемое значение** -## dictGetTOrDefault +- Если ClickHouse успешно обработал атрибут в соответствии с [заданным типом данных](../dicts/external_dicts_dict_structure.md#ext_dict_structure-attributes), то функции возвращают значение атрибута, соответствующее ключу `id_expr`. -`dictGetT('dict_name', 'attr_name', id, default)` +- Если запрошенного `id_expr` в словаре нет, то: + - `dictGet` возвращает содержимое элемента ``, указанного для атрибута в конфигурации словаря. + - `dictGetOrDefault` возвращает атрибут `default_value_expr`. -Аналогично функциям `dictGetT`, но значение по умолчанию берётся из последнего аргумента функции. +Если значение атрибута не удалось обработать или оно не соответствует типу данных атрибута, то ClickHouse генерирует исключение. -## dictIsIn -`dictIsIn('dict_name', child_id, ancestor_id)` -- для иерархического словаря dict_name - узнать, находится ли ключ child_id внутри ancestor_id (или совпадает с ancestor_id). Возвращает UInt8. +**Пример** -## dictGetHierarchy -`dictGetHierarchy('dict_name', id)` -- для иерархического словаря dict_name - вернуть массив ключей словаря, начиная с id и продолжая цепочкой родительских элементов. Возвращает Array(UInt64). +Создадим текстовый файл `ext-dict-text.csv` со следующим содержимым: + +```text +1,1 +2,2 +``` + +Первый столбец — `id`, второй столбец — `c1`. + +Настройка внешнего словаря: + +```xml + + + ext-dict-test + + + /path-to/ext-dict-test.csv + CSV + + + + + + + + id + + + c1 + UInt32 + + + + 0 + + +``` + +Выполним запрос: + +```sql +SELECT + dictGetOrDefault('ext-dict-test', 'c1', number + 1, toUInt32(number * 10)) AS val, + toTypeName(val) AS type +FROM system.numbers +LIMIT 3 +``` + +```text +┌─val─┬─type───┐ +│ 1 │ UInt32 │ +│ 2 │ UInt32 │ +│ 20 │ UInt32 │ +└─────┴────────┘ +``` + +**Смотрите также** + +- [Внешние словари](../dicts/external_dicts.md) ## dictHas -`dictHas('dict_name', id)` -- проверить наличие ключа в словаре. Возвращает значение типа UInt8, равное 0, если ключа нет и 1, если ключ есть. + +Проверяет, присутствует ли ключ в словаре. + +``` +dictHas('dict_name', id) +``` + +**Параметры** + +- `dict_name` — имя словаря. [Строковый литерал](../syntax.md#syntax-string-literal). +- `id_expr` — значение ключа словаря. [Выражение](../syntax.md#syntax-expressions), возвращающее значение типа [UInt64](../../data_types/int_uint.md). + +**Возвращаемое значение** + +- 0, если ключа нет. +- 1, если ключ есть. + +Тип — `UInt8`. + +## dictGetHierarchy + +Для иерархического словаря возвращает массив ключей словаря, начиная с переданного `id_expr` и продолжая цепочкой родительских элементов. + +``` +dictGetHierarchy('dict_name', id) +``` + +**Параметры** + +- `dict_name` — имя словаря. [Строковый литерал](../syntax.md#syntax-string-literal). +- `id_expr` — значение ключа словаря. [Выражение](../syntax.md#syntax-expressions), возвращающее значение типа [UInt64](../../data_types/int_uint.md). + +**Возвращаемое значение** + +Иерархия ключей словаря. + +Тип — Array(UInt64). + +## dictIsIn + +Проверяет предка ключа в иерархическом словаре. + +`dictIsIn ('dict_name', child_id_expr, ancestor_id_expr)` + +**Параметры** + +- `dict_name` — имя словаря. [Строковый литерал](../syntax.md#syntax-string-literal). +- `child_id_expr` — ключ для проверки. [Выражение](../syntax.md#syntax-expressions), возвращающее значение типа [UInt64](../../data_types/int_uint.md). +- `ancestor_id_expr` — предполагаемый предок ключа `child_id_expr`. [выражение](../syntax.md#syntax-expressions), возвращающее значение типа [UInt64](../../data_types/int_uint.md). + +**Возвращаемое значение** + +- 0, если `child_id_expr` — не дочерний элемент `ancestor_id_expr`. +- 1, если `child_id_expr` — дочерний элемент `ancestor_id_expr` или если `child_id_expr` и есть `ancestor_id_expr`. + +Тип — `UInt8`. + +## Прочие функции {#ext_dict_functions-other} + +ClickHouse поддерживает специализированные функции, которые приводят значения атрибутов справочника к определенному типу данных независимо от конфигурации справочника. + +Функции: + +- `dictGetInt8`, `dictGetInt16`, `dictGetInt32`, `dictGetInt64` +- `dictGetUInt8`, `dictGetUInt16`, `dictGetUInt32`, `dictGetUInt64` +- `dictGetFloat32`, `dictGetFloat64` +- `dictGetDate` +- `dictGetDateTime` +- `dictGetUUID` +- `dictGetString` + +Все эти функции можно использовать с модификатором `OrDefault`. Например, `dictGetDateOrDefault`. + +Синтаксис: + +``` +dictGet[Type]('dict_name', 'attr_name', id_expr) +dictGet[Type]OrDefault('dict_name', 'attr_name', id_expr, default_value_expr) +``` + +**Параметры** + +- `dict_name` — имя словаря. [Строковый литерал](../syntax.md#syntax-string-literal). +- `attr_name` — имя столбца словаря. [Строковый литерал](../syntax.md#syntax-string-literal). +- `id_expr` — значение ключа словаря. [Выражение](../syntax.md#syntax-expressions), возвращающее значение типа [UInt64](../../data_types/int_uint.md). +- `default_value_expr` — значение, возвращаемое в том случае, когда словарь не содержит строки с заданным ключем `id_expr`. [Выражение](../syntax.md#syntax-expressions) возвращающее значение с типом данных, сконфигурированным для атрибута `attr_name`. + +**Возвращаемое значение** + +- Если ClickHouse успешно обработал атрибут в соответствии с [заданным типом данных](../dicts/external_dicts_dict_structure.md#ext_dict_structure-attributes), то функции возвращают значение атрибута, соответствующее ключу `id_expr`. + +- Если запрошенного `id_expr` нет в словаре, то: + - `dictGet[Type]` возвращает содержимое элемента ``, указанного для атрибута в конфигурации словаря. + - `dictGet[Type]OrDefault` возвращает аргумент `default_value_expr`. + +Если значение атрибута не удалось обработать или оно не соответствует типу данных атрибута, то ClickHouse генерирует исключение. [Оригинальная статья](https://clickhouse.yandex/docs/ru/query_language/functions/ext_dict_functions/) + diff --git a/docs/ru/query_language/syntax.md b/docs/ru/query_language/syntax.md index e1eca7e3ff7..f48c8d236e4 100644 --- a/docs/ru/query_language/syntax.md +++ b/docs/ru/query_language/syntax.md @@ -65,7 +65,7 @@ INSERT INTO t VALUES (1, 'Hello, world'), (2, 'abc'), (3, 'def') Примеры: `1`, `18446744073709551615`, `0xDEADBEEF`, `01`, `0.1`, `1e100`, `-1e-100`, `inf`, `nan`. -### Строковые +### Строковые {#syntax-string-literal} Поддерживаются только строковые литералы в одинарных кавычках. Символы внутри могут быть экранированы с помощью обратного слеша. Следующие escape-последовательности имеют соответствующее специальное значение: `\b`, `\f`, `\r`, `\n`, `\t`, `\0`, `\a`, `\v`, `\xHH`. Во всех остальных случаях, последовательности вида `\c`, где `c` — любой символ, преобразуется в `c` . Таким образом, могут быть использованы последовательности `\'` и `\\`. Значение будет иметь тип [String](../data_types/string.md). From bb40d4729c234b9a3b7eb62bcf060a320a5e84ec Mon Sep 17 00:00:00 2001 From: Maxim Fridental Date: Fri, 12 Jul 2019 13:17:38 +0200 Subject: [PATCH 0166/1165] Implement COLUMNS clause --- dbms/src/Interpreters/AsteriskSemantic.h | 3 ++ .../PredicateExpressionsOptimizer.cpp | 19 +++++-- .../TranslateQualifiedNamesVisitor.cpp | 20 +++++++- dbms/src/Parsers/ASTColumnsClause.cpp | 22 ++++++++ dbms/src/Parsers/ASTColumnsClause.h | 51 +++++++++++++++++++ dbms/src/Parsers/ExpressionElementParsers.cpp | 21 ++++++++ dbms/src/Parsers/ExpressionElementParsers.h | 10 +++- .../00969_columns_clause.reference | 2 + .../0_stateless/00969_columns_clause.sql | 3 ++ 9 files changed, 145 insertions(+), 6 deletions(-) create mode 100644 dbms/src/Parsers/ASTColumnsClause.cpp create mode 100644 dbms/src/Parsers/ASTColumnsClause.h create mode 100644 dbms/tests/queries/0_stateless/00969_columns_clause.reference create mode 100644 dbms/tests/queries/0_stateless/00969_columns_clause.sql diff --git a/dbms/src/Interpreters/AsteriskSemantic.h b/dbms/src/Interpreters/AsteriskSemantic.h index c0928a42691..1dcfd344a72 100644 --- a/dbms/src/Interpreters/AsteriskSemantic.h +++ b/dbms/src/Interpreters/AsteriskSemantic.h @@ -4,6 +4,7 @@ #include #include +#include "../Parsers/ASTColumnsClause.h" namespace DB { @@ -24,9 +25,11 @@ struct AsteriskSemantic static void setAliases(ASTAsterisk & node, const RevertedAliasesPtr & aliases) { node.semantic = makeSemantic(aliases); } static void setAliases(ASTQualifiedAsterisk & node, const RevertedAliasesPtr & aliases) { node.semantic = makeSemantic(aliases); } + static void setAliases(ASTColumnsClause & node, const RevertedAliasesPtr & aliases) { node.semantic = makeSemantic(aliases); } static RevertedAliasesPtr getAliases(const ASTAsterisk & node) { return node.semantic ? node.semantic->aliases : nullptr; } static RevertedAliasesPtr getAliases(const ASTQualifiedAsterisk & node) { return node.semantic ? node.semantic->aliases : nullptr; } + static RevertedAliasesPtr getAliases(const ASTColumnsClause & node) { return node.semantic ? node.semantic->aliases : nullptr; } private: static std::shared_ptr makeSemantic(const RevertedAliasesPtr & aliases) diff --git a/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp b/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp index 3d2f465bde8..1e92f7b348b 100644 --- a/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp +++ b/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp @@ -24,6 +24,7 @@ #include #include #include +#include "../Parsers/ASTColumnsClause.h" namespace DB { @@ -412,7 +413,7 @@ ASTs PredicateExpressionsOptimizer::getSelectQueryProjectionColumns(ASTPtr & ast for (const auto & projection_column : select_query->select()->children) { - if (projection_column->as() || projection_column->as()) + if (projection_column->as() || projection_column->as() || projection_column->as()) { ASTs evaluated_columns = evaluateAsterisk(select_query, projection_column); @@ -483,8 +484,20 @@ ASTs PredicateExpressionsOptimizer::evaluateAsterisk(ASTSelectQuery * select_que throw Exception("Logical error: unexpected table expression", ErrorCodes::LOGICAL_ERROR); const auto block = storage->getSampleBlock(); - for (size_t idx = 0; idx < block.columns(); idx++) - projection_columns.emplace_back(std::make_shared(block.getByPosition(idx).name)); + if (const auto * asterisk_pattern = asterisk->as()) + { + for (size_t idx = 0; idx < block.columns(); idx++) + { + auto & col = block.getByPosition(idx); + if (asterisk_pattern->isColumnMatching(col.name)) + projection_columns.emplace_back(std::make_shared(col.name)); + } + } + else + { + for (size_t idx = 0; idx < block.columns(); idx++) + projection_columns.emplace_back(std::make_shared(block.getByPosition(idx).name)); + } } } return projection_columns; diff --git a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp index e2d38422ef1..a418708f1dd 100644 --- a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp +++ b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp @@ -17,6 +17,7 @@ #include #include #include +#include "../Parsers/ASTColumnsClause.h" namespace DB @@ -166,7 +167,7 @@ void TranslateQualifiedNamesMatcher::visit(ASTExpressionList & node, const ASTPt bool has_asterisk = false; for (const auto & child : node.children) { - if (child->as()) + if (child->as() || child->as()) { if (tables_with_columns.empty()) throw Exception("An asterisk cannot be replaced with empty columns.", ErrorCodes::LOGICAL_ERROR); @@ -207,6 +208,23 @@ void TranslateQualifiedNamesMatcher::visit(ASTExpressionList & node, const ASTPt first_table = false; } } + else if (const auto * asterisk_pattern = child->as()) + { + bool first_table = true; + for (const auto & [table, table_columns] : tables_with_columns) + { + for (const auto & column_name : table_columns) + { + if (asterisk_pattern->isColumnMatching(column_name) && (first_table || !data.join_using_columns.count(column_name))) + { + String table_name = table.getQualifiedNamePrefix(false); + addIdentifier(node.children, table_name, column_name, AsteriskSemantic::getAliases(*asterisk_pattern)); + } + } + + first_table = false; + } + } else if (const auto * qualified_asterisk = child->as()) { DatabaseAndTableWithAlias ident_db_and_name(qualified_asterisk->children[0]); diff --git a/dbms/src/Parsers/ASTColumnsClause.cpp b/dbms/src/Parsers/ASTColumnsClause.cpp new file mode 100644 index 00000000000..2f2dca471b7 --- /dev/null +++ b/dbms/src/Parsers/ASTColumnsClause.cpp @@ -0,0 +1,22 @@ +#include +#include +#include "ASTColumnsClause.h" + +namespace DB +{ + +ASTPtr ASTColumnsClause::clone() const +{ + auto clone = std::make_shared(*this); + clone->cloneChildren(); + return clone; +} + +void ASTColumnsClause::appendColumnName(WriteBuffer & ostr) const { writeString(originalPattern, ostr); } + +void ASTColumnsClause::formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const +{ + settings.ostr << (settings.hilite ? hilite_keyword : "") << "COLUMNS" << (settings.hilite ? hilite_none : "") << " '" << originalPattern << "'"; +} + +} diff --git a/dbms/src/Parsers/ASTColumnsClause.h b/dbms/src/Parsers/ASTColumnsClause.h new file mode 100644 index 00000000000..67f400b305c --- /dev/null +++ b/dbms/src/Parsers/ASTColumnsClause.h @@ -0,0 +1,51 @@ +#pragma once +#include +#include + +#include +#include + +namespace DB +{ + +namespace ErrorCodes +{ + extern const int CANNOT_COMPILE_REGEXP; +} + +struct AsteriskSemantic; +struct AsteriskSemanticImpl; + + +class ASTColumnsClause : public IAST +{ +public: + + String getID(char) const override { return "ColumnsClause"; } + ASTPtr clone() const override; + void appendColumnName(WriteBuffer & ostr) const override; + void setPattern(String pattern) + { + originalPattern = pattern; + columnMatcher = std::make_shared(pattern, RE2::Quiet); + if (!columnMatcher->ok()) + throw DB::Exception("COLUMNS pattern " + originalPattern + " cannot be compiled: " + columnMatcher->error(), DB::ErrorCodes::CANNOT_COMPILE_REGEXP); + } + bool isColumnMatching(String columnName) const + { + return RE2::FullMatch(columnName, *columnMatcher); + } + +protected: + void formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const override; + +private: + std::shared_ptr columnMatcher; + String originalPattern; + std::shared_ptr semantic; /// pimpl + + friend struct AsteriskSemantic; +}; + + +} diff --git a/dbms/src/Parsers/ExpressionElementParsers.cpp b/dbms/src/Parsers/ExpressionElementParsers.cpp index 9c0071c64e8..4669c37edae 100644 --- a/dbms/src/Parsers/ExpressionElementParsers.cpp +++ b/dbms/src/Parsers/ExpressionElementParsers.cpp @@ -29,6 +29,7 @@ #include #include +#include "ASTColumnsClause.h" namespace DB @@ -1168,6 +1169,25 @@ bool ParserAlias::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) } +bool ParserColumnsClause::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) +{ + ParserKeyword columns("COLUMNS"); + ParserStringLiteral regex; + + if (!columns.ignore(pos, expected)) + return false; + + ASTPtr regex_node; + if (!regex.parse(pos, regex_node, expected)) + return false; + + auto res = std::make_shared(); + res->setPattern(regex_node->as().value.get()); + res->children.push_back(regex_node); + node = std::move(res); + return true; +} + bool ParserAsterisk::parseImpl(Pos & pos, ASTPtr & node, Expected &) { if (pos->type == TokenType::Asterisk) @@ -1265,6 +1285,7 @@ bool ParserExpressionElement::parseImpl(Pos & pos, ASTPtr & node, Expected & exp || ParserFunction().parse(pos, node, expected) || ParserQualifiedAsterisk().parse(pos, node, expected) || ParserAsterisk().parse(pos, node, expected) + || ParserColumnsClause().parse(pos, node, expected) || ParserCompoundIdentifier().parse(pos, node, expected) || ParserSubstitution().parse(pos, node, expected); } diff --git a/dbms/src/Parsers/ExpressionElementParsers.h b/dbms/src/Parsers/ExpressionElementParsers.h index b4fe77e8bb3..d3a9f97f0b8 100644 --- a/dbms/src/Parsers/ExpressionElementParsers.h +++ b/dbms/src/Parsers/ExpressionElementParsers.h @@ -56,7 +56,6 @@ protected: bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected); }; - /// Just * class ParserAsterisk : public IParserBase { @@ -65,7 +64,6 @@ protected: bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected); }; - /** Something like t.* or db.table.* */ class ParserQualifiedAsterisk : public IParserBase @@ -75,6 +73,14 @@ protected: bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected); }; +/** COLUMNS '' + */ +class ParserColumnsClause : public IParserBase +{ +protected: + const char * getName() const { return "COLUMNS clause"; } + bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected); +}; /** A function, for example, f(x, y + 1, g(z)). * Or an aggregate function: sum(x + f(y)), corr(x, y). The syntax is the same as the usual function. diff --git a/dbms/tests/queries/0_stateless/00969_columns_clause.reference b/dbms/tests/queries/0_stateless/00969_columns_clause.reference new file mode 100644 index 00000000000..fcfd7d0919e --- /dev/null +++ b/dbms/tests/queries/0_stateless/00969_columns_clause.reference @@ -0,0 +1,2 @@ +100 10 +120 8 diff --git a/dbms/tests/queries/0_stateless/00969_columns_clause.sql b/dbms/tests/queries/0_stateless/00969_columns_clause.sql new file mode 100644 index 00000000000..63d041984c1 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00969_columns_clause.sql @@ -0,0 +1,3 @@ +CREATE TABLE IF NOT EXISTS ColumnsClauseTest (product_price Int64, product_weight Int16, amount Int64) Engine=TinyLog; +INSERT INTO ColumnsClauseTest VALUES (100, 10, 324), (120, 8, 23); +SELECT COLUMNS 'product.*' from ColumnsClauseTest ORDER BY product_price; From a6bd5bccff99f6cf6c37ddad50427c7927bb3fc4 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Sun, 14 Jul 2019 11:22:55 +0300 Subject: [PATCH 0167/1165] tiny fix --- dbms/programs/server/MySQLHandler.cpp | 13 +++++++------ dbms/src/Core/MySQLProtocol.h | 2 +- dbms/src/IO/WriteHelpers.h | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/dbms/programs/server/MySQLHandler.cpp b/dbms/programs/server/MySQLHandler.cpp index 178778c0227..4e91b8de106 100644 --- a/dbms/programs/server/MySQLHandler.cpp +++ b/dbms/programs/server/MySQLHandler.cpp @@ -360,18 +360,19 @@ void MySQLHandler::comQuery(Vector && payload) }; // MariaDB client starts session with that query - String select_version = "select @@version_comment limit 1"; + const String select_version = "\x03select @@version_comment limit 1"; // Translate query from MySQL to ClickHouse. // This is a temporary workaround until ClickHouse supports the syntax "@@var_name". - if (payload.size() > 1 && String(payload.data() + 1, payload.data() - 1) == select_version) + if (payload == Vector(select_version.data(), select_version.data() + select_version.size())) { - payload.clear(); - WriteBufferFromVector buffer(payload); - writeString(select_version, buffer); + const char select_empty[] = "\x03select ''"; + payload = Vector(select_empty, select_empty + strlen(select_empty)); } - ReadBufferFromMemory buf(payload.data() + 1, payload.size() - 1); + ReadBufferFromMemory buf(payload.data(), payload.size()); + buf.ignore(); // Command byte + executeQuery(buf, *out, true, connection_context, set_content_type, nullptr); if (!with_output) packet_sender->sendPacket(OK_Packet(0x00, client_capability_flags, 0, 0, 0), true); diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index a4d03908bad..c415609d682 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -245,6 +245,7 @@ public: Vector payload; WriteBufferFromVector buffer(payload); packet.writePayload(buffer); + buffer.finish(); size_t pos = 0; do { @@ -360,7 +361,6 @@ public: void readPayload(Vector && payload) override { - std::cerr << PacketSender::packetToText(payload) << std::endl; tracker.alloc(payload.size()); ReadBufferFromMemory buffer(payload.data(), payload.size()); diff --git a/dbms/src/IO/WriteHelpers.h b/dbms/src/IO/WriteHelpers.h index 3945ed3965c..2f2746b5564 100644 --- a/dbms/src/IO/WriteHelpers.h +++ b/dbms/src/IO/WriteHelpers.h @@ -54,7 +54,7 @@ inline void writeChar(char c, size_t n, WriteBuffer & buf) size_t count = std::min(n, buf.available()); memset(buf.position(), c, count); n -= count; - buf.position() += buf.available(); + buf.position() += count; } } From 0ed77453d35c2f9dae0c780dec2362b12b76e945 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Mon, 15 Jul 2019 01:13:56 +0300 Subject: [PATCH 0168/1165] reading packets in parts --- dbms/programs/server/MySQLHandler.cpp | 56 +++----- dbms/programs/server/MySQLHandler.h | 6 +- dbms/src/Core/MySQLProtocol.h | 194 +++++++++++++------------- dbms/src/IO/ReadHelpers.cpp | 1 - 4 files changed, 125 insertions(+), 132 deletions(-) diff --git a/dbms/programs/server/MySQLHandler.cpp b/dbms/programs/server/MySQLHandler.cpp index 4e91b8de106..5edebb04ac0 100644 --- a/dbms/programs/server/MySQLHandler.cpp +++ b/dbms/programs/server/MySQLHandler.cpp @@ -105,9 +105,12 @@ void MySQLHandler::run() while (true) { packet_sender->resetSequenceId(); - Vector payload = packet_sender->receivePacketPayload(); - int command = payload[0]; - LOG_DEBUG(log, "Received command: " << std::to_string(command) << ". Connection id: " << connection_id << "."); + PacketPayloadReadBuffer payload = packet_sender->getPayload(); + + unsigned char command = 0; + payload.readStrict(reinterpret_cast(command)); + + LOG_DEBUG(log, "Received command: " << static_cast(command) << ". Connection id: " << connection_id << "."); try { switch (command) @@ -115,13 +118,13 @@ void MySQLHandler::run() case COM_QUIT: return; case COM_INIT_DB: - comInitDB(std::move(payload)); + comInitDB(payload); break; case COM_QUERY: - comQuery(std::move(payload)); + comQuery(payload); break; case COM_FIELD_LIST: - comFieldList(std::move(payload)); + comFieldList(payload); break; case COM_PING: comPing(); @@ -181,10 +184,9 @@ void MySQLHandler::finishHandshake(MySQLProtocol::HandshakeResponse & packet) { read_bytes(packet_size); /// Reading rest SSLRequest. SSLRequest ssl_request; - Vector payload; - WriteBufferFromVector buffer(payload); - buffer.write(buf + PACKET_HEADER_SIZE, pos - PACKET_HEADER_SIZE); - ssl_request.readPayload(std::move(payload)); + ReadBufferFromMemory payload(buf, pos); + payload.ignore(PACKET_HEADER_SIZE); + ssl_request.readPayload(payload); connection_context.client_capabilities = ssl_request.capability_flags; connection_context.max_packet_size = ssl_request.max_packet_size ? ssl_request.max_packet_size : MAX_PACKET_LENGTH; secure_connection = true; @@ -200,12 +202,12 @@ void MySQLHandler::finishHandshake(MySQLProtocol::HandshakeResponse & packet) { /// Reading rest of HandshakeResponse. packet_size = PACKET_HEADER_SIZE + payload_size; - Vector packet_data; - WriteBufferFromVector buf_for_handshake_response(packet_data); + WriteBufferFromOwnString buf_for_handshake_response; buf_for_handshake_response.write(buf, pos); copyData(*packet_sender->in, buf_for_handshake_response, packet_size - pos); - Vector payload(Vector::const_iterator(packet_data.data() + PACKET_HEADER_SIZE), const_cast(packet_data).end()); - packet.readPayload(std::move(payload)); + ReadBufferFromString payload(buf_for_handshake_response.str()); + payload.ignore(PACKET_HEADER_SIZE); + packet.readPayload(payload); packet_sender->sequence_id++; } } @@ -323,18 +325,19 @@ void MySQLHandler::authenticate(const HandshakeResponse & handshake_response, co } } -void MySQLHandler::comInitDB(Vector && payload) +void MySQLHandler::comInitDB(ReadBuffer & payload) { - String database(payload.data() + 1, payload.size() - 1); + String database; + readStringUntilEOF(database, payload); LOG_DEBUG(log, "Setting current database to " << database); connection_context.setCurrentDatabase(database); packet_sender->sendPacket(OK_Packet(0, client_capability_flags, 0, 0, 1), true); } -void MySQLHandler::comFieldList(Vector && payload) +void MySQLHandler::comFieldList(ReadBuffer & payload) { ComFieldList packet; - packet.readPayload(std::move(payload)); + packet.readPayload(payload); String database = connection_context.getCurrentDatabase(); StoragePtr tablePtr = connection_context.getTable(database, packet.table); for (const NameAndTypePair & column: tablePtr->getColumns().getAll()) @@ -352,28 +355,15 @@ void MySQLHandler::comPing() packet_sender->sendPacket(OK_Packet(0x0, client_capability_flags, 0, 0, 0), true); } -void MySQLHandler::comQuery(Vector && payload) +void MySQLHandler::comQuery(ReadBuffer & payload) { bool with_output = false; std::function set_content_type = [&with_output](const String &) -> void { with_output = true; }; - // MariaDB client starts session with that query - const String select_version = "\x03select @@version_comment limit 1"; + executeQuery(payload, *out, true, connection_context, set_content_type, nullptr); - // Translate query from MySQL to ClickHouse. - // This is a temporary workaround until ClickHouse supports the syntax "@@var_name". - if (payload == Vector(select_version.data(), select_version.data() + select_version.size())) - { - const char select_empty[] = "\x03select ''"; - payload = Vector(select_empty, select_empty + strlen(select_empty)); - } - - ReadBufferFromMemory buf(payload.data(), payload.size()); - buf.ignore(); // Command byte - - executeQuery(buf, *out, true, connection_context, set_content_type, nullptr); if (!with_output) packet_sender->sendPacket(OK_Packet(0x00, client_capability_flags, 0, 0, 0), true); } diff --git a/dbms/programs/server/MySQLHandler.h b/dbms/programs/server/MySQLHandler.h index f2161c7bd60..2bb3f07ccfa 100644 --- a/dbms/programs/server/MySQLHandler.h +++ b/dbms/programs/server/MySQLHandler.h @@ -23,13 +23,13 @@ private: /// Enables SSL, if client requested. void finishHandshake(MySQLProtocol::HandshakeResponse &); - void comQuery(MySQLProtocol::Vector && payload); + void comQuery(ReadBuffer & payload); - void comFieldList(MySQLProtocol::Vector && payload); + void comFieldList(ReadBuffer & payload); void comPing(); - void comInitDB(MySQLProtocol::Vector && payload); + void comInitDB(ReadBuffer & payload); static String generateScramble(); diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index c415609d682..57288664309 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -121,24 +121,6 @@ enum ColumnType }; -// For tracking memory of packets with String fields. -class PacketMemoryTracker -{ - Int64 allocated = 0; -public: - void alloc(Int64 size) - { - CurrentMemoryTracker::alloc(allocated); - allocated = size; - } - - ~PacketMemoryTracker() - { - CurrentMemoryTracker::free(allocated); - } -}; - - using Vector = PODArray; @@ -163,12 +145,79 @@ class ReadPacket public: ReadPacket() = default; ReadPacket(ReadPacket &&) = default; - virtual void readPayload(Vector && payload) = 0; + virtual void readPayload(ReadBuffer & buf) = 0; virtual ~ReadPacket() = default; }; +class PacketPayloadReadBuffer : public ReadBuffer +{ +public: + PacketPayloadReadBuffer(ReadBuffer & in, size_t & sequence_id): ReadBuffer(in.position(), 0), in(in), sequence_id(sequence_id) { + nextImpl(); + } + +private: + ReadBuffer & in; + size_t & sequence_id; + const size_t max_packet_size = MAX_PACKET_LENGTH; + + // Size of packet which is being read now. + size_t payload_length = 0; + + // Offset in packet payload. + size_t offset = 0; +protected: + bool nextImpl() override + { + if (payload_length == 0 || (payload_length == max_packet_size && offset == payload_length)) + { + working_buffer.resize(0); + offset = 0; + payload_length = 0; + in.readStrict(reinterpret_cast(&payload_length), 3); + + if (payload_length > max_packet_size) + { + std::ostringstream tmp; + tmp << "Received packet with payload larger than max_packet_size: " << payload_length; + throw ProtocolError(tmp.str(), ErrorCodes::UNKNOWN_PACKET_FROM_CLIENT); + } + else if (payload_length == 0) + { + return false; + } + + size_t packet_sequence_id = 0; + in.read(reinterpret_cast(packet_sequence_id)); + if (packet_sequence_id != sequence_id) + { + std::ostringstream tmp; + tmp << "Received packet with wrong sequence-id: " << packet_sequence_id << ". Expected: " << sequence_id << '.'; + throw ProtocolError(tmp.str(), ErrorCodes::UNKNOWN_PACKET_FROM_CLIENT); + } + sequence_id++; + } + else if (offset == payload_length) + { + return false; + } + + in.nextIfAtEnd(); + working_buffer = ReadBuffer::Buffer(in.position(), in.buffer().end()); + size_t count = std::min(in.available(), payload_length - offset); + working_buffer.resize(count); + in.ignore(count); + + offset += count; + pos = working_buffer.begin(); + + return true; + } +}; + + /* Writes and reads packets, keeping sequence-id. * Throws ProtocolError, if packet with incorrect sequence-id was received. */ @@ -196,46 +245,15 @@ public: { } - Vector receivePacketPayload() + PacketPayloadReadBuffer getPayload() { - Vector result; - WriteBufferFromVector buf(result); - - size_t payload_length = 0; - size_t packet_sequence_id = 0; - - // packets which are larger than or equal to 16MB are splitted - do - { - in->readStrict(reinterpret_cast(&payload_length), 3); - - if (payload_length > max_packet_size) - { - std::ostringstream tmp; - tmp << "Received packet with payload larger than max_packet_size: " << payload_length; - throw ProtocolError(tmp.str(), ErrorCodes::UNKNOWN_PACKET_FROM_CLIENT); - } - - in->readStrict(reinterpret_cast(&packet_sequence_id), 1); - - if (packet_sequence_id != sequence_id) - { - std::ostringstream tmp; - tmp << "Received packet with wrong sequence-id: " << packet_sequence_id << ". Expected: " << sequence_id << '.'; - throw ProtocolError(tmp.str(), ErrorCodes::UNKNOWN_PACKET_FROM_CLIENT); - } - sequence_id++; - - copyData(*in, static_cast(buf), payload_length); - } while (payload_length == max_packet_size); - - return result; + return PacketPayloadReadBuffer(*in, sequence_id); } void receivePacket(ReadPacket & packet) { - auto payload = receivePacketPayload(); - packet.readPayload(std::move(payload)); + auto payload = getPayload(); + packet.readPayload(payload); } template @@ -336,12 +354,11 @@ public: uint32_t max_packet_size; uint8_t character_set; - void readPayload(Vector && s) override + void readPayload(ReadBuffer & buf) override { - ReadBufferFromMemory buffer(s.data(), s.size()); - buffer.readStrict(reinterpret_cast(&capability_flags), 4); - buffer.readStrict(reinterpret_cast(&max_packet_size), 4); - buffer.readStrict(reinterpret_cast(&character_set), 1); + buf.readStrict(reinterpret_cast(&capability_flags), 4); + buf.readStrict(reinterpret_cast(&max_packet_size), 4); + buf.readStrict(reinterpret_cast(&character_set), 1); } }; @@ -355,48 +372,44 @@ public: String auth_response; String database; String auth_plugin_name; - PacketMemoryTracker tracker; HandshakeResponse() = default; - void readPayload(Vector && payload) override + void readPayload(ReadBuffer & payload) override { - tracker.alloc(payload.size()); - ReadBufferFromMemory buffer(payload.data(), payload.size()); + payload.readStrict(reinterpret_cast(&capability_flags), 4); + payload.readStrict(reinterpret_cast(&max_packet_size), 4); + payload.readStrict(reinterpret_cast(&character_set), 1); + payload.ignore(23); - buffer.readStrict(reinterpret_cast(&capability_flags), 4); - buffer.readStrict(reinterpret_cast(&max_packet_size), 4); - buffer.readStrict(reinterpret_cast(&character_set), 1); - buffer.ignore(23); - - readNullTerminated(username, buffer); + readNullTerminated(username, payload); if (capability_flags & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA) { - auto len = readLengthEncodedNumber(buffer); + auto len = readLengthEncodedNumber(payload); auth_response.resize(len); - buffer.readStrict(auth_response.data(), len); + payload.readStrict(auth_response.data(), len); } else if (capability_flags & CLIENT_SECURE_CONNECTION) { char len; - buffer.readStrict(len); + payload.readStrict(len); auth_response.resize(static_cast(len)); - buffer.readStrict(auth_response.data(), len); + payload.readStrict(auth_response.data(), len); } else { - readNullTerminated(auth_response, buffer); + readNullTerminated(auth_response, payload); } if (capability_flags & CLIENT_CONNECT_WITH_DB) { - readNullTerminated(database, buffer); + readNullTerminated(database, payload); } if (capability_flags & CLIENT_PLUGIN_AUTH) { - readNullTerminated(auth_plugin_name, buffer); + readNullTerminated(auth_plugin_name, payload); } } }; @@ -424,12 +437,10 @@ class AuthSwitchResponse : public ReadPacket { public: String value; - PacketMemoryTracker tracker; - void readPayload(Vector && payload) override + void readPayload(ReadBuffer & payload) override { - tracker.alloc(payload.size()); - value.assign(payload.data(), payload.size()); + readStringUntilEOF(value, payload); } }; @@ -450,16 +461,11 @@ public: class NullTerminatedString : public ReadPacket { public: - Vector value; + String value; - void readPayload(Vector && payload) override + void readPayload(ReadBuffer & payload) override { - if (payload.empty() || payload.back() != 0) - { - throw ProtocolError("String is not null terminated.", ErrorCodes::UNKNOWN_PACKET_FROM_CLIENT); - } - value = std::move(payload); - value.pop_back(); + readNullTerminated(value, payload); } }; @@ -486,7 +492,7 @@ public: , warnings(warnings) , status_flags(status_flags) , session_state_changes(std::move(session_state_changes)) - , info(info) + , info(std::move(info)) { } @@ -627,13 +633,11 @@ class ComFieldList : public ReadPacket public: String table, field_wildcard; - void readPayload(Vector && payload) override + void readPayload(ReadBuffer & payload) override { - ReadBufferFromMemory buffer(payload.data(), payload.size()); - buffer.ignore(1); // command byte - readNullTerminated(table, buffer); - field_wildcard.assign(payload.data() + table.size() + 2); - readStringUntilEOFInto(field_wildcard, buffer); + // Command byte has been already read from payload. + readNullTerminated(table, payload); + readStringUntilEOF(field_wildcard, payload); } }; diff --git a/dbms/src/IO/ReadHelpers.cpp b/dbms/src/IO/ReadHelpers.cpp index 28001cb74d0..7c0c2301c28 100644 --- a/dbms/src/IO/ReadHelpers.cpp +++ b/dbms/src/IO/ReadHelpers.cpp @@ -202,7 +202,6 @@ void readNullTerminated(Vector & s, ReadBuffer & buf) char * next_pos = find_first_symbols<'\0'>(buf.position(), buf.buffer().end()); appendToStringOrVector(s, buf, next_pos); - buf.position() = next_pos; if (buf.hasPendingData()) From baa62f2abaab2bdda6302d247c536ce810b74f6d Mon Sep 17 00:00:00 2001 From: Yuriy Date: Mon, 15 Jul 2019 01:53:30 +0300 Subject: [PATCH 0169/1165] style check --- dbms/src/Core/MySQLProtocol.h | 16 +++++++--------- dbms/src/IO/WriteHelpers.h | 3 ++- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index 57288664309..3502356ef07 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -154,8 +154,8 @@ public: class PacketPayloadReadBuffer : public ReadBuffer { public: - PacketPayloadReadBuffer(ReadBuffer & in, size_t & sequence_id): ReadBuffer(in.position(), 0), in(in), sequence_id(sequence_id) { - nextImpl(); + PacketPayloadReadBuffer(ReadBuffer & in, size_t & sequence_id): ReadBuffer(in.position(), 0), in(in), sequence_id(sequence_id) + { } private: @@ -645,7 +645,7 @@ class LengthEncodedNumber : public WritePacket { uint64_t value; public: - LengthEncodedNumber(uint64_t value): value(value) + explicit LengthEncodedNumber(uint64_t value): value(value) { } @@ -657,20 +657,18 @@ public: class ResultsetRow : public WritePacket { - std::vector columns; + std::vector columns; public: - ResultsetRow() - { - } + ResultsetRow() = default; - void appendColumn(Vector value) + void appendColumn(String & value) { columns.emplace_back(std::move(value)); } void writePayload(WriteBuffer & buffer) const override { - for (const Vector & column : columns) + for (const String & column : columns) writeLengthEncodedString(column, buffer); } }; diff --git a/dbms/src/IO/WriteHelpers.h b/dbms/src/IO/WriteHelpers.h index 2f2746b5564..c531fafb26b 100644 --- a/dbms/src/IO/WriteHelpers.h +++ b/dbms/src/IO/WriteHelpers.h @@ -49,7 +49,8 @@ inline void writeChar(char x, WriteBuffer & buf) inline void writeChar(char c, size_t n, WriteBuffer & buf) { - while (n) { + while (n) + { buf.nextIfAtEnd(); size_t count = std::min(n, buf.available()); memset(buf.position(), c, count); From 828f4e1d2923dfdaccbdddc0870faef5d529bf82 Mon Sep 17 00:00:00 2001 From: proller Date: Mon, 15 Jul 2019 15:27:12 +0300 Subject: [PATCH 0170/1165] Fix freebsd build --- dbms/src/Common/Arena.h | 26 +++++++++++++++++++++++++- dbms/src/Common/ArenaWithFreeLists.h | 8 +++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/dbms/src/Common/Arena.h b/dbms/src/Common/Arena.h index 05154f56c19..0f04e7fc762 100644 --- a/dbms/src/Common/Arena.h +++ b/dbms/src/Common/Arena.h @@ -5,7 +5,9 @@ #include #include #include -#include +#if __has_include() +# include +#endif #include #include #include @@ -55,7 +57,9 @@ private: end = begin + size_ - pad_right; prev = prev_; +#if __has_include() ASAN_POISON_MEMORY_REGION(begin, size_); +#endif } ~Chunk() @@ -64,7 +68,9 @@ private: /// because the allocator might not have asan integration, and the /// memory would stay poisoned forever. If the allocator supports /// asan, it will correctly poison the memory by itself. +#if __has_include() ASAN_UNPOISON_MEMORY_REGION(begin, size()); +#endif Allocator::free(begin, size()); @@ -135,7 +141,11 @@ public: char * res = head->pos; head->pos += size; + +#if __has_include() ASAN_UNPOISON_MEMORY_REGION(res, size + pad_right); +#endif + return res; } @@ -152,7 +162,11 @@ public: { head->pos = static_cast(head_pos); head->pos += size; + +#if __has_include() ASAN_UNPOISON_MEMORY_REGION(res, size + pad_right); +#endif + return res; } @@ -172,7 +186,9 @@ public: void rollback(size_t size) { head->pos -= size; +#if __has_include() ASAN_POISON_MEMORY_REGION(head->pos, size + pad_right); +#endif } /** Begin or expand allocation of contiguous piece of memory without alignment. @@ -199,7 +215,9 @@ public: if (!begin) begin = res; +#if __has_include() ASAN_UNPOISON_MEMORY_REGION(res, size + pad_right); +#endif return res; } @@ -232,7 +250,9 @@ public: if (!begin) begin = res; +#if __has_include() ASAN_UNPOISON_MEMORY_REGION(res, size + pad_right); +#endif return res; } @@ -243,7 +263,9 @@ public: if (old_data) { memcpy(res, old_data, old_size); +#if __has_include() ASAN_POISON_MEMORY_REGION(old_data, old_size); +#endif } return res; } @@ -254,7 +276,9 @@ public: if (old_data) { memcpy(res, old_data, old_size); +#if __has_include() ASAN_POISON_MEMORY_REGION(old_data, old_size); +#endif } return res; } diff --git a/dbms/src/Common/ArenaWithFreeLists.h b/dbms/src/Common/ArenaWithFreeLists.h index 2f1f0ddfb0b..79cd45c0572 100644 --- a/dbms/src/Common/ArenaWithFreeLists.h +++ b/dbms/src/Common/ArenaWithFreeLists.h @@ -1,6 +1,8 @@ #pragma once -#include +#if __has_include() +# include +#endif #include #include @@ -68,8 +70,10 @@ public: /// item in the list. We poisoned the free block before putting /// it into the free list, so we have to unpoison it before /// reading anything. +#if __has_include() ASAN_UNPOISON_MEMORY_REGION(free_block_ptr, std::max(size, sizeof(Block))); +#endif const auto res = free_block_ptr->data; free_block_ptr = free_block_ptr->next; @@ -100,7 +104,9 @@ public: /// destructor, to support an underlying allocator that doesn't /// integrate with asan. We don't do that, and rely on the fact that /// our underlying allocator is Arena, which does have asan integration. +#if __has_include() ASAN_POISON_MEMORY_REGION(ptr, 1ULL << (list_idx + 1)); +#endif } /// Size of the allocated pool in bytes From b2eb9c3e57436d1737e7140848bc1e3a4e9c58c4 Mon Sep 17 00:00:00 2001 From: proller Date: Mon, 15 Jul 2019 17:16:29 +0300 Subject: [PATCH 0171/1165] Fix shared build --- CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6262d17f2d2..8d3a2b84864 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -251,7 +251,7 @@ if (USE_STATIC_LIBRARIES AND HAVE_NO_PIE) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAG_NO_PIE}") endif () -if (NOT SANITIZE) +if (NOT SANITIZE AND NOT SPLIT_SHARED_LIBRARIES) set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined") set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") endif() @@ -301,7 +301,11 @@ if (OS_LINUX AND NOT UNBUNDLED AND (GLIBC_COMPATIBILITY OR USE_INTERNAL_UNWIND_L if (USE_INTERNAL_UNWIND_LIBRARY_FOR_EXCEPTION_HANDLING) # TODO: Allow to use non-static library as well. - set (EXCEPTION_HANDLING_LIBRARY "${ClickHouse_BINARY_DIR}/contrib/libunwind-cmake/libunwind_static${${CMAKE_POSTFIX_VARIABLE}}.a") + if (USE_STATIC_LIBRARIES) + set (EXCEPTION_HANDLING_LIBRARY "${ClickHouse_BINARY_DIR}/contrib/libunwind-cmake/libunwind_static${${CMAKE_POSTFIX_VARIABLE}}.a") + else () + set (EXCEPTION_HANDLING_LIBRARY "${ClickHouse_BINARY_DIR}/contrib/libunwind-cmake/libunwind_shared${${CMAKE_POSTFIX_VARIABLE}}.so") + endif () else () set (EXCEPTION_HANDLING_LIBRARY "-lgcc_eh") endif () From 7695ff8035805e7553641112573505e303d0da26 Mon Sep 17 00:00:00 2001 From: proller Date: Mon, 15 Jul 2019 18:02:43 +0300 Subject: [PATCH 0172/1165] Fix build in gcc9 --- dbms/src/IO/ReadBufferAIO.cpp | 2 +- dbms/src/IO/WriteBufferAIO.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/IO/ReadBufferAIO.cpp b/dbms/src/IO/ReadBufferAIO.cpp index f47e04bff75..162a83b7b94 100644 --- a/dbms/src/IO/ReadBufferAIO.cpp +++ b/dbms/src/IO/ReadBufferAIO.cpp @@ -254,7 +254,7 @@ void ReadBufferAIO::prepare() /// Region of the disk from which we want to read data. const off_t region_begin = first_unread_pos_in_file; - if ((requested_byte_count > std::numeric_limits::max()) || + if ((static_cast(requested_byte_count) > std::numeric_limits::max()) || (first_unread_pos_in_file > (std::numeric_limits::max() - static_cast(requested_byte_count)))) throw Exception("An overflow occurred during file operation", ErrorCodes::LOGICAL_ERROR); diff --git a/dbms/src/IO/WriteBufferAIO.cpp b/dbms/src/IO/WriteBufferAIO.cpp index 2fe7da27809..37661473d9c 100644 --- a/dbms/src/IO/WriteBufferAIO.cpp +++ b/dbms/src/IO/WriteBufferAIO.cpp @@ -274,7 +274,7 @@ void WriteBufferAIO::prepare() /// Region of the disk in which we want to write data. const off_t region_begin = pos_in_file; - if ((flush_buffer.offset() > std::numeric_limits::max()) || + if ((static_cast(flush_buffer.offset()) > std::numeric_limits::max()) || (pos_in_file > (std::numeric_limits::max() - static_cast(flush_buffer.offset())))) throw Exception("An overflow occurred during file operation", ErrorCodes::LOGICAL_ERROR); From 9144e1f520e484fc0b3cf624d5adf8ea894a6bf0 Mon Sep 17 00:00:00 2001 From: proller Date: Mon, 15 Jul 2019 18:54:14 +0300 Subject: [PATCH 0173/1165] Fix split build --- contrib/arrow-cmake/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/arrow-cmake/CMakeLists.txt b/contrib/arrow-cmake/CMakeLists.txt index c0b87efc63e..a7b6628ea4e 100644 --- a/contrib/arrow-cmake/CMakeLists.txt +++ b/contrib/arrow-cmake/CMakeLists.txt @@ -44,6 +44,7 @@ set( thriftcpp_threads_SOURCES add_library(${THRIFT_LIBRARY} ${thriftcpp_SOURCES} ${thriftcpp_threads_SOURCES}) set_target_properties(${THRIFT_LIBRARY} PROPERTIES CXX_STANDARD 14) # REMOVE after https://github.com/apache/thrift/pull/1641 target_include_directories(${THRIFT_LIBRARY} SYSTEM PUBLIC ${ClickHouse_SOURCE_DIR}/contrib/thrift/lib/cpp/src PRIVATE ${Boost_INCLUDE_DIRS}) +target_link_libraries(${THRIFT_LIBRARY} PRIVATE Threads::Threads) From 8caf119e53b88beb3901e44a85553ddea7f6f06b Mon Sep 17 00:00:00 2001 From: proller Date: Mon, 15 Jul 2019 20:17:36 +0300 Subject: [PATCH 0174/1165] fix --- dbms/src/IO/ReadBufferAIO.cpp | 2 +- dbms/src/IO/WriteBufferAIO.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/IO/ReadBufferAIO.cpp b/dbms/src/IO/ReadBufferAIO.cpp index 162a83b7b94..f47e04bff75 100644 --- a/dbms/src/IO/ReadBufferAIO.cpp +++ b/dbms/src/IO/ReadBufferAIO.cpp @@ -254,7 +254,7 @@ void ReadBufferAIO::prepare() /// Region of the disk from which we want to read data. const off_t region_begin = first_unread_pos_in_file; - if ((static_cast(requested_byte_count) > std::numeric_limits::max()) || + if ((requested_byte_count > std::numeric_limits::max()) || (first_unread_pos_in_file > (std::numeric_limits::max() - static_cast(requested_byte_count)))) throw Exception("An overflow occurred during file operation", ErrorCodes::LOGICAL_ERROR); diff --git a/dbms/src/IO/WriteBufferAIO.cpp b/dbms/src/IO/WriteBufferAIO.cpp index 37661473d9c..2fe7da27809 100644 --- a/dbms/src/IO/WriteBufferAIO.cpp +++ b/dbms/src/IO/WriteBufferAIO.cpp @@ -274,7 +274,7 @@ void WriteBufferAIO::prepare() /// Region of the disk in which we want to write data. const off_t region_begin = pos_in_file; - if ((static_cast(flush_buffer.offset()) > std::numeric_limits::max()) || + if ((flush_buffer.offset() > std::numeric_limits::max()) || (pos_in_file > (std::numeric_limits::max() - static_cast(flush_buffer.offset())))) throw Exception("An overflow occurred during file operation", ErrorCodes::LOGICAL_ERROR); From f8d710dd8464c2af6784c399a9cc677624000bae Mon Sep 17 00:00:00 2001 From: proller Date: Mon, 15 Jul 2019 20:44:03 +0300 Subject: [PATCH 0175/1165] fix --- dbms/src/IO/ReadBufferAIO.cpp | 3 +++ dbms/src/IO/WriteBufferAIO.cpp | 3 +++ 2 files changed, 6 insertions(+) diff --git a/dbms/src/IO/ReadBufferAIO.cpp b/dbms/src/IO/ReadBufferAIO.cpp index f47e04bff75..eccebf854f0 100644 --- a/dbms/src/IO/ReadBufferAIO.cpp +++ b/dbms/src/IO/ReadBufferAIO.cpp @@ -254,9 +254,12 @@ void ReadBufferAIO::prepare() /// Region of the disk from which we want to read data. const off_t region_begin = first_unread_pos_in_file; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-compare" if ((requested_byte_count > std::numeric_limits::max()) || (first_unread_pos_in_file > (std::numeric_limits::max() - static_cast(requested_byte_count)))) throw Exception("An overflow occurred during file operation", ErrorCodes::LOGICAL_ERROR); +#pragma GCC diagnostic pop const off_t region_end = first_unread_pos_in_file + requested_byte_count; diff --git a/dbms/src/IO/WriteBufferAIO.cpp b/dbms/src/IO/WriteBufferAIO.cpp index 2fe7da27809..dcceff96d02 100644 --- a/dbms/src/IO/WriteBufferAIO.cpp +++ b/dbms/src/IO/WriteBufferAIO.cpp @@ -274,9 +274,12 @@ void WriteBufferAIO::prepare() /// Region of the disk in which we want to write data. const off_t region_begin = pos_in_file; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-compare" if ((flush_buffer.offset() > std::numeric_limits::max()) || (pos_in_file > (std::numeric_limits::max() - static_cast(flush_buffer.offset())))) throw Exception("An overflow occurred during file operation", ErrorCodes::LOGICAL_ERROR); +#pragma GCC diagnostic pop const off_t region_end = pos_in_file + flush_buffer.offset(); const size_t region_size = region_end - region_begin; From c13ea83f91f45a2b0a333cd68fac6e0e3a7b78c4 Mon Sep 17 00:00:00 2001 From: proller Date: Mon, 15 Jul 2019 21:00:40 +0300 Subject: [PATCH 0176/1165] fix --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d3a2b84864..34b5936773c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -300,7 +300,6 @@ if (OS_LINUX AND NOT UNBUNDLED AND (GLIBC_COMPATIBILITY OR USE_INTERNAL_UNWIND_L # There are two variants of C++ library: libc++ (from LLVM compiler infrastructure) and libstdc++ (from GCC). if (USE_INTERNAL_UNWIND_LIBRARY_FOR_EXCEPTION_HANDLING) - # TODO: Allow to use non-static library as well. if (USE_STATIC_LIBRARIES) set (EXCEPTION_HANDLING_LIBRARY "${ClickHouse_BINARY_DIR}/contrib/libunwind-cmake/libunwind_static${${CMAKE_POSTFIX_VARIABLE}}.a") else () From f221fb0999e6b198a34735c688d00ac8bfa5145a Mon Sep 17 00:00:00 2001 From: Yuriy Date: Mon, 15 Jul 2019 23:37:01 +0300 Subject: [PATCH 0177/1165] build fix --- dbms/src/Core/MySQLProtocol.h | 15 +++++++++++++-- dbms/src/Formats/MySQLWireBlockOutputStream.cpp | 7 ++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index 3502356ef07..3cb5d4d8da5 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -211,13 +211,24 @@ protected: in.ignore(count); offset += count; - pos = working_buffer.begin(); return true; } }; +class PacketPayloadWriteBuffer : public WriteBuffer +{ +private: + +protected: + void nextImpl() override + { + + } +}; + + /* Writes and reads packets, keeping sequence-id. * Throws ProtocolError, if packet with incorrect sequence-id was received. */ @@ -661,7 +672,7 @@ class ResultsetRow : public WritePacket public: ResultsetRow() = default; - void appendColumn(String & value) + void appendColumn(String && value) { columns.emplace_back(std::move(value)); } diff --git a/dbms/src/Formats/MySQLWireBlockOutputStream.cpp b/dbms/src/Formats/MySQLWireBlockOutputStream.cpp index f70cfc2d4d9..9ba62230071 100644 --- a/dbms/src/Formats/MySQLWireBlockOutputStream.cpp +++ b/dbms/src/Formats/MySQLWireBlockOutputStream.cpp @@ -45,12 +45,9 @@ void MySQLWireBlockOutputStream::write(const Block & block) ResultsetRow row_packet; for (const ColumnWithTypeAndName & column : block) { - Vector column_value; - WriteBufferFromVector ostr(column_value); + WriteBufferFromOwnString ostr; column.type->serializeAsText(*column.column.get(), i, ostr, format_settings); - ostr.finish(); - - row_packet.appendColumn(std::move(column_value)); + row_packet.appendColumn(std::move(ostr.str())); } packet_sender->sendPacket(row_packet); } From 4df72f18ce3825c747773c5638f7345b9e1311af Mon Sep 17 00:00:00 2001 From: Yuriy Date: Tue, 16 Jul 2019 09:39:18 +0300 Subject: [PATCH 0178/1165] writing packets in parts --- dbms/programs/server/MySQLHandler.cpp | 21 +- dbms/programs/server/MySQLHandler.h | 2 +- dbms/src/Core/MySQLProtocol.cpp | 27 +- dbms/src/Core/MySQLProtocol.h | 242 ++++++++++++++---- .../Formats/MySQLWireBlockOutputStream.cpp | 12 +- dbms/src/Interpreters/Context.h | 12 +- 6 files changed, 237 insertions(+), 79 deletions(-) diff --git a/dbms/programs/server/MySQLHandler.cpp b/dbms/programs/server/MySQLHandler.cpp index 5edebb04ac0..931cb35676b 100644 --- a/dbms/programs/server/MySQLHandler.cpp +++ b/dbms/programs/server/MySQLHandler.cpp @@ -47,13 +47,12 @@ MySQLHandler::MySQLHandler(IServer & server_, const Poco::Net::StreamSocket & so void MySQLHandler::run() { - connection_context = server.context(); connection_context.setSessionContext(connection_context); connection_context.setDefaultFormat("MySQLWire"); in = std::make_shared(socket()); out = std::make_shared(socket()); - packet_sender = std::make_shared(*in, *out, connection_context.sequence_id); + packet_sender = std::make_shared(*in, *out, connection_context.mysql.sequence_id); try { @@ -70,11 +69,11 @@ void MySQLHandler::run() HandshakeResponse handshake_response; finishHandshake(handshake_response); - connection_context.client_capabilities = handshake_response.capability_flags; + connection_context.mysql.client_capabilities = handshake_response.capability_flags; if (handshake_response.max_packet_size) - connection_context.max_packet_size = handshake_response.max_packet_size; - if (!connection_context.max_packet_size) - connection_context.max_packet_size = MAX_PACKET_LENGTH; + connection_context.mysql.max_packet_size = handshake_response.max_packet_size; + if (!connection_context.mysql.max_packet_size) + connection_context.mysql.max_packet_size = MAX_PACKET_LENGTH; LOG_DEBUG(log, "Capabilities: " << handshake_response.capability_flags << "\nmax_packet_size: " @@ -187,15 +186,15 @@ void MySQLHandler::finishHandshake(MySQLProtocol::HandshakeResponse & packet) ReadBufferFromMemory payload(buf, pos); payload.ignore(PACKET_HEADER_SIZE); ssl_request.readPayload(payload); - connection_context.client_capabilities = ssl_request.capability_flags; - connection_context.max_packet_size = ssl_request.max_packet_size ? ssl_request.max_packet_size : MAX_PACKET_LENGTH; + connection_context.mysql.client_capabilities = ssl_request.capability_flags; + connection_context.mysql.max_packet_size = ssl_request.max_packet_size ? ssl_request.max_packet_size : MAX_PACKET_LENGTH; secure_connection = true; ss = std::make_shared(SecureStreamSocket::attach(socket(), SSLManager::instance().defaultServerContext())); in = std::make_shared(*ss); out = std::make_shared(*ss); - connection_context.sequence_id = 2; - packet_sender = std::make_shared(*in, *out, connection_context.sequence_id); - packet_sender->max_packet_size = connection_context.max_packet_size; + connection_context.mysql.sequence_id = 2; + packet_sender = std::make_shared(*in, *out, connection_context.mysql.sequence_id); + packet_sender->max_packet_size = connection_context.mysql.max_packet_size; packet_sender->receivePacket(packet); /// Reading HandshakeResponse from secure socket. } else diff --git a/dbms/programs/server/MySQLHandler.h b/dbms/programs/server/MySQLHandler.h index 2bb3f07ccfa..b9ba698fb08 100644 --- a/dbms/programs/server/MySQLHandler.h +++ b/dbms/programs/server/MySQLHandler.h @@ -49,11 +49,11 @@ private: RSA & public_key; RSA & private_key; + std::shared_ptr ss; std::shared_ptr in; std::shared_ptr out; bool secure_connection = false; - std::shared_ptr ss; }; } diff --git a/dbms/src/Core/MySQLProtocol.cpp b/dbms/src/Core/MySQLProtocol.cpp index 0e2766c8f9a..1e05eaf883b 100644 --- a/dbms/src/Core/MySQLProtocol.cpp +++ b/dbms/src/Core/MySQLProtocol.cpp @@ -15,7 +15,7 @@ void PacketSender::resetSequenceId() sequence_id = 0; } -String PacketSender::packetToText(const PODArray & payload) +String PacketSender::packetToText(const String & payload) { String result; for (auto c : payload) @@ -74,4 +74,29 @@ void writeLengthEncodedNumber(uint64_t x, WriteBuffer & buffer) } } +size_t getLengthEncodedNumberSize(uint64_t x) +{ + if (x < 251) + { + return 1; + } + else if (x < (1 << 16)) + { + return 3; + } + else if (x < (1 << 24)) + { + return 4; + } + else + { + return 9; + } +} + +size_t getLengthEncodedStringSize(const String & s) +{ + return getLengthEncodedNumberSize(s.size()) + s.size(); +} + } diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index 3cb5d4d8da5..beea12a1294 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -131,15 +131,6 @@ public: }; -class WritePacket -{ -public: - virtual void writePayload(WriteBuffer & buffer) const = 0; - - virtual ~WritePacket() = default; -}; - - class ReadPacket { public: @@ -150,17 +141,21 @@ public: virtual ~ReadPacket() = default; }; - +/** Reading packets. + * Internally, it calls (if no more data) next() method of the underlying ReadBufferFromPocoSocket, and sets the working buffer to the rest part of the current packet payload. + */ class PacketPayloadReadBuffer : public ReadBuffer { public: - PacketPayloadReadBuffer(ReadBuffer & in, size_t & sequence_id): ReadBuffer(in.position(), 0), in(in), sequence_id(sequence_id) + PacketPayloadReadBuffer(ReadBuffer & in, uint8_t & sequence_id) + : ReadBuffer(in.position(), 0) // not in.buffer().begin(), because working buffer may include previous packet + , in(in) + , sequence_id(sequence_id) { } - private: ReadBuffer & in; - size_t & sequence_id; + uint8_t & sequence_id; const size_t max_packet_size = MAX_PACKET_LENGTH; // Size of packet which is being read now. @@ -168,6 +163,7 @@ private: // Offset in packet payload. size_t offset = 0; + protected: bool nextImpl() override { @@ -194,7 +190,7 @@ protected: if (packet_sequence_id != sequence_id) { std::ostringstream tmp; - tmp << "Received packet with wrong sequence-id: " << packet_sequence_id << ". Expected: " << sequence_id << '.'; + tmp << "Received packet with wrong sequence-id: " << packet_sequence_id << ". Expected: " << static_cast(sequence_id) << '.'; throw ProtocolError(tmp.str(), ErrorCodes::UNKNOWN_PACKET_FROM_CLIENT); } sequence_id++; @@ -217,31 +213,105 @@ protected: }; +/** Writing packets. + * https://dev.mysql.com/doc/internals/en/mysql-packet.html + */ class PacketPayloadWriteBuffer : public WriteBuffer { -private: +public: + PacketPayloadWriteBuffer(WriteBuffer & out, size_t payload_length, uint8_t & sequence_id) + : WriteBuffer(out.position(), 0) + , out(out) + , sequence_id(sequence_id) + , total_left(payload_length) + { + startPacket(); + } + void checkPayloadSize() + { + if (bytes_written + offset() < payload_length) + { + std::stringstream ss; + ss << "Incomplete payload. Written " << bytes << " bytes, expected " << payload_length << " bytes."; + throw Exception(ss.str(), 0); + + } + } + + ~PacketPayloadWriteBuffer() override { next(); } +private: + WriteBuffer & out; + uint8_t & sequence_id; + + size_t total_left = 0; + size_t payload_length = 0; + size_t bytes_written = 0; + + void startPacket() + { + payload_length = std::min(total_left, MAX_PACKET_LENGTH); + bytes_written = 0; + total_left -= payload_length; + + out.write(reinterpret_cast(&payload_length), 3); + out.write(sequence_id++); + + working_buffer = WriteBuffer::Buffer(out.position(), out.position() + std::min(payload_length - bytes_written, out.available())); + pos = working_buffer.begin(); + } protected: void nextImpl() override { + int written = pos - working_buffer.begin(); + out.position() += written; + bytes_written += written; + if (bytes_written < payload_length) + { + out.nextIfAtEnd(); + working_buffer = WriteBuffer::Buffer(out.position(), out.position() + std::min(payload_length - bytes_written, out.available())); + } + else if (total_left > 0 || payload_length == MAX_PACKET_LENGTH) + { + startPacket(); + } } }; +class WritePacket +{ +public: + virtual void writePayload(WriteBuffer & buffer, uint8_t & sequence_id) const + { + PacketPayloadWriteBuffer buf(buffer, getPayloadSize(), sequence_id); + writePayloadImpl(buf); + buf.checkPayloadSize(); + } + + virtual ~WritePacket() = default; + +protected: + virtual size_t getPayloadSize() const = 0; + + virtual void writePayloadImpl(WriteBuffer & buffer) const = 0; +}; + + /* Writes and reads packets, keeping sequence-id. * Throws ProtocolError, if packet with incorrect sequence-id was received. */ class PacketSender { public: - size_t & sequence_id; + uint8_t & sequence_id; ReadBuffer * in; WriteBuffer * out; size_t max_packet_size = MAX_PACKET_LENGTH; /// For reading and writing. - PacketSender(ReadBuffer & in, WriteBuffer & out, size_t & sequence_id) + PacketSender(ReadBuffer & in, WriteBuffer & out, uint8_t & sequence_id) : sequence_id(sequence_id) , in(&in) , out(&out) @@ -249,7 +319,7 @@ public: } /// For writing. - PacketSender(WriteBuffer & out, size_t & sequence_id) + PacketSender(WriteBuffer & out, uint8_t & sequence_id) : sequence_id(sequence_id) , in(nullptr) , out(&out) @@ -271,23 +341,7 @@ public: void sendPacket(const T & packet, bool flush = false) { static_assert(std::is_base_of()); - Vector payload; - WriteBufferFromVector buffer(payload); - packet.writePayload(buffer); - buffer.finish(); - size_t pos = 0; - do - { - size_t payload_length = std::min(payload.size() - pos, max_packet_size); - - out->write(reinterpret_cast(&payload_length), 3); - out->write(reinterpret_cast(&sequence_id), 1); - out->write(payload.data() + pos, payload_length); - - pos += payload_length; - sequence_id++; - } while (pos < payload.size()); - + packet.writePayload(*out, sequence_id); if (flush) out->next(); } @@ -296,7 +350,7 @@ public: void resetSequenceId(); /// Converts packet to text. Is used for debug output. - static String packetToText(const Vector & payload); + static String packetToText(const String & payload); }; @@ -304,20 +358,22 @@ uint64_t readLengthEncodedNumber(ReadBuffer & ss); void writeLengthEncodedNumber(uint64_t x, WriteBuffer & buffer); -template -void writeLengthEncodedString(const T & s, WriteBuffer & buffer) +inline void writeLengthEncodedString(const String & s, WriteBuffer & buffer) { writeLengthEncodedNumber(s.size(), buffer); buffer.write(s.data(), s.size()); } -template -void writeNulTerminatedString(const T & s, WriteBuffer & buffer) +inline void writeNulTerminatedString(const String & s, WriteBuffer & buffer) { buffer.write(s.data(), s.size()); buffer.write(0); } +size_t getLengthEncodedNumberSize(uint64_t x); + +size_t getLengthEncodedStringSize(const String & s); + class Handshake : public WritePacket { @@ -340,7 +396,13 @@ public: { } - void writePayload(WriteBuffer & buffer) const override +protected: + size_t getPayloadSize() const override + { + return 26 + server_version.size() + auth_plugin_data.size() + Authentication::SHA256.size(); + } + + void writePayloadImpl(WriteBuffer & buffer) const override { buffer.write(static_cast(protocol_version)); writeNulTerminatedString(server_version, buffer); @@ -435,12 +497,17 @@ public: { } - void writePayload(WriteBuffer & buffer) const override +protected: + size_t getPayloadSize() const override + { + return 2 + plugin_name.size() + auth_plugin_data.size(); + } + + void writePayloadImpl(WriteBuffer & buffer) const override { buffer.write(0xfe); writeNulTerminatedString(plugin_name, buffer); writeString(auth_plugin_data, buffer); - std::cerr << auth_plugin_data.size() << std::endl; } }; @@ -461,7 +528,13 @@ class AuthMoreData : public WritePacket public: explicit AuthMoreData(String data): data(std::move(data)) {} - void writePayload(WriteBuffer & buffer) const override +protected: + size_t getPayloadSize() const override + { + return 1 + data.size(); + } + + void writePayloadImpl(WriteBuffer & buffer) const override { buffer.write(0x01); writeString(data, buffer); @@ -507,7 +580,35 @@ public: { } - void writePayload(WriteBuffer & buffer) const override +protected: + size_t getPayloadSize() const override + { + size_t result = 2 + getLengthEncodedNumberSize(affected_rows); + + if (capabilities & CLIENT_PROTOCOL_41) + { + result += 4; + } + else if (capabilities & CLIENT_TRANSACTIONS) + { + result += 2; + } + + if (capabilities & CLIENT_SESSION_TRACK) + { + result += getLengthEncodedStringSize(info); + if (status_flags & SERVER_SESSION_STATE_CHANGED) + result += getLengthEncodedStringSize(session_state_changes); + } + else + { + result += info.size(); + } + + return result; + } + + void writePayloadImpl(WriteBuffer & buffer) const override { buffer.write(header); writeLengthEncodedNumber(affected_rows, buffer); @@ -525,13 +626,9 @@ public: if (capabilities & CLIENT_SESSION_TRACK) { - writeLengthEncodedNumber(info.length(), buffer); - writeString(info, buffer); + writeLengthEncodedString(info, buffer); if (status_flags & SERVER_SESSION_STATE_CHANGED) - { - writeLengthEncodedNumber(session_state_changes.length(), buffer); - writeString(session_state_changes, buffer); - } + writeLengthEncodedString(session_state_changes, buffer); } else { @@ -548,7 +645,13 @@ public: EOF_Packet(int warnings, int status_flags) : warnings(warnings), status_flags(status_flags) {} - void writePayload(WriteBuffer & buffer) const override +protected: + size_t getPayloadSize() const override + { + return 5; + } + + void writePayloadImpl(WriteBuffer & buffer) const override { buffer.write(0xfe); // EOF header buffer.write(reinterpret_cast(&warnings), 2); @@ -567,7 +670,13 @@ public: { } - void writePayload(WriteBuffer & buffer) const override +protected: + size_t getPayloadSize() const override + { + return 4 + sql_state.length() + std::min(error_message.length(), MYSQL_ERRMSG_SIZE); + } + + void writePayloadImpl(WriteBuffer & buffer) const override { buffer.write(0xff); buffer.write(reinterpret_cast(&error_code), 2); @@ -621,7 +730,14 @@ public: { } - void writePayload(WriteBuffer & buffer) const override +protected: + size_t getPayloadSize() const override + { + return 13 + getLengthEncodedStringSize("def") + getLengthEncodedStringSize(schema) + getLengthEncodedStringSize(table) + getLengthEncodedStringSize(org_table) + \ + getLengthEncodedStringSize(name) + getLengthEncodedStringSize(org_name) + getLengthEncodedNumberSize(next_length); + } + + void writePayloadImpl(WriteBuffer & buffer) const override { writeLengthEncodedString(std::string("def"), buffer); /// always "def" writeLengthEncodedString(schema, buffer); @@ -660,7 +776,13 @@ public: { } - void writePayload(WriteBuffer & buffer) const override +protected: + size_t getPayloadSize() const override + { + return getLengthEncodedNumberSize(value); + } + + void writePayloadImpl(WriteBuffer & buffer) const override { writeLengthEncodedNumber(value, buffer); } @@ -669,15 +791,23 @@ public: class ResultsetRow : public WritePacket { std::vector columns; + size_t payload_size = 0; public: ResultsetRow() = default; void appendColumn(String && value) { + payload_size += getLengthEncodedStringSize(value); columns.emplace_back(std::move(value)); } - void writePayload(WriteBuffer & buffer) const override +protected: + size_t getPayloadSize() const override + { + return payload_size; + } + + void writePayloadImpl(WriteBuffer & buffer) const override { for (const String & column : columns) writeLengthEncodedString(column, buffer); diff --git a/dbms/src/Formats/MySQLWireBlockOutputStream.cpp b/dbms/src/Formats/MySQLWireBlockOutputStream.cpp index 9ba62230071..621a624fb0e 100644 --- a/dbms/src/Formats/MySQLWireBlockOutputStream.cpp +++ b/dbms/src/Formats/MySQLWireBlockOutputStream.cpp @@ -12,9 +12,9 @@ using namespace MySQLProtocol; MySQLWireBlockOutputStream::MySQLWireBlockOutputStream(WriteBuffer & buf, const Block & header, Context & context) : header(header) , context(context) - , packet_sender(std::make_shared(buf, context.sequence_id)) + , packet_sender(std::make_shared(buf, context.mysql.sequence_id)) { - packet_sender->max_packet_size = context.max_packet_size; + packet_sender->max_packet_size = context.mysql.max_packet_size; } void MySQLWireBlockOutputStream::writePrefix() @@ -30,7 +30,7 @@ void MySQLWireBlockOutputStream::writePrefix() packet_sender->sendPacket(column_definition); } - if (!(context.client_capabilities & Capability::CLIENT_DEPRECATE_EOF)) + if (!(context.mysql.client_capabilities & Capability::CLIENT_DEPRECATE_EOF)) { packet_sender->sendPacket(EOF_Packet(0, 0)); } @@ -67,10 +67,10 @@ void MySQLWireBlockOutputStream::writeSuffix() << formatReadableSizeWithBinarySuffix(info.read_bytes / info.elapsed_seconds) << "/sec."; if (header.columns() == 0) - packet_sender->sendPacket(OK_Packet(0x0, context.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); + packet_sender->sendPacket(OK_Packet(0x0, context.mysql.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); else - if (context.client_capabilities & CLIENT_DEPRECATE_EOF) - packet_sender->sendPacket(OK_Packet(0xfe, context.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); + if (context.mysql.client_capabilities & CLIENT_DEPRECATE_EOF) + packet_sender->sendPacket(OK_Packet(0xfe, context.mysql.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); else packet_sender->sendPacket(EOF_Packet(0, 0), true); } diff --git a/dbms/src/Interpreters/Context.h b/dbms/src/Interpreters/Context.h index 443ea3bdb55..5ba6571754b 100644 --- a/dbms/src/Interpreters/Context.h +++ b/dbms/src/Interpreters/Context.h @@ -484,10 +484,14 @@ public: IHostContextPtr & getHostContext(); const IHostContextPtr & getHostContext() const; - /// MySQL wire protocol state. - size_t sequence_id = 0; - uint32_t client_capabilities = 0; - size_t max_packet_size = 0; + typedef struct MySQLWireContext + { + uint8_t sequence_id = 0; + uint32_t client_capabilities = 0; + size_t max_packet_size = 0; + } MySQLState; + + struct MySQLWireContext mysql; private: /** Check if the current client has access to the specified database. * If access is denied, throw an exception. From a514de943c8932abc4f7aba1756c10b5a01f0fb5 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Tue, 16 Jul 2019 10:11:59 +0300 Subject: [PATCH 0179/1165] replacing not implemented query --- dbms/programs/server/MySQLHandler.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/dbms/programs/server/MySQLHandler.cpp b/dbms/programs/server/MySQLHandler.cpp index 931cb35676b..575970ad07b 100644 --- a/dbms/programs/server/MySQLHandler.cpp +++ b/dbms/programs/server/MySQLHandler.cpp @@ -361,7 +361,17 @@ void MySQLHandler::comQuery(ReadBuffer & payload) with_output = true; }; - executeQuery(payload, *out, true, connection_context, set_content_type, nullptr); + ReadBufferFromString empty_select(std::string("select ''")); + + bool should_replace = false; + // Translate query from MySQL to ClickHouse. + // This is a temporary workaround until ClickHouse supports the syntax "@@var_name". + if (std::string(payload.position(), payload.buffer().end()) == "select @@version_comment limit 1") // MariaDB client starts session with that query + { + should_replace = true; + } + + executeQuery(should_replace ? empty_select : payload, *out, true, connection_context, set_content_type, nullptr); if (!with_output) packet_sender->sendPacket(OK_Packet(0x00, client_capability_flags, 0, 0, 0), true); From c370de432ade8dadb39dd02765cce6c85878df61 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Tue, 16 Jul 2019 10:28:53 +0300 Subject: [PATCH 0180/1165] better --- dbms/src/Interpreters/Context.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Interpreters/Context.h b/dbms/src/Interpreters/Context.h index 5ba6571754b..776a60f1ccd 100644 --- a/dbms/src/Interpreters/Context.h +++ b/dbms/src/Interpreters/Context.h @@ -491,7 +491,7 @@ public: size_t max_packet_size = 0; } MySQLState; - struct MySQLWireContext mysql; + MySQLWireContext mysql; private: /** Check if the current client has access to the specified database. * If access is denied, throw an exception. From d74be1dc9c87ae6a67f830d4c6ce46010b8612e4 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Tue, 16 Jul 2019 11:24:51 +0300 Subject: [PATCH 0181/1165] fixed MySQLOutputFormat used by new query processing pipeline --- dbms/src/Core/MySQLProtocol.h | 3 --- dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp | 10 +++++----- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index beea12a1294..15025b73425 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -121,9 +121,6 @@ enum ColumnType }; -using Vector = PODArray; - - class ProtocolError : public DB::Exception { public: diff --git a/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp b/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp index 4dc4a32c672..7a0a8d213e0 100644 --- a/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp @@ -17,7 +17,7 @@ using namespace MySQLProtocol; MySQLOutputFormat::MySQLOutputFormat(WriteBuffer & out_, const Block & header, const Context & context, const FormatSettings & settings) : IOutputFormat(header, out_) , context(context) - , packet_sender(std::make_shared(out, const_cast(context.sequence_id))) /// TODO: fix it + , packet_sender(std::make_shared(out, const_cast(context.mysql.sequence_id))) /// TODO: fix it , format_settings(settings) { } @@ -43,7 +43,7 @@ void MySQLOutputFormat::consume(Chunk chunk) packet_sender->sendPacket(column_definition); } - if (!(context.client_capabilities & Capability::CLIENT_DEPRECATE_EOF)) + if (!(context.mysql.client_capabilities & Capability::CLIENT_DEPRECATE_EOF)) { packet_sender->sendPacket(EOF_Packet(0, 0)); } @@ -85,10 +85,10 @@ void MySQLOutputFormat::finalize() auto & header = getPort(PortKind::Main).getHeader(); if (header.columns() == 0) - packet_sender->sendPacket(OK_Packet(0x0, context.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); + packet_sender->sendPacket(OK_Packet(0x0, context.mysql.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); else - if (context.client_capabilities & CLIENT_DEPRECATE_EOF) - packet_sender->sendPacket(OK_Packet(0xfe, context.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); + if (context.mysql.client_capabilities & CLIENT_DEPRECATE_EOF) + packet_sender->sendPacket(OK_Packet(0xfe, context.mysql.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); else packet_sender->sendPacket(EOF_Packet(0, 0), true); } From a03114ede2b0d889d0c23a2dc5f8d92a87d53eb2 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Tue, 16 Jul 2019 11:47:54 +0300 Subject: [PATCH 0182/1165] cast to proper type --- dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp b/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp index 7a0a8d213e0..3ddaed53687 100644 --- a/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp @@ -17,7 +17,7 @@ using namespace MySQLProtocol; MySQLOutputFormat::MySQLOutputFormat(WriteBuffer & out_, const Block & header, const Context & context, const FormatSettings & settings) : IOutputFormat(header, out_) , context(context) - , packet_sender(std::make_shared(out, const_cast(context.mysql.sequence_id))) /// TODO: fix it + , packet_sender(std::make_shared(out, const_cast(context.mysql.sequence_id))) /// TODO: fix it , format_settings(settings) { } From 922c3eb22e0d2e02e0a3c01160f48c441e00877d Mon Sep 17 00:00:00 2001 From: Nik Date: Tue, 16 Jul 2019 19:27:42 +0400 Subject: [PATCH 0183/1165] Clear Kafka's buffer if an invalid message is found. --- dbms/src/IO/DelimitedReadBuffer.h | 4 ++++ dbms/src/Storages/Kafka/KafkaBlockInputStream.cpp | 4 +++- dbms/src/Storages/Kafka/ReadBufferFromKafkaConsumer.cpp | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/dbms/src/IO/DelimitedReadBuffer.h b/dbms/src/IO/DelimitedReadBuffer.h index 1d4b07265ae..4d6b74e6bcd 100644 --- a/dbms/src/IO/DelimitedReadBuffer.h +++ b/dbms/src/IO/DelimitedReadBuffer.h @@ -21,6 +21,10 @@ public: return typeid_cast(buffer.get()); } + void reset(){ + BufferBase::set(nullptr, 0, 0); + } + protected: // XXX: don't know how to guarantee that the next call to this method is done after we read all previous data. bool nextImpl() override diff --git a/dbms/src/Storages/Kafka/KafkaBlockInputStream.cpp b/dbms/src/Storages/Kafka/KafkaBlockInputStream.cpp index 5b8d80cb062..2c949e620c8 100644 --- a/dbms/src/Storages/Kafka/KafkaBlockInputStream.cpp +++ b/dbms/src/Storages/Kafka/KafkaBlockInputStream.cpp @@ -27,8 +27,10 @@ KafkaBlockInputStream::~KafkaBlockInputStream() if (!claimed) return; - if (broken) + if (broken){ buffer->subBufferAs()->unsubscribe(); + buffer->reset(); + } storage.pushBuffer(buffer); } diff --git a/dbms/src/Storages/Kafka/ReadBufferFromKafkaConsumer.cpp b/dbms/src/Storages/Kafka/ReadBufferFromKafkaConsumer.cpp index fc81e38bb63..ea016c75e19 100644 --- a/dbms/src/Storages/Kafka/ReadBufferFromKafkaConsumer.cpp +++ b/dbms/src/Storages/Kafka/ReadBufferFromKafkaConsumer.cpp @@ -74,6 +74,11 @@ void ReadBufferFromKafkaConsumer::subscribe(const Names & topics) void ReadBufferFromKafkaConsumer::unsubscribe() { LOG_TRACE(log, "Re-joining claimed consumer after failure"); + + messages.clear(); + current = messages.begin(); + BufferBase::set(nullptr, 0, 0); + consumer->unsubscribe(); } From 4a30eba32f645a13651eb3dfbd99c8dea285dc36 Mon Sep 17 00:00:00 2001 From: Nik Date: Tue, 16 Jul 2019 22:34:47 +0400 Subject: [PATCH 0184/1165] Fix style check --- dbms/src/IO/DelimitedReadBuffer.h | 3 ++- dbms/src/Storages/Kafka/KafkaBlockInputStream.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dbms/src/IO/DelimitedReadBuffer.h b/dbms/src/IO/DelimitedReadBuffer.h index 4d6b74e6bcd..a2a781185ce 100644 --- a/dbms/src/IO/DelimitedReadBuffer.h +++ b/dbms/src/IO/DelimitedReadBuffer.h @@ -21,7 +21,8 @@ public: return typeid_cast(buffer.get()); } - void reset(){ + void reset() + { BufferBase::set(nullptr, 0, 0); } diff --git a/dbms/src/Storages/Kafka/KafkaBlockInputStream.cpp b/dbms/src/Storages/Kafka/KafkaBlockInputStream.cpp index 2c949e620c8..19b496e0e60 100644 --- a/dbms/src/Storages/Kafka/KafkaBlockInputStream.cpp +++ b/dbms/src/Storages/Kafka/KafkaBlockInputStream.cpp @@ -27,7 +27,8 @@ KafkaBlockInputStream::~KafkaBlockInputStream() if (!claimed) return; - if (broken){ + if (broken) + { buffer->subBufferAs()->unsubscribe(); buffer->reset(); } From ef6c7ea5be41c608044fefce961a6f2473f45e52 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 16 Jul 2019 23:05:00 +0300 Subject: [PATCH 0185/1165] Merge COLUMNS matcher (incomplete) --- dbms/src/Interpreters/AsteriskSemantic.h | 2 +- .../PredicateExpressionsOptimizer.cpp | 9 ++--- .../TranslateQualifiedNamesVisitor.cpp | 3 +- dbms/src/Parsers/ASTColumnsClause.cpp | 29 ++++++++++++++-- dbms/src/Parsers/ASTColumnsClause.h | 33 +++++++++---------- dbms/src/Parsers/ExpressionElementParsers.cpp | 11 ++++++- dbms/src/Parsers/ExpressionElementParsers.h | 4 +-- .../0_stateless/00969_columns_clause.sql | 2 +- 8 files changed, 62 insertions(+), 31 deletions(-) diff --git a/dbms/src/Interpreters/AsteriskSemantic.h b/dbms/src/Interpreters/AsteriskSemantic.h index 1dcfd344a72..9b0939f6001 100644 --- a/dbms/src/Interpreters/AsteriskSemantic.h +++ b/dbms/src/Interpreters/AsteriskSemantic.h @@ -4,7 +4,7 @@ #include #include -#include "../Parsers/ASTColumnsClause.h" +#include namespace DB { diff --git a/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp b/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp index 1e92f7b348b..eb7c34be9b8 100644 --- a/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp +++ b/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -24,7 +25,7 @@ #include #include #include -#include "../Parsers/ASTColumnsClause.h" + namespace DB { @@ -267,7 +268,7 @@ std::vector PredicateExpressionsOptimizer::splitConjunctionPredicate(con continue; } } - idx++; + ++idx; } } return predicate_expressions; @@ -486,7 +487,7 @@ ASTs PredicateExpressionsOptimizer::evaluateAsterisk(ASTSelectQuery * select_que const auto block = storage->getSampleBlock(); if (const auto * asterisk_pattern = asterisk->as()) { - for (size_t idx = 0; idx < block.columns(); idx++) + for (size_t idx = 0; idx < block.columns(); ++idx) { auto & col = block.getByPosition(idx); if (asterisk_pattern->isColumnMatching(col.name)) @@ -495,7 +496,7 @@ ASTs PredicateExpressionsOptimizer::evaluateAsterisk(ASTSelectQuery * select_que } else { - for (size_t idx = 0; idx < block.columns(); idx++) + for (size_t idx = 0; idx < block.columns(); ++idx) projection_columns.emplace_back(std::make_shared(block.getByPosition(idx).name)); } } diff --git a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp index a418708f1dd..1ca5fa69ce5 100644 --- a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp +++ b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp @@ -16,8 +16,7 @@ #include #include #include -#include -#include "../Parsers/ASTColumnsClause.h" +#include namespace DB diff --git a/dbms/src/Parsers/ASTColumnsClause.cpp b/dbms/src/Parsers/ASTColumnsClause.cpp index 2f2dca471b7..8fbcfce471f 100644 --- a/dbms/src/Parsers/ASTColumnsClause.cpp +++ b/dbms/src/Parsers/ASTColumnsClause.cpp @@ -1,6 +1,12 @@ +#include "ASTColumnsClause.h" + #include #include -#include "ASTColumnsClause.h" +#include + +#include + + namespace DB { @@ -12,11 +18,28 @@ ASTPtr ASTColumnsClause::clone() const return clone; } -void ASTColumnsClause::appendColumnName(WriteBuffer & ostr) const { writeString(originalPattern, ostr); } +void ASTColumnsClause::appendColumnName(WriteBuffer & ostr) const { writeString(original_pattern, ostr); } void ASTColumnsClause::formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const { - settings.ostr << (settings.hilite ? hilite_keyword : "") << "COLUMNS" << (settings.hilite ? hilite_none : "") << " '" << originalPattern << "'"; + WriteBufferFromOwnString pattern_quoted; + writeQuotedString(original_pattern, pattern_quoted); + + settings.ostr << (settings.hilite ? hilite_keyword : "") << "COLUMNS" << (settings.hilite ? hilite_none : "") << "(" << pattern_quoted.str() << ")"; } +void ASTColumnsClause::setPattern(String pattern) +{ + original_pattern = std::move(pattern); + column_matcher = std::make_shared(pattern, RE2::Quiet); + if (!column_matcher->ok()) + throw DB::Exception("COLUMNS pattern " + original_pattern + " cannot be compiled: " + column_matcher->error(), DB::ErrorCodes::CANNOT_COMPILE_REGEXP); +} + +bool ASTColumnsClause::isColumnMatching(const String & column_name) const +{ + return RE2::FullMatch(column_name, *column_matcher); +} + + } diff --git a/dbms/src/Parsers/ASTColumnsClause.h b/dbms/src/Parsers/ASTColumnsClause.h index 67f400b305c..1cf13941420 100644 --- a/dbms/src/Parsers/ASTColumnsClause.h +++ b/dbms/src/Parsers/ASTColumnsClause.h @@ -1,13 +1,19 @@ #pragma once -#include -#include #include -#include + + +namespace re2 +{ + class RE2; +} + namespace DB { +class WriteBuffer; + namespace ErrorCodes { extern const int CANNOT_COMPILE_REGEXP; @@ -17,31 +23,24 @@ struct AsteriskSemantic; struct AsteriskSemanticImpl; +/** SELECT COLUMNS('regexp') is expanded to multiple columns like * (asterisk). + */ class ASTColumnsClause : public IAST { public: - String getID(char) const override { return "ColumnsClause"; } ASTPtr clone() const override; + void appendColumnName(WriteBuffer & ostr) const override; - void setPattern(String pattern) - { - originalPattern = pattern; - columnMatcher = std::make_shared(pattern, RE2::Quiet); - if (!columnMatcher->ok()) - throw DB::Exception("COLUMNS pattern " + originalPattern + " cannot be compiled: " + columnMatcher->error(), DB::ErrorCodes::CANNOT_COMPILE_REGEXP); - } - bool isColumnMatching(String columnName) const - { - return RE2::FullMatch(columnName, *columnMatcher); - } + void setPattern(String pattern); + bool isColumnMatching(const String & column_name) const; protected: void formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const override; private: - std::shared_ptr columnMatcher; - String originalPattern; + std::shared_ptr column_matcher; + String original_pattern; std::shared_ptr semantic; /// pimpl friend struct AsteriskSemantic; diff --git a/dbms/src/Parsers/ExpressionElementParsers.cpp b/dbms/src/Parsers/ExpressionElementParsers.cpp index 4669c37edae..80ec890b5d5 100644 --- a/dbms/src/Parsers/ExpressionElementParsers.cpp +++ b/dbms/src/Parsers/ExpressionElementParsers.cpp @@ -1177,10 +1177,18 @@ bool ParserColumnsClause::parseImpl(Pos & pos, ASTPtr & node, Expected & expecte if (!columns.ignore(pos, expected)) return false; + if (pos->type != TokenType::OpeningRoundBracket) + return false; + ++pos; + ASTPtr regex_node; if (!regex.parse(pos, regex_node, expected)) return false; + if (pos->type != TokenType::ClosingRoundBracket) + return false; + ++pos; + auto res = std::make_shared(); res->setPattern(regex_node->as().value.get()); res->children.push_back(regex_node); @@ -1188,6 +1196,7 @@ bool ParserColumnsClause::parseImpl(Pos & pos, ASTPtr & node, Expected & expecte return true; } + bool ParserAsterisk::parseImpl(Pos & pos, ASTPtr & node, Expected &) { if (pos->type == TokenType::Asterisk) @@ -1282,10 +1291,10 @@ bool ParserExpressionElement::parseImpl(Pos & pos, ASTPtr & node, Expected & exp || ParserLeftExpression().parse(pos, node, expected) || ParserRightExpression().parse(pos, node, expected) || ParserCase().parse(pos, node, expected) + || ParserColumnsClause().parse(pos, node, expected) /// before ParserFunction because it can be also parsed as a function. || ParserFunction().parse(pos, node, expected) || ParserQualifiedAsterisk().parse(pos, node, expected) || ParserAsterisk().parse(pos, node, expected) - || ParserColumnsClause().parse(pos, node, expected) || ParserCompoundIdentifier().parse(pos, node, expected) || ParserSubstitution().parse(pos, node, expected); } diff --git a/dbms/src/Parsers/ExpressionElementParsers.h b/dbms/src/Parsers/ExpressionElementParsers.h index d3a9f97f0b8..bcf7be49e4e 100644 --- a/dbms/src/Parsers/ExpressionElementParsers.h +++ b/dbms/src/Parsers/ExpressionElementParsers.h @@ -73,12 +73,12 @@ protected: bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected); }; -/** COLUMNS '' +/** COLUMNS('') */ class ParserColumnsClause : public IParserBase { protected: - const char * getName() const { return "COLUMNS clause"; } + const char * getName() const { return "COLUMNS matcher"; } bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected); }; diff --git a/dbms/tests/queries/0_stateless/00969_columns_clause.sql b/dbms/tests/queries/0_stateless/00969_columns_clause.sql index 63d041984c1..b1d7949b8ee 100644 --- a/dbms/tests/queries/0_stateless/00969_columns_clause.sql +++ b/dbms/tests/queries/0_stateless/00969_columns_clause.sql @@ -1,3 +1,3 @@ CREATE TABLE IF NOT EXISTS ColumnsClauseTest (product_price Int64, product_weight Int16, amount Int64) Engine=TinyLog; INSERT INTO ColumnsClauseTest VALUES (100, 10, 324), (120, 8, 23); -SELECT COLUMNS 'product.*' from ColumnsClauseTest ORDER BY product_price; +SELECT COLUMNS('product.*') from ColumnsClauseTest ORDER BY product_price; From bdd3bc816971cab1359e70adace15099d0d3eb74 Mon Sep 17 00:00:00 2001 From: proller Date: Wed, 17 Jul 2019 12:21:32 +0300 Subject: [PATCH 0186/1165] fix --- dbms/src/Common/Arena.h | 18 ------------------ dbms/src/Common/ArenaWithFreeLists.h | 5 +---- dbms/src/Core/Defines.h | 5 +++++ 3 files changed, 6 insertions(+), 22 deletions(-) diff --git a/dbms/src/Common/Arena.h b/dbms/src/Common/Arena.h index 0f04e7fc762..e4c2e973095 100644 --- a/dbms/src/Common/Arena.h +++ b/dbms/src/Common/Arena.h @@ -57,9 +57,7 @@ private: end = begin + size_ - pad_right; prev = prev_; -#if __has_include() ASAN_POISON_MEMORY_REGION(begin, size_); -#endif } ~Chunk() @@ -68,9 +66,7 @@ private: /// because the allocator might not have asan integration, and the /// memory would stay poisoned forever. If the allocator supports /// asan, it will correctly poison the memory by itself. -#if __has_include() ASAN_UNPOISON_MEMORY_REGION(begin, size()); -#endif Allocator::free(begin, size()); @@ -142,9 +138,7 @@ public: char * res = head->pos; head->pos += size; -#if __has_include() ASAN_UNPOISON_MEMORY_REGION(res, size + pad_right); -#endif return res; } @@ -163,9 +157,7 @@ public: head->pos = static_cast(head_pos); head->pos += size; -#if __has_include() ASAN_UNPOISON_MEMORY_REGION(res, size + pad_right); -#endif return res; } @@ -186,9 +178,7 @@ public: void rollback(size_t size) { head->pos -= size; -#if __has_include() ASAN_POISON_MEMORY_REGION(head->pos, size + pad_right); -#endif } /** Begin or expand allocation of contiguous piece of memory without alignment. @@ -215,9 +205,7 @@ public: if (!begin) begin = res; -#if __has_include() ASAN_UNPOISON_MEMORY_REGION(res, size + pad_right); -#endif return res; } @@ -250,9 +238,7 @@ public: if (!begin) begin = res; -#if __has_include() ASAN_UNPOISON_MEMORY_REGION(res, size + pad_right); -#endif return res; } @@ -263,9 +249,7 @@ public: if (old_data) { memcpy(res, old_data, old_size); -#if __has_include() ASAN_POISON_MEMORY_REGION(old_data, old_size); -#endif } return res; } @@ -276,9 +260,7 @@ public: if (old_data) { memcpy(res, old_data, old_size); -#if __has_include() ASAN_POISON_MEMORY_REGION(old_data, old_size); -#endif } return res; } diff --git a/dbms/src/Common/ArenaWithFreeLists.h b/dbms/src/Common/ArenaWithFreeLists.h index 79cd45c0572..6092f03ce19 100644 --- a/dbms/src/Common/ArenaWithFreeLists.h +++ b/dbms/src/Common/ArenaWithFreeLists.h @@ -3,6 +3,7 @@ #if __has_include() # include #endif +#include #include #include @@ -70,10 +71,8 @@ public: /// item in the list. We poisoned the free block before putting /// it into the free list, so we have to unpoison it before /// reading anything. -#if __has_include() ASAN_UNPOISON_MEMORY_REGION(free_block_ptr, std::max(size, sizeof(Block))); -#endif const auto res = free_block_ptr->data; free_block_ptr = free_block_ptr->next; @@ -104,9 +103,7 @@ public: /// destructor, to support an underlying allocator that doesn't /// integrate with asan. We don't do that, and rely on the fact that /// our underlying allocator is Arena, which does have asan integration. -#if __has_include() ASAN_POISON_MEMORY_REGION(ptr, 1ULL << (list_idx + 1)); -#endif } /// Size of the allocated pool in bytes diff --git a/dbms/src/Core/Defines.h b/dbms/src/Core/Defines.h index 461278fad3b..75d1ed2caef 100644 --- a/dbms/src/Core/Defines.h +++ b/dbms/src/Core/Defines.h @@ -139,3 +139,8 @@ /// This number is only used for distributed version compatible. /// It could be any magic number. #define DBMS_DISTRIBUTED_SENDS_MAGIC_NUMBER 0xCAFECABE + +#if !__has_include() +# define ASAN_UNPOISON_MEMORY_REGION(a,b) +# define ASAN_POISON_MEMORY_REGION(a,b) +#endif From 67c647bb9ed58e181e4be679694d8678c0280d50 Mon Sep 17 00:00:00 2001 From: proller Date: Wed, 17 Jul 2019 14:43:17 +0300 Subject: [PATCH 0187/1165] clean --- dbms/src/Common/Arena.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dbms/src/Common/Arena.h b/dbms/src/Common/Arena.h index e4c2e973095..e8b6ada44cb 100644 --- a/dbms/src/Common/Arena.h +++ b/dbms/src/Common/Arena.h @@ -137,9 +137,7 @@ public: char * res = head->pos; head->pos += size; - ASAN_UNPOISON_MEMORY_REGION(res, size + pad_right); - return res; } @@ -156,9 +154,7 @@ public: { head->pos = static_cast(head_pos); head->pos += size; - ASAN_UNPOISON_MEMORY_REGION(res, size + pad_right); - return res; } From 436fb279d34751a7f4ad98ad48d3b5c1f16a9399 Mon Sep 17 00:00:00 2001 From: proller Date: Wed, 17 Jul 2019 15:07:10 +0300 Subject: [PATCH 0188/1165] zstd --- dbms/CMakeLists.txt | 9 ++++----- dbms/src/Compression/CompressedReadBufferBase.cpp | 3 --- dbms/src/Compression/CompressedWriteBuffer.cpp | 3 --- dbms/src/Compression/ICompressionCodec.cpp | 1 - 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/dbms/CMakeLists.txt b/dbms/CMakeLists.txt index f18608f3256..bcb44b468d8 100644 --- a/dbms/CMakeLists.txt +++ b/dbms/CMakeLists.txt @@ -235,10 +235,6 @@ target_link_libraries(clickhouse_common_io roaring ) -if(ZSTD_LIBRARY) - target_link_libraries(clickhouse_common_io PUBLIC ${ZSTD_LIBRARY}) -endif() - if (USE_RDKAFKA) target_link_libraries(dbms PRIVATE ${CPPKAFKA_LIBRARY} ${RDKAFKA_LIBRARY}) if(NOT USE_INTERNAL_RDKAFKA_LIBRARY) @@ -294,11 +290,14 @@ target_include_directories(dbms SYSTEM PUBLIC ${PCG_RANDOM_INCLUDE_DIR}) if (NOT USE_INTERNAL_LZ4_LIBRARY) target_include_directories(dbms SYSTEM BEFORE PRIVATE ${LZ4_INCLUDE_DIR}) endif () + +if(ZSTD_LIBRARY) + target_link_libraries(dbms PRIVATE ${ZSTD_LIBRARY}) +endif() if (NOT USE_INTERNAL_ZSTD_LIBRARY AND ZSTD_INCLUDE_DIR) target_include_directories(dbms SYSTEM BEFORE PRIVATE ${ZSTD_INCLUDE_DIR}) endif () - if (NOT USE_INTERNAL_BOOST_LIBRARY) target_include_directories (clickhouse_common_io SYSTEM BEFORE PUBLIC ${Boost_INCLUDE_DIRS}) endif () diff --git a/dbms/src/Compression/CompressedReadBufferBase.cpp b/dbms/src/Compression/CompressedReadBufferBase.cpp index bd2078175dc..9f3664b4c9f 100644 --- a/dbms/src/Compression/CompressedReadBufferBase.cpp +++ b/dbms/src/Compression/CompressedReadBufferBase.cpp @@ -1,11 +1,8 @@ #include "CompressedReadBufferBase.h" #include - #include #include -#include - #include #include #include diff --git a/dbms/src/Compression/CompressedWriteBuffer.cpp b/dbms/src/Compression/CompressedWriteBuffer.cpp index 1285949c863..9dd3c23100f 100644 --- a/dbms/src/Compression/CompressedWriteBuffer.cpp +++ b/dbms/src/Compression/CompressedWriteBuffer.cpp @@ -1,8 +1,5 @@ #include #include -#include -#include -#include #include #include diff --git a/dbms/src/Compression/ICompressionCodec.cpp b/dbms/src/Compression/ICompressionCodec.cpp index ddedf8a4c9c..a50001238da 100644 --- a/dbms/src/Compression/ICompressionCodec.cpp +++ b/dbms/src/Compression/ICompressionCodec.cpp @@ -7,7 +7,6 @@ #include #include #include -#include namespace ProfileEvents { From 1913ae9ceea9d11ff569b6c5e22c42f55a5d4a0a Mon Sep 17 00:00:00 2001 From: Yuriy Date: Thu, 18 Jul 2019 07:54:26 +0300 Subject: [PATCH 0189/1165] fixed asan check --- dbms/programs/server/MySQLHandler.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dbms/programs/server/MySQLHandler.cpp b/dbms/programs/server/MySQLHandler.cpp index 9a78cec3783..9cc03cc9a31 100644 --- a/dbms/programs/server/MySQLHandler.cpp +++ b/dbms/programs/server/MySQLHandler.cpp @@ -320,7 +320,7 @@ void MySQLHandler::authenticate(const HandshakeResponse & handshake_response, co connection_context.setUser(handshake_response.username, password, socket().address(), ""); if (!handshake_response.database.empty()) connection_context.setCurrentDatabase(handshake_response.database); connection_context.setCurrentQueryId(""); - LOG_ERROR(log, "Authentication for user " << handshake_response.username << " succeeded."); + LOG_INFO(log, "Authentication for user " << handshake_response.username << " succeeded."); } catch (const Exception & exc) { @@ -367,7 +367,8 @@ void MySQLHandler::comQuery(ReadBuffer & payload) with_output = true; }; - ReadBufferFromString empty_select(std::string("select ''")); + const String query("select ''"); + ReadBufferFromString empty_select(query); bool should_replace = false; // Translate query from MySQL to ClickHouse. From 668959b300921495054b0a94a5a3772a1841f8f4 Mon Sep 17 00:00:00 2001 From: Alexander Tokmakov Date: Thu, 18 Jul 2019 16:43:20 +0300 Subject: [PATCH 0190/1165] use default if not nullable --- dbms/src/Core/Settings.h | 2 ++ dbms/src/Formats/CSVRowInputStream.cpp | 34 ++++++++++++++++++++++---- dbms/src/Formats/CSVRowInputStream.h | 2 ++ dbms/src/Formats/FormatFactory.cpp | 2 ++ dbms/src/Formats/FormatSettings.h | 2 ++ 5 files changed, 37 insertions(+), 5 deletions(-) diff --git a/dbms/src/Core/Settings.h b/dbms/src/Core/Settings.h index e06e953810b..65b205f806c 100644 --- a/dbms/src/Core/Settings.h +++ b/dbms/src/Core/Settings.h @@ -171,6 +171,7 @@ struct Settings : public SettingsCollection M(SettingBool, input_format_with_names_use_header, false, "For TSVWithNames and CSVWithNames input formats this controls whether format parser is to assume that column data appear in the input exactly as they are specified in the header.") \ M(SettingBool, input_format_import_nested_json, false, "Map nested JSON data to nested tables (it works for JSONEachRow format).") \ M(SettingBool, input_format_defaults_for_omitted_fields, false, "For input data calculate default expressions for omitted fields (it works for JSONEachRow format).") \ + M(SettingBool, input_format_null_as_default, false, "For CSV format initialize null fields with default values if data type of this field is not nullable") \ \ M(SettingBool, input_format_values_interpret_expressions, true, "For Values format: if field could not be parsed by streaming parser, run SQL parser and try to interpret it as SQL expression.") \ \ @@ -298,6 +299,7 @@ struct Settings : public SettingsCollection M(SettingChar, format_csv_delimiter, ',', "The character to be considered as a delimiter in CSV data. If setting with a string, a string has to have a length of 1.") \ M(SettingBool, format_csv_allow_single_quotes, 1, "If it is set to true, allow strings in single quotes.") \ M(SettingBool, format_csv_allow_double_quotes, 1, "If it is set to true, allow strings in double quotes.") \ + M(SettingBool, format_csv_unquoted_null_literal_as_null, false, "Consider unquoted NULL literal as \N") \ \ M(SettingDateTimeInputFormat, date_time_input_format, FormatSettings::DateTimeInputFormat::Basic, "Method to read DateTime from text input formats. Possible values: 'basic' and 'best_effort'.") \ M(SettingBool, log_profile_events, true, "Log query performance statistics into the query_log and query_thread_log.") \ diff --git a/dbms/src/Formats/CSVRowInputStream.cpp b/dbms/src/Formats/CSVRowInputStream.cpp index 07cfd4826df..d13b281ba6a 100644 --- a/dbms/src/Formats/CSVRowInputStream.cpp +++ b/dbms/src/Formats/CSVRowInputStream.cpp @@ -8,6 +8,8 @@ #include #include +#include + namespace DB { @@ -215,6 +217,7 @@ bool CSVRowInputStream::read(MutableColumns & columns, RowReadExtension & ext) if (table_column) { + skipWhitespacesAndTabs(istr); const auto & type = data_types[*table_column]; const bool at_delimiter = *istr.position() == delimiter; const bool at_last_column_line_end = is_last_file_column @@ -233,15 +236,31 @@ bool CSVRowInputStream::read(MutableColumns & columns, RowReadExtension & ext) read_columns[*table_column] = false; have_default_columns = true; } + else if (format_settings.csv.null_as_default && !type->isNullable() && type->canBeInsideNullable()) + { + /// If value is null but type is not nullable then use default value instead. + DataTypeNullable nullable(type); + auto tmp_col = nullable.createColumn(); + readField(*tmp_col, nullable); + if (tmp_col->isNullAt(0)) + { + read_columns[*table_column] = false; + have_default_columns = true; + } + else + { + columns[*table_column]->insert((*tmp_col)[0]); + read_columns[*table_column] = true; + } + } else { /// Read the column normally. + readField(*columns[*table_column], *type); read_columns[*table_column] = true; - skipWhitespacesAndTabs(istr); - type->deserializeAsTextCSV(*columns[*table_column], istr, - format_settings); - skipWhitespacesAndTabs(istr); + } + skipWhitespacesAndTabs(istr); } else { @@ -520,8 +539,13 @@ void CSVRowInputStream::updateDiagnosticInfo() pos_of_current_row = istr.position(); } +void CSVRowInputStream::readField(IColumn & column, const IDataType & type) +{ + type.deserializeAsTextCSV(column, istr, format_settings); +} -void registerInputFormatCSV(FormatFactory & factory) + + void registerInputFormatCSV(FormatFactory & factory) { for (bool with_names : {false, true}) { diff --git a/dbms/src/Formats/CSVRowInputStream.h b/dbms/src/Formats/CSVRowInputStream.h index b282b22570e..2dbff3457c8 100644 --- a/dbms/src/Formats/CSVRowInputStream.h +++ b/dbms/src/Formats/CSVRowInputStream.h @@ -71,6 +71,8 @@ private: bool parseRowAndPrintDiagnosticInfo(MutableColumns & columns, WriteBuffer & out, size_t max_length_of_column_name, size_t max_length_of_data_type_name); + + void readField(IColumn & column, const IDataType & type); }; } diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 4fae140abee..b1c4b861162 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -41,7 +41,9 @@ static FormatSettings getInputFormatSetting(const Settings & settings) format_settings.csv.delimiter = settings.format_csv_delimiter; format_settings.csv.allow_single_quotes = settings.format_csv_allow_single_quotes; format_settings.csv.allow_double_quotes = settings.format_csv_allow_double_quotes; + format_settings.csv.unquoted_null_literal_as_null = settings.format_csv_unquoted_null_literal_as_null; format_settings.csv.empty_as_default = settings.input_format_defaults_for_omitted_fields; + format_settings.csv.null_as_default = settings.input_format_null_as_default; format_settings.values.interpret_expressions = settings.input_format_values_interpret_expressions; format_settings.with_names_use_header = settings.input_format_with_names_use_header; format_settings.skip_unknown_fields = settings.input_format_skip_unknown_fields; diff --git a/dbms/src/Formats/FormatSettings.h b/dbms/src/Formats/FormatSettings.h index 0bb71e6e50e..f4dd8e6cb8a 100644 --- a/dbms/src/Formats/FormatSettings.h +++ b/dbms/src/Formats/FormatSettings.h @@ -27,7 +27,9 @@ struct FormatSettings char delimiter = ','; bool allow_single_quotes = true; bool allow_double_quotes = true; + bool unquoted_null_literal_as_null = false; bool empty_as_default = false; + bool null_as_default = false; }; CSV csv; From a3d25790bdf1a54842c13f878a576533acc842d1 Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Thu, 18 Jul 2019 17:41:11 +0300 Subject: [PATCH 0191/1165] basic implementation of reading in pk order and 'order by' optimization --- .../FinishSortingBlockInputStream.cpp | 34 +- .../Interpreters/InterpreterSelectQuery.cpp | 290 +++++++++--------- .../src/Interpreters/InterpreterSelectQuery.h | 2 +- dbms/src/Storages/IStorage.h | 5 - .../MergeTreeBaseSelectBlockInputStream.cpp | 93 +++--- .../MergeTreeBaseSelectBlockInputStream.h | 8 +- dbms/src/Storages/MergeTree/MergeTreeData.cpp | 2 +- .../Storages/MergeTree/MergeTreeDataPart.cpp | 7 +- .../Storages/MergeTree/MergeTreeDataPart.h | 12 +- .../MergeTree/MergeTreeDataSelectExecutor.cpp | 224 ++++++++++---- .../MergeTree/MergeTreeDataSelectExecutor.h | 1 + .../MergeTree/MergeTreeRangeReader.cpp | 1 + ...MergeTreeReverseSelectBlockInputStream.cpp | 238 ++++++++++++++ .../MergeTreeReverseSelectBlockInputStream.h | 84 +++++ .../src/Storages/MergeTree/RangesInDataPart.h | 9 + dbms/src/Storages/SelectQueryInfo.h | 17 +- 16 files changed, 719 insertions(+), 308 deletions(-) create mode 100644 dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.cpp create mode 100644 dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.h diff --git a/dbms/src/DataStreams/FinishSortingBlockInputStream.cpp b/dbms/src/DataStreams/FinishSortingBlockInputStream.cpp index a8e09c86721..461a1b36a65 100644 --- a/dbms/src/DataStreams/FinishSortingBlockInputStream.cpp +++ b/dbms/src/DataStreams/FinishSortingBlockInputStream.cpp @@ -62,30 +62,6 @@ struct Less } }; -template -ForwardIt upperBoundWithoutSWO(ForwardIt first, ForwardIt last, const T& value, Comparator comp) -{ - ForwardIt it; - typename std::iterator_traits::difference_type count, step; - count = std::distance(first, last); - - while (count > 0) - { - it = first; - step = count / 2; - std::advance(it, step); - if (!comp(value, *it)) - { - first = ++it; - count -= step + 1; - } - else - { - count = step; - } - } - return first; -} Block FinishSortingBlockInputStream::readImpl() { @@ -123,12 +99,11 @@ Block FinishSortingBlockInputStream::readImpl() if (description_to_sort.empty()) return block; - size_t size = block.rows(); - if (size == 0) + if (block.rows() == 0) continue; - /// We need to sort each block separately before merging. - sortBlock(block, description_to_sort); + // We need to sort each block separately before merging. + sortBlock(block, description_to_sort, limit); removeConstantsFromBlock(block); @@ -141,11 +116,12 @@ Block FinishSortingBlockInputStream::readImpl() Less less(last_columns, current_columns); + size_t size = block.rows(); IColumn::Permutation perm(size); for (size_t i = 0; i < size; ++i) perm[i] = i; - auto it = upperBoundWithoutSWO(perm.begin(), perm.end(), last_block.rows() - 1, less); + auto it = std::upper_bound(perm.begin(), perm.end(), last_block.rows() - 1, less); /// We need to save tail of block, because next block may starts with the same key as in tail /// and we should sort these rows in one chunk. diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.cpp b/dbms/src/Interpreters/InterpreterSelectQuery.cpp index 09b1cc41107..505cfdd00d8 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSelectQuery.cpp @@ -557,6 +557,69 @@ InterpreterSelectQuery::analyzeExpressions(QueryProcessingStage::Enum from_stage } +static SortDescription getSortDescription(const ASTSelectQuery & query) +{ + SortDescription order_descr; + order_descr.reserve(query.orderBy()->children.size()); + for (const auto & elem : query.orderBy()->children) + { + String name = elem->children.front()->getColumnName(); + const auto & order_by_elem = elem->as(); + + std::shared_ptr collator; + if (order_by_elem.collation) + collator = std::make_shared(order_by_elem.collation->as().value.get()); + + order_descr.emplace_back(name, order_by_elem.direction, order_by_elem.nulls_direction, collator); + } + + return order_descr; +} + + +static UInt64 getLimitUIntValue(const ASTPtr & node, const Context & context) +{ + const auto & [field, type] = evaluateConstantExpression(node, context); + + if (!isNativeNumber(type)) + throw Exception("Illegal type " + type->getName() + " of LIMIT expression, must be numeric type", ErrorCodes::INVALID_LIMIT_EXPRESSION); + + Field converted = convertFieldToType(field, DataTypeUInt64()); + if (converted.isNull()) + throw Exception("The value " + applyVisitor(FieldVisitorToString(), field) + " of LIMIT expression is not representable as UInt64", ErrorCodes::INVALID_LIMIT_EXPRESSION); + + return converted.safeGet(); +} + + +static std::pair getLimitLengthAndOffset(const ASTSelectQuery & query, const Context & context) +{ + UInt64 length = 0; + UInt64 offset = 0; + + if (query.limitLength()) + { + length = getLimitUIntValue(query.limitLength(), context); + if (query.limitOffset()) + offset = getLimitUIntValue(query.limitOffset(), context); + } + + return {length, offset}; +} + + +static UInt64 getLimitForSorting(const ASTSelectQuery & query, const Context & context) +{ + /// Partial sort can be done if there is LIMIT but no DISTINCT or LIMIT BY. + if (!query.distinct && !query.limitBy()) + { + auto [limit_length, limit_offset] = getLimitLengthAndOffset(query, context); + return limit_length + limit_offset; + } + return 0; +} + + void InterpreterSelectQuery::executeImpl(Pipeline & pipeline, const BlockInputStreamPtr & prepared_input, bool dry_run) { /** Streams of data. When the query is executed in parallel, we have several data streams. @@ -611,6 +674,41 @@ void InterpreterSelectQuery::executeImpl(Pipeline & pipeline, const BlockInputSt source_header = storage->getSampleBlockForColumns(filter_info->actions->getRequiredColumns()); } + if (settings.optimize_pk_order && storage && query.orderBy() && !query.groupBy() && !query.final()) + { + auto optimize_pk_order = [&](const auto & merge_tree) + { + if (!merge_tree.hasSortingKey()) + return; + + auto sorting_info = std::make_shared(); + + auto order_descr = getSortDescription(query); + const auto & sorting_key_columns = merge_tree.getSortingKeyColumns(); + int direction = order_descr.at(0).direction; + size_t prefix_size = std::min(order_descr.size(), sorting_key_columns.size()); + + for (size_t i = 0; i < prefix_size; ++i) + { + if (order_descr[i].column_name != sorting_key_columns[i] + || order_descr[i].direction != direction) + break; + sorting_info->prefix_order_descr.push_back(order_descr[i]); + } + + if (sorting_info->prefix_order_descr.empty()) + return; + + sorting_info->direction = direction; + sorting_info->limit = getLimitForSorting(query, context); + + query_info.sorting_info = sorting_info; + }; + + if (const MergeTreeData * merge_tree_data = dynamic_cast(storage.get())) + optimize_pk_order(*merge_tree_data); + } + if (dry_run) { pipeline.streams.emplace_back(std::make_shared(source_header)); @@ -704,7 +802,7 @@ void InterpreterSelectQuery::executeImpl(Pipeline & pipeline, const BlockInputSt if (!expressions.second_stage && !expressions.need_aggregate && !expressions.has_having) { if (expressions.has_order_by) - executeOrder(pipeline, query_info); + executeOrder(pipeline, query_info.sorting_info); if (expressions.has_order_by && query.limitLength()) executeDistinct(pipeline, false, expressions.selected_columns); @@ -798,7 +896,7 @@ void InterpreterSelectQuery::executeImpl(Pipeline & pipeline, const BlockInputSt if (!expressions.first_stage && !expressions.need_aggregate && !(query.group_by_with_totals && !aggregate_final)) executeMergeSorted(pipeline); else /// Otherwise, just sort. - executeOrder(pipeline, query_info); + executeOrder(pipeline, query_info.sorting_info); } /** Optimization - if there are several sources and there is LIMIT, then first apply the preliminary LIMIT, @@ -849,47 +947,6 @@ void InterpreterSelectQuery::executeImpl(Pipeline & pipeline, const BlockInputSt } -static UInt64 getLimitUIntValue(const ASTPtr & node, const Context & context) -{ - const auto & [field, type] = evaluateConstantExpression(node, context); - - if (!isNativeNumber(type)) - throw Exception("Illegal type " + type->getName() + " of LIMIT expression, must be numeric type", ErrorCodes::INVALID_LIMIT_EXPRESSION); - - Field converted = convertFieldToType(field, DataTypeUInt64()); - if (converted.isNull()) - throw Exception("The value " + applyVisitor(FieldVisitorToString(), field) + " of LIMIT expression is not representable as UInt64", ErrorCodes::INVALID_LIMIT_EXPRESSION); - - return converted.safeGet(); -} - -static std::pair getLimitLengthAndOffset(const ASTSelectQuery & query, const Context & context) -{ - UInt64 length = 0; - UInt64 offset = 0; - - if (query.limitLength()) - { - length = getLimitUIntValue(query.limitLength(), context); - if (query.limitOffset()) - offset = getLimitUIntValue(query.limitOffset(), context); - } - - return {length, offset}; -} - -static UInt64 getLimitForSorting(const ASTSelectQuery & query, const Context & context) -{ - /// Partial sort can be done if there is LIMIT but no DISTINCT or LIMIT BY. - if (!query.distinct && !query.limitBy()) - { - auto [limit_length, limit_offset] = getLimitLengthAndOffset(query, context); - return limit_length + limit_offset; - } - return 0; -} - - void InterpreterSelectQuery::executeFetchColumns( QueryProcessingStage::Enum processing_stage, Pipeline & pipeline, const PrewhereInfoPtr & prewhere_info, const Names & columns_to_remove_after_prewhere, @@ -1413,134 +1470,69 @@ void InterpreterSelectQuery::executeExpression(Pipeline & pipeline, const Expres } -static SortDescription getSortDescription(const ASTSelectQuery & query) -{ - SortDescription order_descr; - order_descr.reserve(query.orderBy()->children.size()); - for (const auto & elem : query.orderBy()->children) - { - String name = elem->children.front()->getColumnName(); - const auto & order_by_elem = elem->as(); - - std::shared_ptr collator; - if (order_by_elem.collation) - collator = std::make_shared(order_by_elem.collation->as().value.get()); - - order_descr.emplace_back(name, order_by_elem.direction, order_by_elem.nulls_direction, collator); - } - - return order_descr; -} - - -void InterpreterSelectQuery::executeOrder(Pipeline & pipeline, SelectQueryInfo & query_info) +void InterpreterSelectQuery::executeOrder(Pipeline & pipeline, SortingInfoPtr sorting_info) { auto & query = getSelectQuery(); SortDescription order_descr = getSortDescription(query); - - UInt64 limit = getLimitForSorting(query, context); const Settings & settings = context.getSettingsRef(); + UInt64 limit = getLimitForSorting(query, context); - const auto & order_direction = order_descr.at(0).direction; - - auto optimize_pk_order = [&](auto & merge_tree) + if (sorting_info) { - ASTPtr order_by_ptr = merge_tree.getSortingKeyAST(); - SortDescription prefix_order_descr; - bool need_sorting = order_by_ptr->children.size() < order_descr.size(); - size_t common_descr_size = std::min(order_descr.size(), order_by_ptr->children.size()); - for (size_t i = 0; i < common_descr_size; ++i) + /* Case of sorting with optimization using sorting key. + * We have several threads, each of them reads batch of parts in direct + * or reverse order of sorting key using one input stream per part + * and then merge them into one sorted stream. + * At this stage we merge per-thread streams into one. + */ + + if (sorting_info->prefix_order_descr.size() < order_descr.size()) { - String name = order_by_ptr->children[i]->getAliasOrColumnName(); - if (order_descr[i].column_name != name - || order_direction != order_descr[i].direction) - { - need_sorting = true; - break; - } - else - { - prefix_order_descr.push_back(order_descr[i]); - } - } - query_info.do_not_steal_task = true; - query_info.read_in_pk_order = true; - if (order_direction == -1) - { - query_info.read_in_reverse_order = true; pipeline.transform([&](auto & stream) { - stream = std::make_shared(stream); + stream = std::make_shared( + stream, sorting_info->prefix_order_descr, + order_descr, settings.max_block_size, limit); }); } - if (need_sorting) + + if (pipeline.hasMoreThanOneStream()) { - if (!prefix_order_descr.empty()) + pipeline.transform([&](auto & stream) { - pipeline.transform([&](auto & stream) - { - stream = std::make_shared( - stream, - prefix_order_descr, - order_descr, - settings.max_block_size, - limit); - }); - } - else - { - pipeline.transform([&](auto & stream) - { - auto sorting_stream = std::make_shared(stream, order_descr, limit); + stream = std::make_shared(stream); + }); - /// Limits on sorting - IBlockInputStream::LocalLimits limits; - limits.mode = IBlockInputStream::LIMITS_TOTAL; - limits.size_limits = SizeLimits(settings.max_rows_to_sort, settings.max_bytes_to_sort, settings.sort_overflow_mode); - sorting_stream->setLimits(limits); - - stream = sorting_stream; - }); - } + pipeline.firstStream() = std::make_shared( + pipeline.streams, order_descr, + settings.max_block_size, limit); + pipeline.streams.resize(1); } + } + else + { + pipeline.transform([&](auto & stream) + { + auto sorting_stream = std::make_shared(stream, order_descr, limit); + /// Limits on sorting + IBlockInputStream::LocalLimits limits; + limits.mode = IBlockInputStream::LIMITS_TOTAL; + limits.size_limits = SizeLimits(settings.max_rows_to_sort, settings.max_bytes_to_sort, settings.sort_overflow_mode); + sorting_stream->setLimits(limits); + + stream = sorting_stream; + }); + + /// If there are several streams, we merge them into one executeUnion(pipeline); + + /// Merge the sorted blocks. pipeline.firstStream() = std::make_shared( pipeline.firstStream(), order_descr, settings.max_block_size, limit, settings.max_bytes_before_remerge_sort, settings.max_bytes_before_external_sort, context.getTemporaryPath()); - }; - - if (settings.optimize_pk_order && !query.groupBy() && !order_descr.empty() && !query.final()) - { - if (const auto * merge_tree = dynamic_cast(storage.get())) - { - optimize_pk_order(*merge_tree); - return; - } } - - pipeline.transform([&](auto & stream) - { - auto sorting_stream = std::make_shared(stream, order_descr, limit); - - /// Limits on sorting - IBlockInputStream::LocalLimits limits; - limits.mode = IBlockInputStream::LIMITS_TOTAL; - limits.size_limits = SizeLimits(settings.max_rows_to_sort, settings.max_bytes_to_sort, settings.sort_overflow_mode); - sorting_stream->setLimits(limits); - - stream = sorting_stream; - }); - - /// If there are several streams, we merge them into one - executeUnion(pipeline); - - /// Merge the sorted blocks. - pipeline.firstStream() = std::make_shared( - pipeline.firstStream(), order_descr, settings.max_block_size, limit, - settings.max_bytes_before_remerge_sort, - settings.max_bytes_before_external_sort, context.getTemporaryPath()); } void InterpreterSelectQuery::executeMergeSorted(Pipeline & pipeline) diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.h b/dbms/src/Interpreters/InterpreterSelectQuery.h index 754162f78bf..18df989cbc5 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.h +++ b/dbms/src/Interpreters/InterpreterSelectQuery.h @@ -187,7 +187,7 @@ private: void executeTotalsAndHaving(Pipeline & pipeline, bool has_having, const ExpressionActionsPtr & expression, bool overflow_row, bool final); void executeHaving(Pipeline & pipeline, const ExpressionActionsPtr & expression); void executeExpression(Pipeline & pipeline, const ExpressionActionsPtr & expression); - void executeOrder(Pipeline & pipeline, SelectQueryInfo & query_info); + void executeOrder(Pipeline & pipeline, SortingInfoPtr sorting_info); void executeMergeSorted(Pipeline & pipeline); void executePreLimit(Pipeline & pipeline); void executeUnion(Pipeline & pipeline); diff --git a/dbms/src/Storages/IStorage.h b/dbms/src/Storages/IStorage.h index fa1516a366e..076a47d9613 100644 --- a/dbms/src/Storages/IStorage.h +++ b/dbms/src/Storages/IStorage.h @@ -333,11 +333,6 @@ public: /// Returns names of primary key + secondary sorting columns virtual Names getSortingKeyColumns() const { return {}; } -protected: - /// Returns whether the column is virtual - by default all columns are real. - /// Initially reserved virtual column name may be shadowed by real column. - /// Returns false even for non-existent non-virtual columns. - virtual bool isVirtualColumn(const String & /* column_name */) const { return false; } private: /// You always need to take the next three locks in this order. diff --git a/dbms/src/Storages/MergeTree/MergeTreeBaseSelectBlockInputStream.cpp b/dbms/src/Storages/MergeTree/MergeTreeBaseSelectBlockInputStream.cpp index ad953357edb..5896b776739 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeBaseSelectBlockInputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeBaseSelectBlockInputStream.cpp @@ -51,23 +51,59 @@ Block MergeTreeBaseSelectBlockInputStream::readImpl() while (!res && !isCancelled()) { - if (!task && !getNewTask()) + if ((!task || task->isFinished()) && !getNewTask()) break; res = readFromPart(); if (res) injectVirtualColumns(res); - - if (task->isFinished()) - task.reset(); } return res; } -Block MergeTreeBaseSelectBlockInputStream::readFromPart() +void MergeTreeBaseSelectBlockInputStream::initializeRangeReaders(MergeTreeReadTask & task) +{ + if (prewhere_info) + { + if (reader->getColumns().empty()) + { + task.range_reader = MergeTreeRangeReader( + pre_reader.get(), nullptr, + prewhere_info->alias_actions, prewhere_info->prewhere_actions, + &prewhere_info->prewhere_column_name, &task.ordered_names, + task.should_reorder, task.remove_prewhere_column, true); + } + else + { + MergeTreeRangeReader * pre_reader_ptr = nullptr; + if (pre_reader != nullptr) + { + task.pre_range_reader = MergeTreeRangeReader( + pre_reader.get(), nullptr, + prewhere_info->alias_actions, prewhere_info->prewhere_actions, + &prewhere_info->prewhere_column_name, &task.ordered_names, + task.should_reorder, task.remove_prewhere_column, false); + pre_reader_ptr = &task.pre_range_reader; + } + + task.range_reader = MergeTreeRangeReader( + reader.get(), pre_reader_ptr, nullptr, nullptr, + nullptr, &task.ordered_names, true, false, true); + } + } + else + { + task.range_reader = MergeTreeRangeReader( + reader.get(), nullptr, nullptr, nullptr, + nullptr, &task.ordered_names, task.should_reorder, false, true); + } +} + + +Block MergeTreeBaseSelectBlockInputStream::readFromPartImpl() { if (task->size_predictor) task->size_predictor->startBlock(); @@ -113,44 +149,6 @@ Block MergeTreeBaseSelectBlockInputStream::readFromPart() return index_granularity.countMarksForRows(current_reader.currentMark(), rows_to_read, current_reader.numReadRowsInCurrentGranule()); }; - if (!task->range_reader.isInitialized()) - { - if (prewhere_info) - { - if (reader->getColumns().empty()) - { - task->range_reader = MergeTreeRangeReader( - pre_reader.get(), nullptr, - prewhere_info->alias_actions, prewhere_info->prewhere_actions, - &prewhere_info->prewhere_column_name, &task->ordered_names, - task->should_reorder, task->remove_prewhere_column, true); - } - else - { - MergeTreeRangeReader * pre_reader_ptr = nullptr; - if (pre_reader != nullptr) - { - task->pre_range_reader = MergeTreeRangeReader( - pre_reader.get(), nullptr, - prewhere_info->alias_actions, prewhere_info->prewhere_actions, - &prewhere_info->prewhere_column_name, &task->ordered_names, - task->should_reorder, task->remove_prewhere_column, false); - pre_reader_ptr = &task->pre_range_reader; - } - - task->range_reader = MergeTreeRangeReader( - reader.get(), pre_reader_ptr, nullptr, nullptr, - nullptr, &task->ordered_names, true, false, true); - } - } - else - { - task->range_reader = MergeTreeRangeReader( - reader.get(), nullptr, nullptr, nullptr, - nullptr, &task->ordered_names, task->should_reorder, false, true); - } - } - UInt64 recommended_rows = estimateNumRows(*task, task->range_reader); UInt64 rows_to_read = std::max(UInt64(1), std::min(current_max_block_size_rows, recommended_rows)); @@ -185,6 +183,15 @@ Block MergeTreeBaseSelectBlockInputStream::readFromPart() } +Block MergeTreeBaseSelectBlockInputStream::readFromPart() +{ + if (!task->range_reader.isInitialized()) + initializeRangeReaders(*task); + + return readFromPartImpl(); +} + + void MergeTreeBaseSelectBlockInputStream::injectVirtualColumns(Block & block) const { /// add virtual columns diff --git a/dbms/src/Storages/MergeTree/MergeTreeBaseSelectBlockInputStream.h b/dbms/src/Storages/MergeTree/MergeTreeBaseSelectBlockInputStream.h index 5f72fb132af..31a1e36921d 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeBaseSelectBlockInputStream.h +++ b/dbms/src/Storages/MergeTree/MergeTreeBaseSelectBlockInputStream.h @@ -36,16 +36,22 @@ public: protected: Block readImpl() final; + Block readFromPartImpl(); + /// Creates new this->task, and initilizes readers virtual bool getNewTask() = 0; /// We will call progressImpl manually. void progress(const Progress &) override {} - Block readFromPart(); + virtual Block readFromPart(); void injectVirtualColumns(Block & block) const; + void initializeRangeReaders(MergeTreeReadTask & task); + + size_t estimateNumRows(MergeTreeReadTask & current_task, MergeTreeRangeReader & current_reader); + protected: const MergeTreeData & storage; diff --git a/dbms/src/Storages/MergeTree/MergeTreeData.cpp b/dbms/src/Storages/MergeTree/MergeTreeData.cpp index e3ee89b7c45..8bc87175bba 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeData.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeData.cpp @@ -751,7 +751,7 @@ void MergeTreeData::loadDataParts(bool skip_sanity_checks) if (!MergeTreePartInfo::tryParsePartName(file_name, &part_info, format_version)) continue; - MutableDataPartPtr part = std::make_shared(*this, file_name, part_info, data_parts_counter); + MutableDataPartPtr part = std::make_shared(*this, file_name, part_info); ++data_parts_counter; part->relative_path = file_name; bool broken = false; diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp index 6ca8e5a75a3..75f87096edf 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp @@ -134,25 +134,22 @@ void MergeTreeDataPart::MinMaxIndex::merge(const MinMaxIndex & other) } -MergeTreeDataPart::MergeTreeDataPart(MergeTreeData & storage_, const String & name_, size_t data_part_id_) +MergeTreeDataPart::MergeTreeDataPart(MergeTreeData & storage_, const String & name_) : storage(storage_) , name(name_) , info(MergeTreePartInfo::fromPartName(name_, storage.format_version)) , index_granularity_info(storage) - , data_part_id(data_part_id_) { } MergeTreeDataPart::MergeTreeDataPart( const MergeTreeData & storage_, const String & name_, - const MergeTreePartInfo & info_, - size_t data_part_id_) + const MergeTreePartInfo & info_) : storage(storage_) , name(name_) , info(info_) , index_granularity_info(storage) - , data_part_id(data_part_id_) { } diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataPart.h b/dbms/src/Storages/MergeTree/MergeTreeDataPart.h index 28e3d483704..f775e5bc085 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataPart.h +++ b/dbms/src/Storages/MergeTree/MergeTreeDataPart.h @@ -31,9 +31,9 @@ struct MergeTreeDataPart using Checksums = MergeTreeDataPartChecksums; using Checksum = MergeTreeDataPartChecksums::Checksum; - MergeTreeDataPart(const MergeTreeData & storage_, const String & name_, const MergeTreePartInfo & info_, size_t data_part_id_ = 0); + MergeTreeDataPart(const MergeTreeData & storage_, const String & name_, const MergeTreePartInfo & info_); - MergeTreeDataPart(MergeTreeData & storage_, const String & name_, size_t data_part_id_ = 0); + MergeTreeDataPart(MergeTreeData & storage_, const String & name_); /// Returns the name of a column with minimum compressed size (as returned by getColumnSize()). /// If no checksums are present returns the name of the first physically existing column. @@ -93,9 +93,6 @@ struct MergeTreeDataPart /// Examples: 'detached/tmp_fetch_', 'tmp_', '' mutable String relative_path; - /// Is used in reading in pk_order - size_t data_part_id = 0; - size_t rows_count = 0; std::atomic bytes_on_disk {0}; /// 0 - if not counted; /// Is used from several threads without locks (it is changed with ALTER). @@ -151,11 +148,6 @@ struct MergeTreeDataPart return name + " (state " + stateString() + ")"; } - void setDataPartId(size_t data_part_id_) - { - data_part_id = data_part_id_; - } - /// Returns true if state of part is one of affordable_states bool checkState(const std::initializer_list & affordable_states) const { diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index 382ea264a8f..8411538c2d1 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,7 @@ namespace std #include #include #include +#include #include #include #include @@ -548,8 +550,7 @@ BlockInputStreams MergeTreeDataSelectExecutor::readFromParts( parts_with_ranges.push_back(ranges); sum_ranges += ranges.ranges.size(); - for (const auto & range : ranges.ranges) - sum_marks += range.end - range.begin; + sum_marks += ranges.getMarksCount(); } } @@ -588,21 +589,11 @@ BlockInputStreams MergeTreeDataSelectExecutor::readFromParts( virt_column_names, settings); } - else if (settings.optimize_pk_order && query_info.read_in_pk_order) + else if (settings.optimize_pk_order && query_info.sorting_info) { - std::vector add_columns = data.sorting_key_expr->getRequiredColumns(); - column_names_to_read.insert(column_names_to_read.end(), add_columns.begin(), add_columns.end()); - - if (!data.merging_params.sign_column.empty()) - column_names_to_read.push_back(data.merging_params.sign_column); - if (!data.merging_params.version_column.empty()) - column_names_to_read.push_back(data.merging_params.version_column); - - std::sort(column_names_to_read.begin(), column_names_to_read.end()); - column_names_to_read.erase(std::unique(column_names_to_read.begin(), column_names_to_read.end()), column_names_to_read.end()); - res = spreadMarkRangesAmongStreamsPKOrder( std::move(parts_with_ranges), + num_streams, column_names_to_read, max_block_size, settings.use_uncompressed_cache, @@ -668,17 +659,6 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreams( const Names & virt_columns, const Settings & settings) const { - const PrewhereInfoPtr prewhere_info = query_info.prewhere_info; - const size_t max_marks_to_use_cache = roundRowsOrBytesToMarks( - settings.merge_tree_max_rows_to_use_cache, - settings.merge_tree_max_bytes_to_use_cache, - data.index_granularity_info); - - const size_t min_marks_for_concurrent_read = roundRowsOrBytesToMarks( - settings.merge_tree_min_rows_for_concurrent_read, - settings.merge_tree_min_bytes_for_concurrent_read, - data.index_granularity_info); - /// Count marks for each part. std::vector sum_marks_in_parts(parts.size()); size_t sum_marks = 0; @@ -691,10 +671,9 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreams( /// Let the ranges be listed from right to left so that the leftmost range can be dropped using `pop_back()`. std::reverse(parts[i].ranges.begin(), parts[i].ranges.end()); - for (const auto & range : parts[i].ranges) - sum_marks_in_parts[i] += range.end - range.begin; - + sum_marks_in_parts[i] = parts[i].getMarksCount(); sum_marks += sum_marks_in_parts[i]; + if (parts[i].data_part->index_granularity_info.is_adaptive) adaptive_parts++; } @@ -727,8 +706,8 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreams( num_streams = std::max((sum_marks + min_marks_for_concurrent_read - 1) / min_marks_for_concurrent_read, parts.size()); MergeTreeReadPoolPtr pool = std::make_shared( - num_streams, sum_marks, min_marks_for_concurrent_read, parts, data, prewhere_info, true, - column_names, MergeTreeReadPool::BackoffSettings(settings), settings.preferred_block_size_bytes, query_info.do_not_steal_task); + num_streams, sum_marks, min_marks_for_concurrent_read, parts, data, query_info.prewhere_info, true, + column_names, MergeTreeReadPool::BackoffSettings(settings), settings.preferred_block_size_bytes, false); /// Let's estimate total number of rows for progress bar. LOG_TRACE(log, "Reading approx. " << total_rows << " rows with " << num_streams << " streams"); @@ -738,7 +717,7 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreams( res.emplace_back(std::make_shared( i, pool, min_marks_for_concurrent_read, max_block_size, settings.preferred_block_size_bytes, settings.preferred_max_column_in_block_size_bytes, data, use_uncompressed_cache, - prewhere_info, settings, virt_columns)); + query_info.prewhere_info, settings, virt_columns)); if (i == 0) { @@ -814,7 +793,7 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreams( BlockInputStreamPtr source_stream = std::make_shared( data, part.data_part, max_block_size, settings.preferred_block_size_bytes, settings.preferred_max_column_in_block_size_bytes, column_names, ranges_to_get_from_part, - use_uncompressed_cache, prewhere_info, true, settings.min_bytes_to_use_direct_io, + use_uncompressed_cache, query_info.prewhere_info, true, settings.min_bytes_to_use_direct_io, settings.max_read_buffer_size, true, virt_columns, part.part_index_in_query); res.push_back(source_stream); @@ -830,6 +809,7 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreams( BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsPKOrder( RangesInDataParts && parts, + size_t num_streams, const Names & column_names, UInt64 max_block_size, bool use_uncompressed_cache, @@ -837,42 +817,171 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsPKOrd const Names & virt_columns, const Settings & settings) const { - const PrewhereInfoPtr prewhere_info = query_info.prewhere_info; + size_t sum_marks = 0; + SortingInfoPtr sorting_info = query_info.sorting_info; + size_t adaptive_parts = 0; + std::vector sum_marks_in_parts(parts.size()); + + size_t index_granularity_bytes = 0; + if (adaptive_parts > parts.size() / 2) + index_granularity_bytes = data.settings.index_granularity_bytes; + const size_t max_marks_to_use_cache = roundRowsOrBytesToMarks( settings.merge_tree_max_rows_to_use_cache, settings.merge_tree_max_bytes_to_use_cache, - data.index_granularity_info); + data.settings.index_granularity, + index_granularity_bytes); - size_t sum_marks = 0; - for (size_t i = 0; i < parts.size(); ++i) - for (size_t j = 0; j < parts[i].ranges.size(); ++j) - sum_marks += parts[i].ranges[j].end - parts[i].ranges[j].begin; + const size_t min_marks_for_concurrent_read = roundRowsOrBytesToMarks( + settings.merge_tree_min_rows_for_concurrent_read, + settings.merge_tree_min_bytes_for_concurrent_read, + data.settings.index_granularity, + index_granularity_bytes); if (sum_marks > max_marks_to_use_cache) use_uncompressed_cache = false; - BlockInputStreams to_merge; - - for (size_t part_index = 0; part_index < parts.size(); ++part_index) + /// In case of reverse order let's split ranges to avoid reading much data. + auto split_ranges = [max_block_size](const auto & ranges, size_t rows_granularity, size_t num_marks_in_part) { - size_t index = part_index; - if (query_info.read_in_reverse_order) - index = parts.size() - part_index - 1; + /// Constants is just a guess. + const size_t min_rows_in_range = max_block_size * 4; + const size_t max_num_ranges = 32; - RangesInDataPart & part = parts[index]; + size_t min_marks_in_range = std::max( + (min_rows_in_range + rows_granularity - 1) / rows_granularity, + (num_marks_in_part + max_num_ranges - 1) / max_num_ranges); - BlockInputStreamPtr source_stream = std::make_shared( - data, part.data_part, max_block_size, settings.preferred_block_size_bytes, - settings.preferred_max_column_in_block_size_bytes, column_names, part.ranges, use_uncompressed_cache, - prewhere_info, true, settings.min_bytes_to_use_direct_io, settings.max_read_buffer_size, true, - virt_columns, part.part_index_in_query); + MarkRanges new_ranges; + for (auto range : ranges) + { + while (range.begin + min_marks_in_range < range.end) + { + new_ranges.emplace_back(range.begin, range.begin + min_marks_in_range); + range.begin += min_marks_in_range; + } + new_ranges.emplace_back(range.begin, range.end); + } - to_merge.emplace_back(source_stream); + return new_ranges; + }; + + for (size_t i = 0; i < parts.size(); ++i) + { + sum_marks_in_parts[i] = parts[i].getMarksCount(); + sum_marks += sum_marks_in_parts[i]; + + if (sorting_info->direction == -1) + parts[i].ranges = split_ranges(parts[i].ranges, data.settings.index_granularity, sum_marks_in_parts[i]); + + /// Let the ranges be listed from right to left so that the leftmost range can be dropped using `pop_back()`. + std::reverse(parts[i].ranges.begin(), parts[i].ranges.end()); + + if (parts[i].data_part->index_granularity_info.is_adaptive) + adaptive_parts++; } - return to_merge; -} + BlockInputStreams streams; + if (sum_marks == 0) + return streams; + + const size_t min_marks_per_stream = (sum_marks - 1) / num_streams + 1; + + for (size_t i = 0; i < num_streams && !parts.empty(); ++i) + { + size_t need_marks = min_marks_per_stream; + + BlockInputStreams streams_per_thread; + + /// Loop over parts. + /// We will iteratively take part or some subrange of a part from the back + /// and assign a stream to read from it. + while (need_marks > 0 && !parts.empty()) + { + RangesInDataPart part = parts.back(); + parts.pop_back(); + + size_t & marks_in_part = sum_marks_in_parts.back(); + + /// We will not take too few rows from a part. + if (marks_in_part >= min_marks_for_concurrent_read && + need_marks < min_marks_for_concurrent_read) + need_marks = min_marks_for_concurrent_read; + + /// Do not leave too few rows in the part. + if (marks_in_part > need_marks && + marks_in_part - need_marks < min_marks_for_concurrent_read) + need_marks = marks_in_part; + + MarkRanges ranges_to_get_from_part; + + /// We take the whole part if it is small enough. + if (marks_in_part <= need_marks) + { + /// Restore the order of segments. + std::reverse(part.ranges.begin(), part.ranges.end()); + + ranges_to_get_from_part = part.ranges; + + need_marks -= marks_in_part; + sum_marks_in_parts.pop_back(); + } + else + { + /// Loop through ranges in part. Take enough ranges to cover "need_marks". + while (need_marks > 0) + { + if (part.ranges.empty()) + throw Exception("Unexpected end of ranges while spreading marks among streams", ErrorCodes::LOGICAL_ERROR); + + MarkRange & range = part.ranges.back(); + + const size_t marks_in_range = range.end - range.begin; + const size_t marks_to_get_from_range = std::min(marks_in_range, need_marks); + + ranges_to_get_from_part.emplace_back(range.begin, range.begin + marks_to_get_from_range); + range.begin += marks_to_get_from_range; + marks_in_part -= marks_to_get_from_range; + need_marks -= marks_to_get_from_range; + if (range.begin == range.end) + part.ranges.pop_back(); + } + parts.emplace_back(part); + } + + BlockInputStreamPtr source_stream; + if (sorting_info->direction == 1) + { + source_stream = std::make_shared( + data, part.data_part, max_block_size, settings.preferred_block_size_bytes, + settings.preferred_max_column_in_block_size_bytes, column_names, ranges_to_get_from_part, + use_uncompressed_cache, query_info.prewhere_info, true, settings.min_bytes_to_use_direct_io, + settings.max_read_buffer_size, true, virt_columns, part.part_index_in_query); + } + else + { + source_stream = std::make_shared( + data, part.data_part, max_block_size, settings.preferred_block_size_bytes, + settings.preferred_max_column_in_block_size_bytes, column_names, ranges_to_get_from_part, + use_uncompressed_cache, query_info.prewhere_info, true, settings.min_bytes_to_use_direct_io, + settings.max_read_buffer_size, true, virt_columns, part.part_index_in_query); + + source_stream = std::make_shared(source_stream); + } + + streams_per_thread.push_back(source_stream); + } + + if (streams_per_thread.size() > 1) + streams.push_back(std::make_shared( + streams_per_thread, sorting_info->prefix_order_descr, max_block_size)); + else + streams.push_back(streams_per_thread.at(0)); + } + + return streams; +} BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsFinal( @@ -884,12 +993,6 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsFinal const Names & virt_columns, const Settings & settings) const { - const PrewhereInfoPtr prewhere_info = query_info.prewhere_info; - const size_t max_marks_to_use_cache = roundRowsOrBytesToMarks( - settings.merge_tree_max_rows_to_use_cache, - settings.merge_tree_max_bytes_to_use_cache, - data.index_granularity_info); - size_t sum_marks = 0; size_t adaptive_parts = 0; for (size_t i = 0; i < parts.size(); ++i) @@ -925,13 +1028,12 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsFinal BlockInputStreamPtr source_stream = std::make_shared( data, part.data_part, max_block_size, settings.preferred_block_size_bytes, settings.preferred_max_column_in_block_size_bytes, column_names, part.ranges, use_uncompressed_cache, - prewhere_info, true, settings.min_bytes_to_use_direct_io, settings.max_read_buffer_size, true, + query_info.prewhere_info, true, settings.min_bytes_to_use_direct_io, settings.max_read_buffer_size, true, virt_columns, part.part_index_in_query); to_merge.emplace_back(std::make_shared(source_stream, data.sorting_key_expr)); } - Names sort_columns = data.sorting_key_columns; SortDescription sort_description; size_t sort_columns_size = sort_columns.size(); diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h index 4f964e8b915..92ea39a80ec 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h +++ b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h @@ -58,6 +58,7 @@ private: BlockInputStreams spreadMarkRangesAmongStreamsPKOrder( RangesInDataParts && parts, + size_t num_streams, const Names & column_names, UInt64 max_block_size, bool use_uncompressed_cache, diff --git a/dbms/src/Storages/MergeTree/MergeTreeRangeReader.cpp b/dbms/src/Storages/MergeTree/MergeTreeRangeReader.cpp index e81737036e4..bc1468f2fb7 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeRangeReader.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeRangeReader.cpp @@ -427,6 +427,7 @@ size_t MergeTreeRangeReader::numReadRowsInCurrentGranule() const { return prev_reader ? prev_reader->numReadRowsInCurrentGranule() : stream.numReadRowsInCurrentGranule(); } + size_t MergeTreeRangeReader::numPendingRowsInCurrentGranule() const { if (prev_reader) diff --git a/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.cpp b/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.cpp new file mode 100644 index 00000000000..b15e3a1ad3a --- /dev/null +++ b/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.cpp @@ -0,0 +1,238 @@ +#include +#include +#include +#include + + +namespace DB +{ + +namespace ErrorCodes +{ + extern const int MEMORY_LIMIT_EXCEEDED; +} + + +MergeTreeReverseSelectBlockInputStream::MergeTreeReverseSelectBlockInputStream( + const MergeTreeData & storage_, + const MergeTreeData::DataPartPtr & owned_data_part_, + UInt64 max_block_size_rows_, + size_t preferred_block_size_bytes_, + size_t preferred_max_column_in_block_size_bytes_, + Names column_names, + const MarkRanges & mark_ranges_, + bool use_uncompressed_cache_, + const PrewhereInfoPtr & prewhere_info_, + bool check_columns, + size_t min_bytes_to_use_direct_io_, + size_t max_read_buffer_size_, + bool save_marks_in_cache_, + const Names & virt_column_names_, + size_t part_index_in_query_, + bool quiet) + : + MergeTreeBaseSelectBlockInputStream{storage_, prewhere_info_, max_block_size_rows_, + preferred_block_size_bytes_, preferred_max_column_in_block_size_bytes_, min_bytes_to_use_direct_io_, + max_read_buffer_size_, use_uncompressed_cache_, save_marks_in_cache_, virt_column_names_}, + required_columns{column_names}, + data_part{owned_data_part_}, + part_columns_lock(data_part->columns_lock), + all_mark_ranges(mark_ranges_), + part_index_in_query(part_index_in_query_), + check_columns(check_columns), + path(data_part->getFullPath()) +{ + /// Let's estimate total number of rows for progress bar. + for (const auto & range : all_mark_ranges) + total_marks_count += range.end - range.begin; + + size_t total_rows = data_part->index_granularity.getTotalRows(); + + if (!quiet) + LOG_TRACE(log, "Reading " << all_mark_ranges.size() << " ranges in reverse order from part " << data_part->name + << ", approx. " << total_rows + << (all_mark_ranges.size() > 1 + ? ", up to " + toString(data_part->index_granularity.getRowsCountInRanges(all_mark_ranges)) + : "") + << " rows starting from " << data_part->index_granularity.getMarkStartingRow(all_mark_ranges.front().begin)); + + addTotalRowsApprox(total_rows); + header = storage.getSampleBlockForColumns(required_columns); + + /// Types may be different during ALTER (when this stream is used to perform an ALTER). + /// NOTE: We may use similar code to implement non blocking ALTERs. + for (const auto & name_type : data_part->columns) + { + if (header.has(name_type.name)) + { + auto & elem = header.getByName(name_type.name); + if (!elem.type->equals(*name_type.type)) + { + elem.type = name_type.type; + elem.column = elem.type->createColumn(); + } + } + } + + executePrewhereActions(header, prewhere_info); + injectVirtualColumns(header); + + ordered_names = getHeader().getNames(); + + Names pre_column_names; + + /// inject columns required for defaults evaluation + should_reorder = !injectRequiredColumns(storage, data_part, required_columns).empty(); + + if (prewhere_info) + { + if (prewhere_info->alias_actions) + pre_column_names = prewhere_info->alias_actions->getRequiredColumns(); + else + pre_column_names = prewhere_info->prewhere_actions->getRequiredColumns(); + + if (pre_column_names.empty()) + pre_column_names.push_back(required_columns[0]); + + const auto injected_pre_columns = injectRequiredColumns(storage, data_part, pre_column_names); + if (!injected_pre_columns.empty()) + should_reorder = true; + + const NameSet pre_name_set(pre_column_names.begin(), pre_column_names.end()); + + Names post_column_names; + for (const auto & name : required_columns) + if (!pre_name_set.count(name)) + post_column_names.push_back(name); + + required_columns = post_column_names; + } + + /// will be used to distinguish between PREWHERE and WHERE columns when applying filter + column_name_set = NameSet{required_columns.begin(), required_columns.end()}; + + if (check_columns) + { + /// Under owned_data_part->columns_lock we check that all requested columns are of the same type as in the table. + /// This may be not true in case of ALTER MODIFY. + if (!pre_column_names.empty()) + storage.check(data_part->columns, pre_column_names); + if (!required_columns.empty()) + storage.check(data_part->columns, required_columns); + + const NamesAndTypesList & physical_columns = storage.getColumns().getAllPhysical(); + pre_columns = physical_columns.addTypes(pre_column_names); + columns = physical_columns.addTypes(column_names); + } + else + { + pre_columns = data_part->columns.addTypes(pre_column_names); + columns = data_part->columns.addTypes(required_columns); + } + + if (use_uncompressed_cache) + owned_uncompressed_cache = storage.global_context.getUncompressedCache(); + + owned_mark_cache = storage.global_context.getMarkCache(); + + reader = std::make_unique( + path, data_part, columns, owned_uncompressed_cache.get(), + owned_mark_cache.get(), save_marks_in_cache, storage, + all_mark_ranges, min_bytes_to_use_direct_io, max_read_buffer_size); + + if (prewhere_info) + pre_reader = std::make_unique( + path, data_part, pre_columns, owned_uncompressed_cache.get(), + owned_mark_cache.get(), save_marks_in_cache, storage, + all_mark_ranges, min_bytes_to_use_direct_io, max_read_buffer_size); +} + + +Block MergeTreeReverseSelectBlockInputStream::getHeader() const +{ + return header; +} + + +bool MergeTreeReverseSelectBlockInputStream::getNewTask() +try +{ + if ((blocks.empty() && all_mark_ranges.empty()) || total_marks_count == 0) + { + finish(); + return false; + } + + /// We have some blocks to return in buffer. + /// Return true to continue reading, but actually don't create a task. + if (all_mark_ranges.empty()) + return true; + + /// Read ranges from right to left. + MarkRanges mark_ranges_for_task = { all_mark_ranges.back() }; + all_mark_ranges.pop_back(); + + auto size_predictor = (preferred_block_size_bytes == 0) + ? nullptr + : std::make_unique(data_part, ordered_names, data_part->storage.getSampleBlock()); + + task = std::make_unique( + data_part, mark_ranges_for_task, part_index_in_query, ordered_names, column_name_set, columns, pre_columns, + prewhere_info && prewhere_info->remove_prewhere_column, should_reorder, std::move(size_predictor)); + + return true; +} +catch (...) +{ + /// Suspicion of the broken part. A part is added to the queue for verification. + if (getCurrentExceptionCode() != ErrorCodes::MEMORY_LIMIT_EXCEEDED) + storage.reportBrokenPart(data_part->name); + throw; +} + +Block MergeTreeReverseSelectBlockInputStream::readFromPart() +{ + Block res; + + if (!blocks.empty()) + { + res = std::move(blocks.back()); + blocks.pop_back(); + return res; + } + + if (!task->range_reader.isInitialized()) + initializeRangeReaders(*task); + + while (!task->isFinished()) + { + Block block = readFromPartImpl(); + blocks.push_back(std::move(block)); + } + + if (blocks.empty()) + return {}; + + res = std::move(blocks.back()); + blocks.pop_back(); + + return res; +} + +void MergeTreeReverseSelectBlockInputStream::finish() +{ + /** Close the files (before destroying the object). + * When many sources are created, but simultaneously reading only a few of them, + * buffers don't waste memory. + */ + reader.reset(); + pre_reader.reset(); + part_columns_lock.unlock(); + data_part.reset(); +} + + +MergeTreeReverseSelectBlockInputStream::~MergeTreeReverseSelectBlockInputStream() = default; + + +} diff --git a/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.h b/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.h new file mode 100644 index 00000000000..381bee4aa95 --- /dev/null +++ b/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.h @@ -0,0 +1,84 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +namespace DB +{ + + +/// Used to read data from single part with select query +/// Cares about PREWHERE, virtual columns, indexes etc. +/// To read data from multiple parts, Storage (MergeTree) creates multiple such objects. +class MergeTreeReverseSelectBlockInputStream : public MergeTreeBaseSelectBlockInputStream +{ +public: + MergeTreeReverseSelectBlockInputStream( + const MergeTreeData & storage, + const MergeTreeData::DataPartPtr & owned_data_part, + UInt64 max_block_size_rows, + size_t preferred_block_size_bytes, + size_t preferred_max_column_in_block_size_bytes, + Names column_names, + const MarkRanges & mark_ranges, + bool use_uncompressed_cache, + const PrewhereInfoPtr & prewhere_info, + bool check_columns, + size_t min_bytes_to_use_direct_io, + size_t max_read_buffer_size, + bool save_marks_in_cache, + const Names & virt_column_names = {}, + size_t part_index_in_query = 0, + bool quiet = false); + + ~MergeTreeReverseSelectBlockInputStream() override; + + String getName() const override { return "MergeTreeReverse"; } + + Block getHeader() const override; + + /// Closes readers and unlock part locks + void finish(); + +protected: + + bool getNewTask() override; + Block readFromPart() override; + +private: + Block header; + + /// Used by Task + Names required_columns; + /// Names from header. Used in order to order columns in read blocks. + Names ordered_names; + NameSet column_name_set; + NamesAndTypesList columns; + NamesAndTypesList pre_columns; + + /// Data part will not be removed if the pointer owns it + MergeTreeData::DataPartPtr data_part; + /// Forbids to change columns list of the part during reading + std::shared_lock part_columns_lock; + + /// Mark ranges we should read (in ascending order) + MarkRanges all_mark_ranges; + /// Total number of marks we should read + size_t total_marks_count = 0; + /// Value of _part_index virtual column (used only in SelectExecutor) + size_t part_index_in_query = 0; + + bool check_columns; + String path; + + bool should_reorder = false; + + Blocks blocks; + + Logger * log = &Logger::get("MergeTreeReverseSelectBlockInputStream"); +}; + +} diff --git a/dbms/src/Storages/MergeTree/RangesInDataPart.h b/dbms/src/Storages/MergeTree/RangesInDataPart.h index 69d38686cc9..a93a2103841 100644 --- a/dbms/src/Storages/MergeTree/RangesInDataPart.h +++ b/dbms/src/Storages/MergeTree/RangesInDataPart.h @@ -22,6 +22,15 @@ struct RangesInDataPart { } + size_t getMarksCount() const + { + size_t total = 0; + for (const auto & range : ranges) + total += range.end - range.begin; + + return total; + } + size_t getRowsCount() const { return data_part->index_granularity.getRowsCountInRanges(ranges); diff --git a/dbms/src/Storages/SelectQueryInfo.h b/dbms/src/Storages/SelectQueryInfo.h index a6649a87e81..93b3e22433b 100644 --- a/dbms/src/Storages/SelectQueryInfo.h +++ b/dbms/src/Storages/SelectQueryInfo.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include namespace DB @@ -33,8 +34,16 @@ struct FilterInfo bool do_remove_column = false; }; +struct SortingInfo +{ + int direction; + SortDescription prefix_order_descr; + UInt64 limit = 0; +}; + using PrewhereInfoPtr = std::shared_ptr; using FilterInfoPtr = std::shared_ptr; +using SortingInfoPtr = std::shared_ptr; struct SyntaxAnalyzerResult; using SyntaxAnalyzerResultPtr = std::shared_ptr; @@ -51,11 +60,13 @@ struct SelectQueryInfo PrewhereInfoPtr prewhere_info; + SortingInfoPtr sorting_info; + /// If set to true, the query from MergeTree will return a set of streams, /// each of them will read data in sorted by sorting key order. - bool do_not_steal_task = false; - bool read_in_pk_order = false; - bool read_in_reverse_order = false; + // bool do_not_steal_task = false; + // bool read_in_pk_order = false; + // bool read_in_reverse_order = false; /// Prepared sets are used for indices by storage engine. /// Example: x IN (1, 2, 3) From 4380404604e4c926bf5107195c039b0b8309f3c1 Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Thu, 18 Jul 2019 18:09:08 +0300 Subject: [PATCH 0192/1165] skip block with zero rows in MergingSortedBlockInputStream --- .../MergingSortedBlockInputStream.cpp | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/dbms/src/DataStreams/MergingSortedBlockInputStream.cpp b/dbms/src/DataStreams/MergingSortedBlockInputStream.cpp index 719977854da..8c0707e09b0 100644 --- a/dbms/src/DataStreams/MergingSortedBlockInputStream.cpp +++ b/dbms/src/DataStreams/MergingSortedBlockInputStream.cpp @@ -123,13 +123,21 @@ void MergingSortedBlockInputStream::fetchNextBlock(const TSortCursor & current, if (order >= size || &cursors[order] != current.impl) throw Exception("Logical error in MergingSortedBlockInputStream", ErrorCodes::LOGICAL_ERROR); - source_blocks[order] = new detail::SharedBlock(children[order]->read()); - if (*source_blocks[order]) + while (true) { - cursors[order].reset(*source_blocks[order]); - queue.push(TSortCursor(&cursors[order])); - source_blocks[order]->all_columns = cursors[order].all_columns; - source_blocks[order]->sort_columns = cursors[order].sort_columns; + source_blocks[order] = new detail::SharedBlock(children[order]->read()); + + if (!*source_blocks[order]) + break; + + if (source_blocks[order]->rows()) + { + cursors[order].reset(*source_blocks[order]); + queue.push(TSortCursor(&cursors[order])); + source_blocks[order]->all_columns = cursors[order].all_columns; + source_blocks[order]->sort_columns = cursors[order].sort_columns; + break; + } } } From 6565d5c15fa837c3765a3744bb9bf0f8fdf2752c Mon Sep 17 00:00:00 2001 From: Alexander Tokmakov Date: Thu, 18 Jul 2019 18:20:45 +0300 Subject: [PATCH 0193/1165] parse unquoted NULL --- dbms/src/Formats/CSVRowInputStream.cpp | 38 ++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/dbms/src/Formats/CSVRowInputStream.cpp b/dbms/src/Formats/CSVRowInputStream.cpp index d13b281ba6a..79e510b9fc3 100644 --- a/dbms/src/Formats/CSVRowInputStream.cpp +++ b/dbms/src/Formats/CSVRowInputStream.cpp @@ -1,5 +1,6 @@ #include +#include #include #include @@ -258,7 +259,6 @@ bool CSVRowInputStream::read(MutableColumns & columns, RowReadExtension & ext) /// Read the column normally. readField(*columns[*table_column], *type); read_columns[*table_column] = true; - } skipWhitespacesAndTabs(istr); } @@ -541,7 +541,41 @@ void CSVRowInputStream::updateDiagnosticInfo() void CSVRowInputStream::readField(IColumn & column, const IDataType & type) { - type.deserializeAsTextCSV(column, istr, format_settings); + if (format_settings.csv.unquoted_null_literal_as_null && type.isNullable()) + { + /// Check for unquoted NULL + constexpr char const * null_literal = "NULL"; + constexpr size_t len = 4; + size_t count = 0; + while (!istr.eof() && count < len && null_literal[count] == *istr.position()) + { + ++count; + ++istr.position(); + } + + if (count == len) + { + column.insert(Field()); /// insert null + } + else if (count == 0) + { + type.deserializeAsTextCSV(column, istr, format_settings); /// parse value + } + else + { + /// Prepend extracted data and parse value (rare case) + ReadBufferFromMemory prepend(null_literal, count); + ConcatReadBuffer buf(prepend, istr); + type.deserializeAsTextCSV(column, buf, format_settings); + + if (count < buf.count()) + istr.position() = buf.position(); + } + } + else + { + type.deserializeAsTextCSV(column, istr, format_settings); + } } From 4c8c516208dc1297ba8b411ea1fd031efa984313 Mon Sep 17 00:00:00 2001 From: Alexander Tokmakov Date: Thu, 18 Jul 2019 18:54:58 +0300 Subject: [PATCH 0194/1165] add tests --- dbms/tests/queries/0_stateless/00301_csv.reference | 4 ++++ dbms/tests/queries/0_stateless/00301_csv.sh | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/dbms/tests/queries/0_stateless/00301_csv.reference b/dbms/tests/queries/0_stateless/00301_csv.reference index 69debccade9..a808d5b5daf 100644 --- a/dbms/tests/queries/0_stateless/00301_csv.reference +++ b/dbms/tests/queries/0_stateless/00301_csv.reference @@ -4,7 +4,11 @@ Hello "world" 789 2016-01-03 Hello\n world 100 2016-01-04 default 1 2019-06-19 default-eof 1 2019-06-19 +0000-00-00 00:00:00 2016-01-01 01:02:03 1 2016-01-02 01:02:03 2 2017-08-15 13:15:01 3 1970-01-02 06:46:39 4 +2016-01-01 01:02:03 NUL +2016-01-02 01:02:03 Nhello +\N \N diff --git a/dbms/tests/queries/0_stateless/00301_csv.sh b/dbms/tests/queries/0_stateless/00301_csv.sh index c7ee476ab40..8ed2a2ca814 100755 --- a/dbms/tests/queries/0_stateless/00301_csv.sh +++ b/dbms/tests/queries/0_stateless/00301_csv.sh @@ -24,5 +24,17 @@ echo '"2016-01-01 01:02:03","1" 1502792101,"3" 99999,"4"' | $CLICKHOUSE_CLIENT --query="INSERT INTO csv FORMAT CSV"; +echo '\N, \N' | $CLICKHOUSE_CLIENT --input_format_null_as_default=1 --query="INSERT INTO csv FORMAT CSV"; + $CLICKHOUSE_CLIENT --query="SELECT * FROM csv ORDER BY s"; $CLICKHOUSE_CLIENT --query="DROP TABLE csv"; + + +$CLICKHOUSE_CLIENT --query="CREATE TABLE csv_null (t Nullable(DateTime('Europe/Moscow')), s Nullable(String)) ENGINE = Memory"; + +echo 'NULL, NULL +"2016-01-01 01:02:03",NUL +"2016-01-02 01:02:03",Nhello' | $CLICKHOUSE_CLIENT --format_csv_unquoted_null_literal_as_null=1 --query="INSERT INTO csv_null FORMAT CSV"; + +$CLICKHOUSE_CLIENT --query="SELECT * FROM csv_null ORDER BY s NULLS LAST"; +$CLICKHOUSE_CLIENT --query="DROP TABLE csv_null"; From 7382cb41fa6d03467eb548ff0f2a585ad965a6f0 Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Thu, 18 Jul 2019 21:29:49 +0300 Subject: [PATCH 0195/1165] CREATE TABLE AS table_function() --- dbms/src/Databases/DatabasesCommon.cpp | 8 ++++ .../ClusterProxy/SelectStreamFactory.cpp | 3 +- dbms/src/Interpreters/Context.cpp | 2 +- .../Interpreters/InterpreterCreateQuery.cpp | 37 ++++++++++++++----- .../Interpreters/InterpreterDescribeQuery.cpp | 2 +- .../Interpreters/InterpreterInsertQuery.cpp | 3 +- dbms/src/Parsers/ASTCreateQuery.cpp | 8 +++- dbms/src/Parsers/ASTCreateQuery.h | 1 + dbms/src/Parsers/ParserCreateQuery.cpp | 30 +++++++++------ .../Storages/getStructureOfRemoteTable.cpp | 3 +- dbms/src/TableFunctions/ITableFunction.cpp | 4 +- dbms/src/TableFunctions/ITableFunction.h | 4 +- .../TableFunctions/ITableFunctionFileLike.cpp | 4 +- .../TableFunctions/ITableFunctionFileLike.h | 4 +- .../src/TableFunctions/ITableFunctionXDBC.cpp | 8 ++-- dbms/src/TableFunctions/ITableFunctionXDBC.h | 2 +- dbms/src/TableFunctions/TableFunctionFile.cpp | 4 +- dbms/src/TableFunctions/TableFunctionFile.h | 2 +- dbms/src/TableFunctions/TableFunctionHDFS.cpp | 4 +- dbms/src/TableFunctions/TableFunctionHDFS.h | 2 +- .../src/TableFunctions/TableFunctionMerge.cpp | 4 +- dbms/src/TableFunctions/TableFunctionMerge.h | 2 +- .../src/TableFunctions/TableFunctionMySQL.cpp | 4 +- dbms/src/TableFunctions/TableFunctionMySQL.h | 2 +- .../TableFunctions/TableFunctionNumbers.cpp | 4 +- .../src/TableFunctions/TableFunctionNumbers.h | 2 +- .../TableFunctions/TableFunctionRemote.cpp | 6 +-- dbms/src/TableFunctions/TableFunctionRemote.h | 2 +- dbms/src/TableFunctions/TableFunctionURL.cpp | 4 +- dbms/src/TableFunctions/TableFunctionURL.h | 2 +- 30 files changed, 105 insertions(+), 62 deletions(-) diff --git a/dbms/src/Databases/DatabasesCommon.cpp b/dbms/src/Databases/DatabasesCommon.cpp index 3d2ca472137..27d236678f1 100644 --- a/dbms/src/Databases/DatabasesCommon.cpp +++ b/dbms/src/Databases/DatabasesCommon.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -68,6 +69,13 @@ std::pair createTableFromDefinition( ast_create_query.attach = true; ast_create_query.database = database_name; + if (ast_create_query.as_table_function) + { + const auto * table_function = ast_create_query.as_table_function->as(); + const auto & factory = TableFunctionFactory::instance(); + StoragePtr storage = factory.get(table_function->name, context)->execute(ast_create_query.as_table_function, context, ast_create_query.table); + return {ast_create_query.table, storage}; + } /// We do not directly use `InterpreterCreateQuery::execute`, because /// - the database has not been created yet; /// - the code is simpler, since the query is already brought to a suitable form. diff --git a/dbms/src/Interpreters/ClusterProxy/SelectStreamFactory.cpp b/dbms/src/Interpreters/ClusterProxy/SelectStreamFactory.cpp index ce16a431b37..ba0571d1863 100644 --- a/dbms/src/Interpreters/ClusterProxy/SelectStreamFactory.cpp +++ b/dbms/src/Interpreters/ClusterProxy/SelectStreamFactory.cpp @@ -99,7 +99,8 @@ void SelectStreamFactory::createForShard( if (table_func_ptr) { const auto * table_function = table_func_ptr->as(); - main_table_storage = TableFunctionFactory::instance().get(table_function->name, context)->execute(table_func_ptr, context); + TableFunctionPtr table_function_ptr = TableFunctionFactory::instance().get(table_function->name, context); + main_table_storage = table_function_ptr->execute(table_func_ptr, context, table_function_ptr->getName()); } else main_table_storage = context.tryGetTable(main_table.database, main_table.table); diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index 2909de8a60b..7b1d138ce3d 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -963,7 +963,7 @@ StoragePtr Context::executeTableFunction(const ASTPtr & table_expression) TableFunctionPtr table_function_ptr = TableFunctionFactory::instance().get(table_expression->as()->name, *this); /// Run it and remember the result - res = table_function_ptr->execute(table_expression, *this); + res = table_function_ptr->execute(table_expression, *this, table_function_ptr->getName()); } return res; diff --git a/dbms/src/Interpreters/InterpreterCreateQuery.cpp b/dbms/src/Interpreters/InterpreterCreateQuery.cpp index 7853e0c0841..7fe907257f7 100644 --- a/dbms/src/Interpreters/InterpreterCreateQuery.cpp +++ b/dbms/src/Interpreters/InterpreterCreateQuery.cpp @@ -46,6 +46,8 @@ #include #include +#include + namespace DB { @@ -389,6 +391,11 @@ ColumnsDescription InterpreterCreateQuery::setColumns( columns = as_storage->getColumns(); indices = as_storage->getIndices(); } + else if (create.as_table_function) + { + columns = as_storage->getColumns(); + indices = as_storage->getIndices(); + } else if (create.select) { columns = ColumnsDescription(as_select_sample.getNamesAndTypesList()); @@ -518,6 +525,13 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create) StoragePtr as_storage; TableStructureReadLockHolder as_storage_lock; + + if (create.as_table_function) + { + const auto * table_function = create.as_table_function->as(); + const auto & factory = TableFunctionFactory::instance(); + as_storage = factory.get(table_function->name, context)->execute(create.as_table_function, context, create.table); + } if (!as_table_name.empty()) { as_storage = context.getTable(as_database_name, as_table_name); @@ -585,15 +599,20 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create) else if (context.tryGetExternalTable(table_name) && create.if_not_exists) return {}; - res = StorageFactory::instance().get(create, - data_path, - table_name, - database_name, - context, - context.getGlobalContext(), - columns, - create.attach, - false); + if (create.as_table_function) + res = as_storage; + else + { + res = StorageFactory::instance().get(create, + data_path, + table_name, + database_name, + context, + context.getGlobalContext(), + columns, + create.attach, + false); + } if (create.temporary) context.getSessionContext().addExternalTable(table_name, res, query_ptr); diff --git a/dbms/src/Interpreters/InterpreterDescribeQuery.cpp b/dbms/src/Interpreters/InterpreterDescribeQuery.cpp index d037f87a857..cc3fd51ac50 100644 --- a/dbms/src/Interpreters/InterpreterDescribeQuery.cpp +++ b/dbms/src/Interpreters/InterpreterDescribeQuery.cpp @@ -79,7 +79,7 @@ BlockInputStreamPtr InterpreterDescribeQuery::executeImpl() const auto & table_function = table_expression.table_function->as(); TableFunctionPtr table_function_ptr = TableFunctionFactory::instance().get(table_function.name, context); /// Run the table function and remember the result - table = table_function_ptr->execute(table_expression.table_function, context); + table = table_function_ptr->execute(table_expression.table_function, context, table_function_ptr->getName()); } else { diff --git a/dbms/src/Interpreters/InterpreterInsertQuery.cpp b/dbms/src/Interpreters/InterpreterInsertQuery.cpp index b906d151415..dbb90028316 100644 --- a/dbms/src/Interpreters/InterpreterInsertQuery.cpp +++ b/dbms/src/Interpreters/InterpreterInsertQuery.cpp @@ -48,7 +48,8 @@ StoragePtr InterpreterInsertQuery::getTable(const ASTInsertQuery & query) { const auto * table_function = query.table_function->as(); const auto & factory = TableFunctionFactory::instance(); - return factory.get(table_function->name, context)->execute(query.table_function, context); + TableFunctionPtr table_function_ptr = factory.get(table_function->name, context); + return table_function_ptr->execute(query.table_function, context, table_function_ptr->getName()); } /// Into what table to write. diff --git a/dbms/src/Parsers/ASTCreateQuery.cpp b/dbms/src/Parsers/ASTCreateQuery.cpp index e99c543f5ec..4c84383af8a 100644 --- a/dbms/src/Parsers/ASTCreateQuery.cpp +++ b/dbms/src/Parsers/ASTCreateQuery.cpp @@ -216,7 +216,11 @@ void ASTCreateQuery::formatQueryImpl(const FormatSettings & settings, FormatStat << (!database.empty() ? backQuoteIfNeed(database) + "." : "") << backQuoteIfNeed(table); formatOnCluster(settings); } - + if (as_table_function) + { + settings.ostr << (settings.hilite ? hilite_keyword : "") << " AS " << (settings.hilite ? hilite_none : ""); + as_table_function->formatImpl(settings, state, frame); + } if (!to_table.empty()) { settings.ostr @@ -231,7 +235,7 @@ void ASTCreateQuery::formatQueryImpl(const FormatSettings & settings, FormatStat << (!as_database.empty() ? backQuoteIfNeed(as_database) + "." : "") << backQuoteIfNeed(as_table); } - if (columns_list) + if (columns_list && !as_table_function) { settings.ostr << (settings.one_line ? " (" : "\n("); FormatStateStacked frame_nested = frame; diff --git a/dbms/src/Parsers/ASTCreateQuery.h b/dbms/src/Parsers/ASTCreateQuery.h index 2755e1a3d78..7e121e4d2d9 100644 --- a/dbms/src/Parsers/ASTCreateQuery.h +++ b/dbms/src/Parsers/ASTCreateQuery.h @@ -63,6 +63,7 @@ public: ASTStorage * storage = nullptr; String as_database; String as_table; + ASTPtr as_table_function; ASTSelectWithUnionQuery * select = nullptr; /** Get the text that identifies this element. */ diff --git a/dbms/src/Parsers/ParserCreateQuery.cpp b/dbms/src/Parsers/ParserCreateQuery.cpp index fd6665a5a2c..be0779c4d52 100644 --- a/dbms/src/Parsers/ParserCreateQuery.cpp +++ b/dbms/src/Parsers/ParserCreateQuery.cpp @@ -319,6 +319,7 @@ bool ParserCreateQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) ParserIdentifier name_p; ParserColumnsOrIndicesDeclarationList columns_or_indices_p; ParserSelectWithUnionQuery select_p; + ParserFunction table_function_p; ASTPtr database; ASTPtr table; @@ -328,6 +329,7 @@ bool ParserCreateQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) ASTPtr storage; ASTPtr as_database; ASTPtr as_table; + ASTPtr as_table_function; ASTPtr select; String cluster_str; bool attach = false; @@ -407,22 +409,25 @@ bool ParserCreateQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) if (!s_as.ignore(pos, expected)) return false; - if (!select_p.parse(pos, select, expected)) /// AS SELECT ... + if (!table_function_p.parse(pos, as_table_function, expected)) { - /// AS [db.]table - if (!name_p.parse(pos, as_table, expected)) - return false; - - if (s_dot.ignore(pos, expected)) + if (!select_p.parse(pos, select, expected)) /// AS SELECT ... { - as_database = as_table; + /// AS [db.]table if (!name_p.parse(pos, as_table, expected)) return false; - } - /// Optional - ENGINE can be specified. - if (!storage) - storage_p.parse(pos, storage, expected); + if (s_dot.ignore(pos, expected)) + { + as_database = as_table; + if (!name_p.parse(pos, as_table, expected)) + return false; + } + + /// Optional - ENGINE can be specified. + if (!storage) + storage_p.parse(pos, storage, expected); + } } } } @@ -526,6 +531,9 @@ bool ParserCreateQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) auto query = std::make_shared(); node = query; + if (as_table_function) + query->as_table_function = as_table_function; + query->attach = attach; query->if_not_exists = if_not_exists; query->is_view = is_view; diff --git a/dbms/src/Storages/getStructureOfRemoteTable.cpp b/dbms/src/Storages/getStructureOfRemoteTable.cpp index 588d6ecc8c5..137abcea649 100644 --- a/dbms/src/Storages/getStructureOfRemoteTable.cpp +++ b/dbms/src/Storages/getStructureOfRemoteTable.cpp @@ -40,7 +40,8 @@ ColumnsDescription getStructureOfRemoteTable( if (shard_info.isLocal()) { const auto * table_function = table_func_ptr->as(); - return TableFunctionFactory::instance().get(table_function->name, context)->execute(table_func_ptr, context)->getColumns(); + TableFunctionPtr table_function_ptr = TableFunctionFactory::instance().get(table_function->name, context); + return table_function_ptr->execute(table_func_ptr, context, table_function_ptr->getName())->getColumns(); } auto table_func_name = queryToString(table_func_ptr); diff --git a/dbms/src/TableFunctions/ITableFunction.cpp b/dbms/src/TableFunctions/ITableFunction.cpp index b15cbbc9fd9..233da7495d8 100644 --- a/dbms/src/TableFunctions/ITableFunction.cpp +++ b/dbms/src/TableFunctions/ITableFunction.cpp @@ -10,10 +10,10 @@ namespace ProfileEvents namespace DB { -StoragePtr ITableFunction::execute(const ASTPtr & ast_function, const Context & context) const +StoragePtr ITableFunction::execute(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const { ProfileEvents::increment(ProfileEvents::TableFunctionExecute); - return executeImpl(ast_function, context); + return executeImpl(ast_function, context, table_name); } } diff --git a/dbms/src/TableFunctions/ITableFunction.h b/dbms/src/TableFunctions/ITableFunction.h index 026ff944976..81463f7baa8 100644 --- a/dbms/src/TableFunctions/ITableFunction.h +++ b/dbms/src/TableFunctions/ITableFunction.h @@ -30,12 +30,12 @@ public: virtual std::string getName() const = 0; /// Create storage according to the query. - StoragePtr execute(const ASTPtr & ast_function, const Context & context) const; + StoragePtr execute(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const; virtual ~ITableFunction() {} private: - virtual StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context) const = 0; + virtual StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const = 0; }; using TableFunctionPtr = std::shared_ptr; diff --git a/dbms/src/TableFunctions/ITableFunctionFileLike.cpp b/dbms/src/TableFunctions/ITableFunctionFileLike.cpp index fe8af831b56..7201af6ca06 100644 --- a/dbms/src/TableFunctions/ITableFunctionFileLike.cpp +++ b/dbms/src/TableFunctions/ITableFunctionFileLike.cpp @@ -19,7 +19,7 @@ namespace ErrorCodes extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; } -StoragePtr ITableFunctionFileLike::executeImpl(const ASTPtr & ast_function, const Context & context) const +StoragePtr ITableFunctionFileLike::executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const { // Parse args ASTs & args_func = ast_function->children; @@ -60,7 +60,7 @@ StoragePtr ITableFunctionFileLike::executeImpl(const ASTPtr & ast_function, cons } // Create table - StoragePtr storage = getStorage(filename, format, sample_block, const_cast(context)); + StoragePtr storage = getStorage(filename, format, sample_block, const_cast(context), table_name); storage->startup(); diff --git a/dbms/src/TableFunctions/ITableFunctionFileLike.h b/dbms/src/TableFunctions/ITableFunctionFileLike.h index 70637946808..26e046f0b41 100644 --- a/dbms/src/TableFunctions/ITableFunctionFileLike.h +++ b/dbms/src/TableFunctions/ITableFunctionFileLike.h @@ -12,8 +12,8 @@ namespace DB class ITableFunctionFileLike : public ITableFunction { private: - StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context) const override; + StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const override; virtual StoragePtr getStorage( - const String & source, const String & format, const Block & sample_block, Context & global_context) const = 0; + const String & source, const String & format, const Block & sample_block, Context & global_context, const std::string & table_name) const = 0; }; } diff --git a/dbms/src/TableFunctions/ITableFunctionXDBC.cpp b/dbms/src/TableFunctions/ITableFunctionXDBC.cpp index 32011dc8f8a..b9b767f2d9e 100644 --- a/dbms/src/TableFunctions/ITableFunctionXDBC.cpp +++ b/dbms/src/TableFunctions/ITableFunctionXDBC.cpp @@ -27,7 +27,7 @@ namespace ErrorCodes extern const int LOGICAL_ERROR; } -StoragePtr ITableFunctionXDBC::executeImpl(const ASTPtr & ast_function, const Context & context) const +StoragePtr ITableFunctionXDBC::executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const { const auto & args_func = ast_function->as(); @@ -45,18 +45,18 @@ StoragePtr ITableFunctionXDBC::executeImpl(const ASTPtr & ast_function, const Co std::string connection_string; std::string schema_name; - std::string table_name; + //std::string table_name; if (args.size() == 3) { connection_string = args[0]->as().value.safeGet(); schema_name = args[1]->as().value.safeGet(); - table_name = args[2]->as().value.safeGet(); + //table_name = args[2]->as().value.safeGet(); } else if (args.size() == 2) { connection_string = args[0]->as().value.safeGet(); - table_name = args[1]->as().value.safeGet(); + //table_name = args[1]->as().value.safeGet(); } /* Infer external table structure */ diff --git a/dbms/src/TableFunctions/ITableFunctionXDBC.h b/dbms/src/TableFunctions/ITableFunctionXDBC.h index 8676b85debf..b585d8228dc 100644 --- a/dbms/src/TableFunctions/ITableFunctionXDBC.h +++ b/dbms/src/TableFunctions/ITableFunctionXDBC.h @@ -15,7 +15,7 @@ namespace DB class ITableFunctionXDBC : public ITableFunction { private: - StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context) const override; + StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const override; /* A factory method to create bridge helper, that will assist in remote interaction */ virtual BridgeHelperPtr createBridgeHelper(Context & context, diff --git a/dbms/src/TableFunctions/TableFunctionFile.cpp b/dbms/src/TableFunctions/TableFunctionFile.cpp index 89531096d35..42ad309ffb4 100644 --- a/dbms/src/TableFunctions/TableFunctionFile.cpp +++ b/dbms/src/TableFunctions/TableFunctionFile.cpp @@ -5,12 +5,12 @@ namespace DB { StoragePtr TableFunctionFile::getStorage( - const String & source, const String & format, const Block & sample_block, Context & global_context) const + const String & source, const String & format, const Block & sample_block, Context & global_context, const std::string & table_name) const { return StorageFile::create(source, -1, global_context.getUserFilesPath(), - getName(), + table_name, format, ColumnsDescription{sample_block.getNamesAndTypesList()}, global_context); diff --git a/dbms/src/TableFunctions/TableFunctionFile.h b/dbms/src/TableFunctions/TableFunctionFile.h index 56cd5002ba1..2a508d06339 100644 --- a/dbms/src/TableFunctions/TableFunctionFile.h +++ b/dbms/src/TableFunctions/TableFunctionFile.h @@ -24,6 +24,6 @@ public: private: StoragePtr getStorage( - const String & source, const String & format, const Block & sample_block, Context & global_context) const override; + const String & source, const String & format, const Block & sample_block, Context & global_context, const std::string & table_name) const override; }; } diff --git a/dbms/src/TableFunctions/TableFunctionHDFS.cpp b/dbms/src/TableFunctions/TableFunctionHDFS.cpp index 9c09ad9313c..5c1fc26b942 100644 --- a/dbms/src/TableFunctions/TableFunctionHDFS.cpp +++ b/dbms/src/TableFunctions/TableFunctionHDFS.cpp @@ -8,10 +8,10 @@ namespace DB { StoragePtr TableFunctionHDFS::getStorage( - const String & source, const String & format, const Block & sample_block, Context & global_context) const + const String & source, const String & format, const Block & sample_block, Context & global_context, const std::string & table_name) const { return StorageHDFS::create(source, - getName(), + table_name, format, ColumnsDescription{sample_block.getNamesAndTypesList()}, global_context); diff --git a/dbms/src/TableFunctions/TableFunctionHDFS.h b/dbms/src/TableFunctions/TableFunctionHDFS.h index 8033034deb8..9dafadc8df8 100644 --- a/dbms/src/TableFunctions/TableFunctionHDFS.h +++ b/dbms/src/TableFunctions/TableFunctionHDFS.h @@ -25,7 +25,7 @@ public: private: StoragePtr getStorage( - const String & source, const String & format, const Block & sample_block, Context & global_context) const override; + const String & source, const String & format, const Block & sample_block, Context & global_context, const std::string & table_name) const override; }; } diff --git a/dbms/src/TableFunctions/TableFunctionMerge.cpp b/dbms/src/TableFunctions/TableFunctionMerge.cpp index cd8d906b94d..f4e947a2835 100644 --- a/dbms/src/TableFunctions/TableFunctionMerge.cpp +++ b/dbms/src/TableFunctions/TableFunctionMerge.cpp @@ -47,7 +47,7 @@ static NamesAndTypesList chooseColumns(const String & source_database, const Str } -StoragePtr TableFunctionMerge::executeImpl(const ASTPtr & ast_function, const Context & context) const +StoragePtr TableFunctionMerge::executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const { ASTs & args_func = ast_function->children; @@ -70,7 +70,7 @@ StoragePtr TableFunctionMerge::executeImpl(const ASTPtr & ast_function, const Co String table_name_regexp = args[1]->as().value.safeGet(); auto res = StorageMerge::create( - getName(), + table_name, ColumnsDescription{chooseColumns(source_database, table_name_regexp, context)}, source_database, table_name_regexp, diff --git a/dbms/src/TableFunctions/TableFunctionMerge.h b/dbms/src/TableFunctions/TableFunctionMerge.h index 2fb512ac590..43d4b692bc8 100644 --- a/dbms/src/TableFunctions/TableFunctionMerge.h +++ b/dbms/src/TableFunctions/TableFunctionMerge.h @@ -16,7 +16,7 @@ public: static constexpr auto name = "merge"; std::string getName() const override { return name; } private: - StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context) const override; + StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const override; }; diff --git a/dbms/src/TableFunctions/TableFunctionMySQL.cpp b/dbms/src/TableFunctions/TableFunctionMySQL.cpp index 71d195e95ed..51b0a144dcd 100644 --- a/dbms/src/TableFunctions/TableFunctionMySQL.cpp +++ b/dbms/src/TableFunctions/TableFunctionMySQL.cpp @@ -37,7 +37,7 @@ namespace ErrorCodes } -StoragePtr TableFunctionMySQL::executeImpl(const ASTPtr & ast_function, const Context & context) const +StoragePtr TableFunctionMySQL::executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const { const auto & args_func = ast_function->as(); @@ -55,7 +55,7 @@ StoragePtr TableFunctionMySQL::executeImpl(const ASTPtr & ast_function, const Co std::string host_port = args[0]->as().value.safeGet(); std::string database_name = args[1]->as().value.safeGet(); - std::string table_name = args[2]->as().value.safeGet(); + // std::string table_name = args[2]->as().value.safeGet(); std::string user_name = args[3]->as().value.safeGet(); std::string password = args[4]->as().value.safeGet(); diff --git a/dbms/src/TableFunctions/TableFunctionMySQL.h b/dbms/src/TableFunctions/TableFunctionMySQL.h index 870b3f75624..fd5b0219df6 100644 --- a/dbms/src/TableFunctions/TableFunctionMySQL.h +++ b/dbms/src/TableFunctions/TableFunctionMySQL.h @@ -19,7 +19,7 @@ public: return name; } private: - StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context) const override; + StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const override; }; } diff --git a/dbms/src/TableFunctions/TableFunctionNumbers.cpp b/dbms/src/TableFunctions/TableFunctionNumbers.cpp index a02cd904882..94c618bd9b1 100644 --- a/dbms/src/TableFunctions/TableFunctionNumbers.cpp +++ b/dbms/src/TableFunctions/TableFunctionNumbers.cpp @@ -17,7 +17,7 @@ namespace ErrorCodes } -StoragePtr TableFunctionNumbers::executeImpl(const ASTPtr & ast_function, const Context & context) const +StoragePtr TableFunctionNumbers::executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const { if (const auto * function = ast_function->as()) { @@ -30,7 +30,7 @@ StoragePtr TableFunctionNumbers::executeImpl(const ASTPtr & ast_function, const UInt64 offset = arguments.size() == 2 ? evaluateArgument(context, arguments[0]) : 0; UInt64 length = arguments.size() == 2 ? evaluateArgument(context, arguments[1]) : evaluateArgument(context, arguments[0]); - auto res = StorageSystemNumbers::create(getName(), false, length, offset); + auto res = StorageSystemNumbers::create(table_name, false, length, offset); res->startup(); return res; } diff --git a/dbms/src/TableFunctions/TableFunctionNumbers.h b/dbms/src/TableFunctions/TableFunctionNumbers.h index ed060a6450a..733b4508f51 100644 --- a/dbms/src/TableFunctions/TableFunctionNumbers.h +++ b/dbms/src/TableFunctions/TableFunctionNumbers.h @@ -17,7 +17,7 @@ public: static constexpr auto name = "numbers"; std::string getName() const override { return name; } private: - StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context) const override; + StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const override; UInt64 evaluateArgument(const Context & context, ASTPtr & argument) const; }; diff --git a/dbms/src/TableFunctions/TableFunctionRemote.cpp b/dbms/src/TableFunctions/TableFunctionRemote.cpp index 21611500eb7..c4e0cd1866a 100644 --- a/dbms/src/TableFunctions/TableFunctionRemote.cpp +++ b/dbms/src/TableFunctions/TableFunctionRemote.cpp @@ -25,7 +25,7 @@ namespace ErrorCodes extern const int BAD_ARGUMENTS; } -StoragePtr TableFunctionRemote::executeImpl(const ASTPtr & ast_function, const Context & context) const +StoragePtr TableFunctionRemote::executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const { ASTs & args_func = ast_function->children; @@ -162,13 +162,13 @@ StoragePtr TableFunctionRemote::executeImpl(const ASTPtr & ast_function, const C StoragePtr res = remote_table_function_ptr ? StorageDistributed::createWithOwnCluster( - getName(), + table_name, structure_remote_table, remote_table_function_ptr, cluster, context) : StorageDistributed::createWithOwnCluster( - getName(), + table_name, structure_remote_table, remote_database, remote_table, diff --git a/dbms/src/TableFunctions/TableFunctionRemote.h b/dbms/src/TableFunctions/TableFunctionRemote.h index dcd0699b064..c9a98cbbc16 100644 --- a/dbms/src/TableFunctions/TableFunctionRemote.h +++ b/dbms/src/TableFunctions/TableFunctionRemote.h @@ -21,7 +21,7 @@ public: std::string getName() const override { return name; } private: - StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context) const override; + StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const override; std::string name; bool is_cluster_function; diff --git a/dbms/src/TableFunctions/TableFunctionURL.cpp b/dbms/src/TableFunctions/TableFunctionURL.cpp index f33e5a92cb3..22ec78648eb 100644 --- a/dbms/src/TableFunctions/TableFunctionURL.cpp +++ b/dbms/src/TableFunctions/TableFunctionURL.cpp @@ -6,10 +6,10 @@ namespace DB { StoragePtr TableFunctionURL::getStorage( - const String & source, const String & format, const Block & sample_block, Context & global_context) const + const String & source, const String & format, const Block & sample_block, Context & global_context, const std::string & table_name) const { Poco::URI uri(source); - return StorageURL::create(uri, getName(), format, ColumnsDescription{sample_block.getNamesAndTypesList()}, global_context); + return StorageURL::create(uri, table_name, format, ColumnsDescription{sample_block.getNamesAndTypesList()}, global_context); } void registerTableFunctionURL(TableFunctionFactory & factory) diff --git a/dbms/src/TableFunctions/TableFunctionURL.h b/dbms/src/TableFunctions/TableFunctionURL.h index 6382beee836..f7b723a422c 100644 --- a/dbms/src/TableFunctions/TableFunctionURL.h +++ b/dbms/src/TableFunctions/TableFunctionURL.h @@ -20,6 +20,6 @@ public: private: StoragePtr getStorage( - const String & source, const String & format, const Block & sample_block, Context & global_context) const override; + const String & source, const String & format, const Block & sample_block, Context & global_context, const std::string & table_name) const override; }; } From 12b3560deff1362413f9364a43cd23ba45119543 Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Thu, 18 Jul 2019 21:34:15 +0300 Subject: [PATCH 0196/1165] build fixes --- .../MergeTreeBaseSelectBlockInputStream.cpp | 24 ++++++------ .../MergeTree/MergeTreeDataSelectExecutor.cpp | 38 +++++++++---------- ...MergeTreeReverseSelectBlockInputStream.cpp | 1 - .../MergeTreeReverseSelectBlockInputStream.h | 1 - 4 files changed, 31 insertions(+), 33 deletions(-) diff --git a/dbms/src/Storages/MergeTree/MergeTreeBaseSelectBlockInputStream.cpp b/dbms/src/Storages/MergeTree/MergeTreeBaseSelectBlockInputStream.cpp index 5896b776739..10d7e3750e4 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeBaseSelectBlockInputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeBaseSelectBlockInputStream.cpp @@ -64,41 +64,41 @@ Block MergeTreeBaseSelectBlockInputStream::readImpl() } -void MergeTreeBaseSelectBlockInputStream::initializeRangeReaders(MergeTreeReadTask & task) +void MergeTreeBaseSelectBlockInputStream::initializeRangeReaders(MergeTreeReadTask & current_task) { if (prewhere_info) { if (reader->getColumns().empty()) { - task.range_reader = MergeTreeRangeReader( + current_task.range_reader = MergeTreeRangeReader( pre_reader.get(), nullptr, prewhere_info->alias_actions, prewhere_info->prewhere_actions, - &prewhere_info->prewhere_column_name, &task.ordered_names, - task.should_reorder, task.remove_prewhere_column, true); + &prewhere_info->prewhere_column_name, ¤t_task.ordered_names, + current_task.should_reorder, current_task.remove_prewhere_column, true); } else { MergeTreeRangeReader * pre_reader_ptr = nullptr; if (pre_reader != nullptr) { - task.pre_range_reader = MergeTreeRangeReader( + current_task.pre_range_reader = MergeTreeRangeReader( pre_reader.get(), nullptr, prewhere_info->alias_actions, prewhere_info->prewhere_actions, - &prewhere_info->prewhere_column_name, &task.ordered_names, - task.should_reorder, task.remove_prewhere_column, false); - pre_reader_ptr = &task.pre_range_reader; + &prewhere_info->prewhere_column_name, ¤t_task.ordered_names, + current_task.should_reorder, current_task.remove_prewhere_column, false); + pre_reader_ptr = ¤t_task.pre_range_reader; } - task.range_reader = MergeTreeRangeReader( + current_task.range_reader = MergeTreeRangeReader( reader.get(), pre_reader_ptr, nullptr, nullptr, - nullptr, &task.ordered_names, true, false, true); + nullptr, ¤t_task.ordered_names, true, false, true); } } else { - task.range_reader = MergeTreeRangeReader( + current_task.range_reader = MergeTreeRangeReader( reader.get(), nullptr, nullptr, nullptr, - nullptr, &task.ordered_names, task.should_reorder, false, true); + nullptr, ¤t_task.ordered_names, current_task.should_reorder, false, true); } } diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index 8411538c2d1..1c9373004c8 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -822,25 +822,6 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsPKOrd size_t adaptive_parts = 0; std::vector sum_marks_in_parts(parts.size()); - size_t index_granularity_bytes = 0; - if (adaptive_parts > parts.size() / 2) - index_granularity_bytes = data.settings.index_granularity_bytes; - - const size_t max_marks_to_use_cache = roundRowsOrBytesToMarks( - settings.merge_tree_max_rows_to_use_cache, - settings.merge_tree_max_bytes_to_use_cache, - data.settings.index_granularity, - index_granularity_bytes); - - const size_t min_marks_for_concurrent_read = roundRowsOrBytesToMarks( - settings.merge_tree_min_rows_for_concurrent_read, - settings.merge_tree_min_bytes_for_concurrent_read, - data.settings.index_granularity, - index_granularity_bytes); - - if (sum_marks > max_marks_to_use_cache) - use_uncompressed_cache = false; - /// In case of reverse order let's split ranges to avoid reading much data. auto split_ranges = [max_block_size](const auto & ranges, size_t rows_granularity, size_t num_marks_in_part) { @@ -881,6 +862,25 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsPKOrd adaptive_parts++; } + size_t index_granularity_bytes = 0; + if (adaptive_parts > parts.size() / 2) + index_granularity_bytes = data.settings.index_granularity_bytes; + + const size_t max_marks_to_use_cache = roundRowsOrBytesToMarks( + settings.merge_tree_max_rows_to_use_cache, + settings.merge_tree_max_bytes_to_use_cache, + data.settings.index_granularity, + index_granularity_bytes); + + const size_t min_marks_for_concurrent_read = roundRowsOrBytesToMarks( + settings.merge_tree_min_rows_for_concurrent_read, + settings.merge_tree_min_bytes_for_concurrent_read, + data.settings.index_granularity, + index_granularity_bytes); + + if (sum_marks > max_marks_to_use_cache) + use_uncompressed_cache = false; + BlockInputStreams streams; if (sum_marks == 0) diff --git a/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.cpp b/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.cpp index b15e3a1ad3a..ef0fb8c0be4 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.cpp @@ -39,7 +39,6 @@ MergeTreeReverseSelectBlockInputStream::MergeTreeReverseSelectBlockInputStream( part_columns_lock(data_part->columns_lock), all_mark_ranges(mark_ranges_), part_index_in_query(part_index_in_query_), - check_columns(check_columns), path(data_part->getFullPath()) { /// Let's estimate total number of rows for progress bar. diff --git a/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.h b/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.h index 381bee4aa95..828bc9c0732 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.h +++ b/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.h @@ -71,7 +71,6 @@ private: /// Value of _part_index virtual column (used only in SelectExecutor) size_t part_index_in_query = 0; - bool check_columns; String path; bool should_reorder = false; From 1ab08934322f58272466fdfaa91c558ded39d0e3 Mon Sep 17 00:00:00 2001 From: dimarub2000 Date: Thu, 18 Jul 2019 21:59:31 +0300 Subject: [PATCH 0197/1165] minor fixes --- dbms/src/TableFunctions/TableFunctionFile.cpp | 1 + dbms/src/TableFunctions/TableFunctionHDFS.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/dbms/src/TableFunctions/TableFunctionFile.cpp b/dbms/src/TableFunctions/TableFunctionFile.cpp index 42ad309ffb4..8b2c3313cb8 100644 --- a/dbms/src/TableFunctions/TableFunctionFile.cpp +++ b/dbms/src/TableFunctions/TableFunctionFile.cpp @@ -10,6 +10,7 @@ StoragePtr TableFunctionFile::getStorage( return StorageFile::create(source, -1, global_context.getUserFilesPath(), + getDatabaseName(), table_name, format, ColumnsDescription{sample_block.getNamesAndTypesList()}, diff --git a/dbms/src/TableFunctions/TableFunctionHDFS.cpp b/dbms/src/TableFunctions/TableFunctionHDFS.cpp index 5c1fc26b942..0cdf0a08b26 100644 --- a/dbms/src/TableFunctions/TableFunctionHDFS.cpp +++ b/dbms/src/TableFunctions/TableFunctionHDFS.cpp @@ -11,6 +11,7 @@ StoragePtr TableFunctionHDFS::getStorage( const String & source, const String & format, const Block & sample_block, Context & global_context, const std::string & table_name) const { return StorageHDFS::create(source, + getDatabaseName(), table_name, format, ColumnsDescription{sample_block.getNamesAndTypesList()}, From c9ec16987e2b069d57839000125d0af0b5b8de8d Mon Sep 17 00:00:00 2001 From: dimarub2000 Date: Thu, 18 Jul 2019 22:09:45 +0300 Subject: [PATCH 0198/1165] minor fixes --- contrib/simdjson | 2 +- dbms/src/TableFunctions/TableFunctionCatBoostPool.cpp | 4 ++-- dbms/src/TableFunctions/TableFunctionCatBoostPool.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/simdjson b/contrib/simdjson index 3bd3116cf8f..2151ad7f34c 160000 --- a/contrib/simdjson +++ b/contrib/simdjson @@ -1 +1 @@ -Subproject commit 3bd3116cf8faf6d482dc31423b16533bfa2696f7 +Subproject commit 2151ad7f34cf773a23f086e941d661f8a8873144 diff --git a/dbms/src/TableFunctions/TableFunctionCatBoostPool.cpp b/dbms/src/TableFunctions/TableFunctionCatBoostPool.cpp index da926dcc906..74fab72fd19 100644 --- a/dbms/src/TableFunctions/TableFunctionCatBoostPool.cpp +++ b/dbms/src/TableFunctions/TableFunctionCatBoostPool.cpp @@ -16,7 +16,7 @@ namespace ErrorCodes } -StoragePtr TableFunctionCatBoostPool::executeImpl(const ASTPtr & ast_function, const Context & context) const +StoragePtr TableFunctionCatBoostPool::executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const { ASTs & args_func = ast_function->children; @@ -45,7 +45,7 @@ StoragePtr TableFunctionCatBoostPool::executeImpl(const ASTPtr & ast_function, c String column_descriptions_file = getStringLiteral(*args[0], "Column descriptions file"); String dataset_description_file = getStringLiteral(*args[1], "Dataset description file"); - return StorageCatBoostPool::create(getDatabaseName(), getName(), context, column_descriptions_file, dataset_description_file); + return StorageCatBoostPool::create(getDatabaseName(), table_name, context, column_descriptions_file, dataset_description_file); } void registerTableFunctionCatBoostPool(TableFunctionFactory & factory) diff --git a/dbms/src/TableFunctions/TableFunctionCatBoostPool.h b/dbms/src/TableFunctions/TableFunctionCatBoostPool.h index 061b5a735f6..cf93308b60c 100644 --- a/dbms/src/TableFunctions/TableFunctionCatBoostPool.h +++ b/dbms/src/TableFunctions/TableFunctionCatBoostPool.h @@ -15,7 +15,7 @@ public: static constexpr auto name = "catBoostPool"; std::string getName() const override { return name; } private: - StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context) const override; + StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const override; }; } From d1e6e6ed4b291be2805aef3b49ebb49c8d9e4bb0 Mon Sep 17 00:00:00 2001 From: dimarub2000 Date: Thu, 18 Jul 2019 22:17:02 +0300 Subject: [PATCH 0199/1165] fix json --- contrib/simdjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/simdjson b/contrib/simdjson index 2151ad7f34c..3bd3116cf8f 160000 --- a/contrib/simdjson +++ b/contrib/simdjson @@ -1 +1 @@ -Subproject commit 2151ad7f34cf773a23f086e941d661f8a8873144 +Subproject commit 3bd3116cf8faf6d482dc31423b16533bfa2696f7 From 2797c16930c01ee88e44060d4c3861a0d9519a17 Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Fri, 19 Jul 2019 13:14:27 +0300 Subject: [PATCH 0200/1165] fix prewhere at fetching columns --- .../Interpreters/InterpreterSelectQuery.cpp | 38 +++++++++---------- .../src/Interpreters/InterpreterSelectQuery.h | 4 +- dbms/src/Storages/MergeTree/MergeTreeData.cpp | 2 - dbms/src/Storages/SelectQueryInfo.h | 12 ++---- 4 files changed, 25 insertions(+), 31 deletions(-) diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.cpp b/dbms/src/Interpreters/InterpreterSelectQuery.cpp index 71619d55c08..a352e625d94 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSelectQuery.cpp @@ -667,7 +667,6 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS QueryProcessingStage::Enum from_stage = QueryProcessingStage::FetchColumns; - SelectQueryInfo query_info; /// PREWHERE optimization /// Turn off, if the table filter is applied. if (storage && !context.hasUserProperty(storage->getDatabaseName(), storage->getTableName(), "filter")) @@ -679,13 +678,14 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS auto optimize_prewhere = [&](auto & merge_tree) { - query_info.query = query_ptr; - query_info.syntax_analyzer_result = syntax_analyzer_result; - query_info.sets = query_analyzer->getPreparedSets(); + SelectQueryInfo current_info; + current_info.query = query_ptr; + current_info.syntax_analyzer_result = syntax_analyzer_result; + current_info.sets = query_analyzer->getPreparedSets(); /// Try transferring some condition from WHERE to PREWHERE if enabled and viable if (settings.optimize_move_to_prewhere && query.where() && !query.prewhere() && !query.final()) - MergeTreeWhereOptimizer{query_info, context, merge_tree, query_analyzer->getRequiredSourceColumns(), log}; + MergeTreeWhereOptimizer{current_info, context, merge_tree, query_analyzer->getRequiredSourceColumns(), log}; }; if (const MergeTreeData * merge_tree_data = dynamic_cast(storage.get())) @@ -703,17 +703,18 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS source_header = storage->getSampleBlockForColumns(filter_info->actions->getRequiredColumns()); } + SortingInfoPtr sorting_info; if (settings.optimize_pk_order && storage && query.orderBy() && !query.groupBy() && !query.final()) { - auto optimize_pk_order = [&](const auto & merge_tree) + auto optimize_pk_order = [&](const auto & merge_tree) -> SortingInfoPtr { if (!merge_tree.hasSortingKey()) - return; - - auto sorting_info = std::make_shared(); + return {}; auto order_descr = getSortDescription(query); const auto & sorting_key_columns = merge_tree.getSortingKeyColumns(); + SortDescription prefix_order_descr; + int direction = order_descr.at(0).direction; size_t prefix_size = std::min(order_descr.size(), sorting_key_columns.size()); @@ -722,20 +723,17 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS if (order_descr[i].column_name != sorting_key_columns[i] || order_descr[i].direction != direction) break; - sorting_info->prefix_order_descr.push_back(order_descr[i]); + prefix_order_descr.push_back(order_descr[i]); } - if (sorting_info->prefix_order_descr.empty()) - return; + if (prefix_order_descr.empty()) + return {}; - sorting_info->direction = direction; - sorting_info->limit = getLimitForSorting(query, context); - - query_info.sorting_info = sorting_info; + return std::make_shared(std::move(prefix_order_descr), direction); }; if (const MergeTreeData * merge_tree_data = dynamic_cast(storage.get())) - optimize_pk_order(*merge_tree_data); + sorting_info = optimize_pk_order(*merge_tree_data); } if (dry_run) @@ -787,7 +785,7 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS throw Exception("PREWHERE is not supported if the table is filtered by row-level security expression", ErrorCodes::ILLEGAL_PREWHERE); /** Read the data from Storage. from_stage - to what stage the request was completed in Storage. */ - executeFetchColumns(from_stage, pipeline, query_info, expressions.columns_to_remove_after_prewhere); + executeFetchColumns(from_stage, pipeline, sorting_info, expressions.prewhere_info, expressions.columns_to_remove_after_prewhere); LOG_TRACE(log, QueryProcessingStage::toString(from_stage) << " -> " << QueryProcessingStage::toString(options.to_stage)); } @@ -1058,13 +1056,12 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS template void InterpreterSelectQuery::executeFetchColumns( QueryProcessingStage::Enum processing_stage, TPipeline & pipeline, - SelectQueryInfo & query_info, const Names & columns_to_remove_after_prewhere) + const SortingInfoPtr & sorting_info, const PrewhereInfoPtr & prewhere_info, const Names & columns_to_remove_after_prewhere) { constexpr bool pipeline_with_processors = std::is_same::value; auto & query = getSelectQuery(); const Settings & settings = context.getSettingsRef(); - const auto & prewhere_info = query_info.prewhere_info; /// Actions to calculate ALIAS if required. ExpressionActionsPtr alias_actions; @@ -1319,6 +1316,7 @@ void InterpreterSelectQuery::executeFetchColumns( query_info.syntax_analyzer_result = syntax_analyzer_result; query_info.sets = query_analyzer->getPreparedSets(); query_info.prewhere_info = prewhere_info; + query_info.sorting_info = sorting_info; auto streams = storage->read(required_columns, query_info, context, processing_stage, max_block_size, max_streams); diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.h b/dbms/src/Interpreters/InterpreterSelectQuery.h index 767e7ad38a3..f6f3c0baf19 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.h +++ b/dbms/src/Interpreters/InterpreterSelectQuery.h @@ -186,7 +186,8 @@ private: template void executeFetchColumns(QueryProcessingStage::Enum processing_stage, TPipeline & pipeline, - SelectQueryInfo & query_info, const Names & columns_to_remove_after_prewhere); + const SortingInfoPtr & sorting_info, const PrewhereInfoPtr & prewhere_info, + const Names & columns_to_remove_after_prewhere); void executeWhere(Pipeline & pipeline, const ExpressionActionsPtr & expression, bool remove_filter); void executeAggregation(Pipeline & pipeline, const ExpressionActionsPtr & expression, bool overflow_row, bool final); @@ -248,6 +249,7 @@ private: NamesAndTypesList source_columns; SyntaxAnalyzerResultPtr syntax_analyzer_result; std::unique_ptr query_analyzer; + SelectQueryInfo query_info; /// How many streams we ask for storage to produce, and in how many threads we will do further processing. size_t max_streams = 1; diff --git a/dbms/src/Storages/MergeTree/MergeTreeData.cpp b/dbms/src/Storages/MergeTree/MergeTreeData.cpp index 488dd94665d..b32470f9f77 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeData.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeData.cpp @@ -744,7 +744,6 @@ void MergeTreeData::loadDataParts(bool skip_sanity_checks) data_parts_indexes.clear(); bool has_adaptive_parts = false, has_non_adaptive_parts = false; - size_t data_parts_counter = 0; for (const String & file_name : part_file_names) { MergeTreePartInfo part_info; @@ -752,7 +751,6 @@ void MergeTreeData::loadDataParts(bool skip_sanity_checks) continue; MutableDataPartPtr part = std::make_shared(*this, file_name, part_info); - ++data_parts_counter; part->relative_path = file_name; bool broken = false; diff --git a/dbms/src/Storages/SelectQueryInfo.h b/dbms/src/Storages/SelectQueryInfo.h index 93b3e22433b..e5de8a1cece 100644 --- a/dbms/src/Storages/SelectQueryInfo.h +++ b/dbms/src/Storages/SelectQueryInfo.h @@ -36,9 +36,11 @@ struct FilterInfo struct SortingInfo { - int direction; SortDescription prefix_order_descr; - UInt64 limit = 0; + int direction; + + SortingInfo(const SortDescription prefix_order_descr_, int direction_) + : prefix_order_descr(prefix_order_descr_), direction(direction_) {} }; using PrewhereInfoPtr = std::shared_ptr; @@ -62,12 +64,6 @@ struct SelectQueryInfo SortingInfoPtr sorting_info; - /// If set to true, the query from MergeTree will return a set of streams, - /// each of them will read data in sorted by sorting key order. - // bool do_not_steal_task = false; - // bool read_in_pk_order = false; - // bool read_in_reverse_order = false; - /// Prepared sets are used for indices by storage engine. /// Example: x IN (1, 2, 3) PreparedSets sets; From 1aca3da1211f8c3fb5362c5d5a2e98515c10c39d Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Fri, 19 Jul 2019 16:28:28 +0300 Subject: [PATCH 0201/1165] Fixed inegration --- .../Interpreters/InterpreterCreateQuery.cpp | 7 +------ .../src/TableFunctions/ITableFunctionXDBC.cpp | 13 +++++++----- .../src/TableFunctions/TableFunctionMySQL.cpp | 21 +++++++++++-------- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/dbms/src/Interpreters/InterpreterCreateQuery.cpp b/dbms/src/Interpreters/InterpreterCreateQuery.cpp index 48bb116736e..a862c7de5c1 100644 --- a/dbms/src/Interpreters/InterpreterCreateQuery.cpp +++ b/dbms/src/Interpreters/InterpreterCreateQuery.cpp @@ -386,12 +386,7 @@ ColumnsDescription InterpreterCreateQuery::setColumns( indices.indices.push_back( std::dynamic_pointer_cast(index->clone())); } - else if (!create.as_table.empty()) - { - columns = as_storage->getColumns(); - indices = as_storage->getIndices(); - } - else if (create.as_table_function) + else if (!create.as_table.empty() || create.as_table_function) { columns = as_storage->getColumns(); indices = as_storage->getIndices(); diff --git a/dbms/src/TableFunctions/ITableFunctionXDBC.cpp b/dbms/src/TableFunctions/ITableFunctionXDBC.cpp index 8ce56568a1e..9998eb87fcf 100644 --- a/dbms/src/TableFunctions/ITableFunctionXDBC.cpp +++ b/dbms/src/TableFunctions/ITableFunctionXDBC.cpp @@ -45,18 +45,18 @@ StoragePtr ITableFunctionXDBC::executeImpl(const ASTPtr & ast_function, const Co std::string connection_string; std::string schema_name; - //std::string table_name; + std::string remote_table_name; if (args.size() == 3) { connection_string = args[0]->as().value.safeGet(); schema_name = args[1]->as().value.safeGet(); - //table_name = args[2]->as().value.safeGet(); + remote_table_name = args[2]->as().value.safeGet(); } else if (args.size() == 2) { connection_string = args[0]->as().value.safeGet(); - //table_name = args[1]->as().value.safeGet(); + remote_table_name = args[1]->as().value.safeGet(); } /* Infer external table structure */ @@ -68,7 +68,7 @@ StoragePtr ITableFunctionXDBC::executeImpl(const ASTPtr & ast_function, const Co columns_info_uri.addQueryParameter("connection_string", connection_string); if (!schema_name.empty()) columns_info_uri.addQueryParameter("schema", schema_name); - columns_info_uri.addQueryParameter("table", table_name); + columns_info_uri.addQueryParameter("table", remote_table_name); ReadWriteBufferFromHTTP buf(columns_info_uri, Poco::Net::HTTPRequest::HTTP_POST, nullptr); @@ -76,7 +76,10 @@ StoragePtr ITableFunctionXDBC::executeImpl(const ASTPtr & ast_function, const Co readStringBinary(columns_info, buf); NamesAndTypesList columns = NamesAndTypesList::parse(columns_info); - auto result = std::make_shared(getDatabaseName(), table_name, schema_name, table_name, ColumnsDescription{columns}, context, helper); + ///If table_name was not specified by user, it will have the same name as remote_table_name + std::string local_table_name = (table_name == getName()) ? remote_table_name : table_name; + + auto result = std::make_shared(getDatabaseName(), local_table_name, schema_name, remote_table_name, ColumnsDescription{columns}, context, helper); if (!result) throw Exception("Failed to instantiate storage from table function " + getName(), ErrorCodes::UNKNOWN_EXCEPTION); diff --git a/dbms/src/TableFunctions/TableFunctionMySQL.cpp b/dbms/src/TableFunctions/TableFunctionMySQL.cpp index 6775363e02c..ac8d2671878 100644 --- a/dbms/src/TableFunctions/TableFunctionMySQL.cpp +++ b/dbms/src/TableFunctions/TableFunctionMySQL.cpp @@ -54,8 +54,8 @@ StoragePtr TableFunctionMySQL::executeImpl(const ASTPtr & ast_function, const Co args[i] = evaluateConstantExpressionOrIdentifierAsLiteral(args[i], context); std::string host_port = args[0]->as().value.safeGet(); - std::string database_name = args[1]->as().value.safeGet(); - // std::string table_name = args[2]->as().value.safeGet(); + std::string remote_database_name = args[1]->as().value.safeGet(); + std::string remote_table_name = args[2]->as().value.safeGet(); std::string user_name = args[3]->as().value.safeGet(); std::string password = args[4]->as().value.safeGet(); @@ -74,7 +74,7 @@ StoragePtr TableFunctionMySQL::executeImpl(const ASTPtr & ast_function, const Co /// 3306 is the default MySQL port number auto parsed_host_port = parseAddress(host_port, 3306); - mysqlxx::Pool pool(database_name, parsed_host_port.first, user_name, password, parsed_host_port.second); + mysqlxx::Pool pool(remote_database_name, parsed_host_port.first, user_name, password, parsed_host_port.second); /// Determine table definition by running a query to INFORMATION_SCHEMA. @@ -95,8 +95,8 @@ StoragePtr TableFunctionMySQL::executeImpl(const ASTPtr & ast_function, const Co " COLUMN_TYPE LIKE '%unsigned' AS is_unsigned," " CHARACTER_MAXIMUM_LENGTH AS length" " FROM INFORMATION_SCHEMA.COLUMNS" - " WHERE TABLE_SCHEMA = " << quote << database_name - << " AND TABLE_NAME = " << quote << table_name + " WHERE TABLE_SCHEMA = " << quote << remote_database_name + << " AND TABLE_NAME = " << quote << remote_table_name << " ORDER BY ORDINAL_POSITION"; NamesAndTypesList columns; @@ -116,14 +116,17 @@ StoragePtr TableFunctionMySQL::executeImpl(const ASTPtr & ast_function, const Co } if (columns.empty()) - throw Exception("MySQL table " + backQuoteIfNeed(database_name) + "." + backQuoteIfNeed(table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE); + throw Exception("MySQL table " + backQuoteIfNeed(remote_database_name) + "." + backQuoteIfNeed(remote_table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE); + + ///If table_name was not specified by user, it will have the same name as remote_table_name + std::string local_table_name = (table_name == getName()) ? remote_table_name : table_name; auto res = StorageMySQL::create( getDatabaseName(), - table_name, + local_table_name, std::move(pool), - database_name, - table_name, + remote_database_name, + remote_table_name, replace_query, on_duplicate_clause, ColumnsDescription{columns}, From 6ba4408741cb3c4b86e0afa725c14223a0b09082 Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Fri, 19 Jul 2019 16:30:22 +0300 Subject: [PATCH 0202/1165] Tests added --- ...3_create_table_as_table_function.reference | 26 +++++++++++++++++++ .../00973_create_table_as_table_function.sh | 26 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00973_create_table_as_table_function.reference create mode 100755 dbms/tests/queries/0_stateless/00973_create_table_as_table_function.sh diff --git a/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.reference b/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.reference new file mode 100644 index 00000000000..830a01e609a --- /dev/null +++ b/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.reference @@ -0,0 +1,26 @@ +1 +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +19 +20 +21 +22 +23 +24 +25 diff --git a/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.sh b/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.sh new file mode 100755 index 00000000000..aff96a364d1 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +. $CURDIR/../shell_config.sh + +$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t1" +$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t2" +$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t3" +$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t4" + +$CLICKHOUSE_CLIENT -q "CREATE TABLE t1 AS remote('127.0.0.1', system.one)" +$CLICKHOUSE_CLIENT -q "SELECT count() FROM t1" + +$CLICKHOUSE_CLIENT -q "CREATE TABLE t2 AS remote('127.0.0.1', system.numbers)" +$CLICKHOUSE_CLIENT -q "SELECT * FROM t2 LIMIT 18" + +$CLICKHOUSE_CLIENT -q "CREATE TABLE t3 AS remote('127.0.0.1', numbers(100))" +$CLICKHOUSE_CLIENT -q "SELECT * FROM t3 where number > 18 and number < 25" + +$CLICKHOUSE_CLIENT -q "CREATE TABLE t4 AS numbers(100)" +$CLICKHOUSE_CLIENT -q "SELECT count() FROM t4 where number > 74" + +$CLICKHOUSE_CLIENT -q "DROP TABLE t1" +$CLICKHOUSE_CLIENT -q "DROP TABLE t2" +$CLICKHOUSE_CLIENT -q "DROP TABLE t3" +$CLICKHOUSE_CLIENT -q "DROP TABLE t4" From 8146126dfd59f83dc464c12463a0bf8a52b18a25 Mon Sep 17 00:00:00 2001 From: Alexander Tokmakov Date: Fri, 19 Jul 2019 15:10:05 +0300 Subject: [PATCH 0203/1165] improvements --- dbms/src/DataTypes/DataTypeNullable.cpp | 55 +++++++++++- dbms/src/DataTypes/DataTypeNullable.h | 3 +- dbms/src/Formats/CSVRowInputStream.cpp | 109 ++++++++---------------- dbms/src/Formats/CSVRowInputStream.h | 2 +- 4 files changed, 89 insertions(+), 80 deletions(-) diff --git a/dbms/src/DataTypes/DataTypeNullable.cpp b/dbms/src/DataTypes/DataTypeNullable.cpp index c56d8616be2..fbeb115b787 100644 --- a/dbms/src/DataTypes/DataTypeNullable.cpp +++ b/dbms/src/DataTypes/DataTypeNullable.cpp @@ -272,9 +272,58 @@ void DataTypeNullable::serializeTextCSV(const IColumn & column, size_t row_num, void DataTypeNullable::deserializeTextCSV(IColumn & column, ReadBuffer & istr, const FormatSettings & settings) const { - safeDeserialize(column, - [&istr] { return checkStringByFirstCharacterAndAssertTheRest("\\N", istr); }, - [this, &settings, &istr] (IColumn & nested) { nested_data_type->deserializeAsTextCSV(nested, istr, settings); }); + constexpr char const * null_literal = "NULL"; + constexpr size_t len = 4; + size_t null_prefix_len = 0; + + auto check_for_null = [&istr, &settings, &null_prefix_len] + { + if (checkStringByFirstCharacterAndAssertTheRest("\\N", istr)) + return true; + if (!settings.csv.unquoted_null_literal_as_null) + return false; + + /// Check for unquoted NULL + while (!istr.eof() && null_prefix_len < len && null_literal[null_prefix_len] == *istr.position()) + { + ++null_prefix_len; + ++istr.position(); + } + if (null_prefix_len == len) + return true; + + /// Value and "NULL" have common prefix, but value is not "NULL". + /// Restore previous buffer position if possible. + if (null_prefix_len <= istr.offset()) + { + istr.position() -= null_prefix_len; + null_prefix_len = 0; + } + return false; + }; + + auto deserialize_nested = [this, &settings, &istr, &null_prefix_len] (IColumn & nested) + { + if (likely(!null_prefix_len)) + nested_data_type->deserializeAsTextCSV(nested, istr, settings); + else + { + /// Previous buffer position was not restored, + /// so we need to prepend extracted characters (rare case) + ReadBufferFromMemory prepend(null_literal, null_prefix_len); + ConcatReadBuffer buf(prepend, istr); + nested_data_type->deserializeAsTextCSV(nested, buf, settings); + + /// Check if all extracted characters was read by nested parser and update buffer position + if (null_prefix_len < buf.count()) + istr.position() = buf.position(); + else if (null_prefix_len > buf.count()) + throw DB::Exception("Some characters were extracted from buffer, but nested parser did not read them", + ErrorCodes::LOGICAL_ERROR); + } + }; + + safeDeserialize(column, check_for_null, deserialize_nested); } void DataTypeNullable::serializeText(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings & settings) const diff --git a/dbms/src/DataTypes/DataTypeNullable.h b/dbms/src/DataTypes/DataTypeNullable.h index 2b098ea0476..6a9308af69f 100644 --- a/dbms/src/DataTypes/DataTypeNullable.h +++ b/dbms/src/DataTypes/DataTypeNullable.h @@ -61,7 +61,8 @@ public: * 1. \N * 2. empty string (without quotes) * 3. NULL - * Now we support only first. + * We support all of them (however, second variant is supported by CSVRowInputStream, not by deserializeTextCSV). + * (see also input_format_defaults_for_omitted_fields and format_csv_unquoted_null_literal_as_null settings) * In CSV, non-NULL string value, starting with \N characters, must be placed in quotes, to avoid ambiguity. */ void deserializeTextCSV(IColumn & column, ReadBuffer & istr, const FormatSettings & settings) const override; diff --git a/dbms/src/Formats/CSVRowInputStream.cpp b/dbms/src/Formats/CSVRowInputStream.cpp index 79e510b9fc3..11108a74142 100644 --- a/dbms/src/Formats/CSVRowInputStream.cpp +++ b/dbms/src/Formats/CSVRowInputStream.cpp @@ -213,53 +213,14 @@ bool CSVRowInputStream::read(MutableColumns & columns, RowReadExtension & ext) for (size_t file_column = 0; file_column < column_indexes_for_input_fields.size(); ++file_column) { const auto & table_column = column_indexes_for_input_fields[file_column]; - const bool is_last_file_column = - file_column + 1 == column_indexes_for_input_fields.size(); + const bool is_last_file_column = file_column + 1 == column_indexes_for_input_fields.size(); if (table_column) { skipWhitespacesAndTabs(istr); - const auto & type = data_types[*table_column]; - const bool at_delimiter = *istr.position() == delimiter; - const bool at_last_column_line_end = is_last_file_column - && (*istr.position() == '\n' || *istr.position() == '\r' - || istr.eof()); - - if (format_settings.csv.empty_as_default - && (at_delimiter || at_last_column_line_end)) - { - /// Treat empty unquoted column value as default value, if - /// specified in the settings. Tuple columns might seem - /// problematic, because they are never quoted but still contain - /// commas, which might be also used as delimiters. However, - /// they do not contain empty unquoted fields, so this check - /// works for tuples as well. - read_columns[*table_column] = false; + read_columns[*table_column] = readField(*columns[*table_column], data_types[*table_column], is_last_file_column); + if (!read_columns[*table_column]) have_default_columns = true; - } - else if (format_settings.csv.null_as_default && !type->isNullable() && type->canBeInsideNullable()) - { - /// If value is null but type is not nullable then use default value instead. - DataTypeNullable nullable(type); - auto tmp_col = nullable.createColumn(); - readField(*tmp_col, nullable); - if (tmp_col->isNullAt(0)) - { - read_columns[*table_column] = false; - have_default_columns = true; - } - else - { - columns[*table_column]->insert((*tmp_col)[0]); - read_columns[*table_column] = true; - } - } - else - { - /// Read the column normally. - readField(*columns[*table_column], *type); - read_columns[*table_column] = true; - } skipWhitespacesAndTabs(istr); } else @@ -399,7 +360,7 @@ bool OPTIMIZE(1) CSVRowInputStream::parseRowAndPrintDiagnosticInfo(MutableColumn { skipWhitespacesAndTabs(istr); prev_position = istr.position(); - current_column_type->deserializeAsTextCSV(*columns[table_column], istr, format_settings); + readField(*columns[table_column], current_column_type, is_last_file_column); curr_position = istr.position(); skipWhitespacesAndTabs(istr); } @@ -539,47 +500,45 @@ void CSVRowInputStream::updateDiagnosticInfo() pos_of_current_row = istr.position(); } -void CSVRowInputStream::readField(IColumn & column, const IDataType & type) +bool CSVRowInputStream::readField(IColumn & column, const DataTypePtr & type, bool is_last_file_column) { - if (format_settings.csv.unquoted_null_literal_as_null && type.isNullable()) + const bool at_delimiter = *istr.position() == format_settings.csv.delimiter; + const bool at_last_column_line_end = is_last_file_column + && (*istr.position() == '\n' || *istr.position() == '\r' + || istr.eof()); + + if (format_settings.csv.empty_as_default + && (at_delimiter || at_last_column_line_end)) { - /// Check for unquoted NULL - constexpr char const * null_literal = "NULL"; - constexpr size_t len = 4; - size_t count = 0; - while (!istr.eof() && count < len && null_literal[count] == *istr.position()) - { - ++count; - ++istr.position(); - } - - if (count == len) - { - column.insert(Field()); /// insert null - } - else if (count == 0) - { - type.deserializeAsTextCSV(column, istr, format_settings); /// parse value - } - else - { - /// Prepend extracted data and parse value (rare case) - ReadBufferFromMemory prepend(null_literal, count); - ConcatReadBuffer buf(prepend, istr); - type.deserializeAsTextCSV(column, buf, format_settings); - - if (count < buf.count()) - istr.position() = buf.position(); - } + /// Treat empty unquoted column value as default value, if + /// specified in the settings. Tuple columns might seem + /// problematic, because they are never quoted but still contain + /// commas, which might be also used as delimiters. However, + /// they do not contain empty unquoted fields, so this check + /// works for tuples as well. + return false; + } + else if (format_settings.csv.null_as_default && !type->isNullable() && type->canBeInsideNullable()) + { + /// If value is null but type is not nullable then use default value instead. + DataTypeNullable nullable(type); + auto tmp_col = nullable.createColumn(); + nullable.deserializeAsTextCSV(*tmp_col, istr, format_settings); + if (tmp_col->isNullAt(0)) + return false; + column.insert((*tmp_col)[0]); + return true; } else { - type.deserializeAsTextCSV(column, istr, format_settings); + /// Read the column normally. + type->deserializeAsTextCSV(column, istr, format_settings); + return true; } } - void registerInputFormatCSV(FormatFactory & factory) +void registerInputFormatCSV(FormatFactory & factory) { for (bool with_names : {false, true}) { diff --git a/dbms/src/Formats/CSVRowInputStream.h b/dbms/src/Formats/CSVRowInputStream.h index 2dbff3457c8..af7f629b5bf 100644 --- a/dbms/src/Formats/CSVRowInputStream.h +++ b/dbms/src/Formats/CSVRowInputStream.h @@ -72,7 +72,7 @@ private: bool parseRowAndPrintDiagnosticInfo(MutableColumns & columns, WriteBuffer & out, size_t max_length_of_column_name, size_t max_length_of_data_type_name); - void readField(IColumn & column, const IDataType & type); + bool readField(IColumn & column, const DataTypePtr & type, bool is_last_file_column); }; } From 646733046292fd7616e7412106ca6c8e31a3665f Mon Sep 17 00:00:00 2001 From: Alexander Tokmakov Date: Fri, 19 Jul 2019 16:57:50 +0300 Subject: [PATCH 0204/1165] update docs --- docs/en/interfaces/formats.md | 2 +- docs/en/operations/settings/settings.md | 9 +++++++++ docs/ru/interfaces/formats.md | 2 +- docs/ru/operations/settings/settings.md | 8 ++++++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/docs/en/interfaces/formats.md b/docs/en/interfaces/formats.md index 71f28263270..7a93d0614a9 100644 --- a/docs/en/interfaces/formats.md +++ b/docs/en/interfaces/formats.md @@ -173,7 +173,7 @@ Empty unquoted input values are replaced with default values for the respective [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#session_settings-input_format_defaults_for_omitted_fields) is enabled. -`NULL` is formatted as `\N`. +`NULL` is formatted as `\N` or `NULL` or an empty unquoted string (see settings [format_csv_unquoted_null_literal_as_null](../operations/settings/settings.md#settings-format_csv_unquoted_null_literal_as_null) and [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#settings-input_format_defaults_for_omitted_fields)). The CSV format supports the output of totals and extremes the same way as `TabSeparated`. diff --git a/docs/en/operations/settings/settings.md b/docs/en/operations/settings/settings.md index c68643d3877..7de2d86120b 100644 --- a/docs/en/operations/settings/settings.md +++ b/docs/en/operations/settings/settings.md @@ -211,6 +211,11 @@ Possible values: Default value: 0. +## input_format_null_as_default {#settings-input_format_null_as_default} + +Enables or disables using default values if input data contain `NULL`, but data type of corresponding column in not `Nullable(T)` (for CSV format). + + ## input_format_skip_unknown_fields {#settings-input_format_skip_unknown_fields} Enables or disables skipping insertion of extra data. @@ -689,6 +694,10 @@ If the value is true, integers appear in quotes when using JSON\* Int64 and UInt The character interpreted as a delimiter in the CSV data. By default, the delimiter is `,`. +## format_csv_unquoted_null_literal_as_null {#settings-format_csv_unquoted_null_literal_as_null} + +For CSV input format enables or disables parsing of unquoted `NULL` as literal (synonym for `\N`). + ## insert_quorum {#settings-insert_quorum} Enables quorum writes. diff --git a/docs/ru/interfaces/formats.md b/docs/ru/interfaces/formats.md index c02ed3d4993..70a4e608e2a 100644 --- a/docs/ru/interfaces/formats.md +++ b/docs/ru/interfaces/formats.md @@ -165,7 +165,7 @@ clickhouse-client --format_csv_delimiter="|" --query="INSERT INTO test.csv FORMA При парсинге, все значения могут парситься как в кавычках, так и без кавычек. Поддерживаются как двойные, так и одинарные кавычки. Строки также могут быть без кавычек. В этом случае они парсятся до символа-разделителя или перевода строки (CR или LF). В нарушение RFC, в случае парсинга строк не в кавычках, начальные и конечные пробелы и табы игнорируются. В качестве перевода строки, поддерживаются как Unix (LF), так и Windows (CR LF) и Mac OS Classic (LF CR) варианты. -`NULL` форматируется в виде `\N`. +`NULL` форматируется в виде `\N` или `NULL` или пустой неэкранированной строки (см. настройки [format_csv_unquoted_null_literal_as_null](../operations/settings/settings.md#settings-format_csv_unquoted_null_literal_as_null) и [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#settings-input_format_defaults_for_omitted_fields)). Формат CSV поддерживает вывод totals и extremes аналогично `TabSeparated`. diff --git a/docs/ru/operations/settings/settings.md b/docs/ru/operations/settings/settings.md index e320231d397..53a4eb181eb 100644 --- a/docs/ru/operations/settings/settings.md +++ b/docs/ru/operations/settings/settings.md @@ -203,6 +203,10 @@ Ok. Значение по умолчанию: 0. +## input_format_null_as_default {#settings-input_format_null_as_default} + +Включает или отключает использование значений по-умолчанию в случаях, когда во входных данных содержится `NULL`, но тип соответствующего столбца не `Nullable(T)` (для фомата CSV). + ## input_format_skip_unknown_fields {#settings-input_format_skip_unknown_fields} Включает или отключает пропускание вставки неизвестных данных. @@ -609,6 +613,10 @@ load_balancing = first_or_random Символ, интерпретируемый как разделитель в данных формата CSV. По умолчанию — `,`. +## format_csv_unquoted_null_literal_as_null {#settings-format_csv_unquoted_null_literal_as_null} + +Для формата CSV включает или выключает парсинг неэкранированной строки `NULL` как литерала (синоним для `\N`) + ## insert_quorum {#settings-insert_quorum} Включает кворумную запись. From 1bec5a8241e332d399a6faf74e68ca97e13922ec Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Fri, 19 Jul 2019 17:56:00 +0300 Subject: [PATCH 0205/1165] refactor MergeTree select streams --- .../MergeTreeBaseSelectBlockInputStream.h | 4 +- .../MergeTree/MergeTreeBlockReadUtils.cpp | 60 ++++++++++++++++ .../MergeTree/MergeTreeBlockReadUtils.h | 12 ++++ .../Storages/MergeTree/MergeTreeReadPool.cpp | 65 +++-------------- ...MergeTreeReverseSelectBlockInputStream.cpp | 66 +++--------------- .../MergeTreeReverseSelectBlockInputStream.h | 6 +- .../MergeTreeSelectBlockInputStream.cpp | 69 ++++--------------- .../MergeTreeSelectBlockInputStream.h | 4 +- 8 files changed, 108 insertions(+), 178 deletions(-) diff --git a/dbms/src/Storages/MergeTree/MergeTreeBaseSelectBlockInputStream.h b/dbms/src/Storages/MergeTree/MergeTreeBaseSelectBlockInputStream.h index 31a1e36921d..a7e37f68f0c 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeBaseSelectBlockInputStream.h +++ b/dbms/src/Storages/MergeTree/MergeTreeBaseSelectBlockInputStream.h @@ -36,8 +36,6 @@ public: protected: Block readImpl() final; - Block readFromPartImpl(); - /// Creates new this->task, and initilizes readers virtual bool getNewTask() = 0; @@ -46,6 +44,8 @@ protected: virtual Block readFromPart(); + Block readFromPartImpl(); + void injectVirtualColumns(Block & block) const; void initializeRangeReaders(MergeTreeReadTask & task); diff --git a/dbms/src/Storages/MergeTree/MergeTreeBlockReadUtils.cpp b/dbms/src/Storages/MergeTree/MergeTreeBlockReadUtils.cpp index 043adc7a259..96ece027694 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeBlockReadUtils.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeBlockReadUtils.cpp @@ -193,4 +193,64 @@ void MergeTreeBlockSizePredictor::update(const Block & block, double decay) } } + +MergeTreeReadTaskColumns getReadTaskColumns(const MergeTreeData & storage, const MergeTreeData::DataPartPtr & data_part, + const Names & required_columns, const PrewhereInfoPtr & prewhere_info, bool check_columns) +{ + Names column_names = required_columns; + Names pre_column_names; + + /// inject columns required for defaults evaluation + bool should_reorder = !injectRequiredColumns(storage, data_part, column_names).empty(); + + if (prewhere_info) + { + if (prewhere_info->alias_actions) + pre_column_names = prewhere_info->alias_actions->getRequiredColumns(); + else + pre_column_names = prewhere_info->prewhere_actions->getRequiredColumns(); + + if (pre_column_names.empty()) + pre_column_names.push_back(column_names[0]); + + const auto injected_pre_columns = injectRequiredColumns(storage, data_part, pre_column_names); + if (!injected_pre_columns.empty()) + should_reorder = true; + + const NameSet pre_name_set(pre_column_names.begin(), pre_column_names.end()); + + Names post_column_names; + for (const auto & name : column_names) + if (!pre_name_set.count(name)) + post_column_names.push_back(name); + + column_names = post_column_names; + } + + MergeTreeReadTaskColumns result; + + if (check_columns) + { + /// Under owned_data_part->columns_lock we check that all requested columns are of the same type as in the table. + /// This may be not true in case of ALTER MODIFY. + if (!pre_column_names.empty()) + storage.check(data_part->columns, pre_column_names); + if (!column_names.empty()) + storage.check(data_part->columns, column_names); + + const NamesAndTypesList & physical_columns = storage.getColumns().getAllPhysical(); + result.pre_columns = physical_columns.addTypes(pre_column_names); + result.columns = physical_columns.addTypes(column_names); + } + else + { + result.pre_columns = data_part->columns.addTypes(pre_column_names); + result.columns = data_part->columns.addTypes(column_names); + } + + result.should_reorder = should_reorder; + + return result; +} + } diff --git a/dbms/src/Storages/MergeTree/MergeTreeBlockReadUtils.h b/dbms/src/Storages/MergeTree/MergeTreeBlockReadUtils.h index cee344b1cef..f0e24d96add 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeBlockReadUtils.h +++ b/dbms/src/Storages/MergeTree/MergeTreeBlockReadUtils.h @@ -64,6 +64,18 @@ struct MergeTreeReadTask virtual ~MergeTreeReadTask(); }; +struct MergeTreeReadTaskColumns +{ + /// column names to read during WHERE + NamesAndTypesList columns; + /// column names to read during PREWHERE + NamesAndTypesList pre_columns; + /// resulting block may require reordering in accordance with `ordered_names` + bool should_reorder; +}; + +MergeTreeReadTaskColumns getReadTaskColumns(const MergeTreeData & storage, const MergeTreeData::DataPartPtr & data_part, + const Names & required_columns, const PrewhereInfoPtr & prewhere_info, bool check_columns); struct MergeTreeBlockSizePredictor { diff --git a/dbms/src/Storages/MergeTree/MergeTreeReadPool.cpp b/dbms/src/Storages/MergeTree/MergeTreeReadPool.cpp index 4cbf28c83c2..a2123fb59cd 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeReadPool.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeReadPool.cpp @@ -219,65 +219,16 @@ std::vector MergeTreeReadPool::fillPerPartInfo( per_part_columns_lock.emplace_back(part.data_part->columns_lock); - /// inject column names required for DEFAULT evaluation in current part - auto required_column_names = column_names; + auto [columns, pre_columns, should_reorder] = + getReadTaskColumns(data, part.data_part, column_names, prewhere_info, check_columns); - const auto injected_columns = injectRequiredColumns(data, part.data_part, required_column_names); - auto should_reoder = !injected_columns.empty(); + /// will be used to distinguish between PREWHERE and WHERE columns when applying filter + const auto & column_names = columns.getNames(); + per_part_column_name_set.emplace_back(column_names.begin(), column_names.end()); - Names required_pre_column_names; - - if (prewhere_info) - { - /// collect columns required for PREWHERE evaluation - if (prewhere_info->alias_actions) - required_pre_column_names = prewhere_info->alias_actions->getRequiredColumns(); - else - required_pre_column_names = prewhere_info->prewhere_actions->getRequiredColumns(); - - /// there must be at least one column required for PREWHERE - if (required_pre_column_names.empty()) - required_pre_column_names.push_back(required_column_names[0]); - - /// PREWHERE columns may require some additional columns for DEFAULT evaluation - const auto injected_pre_columns = injectRequiredColumns(data, part.data_part, required_pre_column_names); - if (!injected_pre_columns.empty()) - should_reoder = true; - - /// will be used to distinguish between PREWHERE and WHERE columns when applying filter - const NameSet pre_name_set(required_pre_column_names.begin(), required_pre_column_names.end()); - - Names post_column_names; - for (const auto & name : required_column_names) - if (!pre_name_set.count(name)) - post_column_names.push_back(name); - - required_column_names = post_column_names; - } - - per_part_column_name_set.emplace_back(std::begin(required_column_names), std::end(required_column_names)); - - if (check_columns) - { - /** Under part->columns_lock check that all requested columns in part are of same type that in table. - * This could be violated during ALTER MODIFY. - */ - if (!required_pre_column_names.empty()) - data.check(part.data_part->columns, required_pre_column_names); - if (!required_column_names.empty()) - data.check(part.data_part->columns, required_column_names); - - const NamesAndTypesList & physical_columns = data.getColumns().getAllPhysical(); - per_part_pre_columns.push_back(physical_columns.addTypes(required_pre_column_names)); - per_part_columns.push_back(physical_columns.addTypes(required_column_names)); - } - else - { - per_part_pre_columns.push_back(part.data_part->columns.addTypes(required_pre_column_names)); - per_part_columns.push_back(part.data_part->columns.addTypes(required_column_names)); - } - - per_part_should_reorder.push_back(should_reoder); + per_part_pre_columns.push_back(std::move(pre_columns)); + per_part_columns.push_back(std::move(columns)); + per_part_should_reorder.push_back(should_reorder); parts_with_idx.push_back({ part.data_part, part.part_index_in_query }); diff --git a/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.cpp b/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.cpp index ef0fb8c0be4..9b78517e742 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.cpp @@ -19,7 +19,7 @@ MergeTreeReverseSelectBlockInputStream::MergeTreeReverseSelectBlockInputStream( UInt64 max_block_size_rows_, size_t preferred_block_size_bytes_, size_t preferred_max_column_in_block_size_bytes_, - Names column_names, + Names required_columns_, const MarkRanges & mark_ranges_, bool use_uncompressed_cache_, const PrewhereInfoPtr & prewhere_info_, @@ -34,7 +34,7 @@ MergeTreeReverseSelectBlockInputStream::MergeTreeReverseSelectBlockInputStream( MergeTreeBaseSelectBlockInputStream{storage_, prewhere_info_, max_block_size_rows_, preferred_block_size_bytes_, preferred_max_column_in_block_size_bytes_, min_bytes_to_use_direct_io_, max_read_buffer_size_, use_uncompressed_cache_, save_marks_in_cache_, virt_column_names_}, - required_columns{column_names}, + required_columns{required_columns_}, data_part{owned_data_part_}, part_columns_lock(data_part->columns_lock), all_mark_ranges(mark_ranges_), @@ -78,56 +78,11 @@ MergeTreeReverseSelectBlockInputStream::MergeTreeReverseSelectBlockInputStream( ordered_names = getHeader().getNames(); - Names pre_column_names; - - /// inject columns required for defaults evaluation - should_reorder = !injectRequiredColumns(storage, data_part, required_columns).empty(); - - if (prewhere_info) - { - if (prewhere_info->alias_actions) - pre_column_names = prewhere_info->alias_actions->getRequiredColumns(); - else - pre_column_names = prewhere_info->prewhere_actions->getRequiredColumns(); - - if (pre_column_names.empty()) - pre_column_names.push_back(required_columns[0]); - - const auto injected_pre_columns = injectRequiredColumns(storage, data_part, pre_column_names); - if (!injected_pre_columns.empty()) - should_reorder = true; - - const NameSet pre_name_set(pre_column_names.begin(), pre_column_names.end()); - - Names post_column_names; - for (const auto & name : required_columns) - if (!pre_name_set.count(name)) - post_column_names.push_back(name); - - required_columns = post_column_names; - } + task_columns = getReadTaskColumns(storage, data_part, required_columns, prewhere_info, check_columns); /// will be used to distinguish between PREWHERE and WHERE columns when applying filter - column_name_set = NameSet{required_columns.begin(), required_columns.end()}; - - if (check_columns) - { - /// Under owned_data_part->columns_lock we check that all requested columns are of the same type as in the table. - /// This may be not true in case of ALTER MODIFY. - if (!pre_column_names.empty()) - storage.check(data_part->columns, pre_column_names); - if (!required_columns.empty()) - storage.check(data_part->columns, required_columns); - - const NamesAndTypesList & physical_columns = storage.getColumns().getAllPhysical(); - pre_columns = physical_columns.addTypes(pre_column_names); - columns = physical_columns.addTypes(column_names); - } - else - { - pre_columns = data_part->columns.addTypes(pre_column_names); - columns = data_part->columns.addTypes(required_columns); - } + const auto & column_names = task_columns.columns.getNames(); + column_name_set = NameSet{column_names.begin(), column_names.end()}; if (use_uncompressed_cache) owned_uncompressed_cache = storage.global_context.getUncompressedCache(); @@ -135,13 +90,13 @@ MergeTreeReverseSelectBlockInputStream::MergeTreeReverseSelectBlockInputStream( owned_mark_cache = storage.global_context.getMarkCache(); reader = std::make_unique( - path, data_part, columns, owned_uncompressed_cache.get(), + path, data_part, task_columns.columns, owned_uncompressed_cache.get(), owned_mark_cache.get(), save_marks_in_cache, storage, all_mark_ranges, min_bytes_to_use_direct_io, max_read_buffer_size); if (prewhere_info) pre_reader = std::make_unique( - path, data_part, pre_columns, owned_uncompressed_cache.get(), + path, data_part, task_columns.pre_columns, owned_uncompressed_cache.get(), owned_mark_cache.get(), save_marks_in_cache, storage, all_mark_ranges, min_bytes_to_use_direct_io, max_read_buffer_size); } @@ -176,8 +131,9 @@ try : std::make_unique(data_part, ordered_names, data_part->storage.getSampleBlock()); task = std::make_unique( - data_part, mark_ranges_for_task, part_index_in_query, ordered_names, column_name_set, columns, pre_columns, - prewhere_info && prewhere_info->remove_prewhere_column, should_reorder, std::move(size_predictor)); + data_part, mark_ranges_for_task, part_index_in_query, ordered_names, column_name_set, + task_columns.columns, task_columns.pre_columns, prewhere_info && prewhere_info->remove_prewhere_column, + task_columns.should_reorder, std::move(size_predictor)); return true; } @@ -230,8 +186,6 @@ void MergeTreeReverseSelectBlockInputStream::finish() data_part.reset(); } - MergeTreeReverseSelectBlockInputStream::~MergeTreeReverseSelectBlockInputStream() = default; - } diff --git a/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.h b/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.h index 828bc9c0732..40af5d5d92a 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.h +++ b/dbms/src/Storages/MergeTree/MergeTreeReverseSelectBlockInputStream.h @@ -56,8 +56,8 @@ private: /// Names from header. Used in order to order columns in read blocks. Names ordered_names; NameSet column_name_set; - NamesAndTypesList columns; - NamesAndTypesList pre_columns; + + MergeTreeReadTaskColumns task_columns; /// Data part will not be removed if the pointer owns it MergeTreeData::DataPartPtr data_part; @@ -73,8 +73,6 @@ private: String path; - bool should_reorder = false; - Blocks blocks; Logger * log = &Logger::get("MergeTreeReverseSelectBlockInputStream"); diff --git a/dbms/src/Storages/MergeTree/MergeTreeSelectBlockInputStream.cpp b/dbms/src/Storages/MergeTree/MergeTreeSelectBlockInputStream.cpp index e1c5e5239b5..2d48b362902 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeSelectBlockInputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeSelectBlockInputStream.cpp @@ -19,7 +19,7 @@ MergeTreeSelectBlockInputStream::MergeTreeSelectBlockInputStream( UInt64 max_block_size_rows_, size_t preferred_block_size_bytes_, size_t preferred_max_column_in_block_size_bytes_, - Names column_names, + Names required_columns_, const MarkRanges & mark_ranges_, bool use_uncompressed_cache_, const PrewhereInfoPtr & prewhere_info_, @@ -34,7 +34,7 @@ MergeTreeSelectBlockInputStream::MergeTreeSelectBlockInputStream( MergeTreeBaseSelectBlockInputStream{storage_, prewhere_info_, max_block_size_rows_, preferred_block_size_bytes_, preferred_max_column_in_block_size_bytes_, min_bytes_to_use_direct_io_, max_read_buffer_size_, use_uncompressed_cache_, save_marks_in_cache_, virt_column_names_}, - required_columns{column_names}, + required_columns{required_columns_}, data_part{owned_data_part_}, part_columns_lock(data_part->columns_lock), all_mark_ranges(mark_ranges_), @@ -99,57 +99,7 @@ try } is_first_task = false; - Names pre_column_names; - Names column_names = required_columns; - - /// inject columns required for defaults evaluation - bool should_reorder = !injectRequiredColumns(storage, data_part, column_names).empty(); - - if (prewhere_info) - { - if (prewhere_info->alias_actions) - pre_column_names = prewhere_info->alias_actions->getRequiredColumns(); - else - pre_column_names = prewhere_info->prewhere_actions->getRequiredColumns(); - - if (pre_column_names.empty()) - pre_column_names.push_back(column_names[0]); - - const auto injected_pre_columns = injectRequiredColumns(storage, data_part, pre_column_names); - if (!injected_pre_columns.empty()) - should_reorder = true; - - const NameSet pre_name_set(pre_column_names.begin(), pre_column_names.end()); - - Names post_column_names; - for (const auto & name : column_names) - if (!pre_name_set.count(name)) - post_column_names.push_back(name); - - column_names = post_column_names; - } - - /// will be used to distinguish between PREWHERE and WHERE columns when applying filter - column_name_set = NameSet{column_names.begin(), column_names.end()}; - - if (check_columns) - { - /// Under owned_data_part->columns_lock we check that all requested columns are of the same type as in the table. - /// This may be not true in case of ALTER MODIFY. - if (!pre_column_names.empty()) - storage.check(data_part->columns, pre_column_names); - if (!column_names.empty()) - storage.check(data_part->columns, column_names); - - const NamesAndTypesList & physical_columns = storage.getColumns().getAllPhysical(); - pre_columns = physical_columns.addTypes(pre_column_names); - columns = physical_columns.addTypes(column_names); - } - else - { - pre_columns = data_part->columns.addTypes(pre_column_names); - columns = data_part->columns.addTypes(column_names); - } + task_columns = getReadTaskColumns(storage, data_part, required_columns, prewhere_info, check_columns); /** @note you could simply swap `reverse` in if and else branches of MergeTreeDataSelectExecutor, * and remove this reverse. */ @@ -160,9 +110,14 @@ try ? nullptr : std::make_unique(data_part, ordered_names, data_part->storage.getSampleBlock()); + /// will be used to distinguish between PREWHERE and WHERE columns when applying filter + const auto & column_names = task_columns.columns.getNames(); + column_name_set = NameSet{column_names.begin(), column_names.end()}; + task = std::make_unique( - data_part, remaining_mark_ranges, part_index_in_query, ordered_names, column_name_set, columns, pre_columns, - prewhere_info && prewhere_info->remove_prewhere_column, should_reorder, std::move(size_predictor)); + data_part, remaining_mark_ranges, part_index_in_query, ordered_names, column_name_set, task_columns.columns, + task_columns.pre_columns, prewhere_info && prewhere_info->remove_prewhere_column, + task_columns.should_reorder, std::move(size_predictor)); if (!reader) { @@ -172,13 +127,13 @@ try owned_mark_cache = storage.global_context.getMarkCache(); reader = std::make_unique( - path, data_part, columns, owned_uncompressed_cache.get(), + path, data_part, task_columns.columns, owned_uncompressed_cache.get(), owned_mark_cache.get(), save_marks_in_cache, storage, all_mark_ranges, min_bytes_to_use_direct_io, max_read_buffer_size); if (prewhere_info) pre_reader = std::make_unique( - path, data_part, pre_columns, owned_uncompressed_cache.get(), + path, data_part, task_columns.pre_columns, owned_uncompressed_cache.get(), owned_mark_cache.get(), save_marks_in_cache, storage, all_mark_ranges, min_bytes_to_use_direct_io, max_read_buffer_size); } diff --git a/dbms/src/Storages/MergeTree/MergeTreeSelectBlockInputStream.h b/dbms/src/Storages/MergeTree/MergeTreeSelectBlockInputStream.h index 243283b9a43..4faeaa0d397 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeSelectBlockInputStream.h +++ b/dbms/src/Storages/MergeTree/MergeTreeSelectBlockInputStream.h @@ -55,8 +55,8 @@ private: /// Names from header. Used in order to order columns in read blocks. Names ordered_names; NameSet column_name_set; - NamesAndTypesList columns; - NamesAndTypesList pre_columns; + + MergeTreeReadTaskColumns task_columns; /// Data part will not be removed if the pointer owns it MergeTreeData::DataPartPtr data_part; From f9945494d9d000d81edc972cdb911ed299dd3b7a Mon Sep 17 00:00:00 2001 From: Ivan Lezhankin Date: Fri, 19 Jul 2019 18:01:34 +0300 Subject: [PATCH 0206/1165] Always resume consumer before subscription. Also add more logs to see the difference between rd_kafka_assignment() vs rd_kafka_subscription() --- .../Kafka/ReadBufferFromKafkaConsumer.cpp | 16 ++++++++++++++++ .../Storages/Kafka/ReadBufferFromKafkaConsumer.h | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/dbms/src/Storages/Kafka/ReadBufferFromKafkaConsumer.cpp b/dbms/src/Storages/Kafka/ReadBufferFromKafkaConsumer.cpp index fc81e38bb63..5c7a8222a69 100644 --- a/dbms/src/Storages/Kafka/ReadBufferFromKafkaConsumer.cpp +++ b/dbms/src/Storages/Kafka/ReadBufferFromKafkaConsumer.cpp @@ -55,6 +55,22 @@ void ReadBufferFromKafkaConsumer::commit() void ReadBufferFromKafkaConsumer::subscribe(const Names & topics) { + { + String message = "Subscribed to topics:"; + for (const auto & topic : consumer->get_subscription()) + message += " " + topic; + LOG_TRACE(log, message); + } + + { + String message = "Assigned to topics:"; + for (const auto & toppar : consumer->get_assignment()) + message += " " + toppar.get_topic(); + LOG_TRACE(log, message); + } + + consumer->resume(); + // While we wait for an assignment after subscribtion, we'll poll zero messages anyway. // If we're doing a manual select then it's better to get something after a wait, then immediate nothing. if (consumer->get_subscription().empty()) diff --git a/dbms/src/Storages/Kafka/ReadBufferFromKafkaConsumer.h b/dbms/src/Storages/Kafka/ReadBufferFromKafkaConsumer.h index ac6011cfed0..2400357d3c3 100644 --- a/dbms/src/Storages/Kafka/ReadBufferFromKafkaConsumer.h +++ b/dbms/src/Storages/Kafka/ReadBufferFromKafkaConsumer.h @@ -24,7 +24,7 @@ public: void subscribe(const Names & topics); // Subscribe internal consumer to topics. void unsubscribe(); // Unsubscribe internal consumer in case of failure. - auto pollTimeout() { return poll_timeout; } + auto pollTimeout() const { return poll_timeout; } // Return values for the message that's being read. String currentTopic() const { return current[-1].get_topic(); } From 475179cec751c4e17f6b7cd7d0e649908b60aa0a Mon Sep 17 00:00:00 2001 From: Yuriy Date: Fri, 19 Jul 2019 20:50:42 +0300 Subject: [PATCH 0207/1165] added size limit for packets which are read without memory tracker (all packets except for COM_QUERY) --- dbms/programs/server/MySQLHandler.cpp | 10 ++- dbms/src/Core/MySQLProtocol.h | 76 +++++++++++-------- .../integration/test_mysql_protocol/test.py | 2 +- 3 files changed, 51 insertions(+), 37 deletions(-) diff --git a/dbms/programs/server/MySQLHandler.cpp b/dbms/programs/server/MySQLHandler.cpp index 9cc03cc9a31..55ebe9602ce 100644 --- a/dbms/programs/server/MySQLHandler.cpp +++ b/dbms/programs/server/MySQLHandler.cpp @@ -19,6 +19,7 @@ #include #include +#include namespace DB @@ -115,6 +116,9 @@ void MySQLHandler::run() unsigned char command = 0; payload.readStrict(reinterpret_cast(command)); + // For commands which are executed without MemoryTracker. + LimitReadBuffer limited_payload(payload, 10000, true, "too long MySQL packet."); + LOG_DEBUG(log, "Received command: " << static_cast(command) << ". Connection id: " << connection_id << "."); try { @@ -123,13 +127,13 @@ void MySQLHandler::run() case COM_QUIT: return; case COM_INIT_DB: - comInitDB(payload); + comInitDB(limited_payload); break; case COM_QUERY: comQuery(payload); break; case COM_FIELD_LIST: - comFieldList(payload); + comFieldList(limited_payload); break; case COM_PING: comPing(); @@ -150,7 +154,7 @@ void MySQLHandler::run() } } } - catch (Poco::Exception & exc) + catch (const Poco::Exception & exc) { log->log(exc); } diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index 15025b73425..52beab16332 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -16,6 +16,7 @@ #include #include #include +#include /// Implementation of MySQL wire protocol @@ -128,16 +129,6 @@ public: }; -class ReadPacket -{ -public: - ReadPacket() = default; - ReadPacket(ReadPacket &&) = default; - virtual void readPayload(ReadBuffer & buf) = 0; - - virtual ~ReadPacket() = default; -}; - /** Reading packets. * Internally, it calls (if no more data) next() method of the underlying ReadBufferFromPocoSocket, and sets the working buffer to the rest part of the current packet payload. */ @@ -150,6 +141,7 @@ public: , sequence_id(sequence_id) { } + private: ReadBuffer & in; uint8_t & sequence_id; @@ -210,6 +202,36 @@ protected: }; +class ClientPacket +{ +public: + ClientPacket() = default; + ClientPacket(ClientPacket &&) = default; + + virtual void read(ReadBuffer & in, uint8_t & sequence_id) + { + PacketPayloadReadBuffer payload(in, sequence_id); + readPayload(payload); + } + + virtual void readPayload(ReadBuffer & buf) = 0; + + virtual ~ClientPacket() = default; +}; + + +class LimitedClientPacket : public ClientPacket +{ + using ClientPacket::read; +public: + void read(ReadBuffer & in, uint8_t & sequence_id) override + { + LimitReadBuffer limited(in, 10000, true, "too long MySQL packet."); + ClientPacket::read(limited, sequence_id); + } +}; + + /** Writing packets. * https://dev.mysql.com/doc/internals/en/mysql-packet.html */ @@ -323,15 +345,9 @@ public: { } - PacketPayloadReadBuffer getPayload() + void receivePacket(ClientPacket & packet) { - return PacketPayloadReadBuffer(*in, sequence_id); - } - - void receivePacket(ReadPacket & packet) - { - auto payload = getPayload(); - packet.readPayload(payload); + packet.read(*in, sequence_id); } template @@ -343,6 +359,11 @@ public: out->next(); } + PacketPayloadReadBuffer getPayload() + { + return PacketPayloadReadBuffer(*in, sequence_id); + } + /// Sets sequence-id to 0. Must be called before each command phase. void resetSequenceId(); @@ -417,7 +438,7 @@ protected: } }; -class SSLRequest : public ReadPacket +class SSLRequest : public ClientPacket { public: uint32_t capability_flags; @@ -432,7 +453,7 @@ public: } }; -class HandshakeResponse : public ReadPacket +class HandshakeResponse : public LimitedClientPacket { public: uint32_t capability_flags = 0; @@ -508,7 +529,7 @@ protected: } }; -class AuthSwitchResponse : public ReadPacket +class AuthSwitchResponse : public LimitedClientPacket { public: String value; @@ -538,17 +559,6 @@ protected: } }; -/// Packet with a single null-terminated string. Is used for clear text authentication. -class NullTerminatedString : public ReadPacket -{ -public: - String value; - - void readPayload(ReadBuffer & payload) override - { - readNullTerminated(value, payload); - } -}; class OK_Packet : public WritePacket { @@ -752,7 +762,7 @@ protected: } }; -class ComFieldList : public ReadPacket +class ComFieldList : public LimitedClientPacket { public: String table, field_wildcard; diff --git a/dbms/tests/integration/test_mysql_protocol/test.py b/dbms/tests/integration/test_mysql_protocol/test.py index 04e6ac1ee8b..d1c22bc6d2e 100644 --- a/dbms/tests/integration/test_mysql_protocol/test.py +++ b/dbms/tests/integration/test_mysql_protocol/test.py @@ -15,7 +15,7 @@ SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) config_dir = os.path.join(SCRIPT_DIR, './configs') cluster = ClickHouseCluster(__file__) -node = cluster.add_instance('node', config_dir=config_dir) +node = cluster.add_instance('node', config_dir=config_dir, env_variables={'UBSAN_OPTIONS': 'print_stacktrace=1'}) server_port = 9001 From 39ea5486f546ea293edf5daff75fadb3bca9b9ef Mon Sep 17 00:00:00 2001 From: Yuriy Date: Fri, 19 Jul 2019 21:29:39 +0300 Subject: [PATCH 0208/1165] removed reinterpret_cast --- dbms/programs/server/MySQLHandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/programs/server/MySQLHandler.cpp b/dbms/programs/server/MySQLHandler.cpp index 55ebe9602ce..8aa4209cc41 100644 --- a/dbms/programs/server/MySQLHandler.cpp +++ b/dbms/programs/server/MySQLHandler.cpp @@ -113,13 +113,13 @@ void MySQLHandler::run() packet_sender->resetSequenceId(); PacketPayloadReadBuffer payload = packet_sender->getPayload(); - unsigned char command = 0; + char command = 0; payload.readStrict(reinterpret_cast(command)); // For commands which are executed without MemoryTracker. LimitReadBuffer limited_payload(payload, 10000, true, "too long MySQL packet."); - LOG_DEBUG(log, "Received command: " << static_cast(command) << ". Connection id: " << connection_id << "."); + LOG_DEBUG(log, "Received command: " << static_cast(static_cast(command)) << ". Connection id: " << connection_id << "."); try { switch (command) From fa2dfcd71d27e0106d10d204de09dde1f9bca274 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Fri, 19 Jul 2019 21:43:52 +0300 Subject: [PATCH 0209/1165] better --- dbms/src/Core/MySQLProtocol.h | 1 - dbms/src/IO/WriteHelpers.h | 1 + dbms/src/Interpreters/Context.h | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index 52beab16332..b9b53647431 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -222,7 +222,6 @@ public: class LimitedClientPacket : public ClientPacket { - using ClientPacket::read; public: void read(ReadBuffer & in, uint8_t & sequence_id) override { diff --git a/dbms/src/IO/WriteHelpers.h b/dbms/src/IO/WriteHelpers.h index 1b16b747533..44d7b7ab540 100644 --- a/dbms/src/IO/WriteHelpers.h +++ b/dbms/src/IO/WriteHelpers.h @@ -47,6 +47,7 @@ inline void writeChar(char x, WriteBuffer & buf) ++buf.position(); } +/// Write the same character n times. inline void writeChar(char c, size_t n, WriteBuffer & buf) { while (n) diff --git a/dbms/src/Interpreters/Context.h b/dbms/src/Interpreters/Context.h index 7e340b07776..a1da148a093 100644 --- a/dbms/src/Interpreters/Context.h +++ b/dbms/src/Interpreters/Context.h @@ -493,12 +493,12 @@ public: IHostContextPtr & getHostContext(); const IHostContextPtr & getHostContext() const; - typedef struct MySQLWireContext + struct MySQLWireContext { uint8_t sequence_id = 0; uint32_t client_capabilities = 0; size_t max_packet_size = 0; - } MySQLState; + }; MySQLWireContext mysql; private: From 34a4d6a57a3cffe352d5d224960eca5decadbcb3 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Fri, 19 Jul 2019 21:46:57 +0300 Subject: [PATCH 0210/1165] better --- dbms/programs/server/MySQLHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/programs/server/MySQLHandler.cpp b/dbms/programs/server/MySQLHandler.cpp index 8aa4209cc41..fec6b57b916 100644 --- a/dbms/programs/server/MySQLHandler.cpp +++ b/dbms/programs/server/MySQLHandler.cpp @@ -114,7 +114,7 @@ void MySQLHandler::run() PacketPayloadReadBuffer payload = packet_sender->getPayload(); char command = 0; - payload.readStrict(reinterpret_cast(command)); + payload.readStrict(command); // For commands which are executed without MemoryTracker. LimitReadBuffer limited_payload(payload, 10000, true, "too long MySQL packet."); From fb06a8518ea56016fe6239a00f7a354e4385a133 Mon Sep 17 00:00:00 2001 From: Alexander Tokmakov Date: Fri, 19 Jul 2019 21:52:54 +0300 Subject: [PATCH 0211/1165] optimization --- dbms/src/Formats/CSVRowInputStream.cpp | 32 ++++++++++++++++++-------- dbms/src/Formats/CSVRowInputStream.h | 7 +++++- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/dbms/src/Formats/CSVRowInputStream.cpp b/dbms/src/Formats/CSVRowInputStream.cpp index 11108a74142..635fef82cd0 100644 --- a/dbms/src/Formats/CSVRowInputStream.cpp +++ b/dbms/src/Formats/CSVRowInputStream.cpp @@ -99,6 +99,7 @@ CSVRowInputStream::CSVRowInputStream(ReadBuffer & istr_, const Block & header_, data_types.resize(num_columns); column_indexes_by_names.reserve(num_columns); + column_idx_to_nullable_column_idx.resize(num_columns); for (size_t i = 0; i < num_columns; ++i) { @@ -106,6 +107,16 @@ CSVRowInputStream::CSVRowInputStream(ReadBuffer & istr_, const Block & header_, data_types[i] = column_info.type; column_indexes_by_names.emplace(column_info.name, i); + + /// If input_format_null_as_default=1 we need ColumnNullable of type DataTypeNullable(nested_type) + /// to parse value as nullable before inserting it in corresponding column of not-nullable type. + /// Constructing temporary column for each row is slow, so we prepare it here + if (format_settings.csv.null_as_default && !column_info.type->isNullable() && column_info.type->canBeInsideNullable()) + { + column_idx_to_nullable_column_idx[i] = nullable_columns.size(); + nullable_types.emplace_back(std::make_shared(column_info.type)); + nullable_columns.emplace_back(nullable_types.back()->createColumn()); + } } } @@ -218,7 +229,8 @@ bool CSVRowInputStream::read(MutableColumns & columns, RowReadExtension & ext) if (table_column) { skipWhitespacesAndTabs(istr); - read_columns[*table_column] = readField(*columns[*table_column], data_types[*table_column], is_last_file_column); + read_columns[*table_column] = readField(*columns[*table_column], data_types[*table_column], + is_last_file_column, *table_column); if (!read_columns[*table_column]) have_default_columns = true; skipWhitespacesAndTabs(istr); @@ -360,7 +372,7 @@ bool OPTIMIZE(1) CSVRowInputStream::parseRowAndPrintDiagnosticInfo(MutableColumn { skipWhitespacesAndTabs(istr); prev_position = istr.position(); - readField(*columns[table_column], current_column_type, is_last_file_column); + readField(*columns[table_column], current_column_type, is_last_file_column, table_column); curr_position = istr.position(); skipWhitespacesAndTabs(istr); } @@ -500,7 +512,7 @@ void CSVRowInputStream::updateDiagnosticInfo() pos_of_current_row = istr.position(); } -bool CSVRowInputStream::readField(IColumn & column, const DataTypePtr & type, bool is_last_file_column) +bool CSVRowInputStream::readField(IColumn & column, const DataTypePtr & type, bool is_last_file_column, size_t column_idx) { const bool at_delimiter = *istr.position() == format_settings.csv.delimiter; const bool at_last_column_line_end = is_last_file_column @@ -518,15 +530,17 @@ bool CSVRowInputStream::readField(IColumn & column, const DataTypePtr & type, bo /// works for tuples as well. return false; } - else if (format_settings.csv.null_as_default && !type->isNullable() && type->canBeInsideNullable()) + else if (column_idx_to_nullable_column_idx[column_idx]) { /// If value is null but type is not nullable then use default value instead. - DataTypeNullable nullable(type); - auto tmp_col = nullable.createColumn(); - nullable.deserializeAsTextCSV(*tmp_col, istr, format_settings); - if (tmp_col->isNullAt(0)) + const size_t nullable_idx = *column_idx_to_nullable_column_idx[column_idx]; + auto & tmp_col = *nullable_columns[nullable_idx]; + nullable_types[nullable_idx]->deserializeAsTextCSV(tmp_col, istr, format_settings); + Field value = tmp_col[0]; + tmp_col.popBack(1); /// do not store copy of values in memory + if (value.isNull()) return false; - column.insert((*tmp_col)[0]); + column.insert(value); return true; } else diff --git a/dbms/src/Formats/CSVRowInputStream.h b/dbms/src/Formats/CSVRowInputStream.h index af7f629b5bf..6cb0fe8e82f 100644 --- a/dbms/src/Formats/CSVRowInputStream.h +++ b/dbms/src/Formats/CSVRowInputStream.h @@ -67,12 +67,17 @@ private: char * pos_of_current_row = nullptr; char * pos_of_prev_row = nullptr; + /// For setting input_format_null_as_default + DataTypes nullable_types; + MutableColumns nullable_columns; + OptionalIndexes column_idx_to_nullable_column_idx; + void updateDiagnosticInfo(); bool parseRowAndPrintDiagnosticInfo(MutableColumns & columns, WriteBuffer & out, size_t max_length_of_column_name, size_t max_length_of_data_type_name); - bool readField(IColumn & column, const DataTypePtr & type, bool is_last_file_column); + bool readField(IColumn & column, const DataTypePtr & type, bool is_last_file_column, size_t column_idx); }; } From be589ed825f402ac078c3433c206661101b90ae7 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Fri, 19 Jul 2019 22:29:44 +0300 Subject: [PATCH 0212/1165] commented about endianness --- dbms/src/Core/MySQLProtocol.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index b9b53647431..9667a040963 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -18,7 +18,8 @@ #include #include -/// Implementation of MySQL wire protocol +/// Implementation of MySQL wire protocol. +/// Works only on little-endian architecture. namespace DB { @@ -212,6 +213,12 @@ public: { PacketPayloadReadBuffer payload(in, sequence_id); readPayload(payload); + if (!payload.eof()) + { + std::stringstream tmp; + tmp << "Packet payload is not fully read. Stopped after " << payload.count() << " bytes, while " << payload.available() << " bytes are in buffer."; + throw ProtocolError(tmp.str(), ErrorCodes::UNKNOWN_PACKET_FROM_CLIENT); + } } virtual void readPayload(ReadBuffer & buf) = 0; From 5b879e143f510c09c538de6d4aa9be88199e36de Mon Sep 17 00:00:00 2001 From: Vitaly Baranov Date: Sat, 20 Jul 2019 00:03:25 +0300 Subject: [PATCH 0213/1165] Fix segfault in ExternalLoader::reloadOutdated(). --- dbms/src/Interpreters/ExternalLoader.cpp | 25 ++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/dbms/src/Interpreters/ExternalLoader.cpp b/dbms/src/Interpreters/ExternalLoader.cpp index c7b3d202a28..3b6f9c21b7d 100644 --- a/dbms/src/Interpreters/ExternalLoader.cpp +++ b/dbms/src/Interpreters/ExternalLoader.cpp @@ -536,7 +536,7 @@ public: for (const auto & name_and_info : infos) { const auto & info = name_and_info.second; - if ((now >= info.next_update_time) && !info.loading() && info.was_loading()) + if ((now >= info.next_update_time) && !info.loading() && info.loaded()) is_modified_map.emplace(info.object, true); } } @@ -558,16 +558,21 @@ public: std::lock_guard lock{mutex}; TimePoint now = std::chrono::system_clock::now(); for (auto & [name, info] : infos) - if ((now >= info.next_update_time) && !info.loading() && info.was_loading()) + if ((now >= info.next_update_time) && !info.loading()) { - auto it = is_modified_map.find(info.object); - if (it == is_modified_map.end()) - continue; /// Object has been just added, it can be simply omitted from this update of outdated. - bool is_modified_flag = it->second; - if (info.loaded() && !is_modified_flag) - info.next_update_time = calculate_next_update_time(info.object, info.error_count); - else - startLoading(name, info); + if (info.loaded()) + { + auto it = is_modified_map.find(info.object); + if (it == is_modified_map.end()) + continue; /// Object has just been added, we can simply omit it from this update of outdated. + bool is_modified_flag = it->second; + if (!is_modified_flag) + { + info.next_update_time = calculate_next_update_time(info.object, info.error_count); + continue; + } + } + startLoading(name, info); } } } From f18e9592a1d3a422a56166dfc33cb9a714d3b5c9 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Fri, 19 Jul 2019 22:37:48 +0300 Subject: [PATCH 0214/1165] Update ExternalLoader.cpp --- dbms/src/Interpreters/ExternalLoader.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dbms/src/Interpreters/ExternalLoader.cpp b/dbms/src/Interpreters/ExternalLoader.cpp index 3b6f9c21b7d..a5863adb92d 100644 --- a/dbms/src/Interpreters/ExternalLoader.cpp +++ b/dbms/src/Interpreters/ExternalLoader.cpp @@ -511,12 +511,14 @@ public: { std::lock_guard lock{mutex}; for (auto & [name, info] : infos) + { if ((info.was_loading() || load_never_loading) && filter_by_name(name)) { cancelLoading(info); info.forced_to_reload = true; startLoading(name, info); } + } } /// Starts reloading of all the objects. @@ -558,6 +560,7 @@ public: std::lock_guard lock{mutex}; TimePoint now = std::chrono::system_clock::now(); for (auto & [name, info] : infos) + { if ((now >= info.next_update_time) && !info.loading()) { if (info.loaded()) @@ -574,6 +577,7 @@ public: } startLoading(name, info); } + } } } From e64f8e606d62dadbe5c9a9fd20a6607709317497 Mon Sep 17 00:00:00 2001 From: Vitaly Baranov Date: Sat, 20 Jul 2019 00:01:20 +0300 Subject: [PATCH 0215/1165] Add comments. --- dbms/src/Interpreters/ExternalLoader.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/dbms/src/Interpreters/ExternalLoader.cpp b/dbms/src/Interpreters/ExternalLoader.cpp index a5863adb92d..31a69086f5c 100644 --- a/dbms/src/Interpreters/ExternalLoader.cpp +++ b/dbms/src/Interpreters/ExternalLoader.cpp @@ -530,8 +530,8 @@ public: /// The function doesn't touch the objects which were never tried to load. void reloadOutdated() { + /// Iterate through all the objects and find loaded ones which should be checked if they were modified. std::unordered_map is_modified_map; - { std::lock_guard lock{mutex}; TimePoint now = std::chrono::system_clock::now(); @@ -543,7 +543,9 @@ public: } } - /// The `mutex` should be unlocked while we're calling the function is_object_modified(). + /// Find out which of the loaded objects were modified. + /// We couldn't perform these checks while we were building `is_modified_map` because + /// the `mutex` should be unlocked while we're calling the function is_object_modified(). for (auto & [object, is_modified_flag] : is_modified_map) { try @@ -556,6 +558,7 @@ public: } } + /// Iterate through all the objects again and either start loading or just set `next_update_time`. { std::lock_guard lock{mutex}; TimePoint now = std::chrono::system_clock::now(); @@ -567,15 +570,24 @@ public: { auto it = is_modified_map.find(info.object); if (it == is_modified_map.end()) - continue; /// Object has just been added, we can simply omit it from this update of outdated. + continue; /// Object has been just loaded (it wasn't loaded while we were building the map `is_modified_map`), so we don't have to reload it right now. + bool is_modified_flag = it->second; if (!is_modified_flag) { + /// Object wasn't modified so we only have to set `next_update_time`. info.next_update_time = calculate_next_update_time(info.object, info.error_count); continue; } + + /// Object was modified and should be reloaded. + startLoading(name, info); + } + else if (info.failed()) + { + /// Object was never loaded successfully and should be reloaded. + startLoading(name, info); } - startLoading(name, info); } } } From 3abf1b278e6b7512e421d315478d262823b09e7d Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Sat, 20 Jul 2019 02:51:20 +0300 Subject: [PATCH 0216/1165] Update DatabasesCommon.cpp --- dbms/src/Databases/DatabasesCommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Databases/DatabasesCommon.cpp b/dbms/src/Databases/DatabasesCommon.cpp index 27d236678f1..de3396b4603 100644 --- a/dbms/src/Databases/DatabasesCommon.cpp +++ b/dbms/src/Databases/DatabasesCommon.cpp @@ -71,7 +71,7 @@ std::pair createTableFromDefinition( if (ast_create_query.as_table_function) { - const auto * table_function = ast_create_query.as_table_function->as(); + const auto & table_function = ast_create_query.as_table_function->as(); const auto & factory = TableFunctionFactory::instance(); StoragePtr storage = factory.get(table_function->name, context)->execute(ast_create_query.as_table_function, context, ast_create_query.table); return {ast_create_query.table, storage}; From f9d1214bbc90390ebfb0f3044af7671a209d2665 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Sat, 20 Jul 2019 02:51:43 +0300 Subject: [PATCH 0217/1165] Update DatabasesCommon.cpp --- dbms/src/Databases/DatabasesCommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Databases/DatabasesCommon.cpp b/dbms/src/Databases/DatabasesCommon.cpp index de3396b4603..3b5654083e0 100644 --- a/dbms/src/Databases/DatabasesCommon.cpp +++ b/dbms/src/Databases/DatabasesCommon.cpp @@ -73,7 +73,7 @@ std::pair createTableFromDefinition( { const auto & table_function = ast_create_query.as_table_function->as(); const auto & factory = TableFunctionFactory::instance(); - StoragePtr storage = factory.get(table_function->name, context)->execute(ast_create_query.as_table_function, context, ast_create_query.table); + StoragePtr storage = factory.get(table_function.name, context)->execute(ast_create_query.as_table_function, context, ast_create_query.table); return {ast_create_query.table, storage}; } /// We do not directly use `InterpreterCreateQuery::execute`, because From b035edefea7e81082697ffe8452dad087cc917b7 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Sat, 20 Jul 2019 03:02:18 +0300 Subject: [PATCH 0218/1165] Update InterpreterCreateQuery.cpp --- dbms/src/Interpreters/InterpreterCreateQuery.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Interpreters/InterpreterCreateQuery.cpp b/dbms/src/Interpreters/InterpreterCreateQuery.cpp index a862c7de5c1..6ecf789076b 100644 --- a/dbms/src/Interpreters/InterpreterCreateQuery.cpp +++ b/dbms/src/Interpreters/InterpreterCreateQuery.cpp @@ -523,9 +523,9 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create) if (create.as_table_function) { - const auto * table_function = create.as_table_function->as(); + const auto & table_function = create.as_table_function->as(); const auto & factory = TableFunctionFactory::instance(); - as_storage = factory.get(table_function->name, context)->execute(create.as_table_function, context, create.table); + as_storage = factory.get(table_function.name, context)->execute(create.as_table_function, context, create.table); } if (!as_table_name.empty()) { From 47058e8e11c93d883ecdba591bd420ac26449271 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 21 Jul 2019 05:13:42 +0300 Subject: [PATCH 0219/1165] Fixed error --- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 1 - dbms/src/Interpreters/QueryNormalizer.cpp | 1 - dbms/src/Parsers/ASTColumnsClause.cpp | 4 ++-- dbms/src/Parsers/ASTSelectQuery.cpp | 1 - dbms/src/Storages/StorageView.cpp | 8 ++++---- dbms/tests/queries/0_stateless/00969_columns_clause.sql | 6 +++++- 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index e8143f3c41a..055f5c8f3ec 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include diff --git a/dbms/src/Interpreters/QueryNormalizer.cpp b/dbms/src/Interpreters/QueryNormalizer.cpp index c35c47179c6..cea801c7c2f 100644 --- a/dbms/src/Interpreters/QueryNormalizer.cpp +++ b/dbms/src/Interpreters/QueryNormalizer.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include diff --git a/dbms/src/Parsers/ASTColumnsClause.cpp b/dbms/src/Parsers/ASTColumnsClause.cpp index 8fbcfce471f..2bd8670480e 100644 --- a/dbms/src/Parsers/ASTColumnsClause.cpp +++ b/dbms/src/Parsers/ASTColumnsClause.cpp @@ -31,14 +31,14 @@ void ASTColumnsClause::formatImpl(const FormatSettings & settings, FormatState & void ASTColumnsClause::setPattern(String pattern) { original_pattern = std::move(pattern); - column_matcher = std::make_shared(pattern, RE2::Quiet); + column_matcher = std::make_shared(original_pattern, RE2::Quiet); if (!column_matcher->ok()) throw DB::Exception("COLUMNS pattern " + original_pattern + " cannot be compiled: " + column_matcher->error(), DB::ErrorCodes::CANNOT_COMPILE_REGEXP); } bool ASTColumnsClause::isColumnMatching(const String & column_name) const { - return RE2::FullMatch(column_name, *column_matcher); + return RE2::PartialMatch(column_name, *column_matcher); } diff --git a/dbms/src/Parsers/ASTSelectQuery.cpp b/dbms/src/Parsers/ASTSelectQuery.cpp index 44012cd071c..16396095ce9 100644 --- a/dbms/src/Parsers/ASTSelectQuery.cpp +++ b/dbms/src/Parsers/ASTSelectQuery.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include diff --git a/dbms/src/Storages/StorageView.cpp b/dbms/src/Storages/StorageView.cpp index 9d4855b586a..153de1ab176 100644 --- a/dbms/src/Storages/StorageView.cpp +++ b/dbms/src/Storages/StorageView.cpp @@ -1,9 +1,12 @@ #include #include +#include + #include #include #include #include +#include #include #include @@ -11,10 +14,7 @@ #include #include -#include -#include -#include -#include + namespace DB { diff --git a/dbms/tests/queries/0_stateless/00969_columns_clause.sql b/dbms/tests/queries/0_stateless/00969_columns_clause.sql index b1d7949b8ee..1ea344f0bcd 100644 --- a/dbms/tests/queries/0_stateless/00969_columns_clause.sql +++ b/dbms/tests/queries/0_stateless/00969_columns_clause.sql @@ -1,3 +1,7 @@ -CREATE TABLE IF NOT EXISTS ColumnsClauseTest (product_price Int64, product_weight Int16, amount Int64) Engine=TinyLog; +DROP TABLE IF EXISTS ColumnsClauseTest; + +CREATE TABLE ColumnsClauseTest (product_price Int64, product_weight Int16, amount Int64) Engine=TinyLog; INSERT INTO ColumnsClauseTest VALUES (100, 10, 324), (120, 8, 23); SELECT COLUMNS('product.*') from ColumnsClauseTest ORDER BY product_price; + +DROP TABLE ColumnsClauseTest; From fb0d09c5d359887c1e5687b83b024b01197c3466 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 21 Jul 2019 20:03:58 +0300 Subject: [PATCH 0220/1165] Rename files --- dbms/src/Interpreters/AsteriskSemantic.h | 6 +++--- .../Interpreters/PredicateExpressionsOptimizer.cpp | 6 +++--- .../TranslateQualifiedNamesVisitor.cpp | 6 +++--- ...{ASTColumnsClause.cpp => ASTColumnsMatcher.cpp} | 14 +++++++------- .../{ASTColumnsClause.h => ASTColumnsMatcher.h} | 4 ++-- dbms/src/Parsers/ExpressionElementParsers.cpp | 8 ++++---- dbms/src/Parsers/ExpressionElementParsers.h | 2 +- 7 files changed, 23 insertions(+), 23 deletions(-) rename dbms/src/Parsers/{ASTColumnsClause.cpp => ASTColumnsMatcher.cpp} (63%) rename dbms/src/Parsers/{ASTColumnsClause.h => ASTColumnsMatcher.h} (88%) diff --git a/dbms/src/Interpreters/AsteriskSemantic.h b/dbms/src/Interpreters/AsteriskSemantic.h index 9b0939f6001..1bd9ecedddd 100644 --- a/dbms/src/Interpreters/AsteriskSemantic.h +++ b/dbms/src/Interpreters/AsteriskSemantic.h @@ -4,7 +4,7 @@ #include #include -#include +#include namespace DB { @@ -25,11 +25,11 @@ struct AsteriskSemantic static void setAliases(ASTAsterisk & node, const RevertedAliasesPtr & aliases) { node.semantic = makeSemantic(aliases); } static void setAliases(ASTQualifiedAsterisk & node, const RevertedAliasesPtr & aliases) { node.semantic = makeSemantic(aliases); } - static void setAliases(ASTColumnsClause & node, const RevertedAliasesPtr & aliases) { node.semantic = makeSemantic(aliases); } + static void setAliases(ASTColumnsMatcher & node, const RevertedAliasesPtr & aliases) { node.semantic = makeSemantic(aliases); } static RevertedAliasesPtr getAliases(const ASTAsterisk & node) { return node.semantic ? node.semantic->aliases : nullptr; } static RevertedAliasesPtr getAliases(const ASTQualifiedAsterisk & node) { return node.semantic ? node.semantic->aliases : nullptr; } - static RevertedAliasesPtr getAliases(const ASTColumnsClause & node) { return node.semantic ? node.semantic->aliases : nullptr; } + static RevertedAliasesPtr getAliases(const ASTColumnsMatcher & node) { return node.semantic ? node.semantic->aliases : nullptr; } private: static std::shared_ptr makeSemantic(const RevertedAliasesPtr & aliases) diff --git a/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp b/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp index eb7c34be9b8..b6e6545e475 100644 --- a/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp +++ b/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include @@ -414,7 +414,7 @@ ASTs PredicateExpressionsOptimizer::getSelectQueryProjectionColumns(ASTPtr & ast for (const auto & projection_column : select_query->select()->children) { - if (projection_column->as() || projection_column->as() || projection_column->as()) + if (projection_column->as() || projection_column->as() || projection_column->as()) { ASTs evaluated_columns = evaluateAsterisk(select_query, projection_column); @@ -485,7 +485,7 @@ ASTs PredicateExpressionsOptimizer::evaluateAsterisk(ASTSelectQuery * select_que throw Exception("Logical error: unexpected table expression", ErrorCodes::LOGICAL_ERROR); const auto block = storage->getSampleBlock(); - if (const auto * asterisk_pattern = asterisk->as()) + if (const auto * asterisk_pattern = asterisk->as()) { for (size_t idx = 0; idx < block.columns(); ++idx) { diff --git a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp index 1ca5fa69ce5..df27a21c9b4 100644 --- a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp +++ b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include namespace DB @@ -166,7 +166,7 @@ void TranslateQualifiedNamesMatcher::visit(ASTExpressionList & node, const ASTPt bool has_asterisk = false; for (const auto & child : node.children) { - if (child->as() || child->as()) + if (child->as() || child->as()) { if (tables_with_columns.empty()) throw Exception("An asterisk cannot be replaced with empty columns.", ErrorCodes::LOGICAL_ERROR); @@ -207,7 +207,7 @@ void TranslateQualifiedNamesMatcher::visit(ASTExpressionList & node, const ASTPt first_table = false; } } - else if (const auto * asterisk_pattern = child->as()) + else if (const auto * asterisk_pattern = child->as()) { bool first_table = true; for (const auto & [table, table_columns] : tables_with_columns) diff --git a/dbms/src/Parsers/ASTColumnsClause.cpp b/dbms/src/Parsers/ASTColumnsMatcher.cpp similarity index 63% rename from dbms/src/Parsers/ASTColumnsClause.cpp rename to dbms/src/Parsers/ASTColumnsMatcher.cpp index 2bd8670480e..e9cdb822c6e 100644 --- a/dbms/src/Parsers/ASTColumnsClause.cpp +++ b/dbms/src/Parsers/ASTColumnsMatcher.cpp @@ -1,4 +1,4 @@ -#include "ASTColumnsClause.h" +#include "ASTColumnsMatcher.h" #include #include @@ -11,16 +11,16 @@ namespace DB { -ASTPtr ASTColumnsClause::clone() const +ASTPtr ASTColumnsMatcher::clone() const { - auto clone = std::make_shared(*this); + auto clone = std::make_shared(*this); clone->cloneChildren(); return clone; } -void ASTColumnsClause::appendColumnName(WriteBuffer & ostr) const { writeString(original_pattern, ostr); } +void ASTColumnsMatcher::appendColumnName(WriteBuffer & ostr) const { writeString(original_pattern, ostr); } -void ASTColumnsClause::formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const +void ASTColumnsMatcher::formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const { WriteBufferFromOwnString pattern_quoted; writeQuotedString(original_pattern, pattern_quoted); @@ -28,7 +28,7 @@ void ASTColumnsClause::formatImpl(const FormatSettings & settings, FormatState & settings.ostr << (settings.hilite ? hilite_keyword : "") << "COLUMNS" << (settings.hilite ? hilite_none : "") << "(" << pattern_quoted.str() << ")"; } -void ASTColumnsClause::setPattern(String pattern) +void ASTColumnsMatcher::setPattern(String pattern) { original_pattern = std::move(pattern); column_matcher = std::make_shared(original_pattern, RE2::Quiet); @@ -36,7 +36,7 @@ void ASTColumnsClause::setPattern(String pattern) throw DB::Exception("COLUMNS pattern " + original_pattern + " cannot be compiled: " + column_matcher->error(), DB::ErrorCodes::CANNOT_COMPILE_REGEXP); } -bool ASTColumnsClause::isColumnMatching(const String & column_name) const +bool ASTColumnsMatcher::isColumnMatching(const String & column_name) const { return RE2::PartialMatch(column_name, *column_matcher); } diff --git a/dbms/src/Parsers/ASTColumnsClause.h b/dbms/src/Parsers/ASTColumnsMatcher.h similarity index 88% rename from dbms/src/Parsers/ASTColumnsClause.h rename to dbms/src/Parsers/ASTColumnsMatcher.h index 1cf13941420..e5ec9a2873d 100644 --- a/dbms/src/Parsers/ASTColumnsClause.h +++ b/dbms/src/Parsers/ASTColumnsMatcher.h @@ -25,10 +25,10 @@ struct AsteriskSemanticImpl; /** SELECT COLUMNS('regexp') is expanded to multiple columns like * (asterisk). */ -class ASTColumnsClause : public IAST +class ASTColumnsMatcher : public IAST { public: - String getID(char) const override { return "ColumnsClause"; } + String getID(char) const override { return "ColumnsMatcher"; } ASTPtr clone() const override; void appendColumnName(WriteBuffer & ostr) const override; diff --git a/dbms/src/Parsers/ExpressionElementParsers.cpp b/dbms/src/Parsers/ExpressionElementParsers.cpp index 80ec890b5d5..8cd017f0710 100644 --- a/dbms/src/Parsers/ExpressionElementParsers.cpp +++ b/dbms/src/Parsers/ExpressionElementParsers.cpp @@ -29,7 +29,7 @@ #include #include -#include "ASTColumnsClause.h" +#include "ASTColumnsMatcher.h" namespace DB @@ -1169,7 +1169,7 @@ bool ParserAlias::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) } -bool ParserColumnsClause::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) +bool ParserColumnsMatcher::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) { ParserKeyword columns("COLUMNS"); ParserStringLiteral regex; @@ -1189,7 +1189,7 @@ bool ParserColumnsClause::parseImpl(Pos & pos, ASTPtr & node, Expected & expecte return false; ++pos; - auto res = std::make_shared(); + auto res = std::make_shared(); res->setPattern(regex_node->as().value.get()); res->children.push_back(regex_node); node = std::move(res); @@ -1291,7 +1291,7 @@ bool ParserExpressionElement::parseImpl(Pos & pos, ASTPtr & node, Expected & exp || ParserLeftExpression().parse(pos, node, expected) || ParserRightExpression().parse(pos, node, expected) || ParserCase().parse(pos, node, expected) - || ParserColumnsClause().parse(pos, node, expected) /// before ParserFunction because it can be also parsed as a function. + || ParserColumnsMatcher().parse(pos, node, expected) /// before ParserFunction because it can be also parsed as a function. || ParserFunction().parse(pos, node, expected) || ParserQualifiedAsterisk().parse(pos, node, expected) || ParserAsterisk().parse(pos, node, expected) diff --git a/dbms/src/Parsers/ExpressionElementParsers.h b/dbms/src/Parsers/ExpressionElementParsers.h index bcf7be49e4e..dca82f72f12 100644 --- a/dbms/src/Parsers/ExpressionElementParsers.h +++ b/dbms/src/Parsers/ExpressionElementParsers.h @@ -75,7 +75,7 @@ protected: /** COLUMNS('') */ -class ParserColumnsClause : public IParserBase +class ParserColumnsMatcher : public IParserBase { protected: const char * getName() const { return "COLUMNS matcher"; } From e559c8f94929d099df200de3cf4d9c392323e63e Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Sun, 21 Jul 2019 21:17:28 +0300 Subject: [PATCH 0221/1165] fix build --- dbms/src/Storages/MergeTree/MergeTreeReadPool.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dbms/src/Storages/MergeTree/MergeTreeReadPool.cpp b/dbms/src/Storages/MergeTree/MergeTreeReadPool.cpp index a2123fb59cd..d98fb8ac87e 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeReadPool.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeReadPool.cpp @@ -219,15 +219,15 @@ std::vector MergeTreeReadPool::fillPerPartInfo( per_part_columns_lock.emplace_back(part.data_part->columns_lock); - auto [columns, pre_columns, should_reorder] = + auto [required_columns, required_pre_columns, should_reorder] = getReadTaskColumns(data, part.data_part, column_names, prewhere_info, check_columns); /// will be used to distinguish between PREWHERE and WHERE columns when applying filter - const auto & column_names = columns.getNames(); - per_part_column_name_set.emplace_back(column_names.begin(), column_names.end()); + const auto & required_column_names = required_columns.getNames(); + per_part_column_name_set.emplace_back(required_column_names.begin(), required_column_names.end()); - per_part_pre_columns.push_back(std::move(pre_columns)); - per_part_columns.push_back(std::move(columns)); + per_part_pre_columns.push_back(std::move(required_pre_columns)); + per_part_columns.push_back(std::move(required_columns)); per_part_should_reorder.push_back(should_reorder); parts_with_idx.push_back({ part.data_part, part.part_index_in_query }); From 8060993ca20a16a0bf25102d78fd8f45d0aade51 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 21 Jul 2019 23:40:34 +0300 Subject: [PATCH 0222/1165] Removed obsolete comment --- dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp index df27a21c9b4..1b063bc4625 100644 --- a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp +++ b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp @@ -124,7 +124,6 @@ void TranslateQualifiedNamesMatcher::visit(ASTSelectQuery & select, const ASTPtr if (auto join = select.join()) extractJoinUsingColumns(join->table_join, data); -#if 1 /// TODO: legacy? /// If the WHERE clause or HAVING consists of a single qualified column, the reference must be translated not only in children, /// but also in where_expression and having_expression. if (select.prewhere()) @@ -133,7 +132,6 @@ void TranslateQualifiedNamesMatcher::visit(ASTSelectQuery & select, const ASTPtr Visitor(data).visit(select.refWhere()); if (select.having()) Visitor(data).visit(select.refHaving()); -#endif } static void addIdentifier(ASTs & nodes, const String & table_name, const String & column_name, AsteriskSemantic::RevertedAliasesPtr aliases) From b2961bcc31450f75b249d512bfde7150e1397712 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 22 Jul 2019 00:19:42 +0300 Subject: [PATCH 0223/1165] Added check for empty number of columns; improved test --- dbms/src/Interpreters/SyntaxAnalyzer.cpp | 5 +++++ .../00969_columns_clause.reference | 22 +++++++++++++++++++ .../0_stateless/00969_columns_clause.sql | 20 +++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/dbms/src/Interpreters/SyntaxAnalyzer.cpp b/dbms/src/Interpreters/SyntaxAnalyzer.cpp index 62982ea1e59..83cacc94692 100644 --- a/dbms/src/Interpreters/SyntaxAnalyzer.cpp +++ b/dbms/src/Interpreters/SyntaxAnalyzer.cpp @@ -41,6 +41,7 @@ namespace ErrorCodes extern const int EMPTY_NESTED_TABLE; extern const int LOGICAL_ERROR; extern const int INVALID_JOIN_ON_EXPRESSION; + extern const int EMPTY_LIST_OF_COLUMNS_QUERIED; } NameSet removeDuplicateColumns(NamesAndTypesList & columns) @@ -110,6 +111,10 @@ void translateQualifiedNames(ASTPtr & query, const ASTSelectQuery & select_query TranslateQualifiedNamesVisitor::Data visitor_data(source_columns_set, tables_with_columns); TranslateQualifiedNamesVisitor visitor(visitor_data, log.stream()); visitor.visit(query); + + /// This may happen after expansion of COLUMNS('regexp'). + if (select_query.select()->children.empty()) + throw Exception("Empty list of columns in SELECT query", ErrorCodes::EMPTY_LIST_OF_COLUMNS_QUERIED); } bool hasArrayJoin(const ASTPtr & ast) diff --git a/dbms/tests/queries/0_stateless/00969_columns_clause.reference b/dbms/tests/queries/0_stateless/00969_columns_clause.reference index fcfd7d0919e..125a49fae0d 100644 --- a/dbms/tests/queries/0_stateless/00969_columns_clause.reference +++ b/dbms/tests/queries/0_stateless/00969_columns_clause.reference @@ -1,2 +1,24 @@ 100 10 120 8 +0 0 +1 1 +0 0 +1 1 +0 +1 +0 +1 +0 +1 +0 +1 +0 +1 +0 +1 +0 +2 +3 +2 +4 +3 diff --git a/dbms/tests/queries/0_stateless/00969_columns_clause.sql b/dbms/tests/queries/0_stateless/00969_columns_clause.sql index 1ea344f0bcd..fc5b72d3913 100644 --- a/dbms/tests/queries/0_stateless/00969_columns_clause.sql +++ b/dbms/tests/queries/0_stateless/00969_columns_clause.sql @@ -5,3 +5,23 @@ INSERT INTO ColumnsClauseTest VALUES (100, 10, 324), (120, 8, 23); SELECT COLUMNS('product.*') from ColumnsClauseTest ORDER BY product_price; DROP TABLE ColumnsClauseTest; + +SELECT number, COLUMNS('') FROM numbers(2); +SELECT number, COLUMNS('ber') FROM numbers(2); -- It works for unanchored regular expressions. +SELECT number, COLUMNS('x') FROM numbers(2); +SELECT COLUMNS('') FROM numbers(2); + +SELECT COLUMNS('x') FROM numbers(10) WHERE number > 5; -- { serverError 51 } + +SELECT * FROM numbers(2) WHERE NOT ignore(); +SELECT * FROM numbers(2) WHERE NOT ignore(*); +SELECT * FROM numbers(2) WHERE NOT ignore(COLUMNS('.+')); +SELECT * FROM numbers(2) WHERE NOT ignore(COLUMNS('x')); +SELECT COLUMNS('n') + COLUMNS('u') FROM system.numbers LIMIT 2; + +SELECT COLUMNS('n') + COLUMNS('u') FROM (SELECT 1 AS a, 2 AS b); -- { serverError 42 } +SELECT COLUMNS('a') + COLUMNS('b') FROM (SELECT 1 AS a, 2 AS b); +SELECT COLUMNS('a') + COLUMNS('a') FROM (SELECT 1 AS a, 2 AS b); +SELECT COLUMNS('b') + COLUMNS('b') FROM (SELECT 1 AS a, 2 AS b); +SELECT COLUMNS('a|b') + COLUMNS('b') FROM (SELECT 1 AS a, 2 AS b); -- { serverError 42 } +SELECT plus(COLUMNS('^(a|b)$')) FROM (SELECT 1 AS a, 2 AS b); From 9b5cba81748026ad183bcbd3ac99cf65cac15409 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 22 Jul 2019 00:35:43 +0300 Subject: [PATCH 0224/1165] Fixed bad code --- dbms/tests/queries/0_stateless/00386_long_in_pk.python | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00386_long_in_pk.python b/dbms/tests/queries/0_stateless/00386_long_in_pk.python index d1db1a32d1e..247e0fe1e61 100644 --- a/dbms/tests/queries/0_stateless/00386_long_in_pk.python +++ b/dbms/tests/queries/0_stateless/00386_long_in_pk.python @@ -8,16 +8,16 @@ def gen_queries(): columns = tuple('a b c d'.split()) order_by_columns = tuple('a b c'.split()) partition_by_columns = tuple(' tuple() a'.split()) - + for partition in partition_by_columns: for key_mask in range(1, 1 << len(order_by_columns)): key = ','.join(order_by_columns[i] for i in range(len(order_by_columns)) if (1 << i) & key_mask != 0) create_query = create_template.format(key, partition) for q in (drop_query, create_query, insert_query): yield q - + for column, value in zip(columns, values): - yield 'select {} in {} from tab_00386'.format(column, value) + yield 'select {} in {} from tab_00386'.format(column, value) yield 'select {} in tuple({}) from tab_00386'.format(column, value) yield 'select {} in (select {} from tab_00386) from tab_00386'.format(column, column) @@ -26,7 +26,7 @@ def gen_queries(): yield 'select ({}, {}) in tuple({}, {}) from tab_00386'.format(columns[i], columns[j], values[i], values[j]) yield 'select ({}, {}) in (select {}, {} from tab_00386) from tab_00386'.format(columns[i], columns[j], columns[i], columns[j]) yield 'select ({}, {}) in (select ({}, {}) from tab_00386) from tab_00386'.format(columns[i], columns[j], columns[i], columns[j]) - + yield "select e in (1, 'a') from tab_00386" yield "select f in tuple((1, 'a')) from tab_00386" yield "select f in tuple(tuple((1, 'a'))) from tab_00386" @@ -41,7 +41,7 @@ import os def main(): url = os.environ['CLICKHOUSE_URL_PARAMS'] - + for q in gen_queries(): resp = requests.post(url, data=q) if resp.status_code != 200 or resp.text.strip() not in ('1', ''): From 969cb2f826757df38dbccbaa4233e6a28a772bca Mon Sep 17 00:00:00 2001 From: Ivan Lezhankin Date: Mon, 22 Jul 2019 14:32:11 +0300 Subject: [PATCH 0225/1165] Append _partition virtual column --- dbms/src/Storages/Kafka/KafkaBlockInputStream.cpp | 13 +++++++------ .../Storages/Kafka/ReadBufferFromKafkaConsumer.h | 1 + dbms/src/Storages/Kafka/StorageKafka.cpp | 3 ++- dbms/tests/integration/test_storage_kafka/test.py | 8 ++++---- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/dbms/src/Storages/Kafka/KafkaBlockInputStream.cpp b/dbms/src/Storages/Kafka/KafkaBlockInputStream.cpp index 5b8d80cb062..3ddb54f848b 100644 --- a/dbms/src/Storages/Kafka/KafkaBlockInputStream.cpp +++ b/dbms/src/Storages/Kafka/KafkaBlockInputStream.cpp @@ -19,7 +19,7 @@ KafkaBlockInputStream::KafkaBlockInputStream( if (!storage.getSchemaName().empty()) context.setSetting("format_schema", storage.getSchemaName()); - virtual_columns = storage.getSampleBlockForColumns({"_topic", "_key", "_offset"}).cloneEmptyColumns(); + virtual_columns = storage.getSampleBlockForColumns({"_topic", "_key", "_offset", "_partition"}).cloneEmptyColumns(); } KafkaBlockInputStream::~KafkaBlockInputStream() @@ -57,9 +57,10 @@ void KafkaBlockInputStream::readPrefixImpl() auto read_callback = [this] { const auto * sub_buffer = buffer->subBufferAs(); - virtual_columns[0]->insert(sub_buffer->currentTopic()); // "topic" - virtual_columns[1]->insert(sub_buffer->currentKey()); // "key" - virtual_columns[2]->insert(sub_buffer->currentOffset()); // "offset" + virtual_columns[0]->insert(sub_buffer->currentTopic()); // "topic" + virtual_columns[1]->insert(sub_buffer->currentKey()); // "key" + virtual_columns[2]->insert(sub_buffer->currentOffset()); // "offset" + virtual_columns[3]->insert(sub_buffer->currentPartition()); // "partition" }; auto child = FormatFactory::instance().getInput( @@ -76,8 +77,8 @@ Block KafkaBlockInputStream::readImpl() if (!block) return block; - Block virtual_block = storage.getSampleBlockForColumns({"_topic", "_key", "_offset"}).cloneWithColumns(std::move(virtual_columns)); - virtual_columns = storage.getSampleBlockForColumns({"_topic", "_key", "_offset"}).cloneEmptyColumns(); + Block virtual_block = storage.getSampleBlockForColumns({"_topic", "_key", "_offset", "_partition"}).cloneWithColumns(std::move(virtual_columns)); + virtual_columns = storage.getSampleBlockForColumns({"_topic", "_key", "_offset", "_partition"}).cloneEmptyColumns(); for (const auto & column : virtual_block.getColumnsWithTypeAndName()) block.insert(column); diff --git a/dbms/src/Storages/Kafka/ReadBufferFromKafkaConsumer.h b/dbms/src/Storages/Kafka/ReadBufferFromKafkaConsumer.h index ac6011cfed0..0de18ba59bf 100644 --- a/dbms/src/Storages/Kafka/ReadBufferFromKafkaConsumer.h +++ b/dbms/src/Storages/Kafka/ReadBufferFromKafkaConsumer.h @@ -30,6 +30,7 @@ public: String currentTopic() const { return current[-1].get_topic(); } String currentKey() const { return current[-1].get_key(); } auto currentOffset() const { return current[-1].get_offset(); } + auto currentPartition() const { return current[-1].get_partition(); } private: using Messages = std::vector; diff --git a/dbms/src/Storages/Kafka/StorageKafka.cpp b/dbms/src/Storages/Kafka/StorageKafka.cpp index 20599c7e4f8..e591649dd6a 100644 --- a/dbms/src/Storages/Kafka/StorageKafka.cpp +++ b/dbms/src/Storages/Kafka/StorageKafka.cpp @@ -85,7 +85,8 @@ StorageKafka::StorageKafka( columns_, ColumnsDescription({{"_topic", std::make_shared()}, {"_key", std::make_shared()}, - {"_offset", std::make_shared()}}, true)) + {"_offset", std::make_shared()}, + {"_partition", std::make_shared()}}, true)) , table_name(table_name_) , database_name(database_name_) , global_context(context_) diff --git a/dbms/tests/integration/test_storage_kafka/test.py b/dbms/tests/integration/test_storage_kafka/test.py index 3f38b068a22..915665ba998 100644 --- a/dbms/tests/integration/test_storage_kafka/test.py +++ b/dbms/tests/integration/test_storage_kafka/test.py @@ -380,7 +380,7 @@ def test_kafka_virtual_columns(kafka_cluster): result = '' while True: time.sleep(1) - result += instance.query('SELECT _key, key, _topic, value, _offset FROM test.kafka') + result += instance.query('SELECT _key, key, _topic, value, _offset, _partition FROM test.kafka') if kafka_check_result(result, False, 'test_kafka_virtual1.reference'): break kafka_check_result(result, True, 'test_kafka_virtual1.reference') @@ -397,11 +397,11 @@ def test_kafka_virtual_columns_with_materialized_view(kafka_cluster): kafka_group_name = 'virt2', kafka_format = 'JSONEachRow', kafka_row_delimiter = '\\n'; - CREATE TABLE test.view (key UInt64, value UInt64, kafka_key String, topic String, offset UInt64) + CREATE TABLE test.view (key UInt64, value UInt64, kafka_key String, topic String, offset UInt64, partition UInt64) ENGINE = MergeTree() ORDER BY key; CREATE MATERIALIZED VIEW test.consumer TO test.view AS - SELECT *, _key as kafka_key, _topic as topic, _offset as offset FROM test.kafka; + SELECT *, _key as kafka_key, _topic as topic, _offset as offset, _partition as partition FROM test.kafka; ''') messages = [] @@ -411,7 +411,7 @@ def test_kafka_virtual_columns_with_materialized_view(kafka_cluster): while True: time.sleep(1) - result = instance.query('SELECT kafka_key, key, topic, value, offset FROM test.view') + result = instance.query('SELECT kafka_key, key, topic, value, offset, partition FROM test.view') if kafka_check_result(result, False, 'test_kafka_virtual2.reference'): break kafka_check_result(result, True, 'test_kafka_virtual2.reference') From 1b6a20d7112dca198e6b2758db0f784d81400eb6 Mon Sep 17 00:00:00 2001 From: Vivien Maisonneuve Date: Mon, 22 Jul 2019 14:13:07 +0200 Subject: [PATCH 0226/1165] Fix typos in docs --- docs/en/operations/server_settings/settings.md | 4 ++-- docs/en/operations/table_engines/mergetree.md | 2 +- docs/en/query_language/select.md | 2 +- docs/ru/operations/server_settings/settings.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/en/operations/server_settings/settings.md b/docs/en/operations/server_settings/settings.md index 2f87233e6a3..bf2a430f7d8 100644 --- a/docs/en/operations/server_settings/settings.md +++ b/docs/en/operations/server_settings/settings.md @@ -322,8 +322,8 @@ Writing to the syslog is also supported. Config example: Keys: -- user_syslog — Required setting if you want to write to the syslog. -- address — The host[:порт] of syslogd. If omitted, the local daemon is used. +- use_syslog — Required setting if you want to write to the syslog. +- address — The host[:port] of syslogd. If omitted, the local daemon is used. - hostname — Optional. The name of the host that logs are sent from. - facility — [The syslog facility keyword](https://en.wikipedia.org/wiki/Syslog#Facility) in uppercase letters with the "LOG_" prefix: (``LOG_USER``, ``LOG_DAEMON``, ``LOG_LOCAL3``, and so on). Default value: ``LOG_USER`` if ``address`` is specified, ``LOG_DAEMON otherwise.`` diff --git a/docs/en/operations/table_engines/mergetree.md b/docs/en/operations/table_engines/mergetree.md index 8610397be7c..f6ee0a7313d 100644 --- a/docs/en/operations/table_engines/mergetree.md +++ b/docs/en/operations/table_engines/mergetree.md @@ -1,6 +1,6 @@ # MergeTree {#table_engines-mergetree} -The `MergeTree` engine and other engines of this family (`*MergeTree`) are the most robust ClickHousе table engines. +The `MergeTree` engine and other engines of this family (`*MergeTree`) are the most robust ClickHouse table engines. The basic idea for `MergeTree` engines family is the following. When you have tremendous amount of a data that should be inserted into the table, you should write them quickly part by part and then merge parts by some rules in background. This method is much more efficient than constantly rewriting data in the storage at the insert. diff --git a/docs/en/query_language/select.md b/docs/en/query_language/select.md index ada90331d6e..b2d17bed674 100644 --- a/docs/en/query_language/select.md +++ b/docs/en/query_language/select.md @@ -694,7 +694,7 @@ The query `SELECT sum(x), y FROM t_null_big GROUP BY y` results in: └────────┴──────┘ ``` -You can see that `GROUP BY` for `У = NULL` summed up `x`, as if `NULL` is this value. +You can see that `GROUP BY` for `y = NULL` summed up `x`, as if `NULL` is this value. If you pass several keys to `GROUP BY`, the result will give you all the combinations of the selection, as if `NULL` were a specific value. diff --git a/docs/ru/operations/server_settings/settings.md b/docs/ru/operations/server_settings/settings.md index c1444668bb2..d0504dd99ca 100644 --- a/docs/ru/operations/server_settings/settings.md +++ b/docs/ru/operations/server_settings/settings.md @@ -319,7 +319,7 @@ ClickHouse проверит условия `min_part_size` и `min_part_size_rat ``` Ключи: -- user_syslog - обязательная настройка, если требуется запись в syslog +- use_syslog - обязательная настройка, если требуется запись в syslog - address - хост[:порт] демона syslogd. Если не указан, используется локальный - hostname - опционально, имя хоста, с которого отсылаются логи - facility - [категория syslog](https://en.wikipedia.org/wiki/Syslog#Facility), From 6c6af60194fd939e33b628ce7cb7434ee66507bc Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Mon, 22 Jul 2019 15:18:53 +0300 Subject: [PATCH 0227/1165] Fixes after review --- .../Interpreters/InterpreterCreateQuery.cpp | 53 ++++++++++--------- dbms/src/Parsers/ASTCreateQuery.cpp | 2 +- .../src/TableFunctions/ITableFunctionXDBC.cpp | 5 +- .../src/TableFunctions/TableFunctionMySQL.cpp | 5 +- ...3_create_table_as_table_function.reference | 1 + .../00973_create_table_as_table_function.sh | 13 ++++- 6 files changed, 42 insertions(+), 37 deletions(-) diff --git a/dbms/src/Interpreters/InterpreterCreateQuery.cpp b/dbms/src/Interpreters/InterpreterCreateQuery.cpp index a862c7de5c1..6685eab841b 100644 --- a/dbms/src/Interpreters/InterpreterCreateQuery.cpp +++ b/dbms/src/Interpreters/InterpreterCreateQuery.cpp @@ -386,7 +386,7 @@ ColumnsDescription InterpreterCreateQuery::setColumns( indices.indices.push_back( std::dynamic_pointer_cast(index->clone())); } - else if (!create.as_table.empty() || create.as_table_function) + else if (!create.as_table.empty()) { columns = as_storage->getColumns(); indices = as_storage->getIndices(); @@ -521,40 +521,43 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create) StoragePtr as_storage; TableStructureReadLockHolder as_storage_lock; - if (create.as_table_function) - { - const auto * table_function = create.as_table_function->as(); - const auto & factory = TableFunctionFactory::instance(); - as_storage = factory.get(table_function->name, context)->execute(create.as_table_function, context, create.table); - } + ColumnsDescription columns; + StoragePtr res; + if (!as_table_name.empty()) { as_storage = context.getTable(as_database_name, as_table_name); as_storage_lock = as_storage->lockStructureForShare(false, context.getCurrentQueryId()); } - - /// Set and retrieve list of columns. - ColumnsDescription columns = setColumns(create, as_select_sample, as_storage); - - /// Check low cardinality types in creating table if it was not allowed in setting - if (!create.attach && !context.getSettingsRef().allow_suspicious_low_cardinality_types) + if (create.as_table_function) { - for (const auto & name_and_type_pair : columns.getAllPhysical()) + const auto * table_function = create.as_table_function->as(); + const auto & factory = TableFunctionFactory::instance(); + res = factory.get(table_function->name, context)->execute(create.as_table_function, context, create.table); + } + else + { + /// Set and retrieve list of columns. + columns = setColumns(create, as_select_sample, as_storage); + + /// Check low cardinality types in creating table if it was not allowed in setting + if (!create.attach && !context.getSettingsRef().allow_suspicious_low_cardinality_types) { - if (const auto * current_type_ptr = typeid_cast(name_and_type_pair.type.get())) + for (const auto & name_and_type_pair : columns.getAllPhysical()) { - if (!isStringOrFixedString(*removeNullable(current_type_ptr->getDictionaryType()))) - throw Exception("Creating columns of type " + current_type_ptr->getName() + " is prohibited by default due to expected negative impact on performance. It can be enabled with the \"allow_suspicious_low_cardinality_types\" setting.", - ErrorCodes::SUSPICIOUS_TYPE_FOR_LOW_CARDINALITY); + if (const auto * current_type_ptr = typeid_cast(name_and_type_pair.type.get())) + { + if (!isStringOrFixedString(*removeNullable(current_type_ptr->getDictionaryType()))) + throw Exception("Creating columns of type " + current_type_ptr->getName() + " is prohibited by default due to expected negative impact on performance. It can be enabled with the \"allow_suspicious_low_cardinality_types\" setting.", + ErrorCodes::SUSPICIOUS_TYPE_FOR_LOW_CARDINALITY); + } } } + + /// Set the table engine if it was not specified explicitly. + setEngine(create); } - /// Set the table engine if it was not specified explicitly. - setEngine(create); - - StoragePtr res; - { std::unique_ptr guard; @@ -594,9 +597,7 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create) else if (context.tryGetExternalTable(table_name) && create.if_not_exists) return {}; - if (create.as_table_function) - res = as_storage; - else + if (!create.as_table_function) { res = StorageFactory::instance().get(create, data_path, diff --git a/dbms/src/Parsers/ASTCreateQuery.cpp b/dbms/src/Parsers/ASTCreateQuery.cpp index 4c84383af8a..d8656d171e5 100644 --- a/dbms/src/Parsers/ASTCreateQuery.cpp +++ b/dbms/src/Parsers/ASTCreateQuery.cpp @@ -235,7 +235,7 @@ void ASTCreateQuery::formatQueryImpl(const FormatSettings & settings, FormatStat << (!as_database.empty() ? backQuoteIfNeed(as_database) + "." : "") << backQuoteIfNeed(as_table); } - if (columns_list && !as_table_function) + if (columns_list) { settings.ostr << (settings.one_line ? " (" : "\n("); FormatStateStacked frame_nested = frame; diff --git a/dbms/src/TableFunctions/ITableFunctionXDBC.cpp b/dbms/src/TableFunctions/ITableFunctionXDBC.cpp index 9998eb87fcf..81e30d0917d 100644 --- a/dbms/src/TableFunctions/ITableFunctionXDBC.cpp +++ b/dbms/src/TableFunctions/ITableFunctionXDBC.cpp @@ -76,10 +76,7 @@ StoragePtr ITableFunctionXDBC::executeImpl(const ASTPtr & ast_function, const Co readStringBinary(columns_info, buf); NamesAndTypesList columns = NamesAndTypesList::parse(columns_info); - ///If table_name was not specified by user, it will have the same name as remote_table_name - std::string local_table_name = (table_name == getName()) ? remote_table_name : table_name; - - auto result = std::make_shared(getDatabaseName(), local_table_name, schema_name, remote_table_name, ColumnsDescription{columns}, context, helper); + auto result = std::make_shared(getDatabaseName(), table_name, schema_name, remote_table_name, ColumnsDescription{columns}, context, helper); if (!result) throw Exception("Failed to instantiate storage from table function " + getName(), ErrorCodes::UNKNOWN_EXCEPTION); diff --git a/dbms/src/TableFunctions/TableFunctionMySQL.cpp b/dbms/src/TableFunctions/TableFunctionMySQL.cpp index ac8d2671878..cee08cf2a1d 100644 --- a/dbms/src/TableFunctions/TableFunctionMySQL.cpp +++ b/dbms/src/TableFunctions/TableFunctionMySQL.cpp @@ -118,12 +118,9 @@ StoragePtr TableFunctionMySQL::executeImpl(const ASTPtr & ast_function, const Co if (columns.empty()) throw Exception("MySQL table " + backQuoteIfNeed(remote_database_name) + "." + backQuoteIfNeed(remote_table_name) + " doesn't exist.", ErrorCodes::UNKNOWN_TABLE); - ///If table_name was not specified by user, it will have the same name as remote_table_name - std::string local_table_name = (table_name == getName()) ? remote_table_name : table_name; - auto res = StorageMySQL::create( getDatabaseName(), - local_table_name, + table_name, std::move(pool), remote_database_name, remote_table_name, diff --git a/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.reference b/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.reference index 830a01e609a..bf96e1a5e55 100644 --- a/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.reference +++ b/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.reference @@ -17,6 +17,7 @@ 15 16 17 +18 19 20 21 diff --git a/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.sh b/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.sh index aff96a364d1..2aedc097d40 100755 --- a/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.sh +++ b/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.sh @@ -7,6 +7,8 @@ $CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t1" $CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t2" $CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t3" $CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t4" +$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t5" +$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t6" $CLICKHOUSE_CLIENT -q "CREATE TABLE t1 AS remote('127.0.0.1', system.one)" $CLICKHOUSE_CLIENT -q "SELECT count() FROM t1" @@ -15,12 +17,19 @@ $CLICKHOUSE_CLIENT -q "CREATE TABLE t2 AS remote('127.0.0.1', system.numbers)" $CLICKHOUSE_CLIENT -q "SELECT * FROM t2 LIMIT 18" $CLICKHOUSE_CLIENT -q "CREATE TABLE t3 AS remote('127.0.0.1', numbers(100))" -$CLICKHOUSE_CLIENT -q "SELECT * FROM t3 where number > 18 and number < 25" +$CLICKHOUSE_CLIENT -q "SELECT * FROM t3 where number > 17 and number < 25" $CLICKHOUSE_CLIENT -q "CREATE TABLE t4 AS numbers(100)" -$CLICKHOUSE_CLIENT -q "SELECT count() FROM t4 where number > 74" +$CLICKHOUSE_CLIENT -q "SELECT count() FROM t4 where number > 74 " + +#Syntax Errors +$CLICKHOUSE_CLIENT -q "CREATE TABLE t5 (d UInt68) AS numbers(10) -- { clientError 62 }" +$CLICKHOUSE_CLIENT -q "CREATE TABLE t6 (d UInt68) Engine = TinyLog AS numbers(10) -- { clientError 62 }" $CLICKHOUSE_CLIENT -q "DROP TABLE t1" $CLICKHOUSE_CLIENT -q "DROP TABLE t2" $CLICKHOUSE_CLIENT -q "DROP TABLE t3" $CLICKHOUSE_CLIENT -q "DROP TABLE t4" +$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t5" +$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t6" + From 42efc1051ed3624c005f7c842fbafd693ae1cfb8 Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Mon, 22 Jul 2019 15:35:29 +0300 Subject: [PATCH 0228/1165] fixes of bad commit --- dbms/src/Interpreters/InterpreterCreateQuery.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/dbms/src/Interpreters/InterpreterCreateQuery.cpp b/dbms/src/Interpreters/InterpreterCreateQuery.cpp index f3f5701c90e..6685eab841b 100644 --- a/dbms/src/Interpreters/InterpreterCreateQuery.cpp +++ b/dbms/src/Interpreters/InterpreterCreateQuery.cpp @@ -531,13 +531,9 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create) } if (create.as_table_function) { - const auto & table_function = create.as_table_function->as(); + const auto * table_function = create.as_table_function->as(); const auto & factory = TableFunctionFactory::instance(); -<<<<<<< HEAD res = factory.get(table_function->name, context)->execute(create.as_table_function, context, create.table); -======= - as_storage = factory.get(table_function.name, context)->execute(create.as_table_function, context, create.table); ->>>>>>> b035edefea7e81082697ffe8452dad087cc917b7 } else { From 9ffbf65741b0a52a43309de7323346b4e11f5a9c Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Mon, 22 Jul 2019 15:50:10 +0300 Subject: [PATCH 0229/1165] Fix of a fix --- dbms/src/Interpreters/InterpreterCreateQuery.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Interpreters/InterpreterCreateQuery.cpp b/dbms/src/Interpreters/InterpreterCreateQuery.cpp index 6685eab841b..4234ff78da9 100644 --- a/dbms/src/Interpreters/InterpreterCreateQuery.cpp +++ b/dbms/src/Interpreters/InterpreterCreateQuery.cpp @@ -531,9 +531,9 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create) } if (create.as_table_function) { - const auto * table_function = create.as_table_function->as(); + const auto & table_function = create.as_table_function->as(); const auto & factory = TableFunctionFactory::instance(); - res = factory.get(table_function->name, context)->execute(create.as_table_function, context, create.table); + res = factory.get(table_function.name, context)->execute(create.as_table_function, context, create.table); } else { From cef18b1e61256cbe9e4bec1498e6b1a0bebcc298 Mon Sep 17 00:00:00 2001 From: Ivan Lezhankin Date: Mon, 22 Jul 2019 15:58:06 +0300 Subject: [PATCH 0230/1165] Fix shared build with rdkafka --- contrib/librdkafka-cmake/CMakeLists.txt | 4 ++++ contrib/librdkafka-cmake/config.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/librdkafka-cmake/CMakeLists.txt b/contrib/librdkafka-cmake/CMakeLists.txt index 54149d0db6f..e0dc6fc2636 100644 --- a/contrib/librdkafka-cmake/CMakeLists.txt +++ b/contrib/librdkafka-cmake/CMakeLists.txt @@ -7,6 +7,8 @@ set(SRCS ${RDKAFKA_SOURCE_DIR}/rdavl.c ${RDKAFKA_SOURCE_DIR}/rdbuf.c ${RDKAFKA_SOURCE_DIR}/rdcrc32.c + ${RDKAFKA_SOURCE_DIR}/rddl.c + ${RDKAFKA_SOURCE_DIR}/rdhdrhistogram.c ${RDKAFKA_SOURCE_DIR}/rdkafka.c ${RDKAFKA_SOURCE_DIR}/rdkafka_assignor.c ${RDKAFKA_SOURCE_DIR}/rdkafka_background.c @@ -28,11 +30,13 @@ set(SRCS ${RDKAFKA_SOURCE_DIR}/rdkafka_op.c ${RDKAFKA_SOURCE_DIR}/rdkafka_partition.c ${RDKAFKA_SOURCE_DIR}/rdkafka_pattern.c + ${RDKAFKA_SOURCE_DIR}/rdkafka_plugin.c ${RDKAFKA_SOURCE_DIR}/rdkafka_queue.c ${RDKAFKA_SOURCE_DIR}/rdkafka_range_assignor.c ${RDKAFKA_SOURCE_DIR}/rdkafka_request.c ${RDKAFKA_SOURCE_DIR}/rdkafka_roundrobin_assignor.c ${RDKAFKA_SOURCE_DIR}/rdkafka_sasl.c + ${RDKAFKA_SOURCE_DIR}/rdkafka_sasl_oauthbearer.c ${RDKAFKA_SOURCE_DIR}/rdkafka_sasl_plain.c ${RDKAFKA_SOURCE_DIR}/rdkafka_sasl_scram.c ${RDKAFKA_SOURCE_DIR}/rdkafka_ssl.c diff --git a/contrib/librdkafka-cmake/config.h b/contrib/librdkafka-cmake/config.h index bf67863ae7d..c8043f8b7dd 100644 --- a/contrib/librdkafka-cmake/config.h +++ b/contrib/librdkafka-cmake/config.h @@ -78,5 +78,5 @@ // python //#define HAVE_PYTHON 1 // disable C11 threads for compatibility with old libc -#define WITH_C11THREADS 0 +//#define WITH_C11THREADS 1 #endif /* _CONFIG_H_ */ From 0320de91321752e1a7d39f2a5183da77ae72c046 Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Mon, 22 Jul 2019 16:49:16 +0300 Subject: [PATCH 0231/1165] test and fixes --- .../Interpreters/InterpreterCreateQuery.cpp | 7 ++-- .../00973_create_table_as_table_function.sh | 35 ------------------- .../00973_create_table_as_table_function.sql | 21 +++++++++++ 3 files changed, 25 insertions(+), 38 deletions(-) delete mode 100755 dbms/tests/queries/0_stateless/00973_create_table_as_table_function.sh create mode 100644 dbms/tests/queries/0_stateless/00973_create_table_as_table_function.sql diff --git a/dbms/src/Interpreters/InterpreterCreateQuery.cpp b/dbms/src/Interpreters/InterpreterCreateQuery.cpp index 4234ff78da9..b44f42f0f13 100644 --- a/dbms/src/Interpreters/InterpreterCreateQuery.cpp +++ b/dbms/src/Interpreters/InterpreterCreateQuery.cpp @@ -521,14 +521,15 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create) StoragePtr as_storage; TableStructureReadLockHolder as_storage_lock; - ColumnsDescription columns; - StoragePtr res; - if (!as_table_name.empty()) { as_storage = context.getTable(as_database_name, as_table_name); as_storage_lock = as_storage->lockStructureForShare(false, context.getCurrentQueryId()); } + + ColumnsDescription columns; + StoragePtr res; + if (create.as_table_function) { const auto & table_function = create.as_table_function->as(); diff --git a/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.sh b/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.sh deleted file mode 100755 index 2aedc097d40..00000000000 --- a/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash - -CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -. $CURDIR/../shell_config.sh - -$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t1" -$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t2" -$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t3" -$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t4" -$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t5" -$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t6" - -$CLICKHOUSE_CLIENT -q "CREATE TABLE t1 AS remote('127.0.0.1', system.one)" -$CLICKHOUSE_CLIENT -q "SELECT count() FROM t1" - -$CLICKHOUSE_CLIENT -q "CREATE TABLE t2 AS remote('127.0.0.1', system.numbers)" -$CLICKHOUSE_CLIENT -q "SELECT * FROM t2 LIMIT 18" - -$CLICKHOUSE_CLIENT -q "CREATE TABLE t3 AS remote('127.0.0.1', numbers(100))" -$CLICKHOUSE_CLIENT -q "SELECT * FROM t3 where number > 17 and number < 25" - -$CLICKHOUSE_CLIENT -q "CREATE TABLE t4 AS numbers(100)" -$CLICKHOUSE_CLIENT -q "SELECT count() FROM t4 where number > 74 " - -#Syntax Errors -$CLICKHOUSE_CLIENT -q "CREATE TABLE t5 (d UInt68) AS numbers(10) -- { clientError 62 }" -$CLICKHOUSE_CLIENT -q "CREATE TABLE t6 (d UInt68) Engine = TinyLog AS numbers(10) -- { clientError 62 }" - -$CLICKHOUSE_CLIENT -q "DROP TABLE t1" -$CLICKHOUSE_CLIENT -q "DROP TABLE t2" -$CLICKHOUSE_CLIENT -q "DROP TABLE t3" -$CLICKHOUSE_CLIENT -q "DROP TABLE t4" -$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t5" -$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS t6" - diff --git a/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.sql b/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.sql new file mode 100644 index 00000000000..147cb87ffcc --- /dev/null +++ b/dbms/tests/queries/0_stateless/00973_create_table_as_table_function.sql @@ -0,0 +1,21 @@ +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP TABLE IF EXISTS t3; +DROP TABLE IF EXISTS t4; + +CREATE TABLE t1 AS remote('127.0.0.1', system.one); +SELECT count() FROM t1; + +CREATE TABLE t2 AS remote('127.0.0.1', system.numbers); +SELECT * FROM t2 LIMIT 18; + +CREATE TABLE t3 AS remote('127.0.0.1', numbers(100)); +SELECT * FROM t3 where number > 17 and number < 25; + +CREATE TABLE t4 AS numbers(100); +SELECT count() FROM t4 where number > 74; + +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; +DROP TABLE t4; From c6667ff88848a0c3bf3ee75fc496579556fbfeb7 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Mon, 22 Jul 2019 16:54:08 +0300 Subject: [PATCH 0232/1165] wip --- dbms/src/Interpreters/Context.cpp | 10 +++ dbms/src/Interpreters/Context.h | 2 + dbms/src/Interpreters/SystemLog.cpp | 5 +- dbms/src/Interpreters/SystemLog.h | 2 + dbms/src/Interpreters/TextLog.cpp | 69 +++++++++++++++++++++ dbms/src/Interpreters/TextLog.h | 41 ++++++++++++ libs/libloggers/loggers/OwnSplitChannel.cpp | 30 ++++++++- 7 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 dbms/src/Interpreters/TextLog.cpp create mode 100644 dbms/src/Interpreters/TextLog.h diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index bf779ada6b4..b5866ed3bef 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -1663,6 +1663,16 @@ std::shared_ptr Context::getPartLog(const String & part_database) return shared->system_logs->part_log; } +std::shared_ptr Context::getTextLog() +{ + auto lock = getLock(); + + if (!shared->system_logs || !shared->system_logs->text_log) + return {}; + + return shared->system_logs->text_log; +} + CompressionCodecPtr Context::chooseCompressionCodec(size_t part_size, double part_size_ratio) const { diff --git a/dbms/src/Interpreters/Context.h b/dbms/src/Interpreters/Context.h index 44547f97ef2..bc471ae39cc 100644 --- a/dbms/src/Interpreters/Context.h +++ b/dbms/src/Interpreters/Context.h @@ -62,6 +62,7 @@ class Clusters; class QueryLog; class QueryThreadLog; class PartLog; +class TextLog; struct MergeTreeSettings; class IDatabase; class DDLGuard; @@ -423,6 +424,7 @@ public: /// Nullptr if the query log is not ready for this moment. std::shared_ptr getQueryLog(); std::shared_ptr getQueryThreadLog(); + std::shared_ptr getTextLog(); /// Returns an object used to log opertaions with parts if it possible. /// Provide table name to make required cheks. diff --git a/dbms/src/Interpreters/SystemLog.cpp b/dbms/src/Interpreters/SystemLog.cpp index f46b348db7a..624c6a8ed75 100644 --- a/dbms/src/Interpreters/SystemLog.cpp +++ b/dbms/src/Interpreters/SystemLog.cpp @@ -2,7 +2,7 @@ #include #include #include - +#include #include @@ -44,6 +44,7 @@ SystemLogs::SystemLogs(Context & global_context, const Poco::Util::AbstractConfi query_log = createSystemLog(global_context, "system", "query_log", config, "query_log"); query_thread_log = createSystemLog(global_context, "system", "query_thread_log", config, "query_thread_log"); part_log = createSystemLog(global_context, "system", "part_log", config, "part_log"); + text_log = createSystemLog(global_context, "system", "text_log", config, "text_log"); part_log_database = config.getString("part_log.database", "system"); } @@ -63,6 +64,8 @@ void SystemLogs::shutdown() query_thread_log->shutdown(); if (part_log) part_log->shutdown(); + if (text_log) + text_log->shutdown(); } } diff --git a/dbms/src/Interpreters/SystemLog.h b/dbms/src/Interpreters/SystemLog.h index 48dbde5a38b..83f4d6bbc12 100644 --- a/dbms/src/Interpreters/SystemLog.h +++ b/dbms/src/Interpreters/SystemLog.h @@ -59,6 +59,7 @@ class Context; class QueryLog; class QueryThreadLog; class PartLog; +class TextLog; /// System logs should be destroyed in destructor of the last Context and before tables, @@ -73,6 +74,7 @@ struct SystemLogs std::shared_ptr query_log; /// Used to log queries. std::shared_ptr query_thread_log; /// Used to log query threads. std::shared_ptr part_log; /// Used to log operations with parts + std::shared_ptr text_log; String part_log_database; }; diff --git a/dbms/src/Interpreters/TextLog.cpp b/dbms/src/Interpreters/TextLog.cpp new file mode 100644 index 00000000000..a3da1100ec4 --- /dev/null +++ b/dbms/src/Interpreters/TextLog.cpp @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace DB { + +Block TextLogElement::createBlock() { + return + { + {std::make_shared(), "event_date"}, + {std::make_shared(), "event_time"}, + {std::make_shared(), "microseconds"}, + + {std::make_shared(std::make_shared()), "thread_name"}, + {std::make_shared(), "thread_number"}, + {std::make_shared(), "os_thread_id"}, + + {std::make_shared(), "level"}, + + {std::make_shared(), "query_id"}, + {std::make_shared(), "logger_name"}, + {std::make_shared(), "message"}, + + {std::make_shared(std::make_shared()), "source_file"}, + {std::make_shared(), "source_line"} + }; +} + +void TextLogElement::appendToBlock(Block & block) const +{ + MutableColumns columns = block.mutateColumns(); + + size_t i = 0; + + columns[i++]->insert(DateLUT::instance().toDayNum(event_time)); + + columns[i++]->insert(event_time); + columns[i++]->insert(microseconds); + + // Thread info + columns[i++]->insertData(thread_name.data(), thread_name.size()); + columns[i++]->insert(thread_number); + columns[i++]->insert(os_thread_id); + + columns[i++]->insert(UInt8(level)); + + columns[i++]->insert(query_id); + columns[i++]->insert(logger_name); + columns[i++]->insert(message); + + columns[i++]->insert(source_file); + columns[i++]->insert(source_line); +} + +} + diff --git a/dbms/src/Interpreters/TextLog.h b/dbms/src/Interpreters/TextLog.h new file mode 100644 index 00000000000..1caca571fe1 --- /dev/null +++ b/dbms/src/Interpreters/TextLog.h @@ -0,0 +1,41 @@ +#pragma once +#include + +namespace DB { + +using Poco::Message; + +struct TextLogElement +{ + time_t event_date{}; + time_t event_time{}; + + UInt32 microseconds; + + String thread_name; + UInt32 os_thread_id; + UInt32 thread_number; + + Message::Priority level; + + String query_id; + + String logger_name; + String message; + + String source_file; + UInt64 source_line; + + static std::string name() { return "TextLog"; } + static Block createBlock(); + void appendToBlock(Block & block) const; +}; + +class TextLog : public SystemLog +{ + using SystemLog::SystemLog; +}; + + +} //namespace DB + diff --git a/libs/libloggers/loggers/OwnSplitChannel.cpp b/libs/libloggers/loggers/OwnSplitChannel.cpp index 0779f6477c3..b96296ee364 100644 --- a/libs/libloggers/loggers/OwnSplitChannel.cpp +++ b/libs/libloggers/loggers/OwnSplitChannel.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -48,7 +49,34 @@ void OwnSplitChannel::log(const Poco::Message & msg) logs_queue->emplace(std::move(columns)); } - /// TODO: Also log to system.internal_text_log table + /// Also log to system.internal_text_log table + + if (CurrentThread::getGroup() != nullptr && + CurrentThread::getGroup()->global_context != nullptr && + CurrentThread::getGroup()->global_context->getTextLog() != nullptr) { + + const auto text_log = CurrentThread::getGroup()->global_context->getTextLog(); + TextLogElement elem; + + elem.event_time = msg_ext.time_seconds; + elem.microseconds = msg_ext.time_microseconds; + + elem.thread_name = getThreadName(); + elem.thread_number = msg_ext.thread_number; + elem.os_thread_id = msg.getOsTid(); + elem.message = msg.getText(); + + elem.level = msg.getPriority(); + + if (msg.getSourceFile() != nullptr) { + elem.source_file = msg.getSourceFile(); + } + + elem.source_line = msg.getSourceLine(); + + text_log->add(elem); + } + } void OwnSplitChannel::addChannel(Poco::AutoPtr channel) From 21ebb72579ac8193c94a253422d12db1ef0705d8 Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Mon, 22 Jul 2019 18:02:03 +0300 Subject: [PATCH 0233/1165] documentation --- docs/en/query_language/create.md | 6 ++++++ docs/ru/query_language/create.md | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/docs/en/query_language/create.md b/docs/en/query_language/create.md index 94d32cc49f5..bd2228efa94 100644 --- a/docs/en/query_language/create.md +++ b/docs/en/query_language/create.md @@ -52,6 +52,12 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name AS [db2.]name2 [ENGINE = engine] Creates a table with the same structure as another table. You can specify a different engine for the table. If the engine is not specified, the same engine will be used as for the `db2.name2` table. +``` sql +CREATE TABLE [IF NOT EXISTS] [db.]table_name AS table_fucntion() +``` + +Creates a table with the same structure and data as the value returned by table function. + ``` sql CREATE TABLE [IF NOT EXISTS] [db.]table_name ENGINE = engine AS SELECT ... ``` diff --git a/docs/ru/query_language/create.md b/docs/ru/query_language/create.md index 9d1149ba466..be75bb9ce51 100644 --- a/docs/ru/query_language/create.md +++ b/docs/ru/query_language/create.md @@ -34,6 +34,12 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name AS [db2.]name2 [ENGINE = engine] Создаёт таблицу с такой же структурой, как другая таблица. Можно указать другой движок для таблицы. Если движок не указан, то будет выбран такой же движок, как у таблицы `db2.name2`. +``` sql +CREATE TABLE [IF NOT EXISTS] [db.]table_name AS table_fucntion() +``` + +Создаёт таблицу с такой же структурой и данными, как результат соотвествующей табличной функцией. + ```sql CREATE TABLE [IF NOT EXISTS] [db.]table_name ENGINE = engine AS SELECT ... ``` From 8289472b9821cc3e813036febb72bb8af8b67765 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Mon, 22 Jul 2019 18:09:33 +0300 Subject: [PATCH 0234/1165] style improvements --- dbms/src/Interpreters/TextLog.cpp | 32 +++++++++++++++++---- dbms/src/Interpreters/TextLog.h | 8 +++--- libs/libloggers/loggers/OwnSplitChannel.cpp | 6 ++-- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/dbms/src/Interpreters/TextLog.cpp b/dbms/src/Interpreters/TextLog.cpp index a3da1100ec4..d11f6246319 100644 --- a/dbms/src/Interpreters/TextLog.cpp +++ b/dbms/src/Interpreters/TextLog.cpp @@ -15,9 +15,27 @@ #include #include -namespace DB { +namespace DB +{ + +template <> struct NearestFieldTypeImpl { using Type = UInt64; }; + +Block TextLogElement::createBlock() +{ + + auto priority_datatype = std::make_shared( + DataTypeEnum8::Values + { + {"FATAL", static_cast(Message::PRIO_FATAL)}, + {"CRITICAL", static_cast(Message::PRIO_CRITICAL)}, + {"ERROR", static_cast(Message::PRIO_ERROR)}, + {"WARNING", static_cast(Message::PRIO_WARNING)}, + {"NOTICE", static_cast(Message::PRIO_NOTICE)}, + {"INFORMATION", static_cast(Message::PRIO_INFORMATION)}, + {"DEBUG", static_cast(Message::PRIO_DEBUG)}, + {"TRACE", static_cast(Message::PRIO_TRACE)} + }); -Block TextLogElement::createBlock() { return { {std::make_shared(), "event_date"}, @@ -28,12 +46,14 @@ Block TextLogElement::createBlock() { {std::make_shared(), "thread_number"}, {std::make_shared(), "os_thread_id"}, - {std::make_shared(), "level"}, + {std::move(priority_datatype), "level"}, {std::make_shared(), "query_id"}, {std::make_shared(), "logger_name"}, {std::make_shared(), "message"}, + {std::make_shared(), "revision"}, + {std::make_shared(std::make_shared()), "source_file"}, {std::make_shared(), "source_line"} }; @@ -46,7 +66,6 @@ void TextLogElement::appendToBlock(Block & block) const size_t i = 0; columns[i++]->insert(DateLUT::instance().toDayNum(event_time)); - columns[i++]->insert(event_time); columns[i++]->insert(microseconds); @@ -55,15 +74,16 @@ void TextLogElement::appendToBlock(Block & block) const columns[i++]->insert(thread_number); columns[i++]->insert(os_thread_id); - columns[i++]->insert(UInt8(level)); + columns[i++]->insert(level); columns[i++]->insert(query_id); columns[i++]->insert(logger_name); columns[i++]->insert(message); + columns[i++]->insert(ClickHouseRevision::get()); + columns[i++]->insert(source_file); columns[i++]->insert(source_line); } } - diff --git a/dbms/src/Interpreters/TextLog.h b/dbms/src/Interpreters/TextLog.h index 1caca571fe1..a8d76896b01 100644 --- a/dbms/src/Interpreters/TextLog.h +++ b/dbms/src/Interpreters/TextLog.h @@ -1,7 +1,8 @@ #pragma once #include -namespace DB { +namespace DB +{ using Poco::Message; @@ -16,7 +17,7 @@ struct TextLogElement UInt32 os_thread_id; UInt32 thread_number; - Message::Priority level; + Message::Priority level = Message::PRIO_TRACE; String query_id; @@ -37,5 +38,4 @@ class TextLog : public SystemLog }; -} //namespace DB - +} diff --git a/libs/libloggers/loggers/OwnSplitChannel.cpp b/libs/libloggers/loggers/OwnSplitChannel.cpp index b96296ee364..c9f8f5e8bb5 100644 --- a/libs/libloggers/loggers/OwnSplitChannel.cpp +++ b/libs/libloggers/loggers/OwnSplitChannel.cpp @@ -64,14 +64,16 @@ void OwnSplitChannel::log(const Poco::Message & msg) elem.thread_name = getThreadName(); elem.thread_number = msg_ext.thread_number; elem.os_thread_id = msg.getOsTid(); - elem.message = msg.getText(); + elem.query_id = msg_ext.query_id; + + elem.message = msg.getText(); + elem.logger_name = msg.getSource(); elem.level = msg.getPriority(); if (msg.getSourceFile() != nullptr) { elem.source_file = msg.getSourceFile(); } - elem.source_line = msg.getSourceLine(); text_log->add(elem); From 0f3a4a34b49849b12aedea840c9a76dc7531410a Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Mon, 22 Jul 2019 18:33:38 +0300 Subject: [PATCH 0235/1165] test + comment --- dbms/src/Interpreters/SystemLog.h | 2 +- dbms/src/Interpreters/TextLog.h | 2 -- .../0_stateless/00974_text_log_table_not_empty.reference | 1 + .../queries/0_stateless/00974_text_log_table_not_empty.sql | 2 ++ 4 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference create mode 100644 dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql diff --git a/dbms/src/Interpreters/SystemLog.h b/dbms/src/Interpreters/SystemLog.h index 83f4d6bbc12..03accf31cd9 100644 --- a/dbms/src/Interpreters/SystemLog.h +++ b/dbms/src/Interpreters/SystemLog.h @@ -74,7 +74,7 @@ struct SystemLogs std::shared_ptr query_log; /// Used to log queries. std::shared_ptr query_thread_log; /// Used to log query threads. std::shared_ptr part_log; /// Used to log operations with parts - std::shared_ptr text_log; + std::shared_ptr text_log; /// Used to save all text logs. String part_log_database; }; diff --git a/dbms/src/Interpreters/TextLog.h b/dbms/src/Interpreters/TextLog.h index a8d76896b01..f56017b13bc 100644 --- a/dbms/src/Interpreters/TextLog.h +++ b/dbms/src/Interpreters/TextLog.h @@ -10,7 +10,6 @@ struct TextLogElement { time_t event_date{}; time_t event_time{}; - UInt32 microseconds; String thread_name; @@ -20,7 +19,6 @@ struct TextLogElement Message::Priority level = Message::PRIO_TRACE; String query_id; - String logger_name; String message; diff --git a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference new file mode 100644 index 00000000000..56a6051ca2b --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql new file mode 100644 index 00000000000..26bf82d62a5 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql @@ -0,0 +1,2 @@ +SELECT count() > 0 +FROM system.text_log \ No newline at end of file From 1d960e5c0b8325cb01d57a8efbcc83b6460704bc Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Mon, 22 Jul 2019 18:41:52 +0300 Subject: [PATCH 0236/1165] Fix CAST from LowCardinality(Nullable). --- dbms/src/Columns/ColumnLowCardinality.cpp | 27 +++++++++++++++++ dbms/src/Columns/ColumnLowCardinality.h | 4 +++ dbms/src/Functions/FunctionsConversion.h | 35 ++++++++++++++++------- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/dbms/src/Columns/ColumnLowCardinality.cpp b/dbms/src/Columns/ColumnLowCardinality.cpp index f2a0ef1f626..47433942c51 100644 --- a/dbms/src/Columns/ColumnLowCardinality.cpp +++ b/dbms/src/Columns/ColumnLowCardinality.cpp @@ -352,6 +352,11 @@ ColumnPtr ColumnLowCardinality::countKeys() const return counter; } +bool ColumnLowCardinality::containsNull() const +{ + return getDictionary().nestedColumnIsNullable() && idx.containsDefault(); +} + ColumnLowCardinality::Index::Index() : positions(ColumnUInt8::create()), size_of_type(sizeof(UInt8)) {} @@ -605,6 +610,28 @@ void ColumnLowCardinality::Index::countKeys(ColumnUInt64::Container & counts) co callForType(std::move(counter), size_of_type); } +bool ColumnLowCardinality::Index::containsDefault() const +{ + bool contains = false; + + auto check_contains_default = [&](auto & x) + { + using CurIndexType = decltype(x); + auto & data = getPositionsData(); + for (auto pos : data) + { + if (pos == 0) + { + contains = true; + break; + } + } + }; + + callForType(std::move(check_contains_default), size_of_type); + return contains; +} + ColumnLowCardinality::Dictionary::Dictionary(MutableColumnPtr && column_unique_, bool is_shared) : column_unique(std::move(column_unique_)), shared(is_shared) diff --git a/dbms/src/Columns/ColumnLowCardinality.h b/dbms/src/Columns/ColumnLowCardinality.h index fc96fc97550..a6a129fbb09 100644 --- a/dbms/src/Columns/ColumnLowCardinality.h +++ b/dbms/src/Columns/ColumnLowCardinality.h @@ -194,6 +194,8 @@ public: ColumnPtr countKeys() const; + bool containsNull() const; + class Index { public: @@ -224,6 +226,8 @@ public: void countKeys(ColumnUInt64::Container & counts) const; + bool containsDefault() const; + private: WrappedPtr positions; size_t size_of_type = 0; diff --git a/dbms/src/Functions/FunctionsConversion.h b/dbms/src/Functions/FunctionsConversion.h index d8b8775a7a0..909cf5c2ef1 100644 --- a/dbms/src/Functions/FunctionsConversion.h +++ b/dbms/src/Functions/FunctionsConversion.h @@ -1896,11 +1896,17 @@ private: }; } - auto wrapper = prepareRemoveNullable(from_nested, to_nested); + bool skip_not_null_check = false; + + if (from_low_cardinality && from_nested->isNullable() && !to_nested->isNullable()) + /// Disable check for dictionary. Will check that column doesn't contain NULL in wrapper below. + skip_not_null_check = true; + + auto wrapper = prepareRemoveNullable(from_nested, to_nested, skip_not_null_check); if (!from_low_cardinality && !to_low_cardinality) return wrapper; - return [wrapper, from_low_cardinality, to_low_cardinality] + return [wrapper, from_low_cardinality, to_low_cardinality, skip_not_null_check] (Block & block, const ColumnNumbers & arguments, const size_t result, size_t input_rows_count) { auto & arg = block.getByPosition(arguments[0]); @@ -1925,6 +1931,11 @@ private: if (from_low_cardinality) { auto * col_low_cardinality = typeid_cast(prev_arg_col.get()); + + if (skip_not_null_check && col_low_cardinality->containsNull()) + throw Exception{"Cannot convert NULL value to non-Nullable type", + ErrorCodes::CANNOT_INSERT_NULL_IN_ORDINARY_COLUMN}; + arg.column = col_low_cardinality->getDictionary().getNestedColumn(); arg.type = from_low_cardinality->getDictionaryType(); @@ -1966,7 +1977,7 @@ private: }; } - WrapperType prepareRemoveNullable(const DataTypePtr & from_type, const DataTypePtr & to_type) const + WrapperType prepareRemoveNullable(const DataTypePtr & from_type, const DataTypePtr & to_type, bool skip_not_null_check) const { /// Determine whether pre-processing and/or post-processing must take place during conversion. @@ -2012,14 +2023,18 @@ private: Block tmp_block = createBlockWithNestedColumns(block, arguments, result); /// Check that all values are not-NULL. + /// Check can be skipped in case if LowCardinality dictionary is transformed. + /// In that case, correctness will be checked beforehand. + if (!skip_not_null_check) + { + const auto & col = block.getByPosition(arguments[0]).column; + const auto & nullable_col = static_cast(*col); + const auto & null_map = nullable_col.getNullMapData(); - const auto & col = block.getByPosition(arguments[0]).column; - const auto & nullable_col = static_cast(*col); - const auto & null_map = nullable_col.getNullMapData(); - - if (!memoryIsZero(null_map.data(), null_map.size())) - throw Exception{"Cannot convert NULL value to non-Nullable type", - ErrorCodes::CANNOT_INSERT_NULL_IN_ORDINARY_COLUMN}; + if (!memoryIsZero(null_map.data(), null_map.size())) + throw Exception{"Cannot convert NULL value to non-Nullable type", + ErrorCodes::CANNOT_INSERT_NULL_IN_ORDINARY_COLUMN}; + } wrapper(tmp_block, arguments, result, input_rows_count); block.getByPosition(result).column = tmp_block.getByPosition(result).column; From a80e066769c999f86b39a1e8f509709dcc275836 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Mon, 22 Jul 2019 19:04:15 +0300 Subject: [PATCH 0237/1165] better --- dbms/src/Interpreters/TextLog.cpp | 4 ---- dbms/src/Interpreters/TextLog.h | 1 - 2 files changed, 5 deletions(-) diff --git a/dbms/src/Interpreters/TextLog.cpp b/dbms/src/Interpreters/TextLog.cpp index d11f6246319..5eb19958ab4 100644 --- a/dbms/src/Interpreters/TextLog.cpp +++ b/dbms/src/Interpreters/TextLog.cpp @@ -22,7 +22,6 @@ template <> struct NearestFieldTypeImpl { using Type = UInt64 Block TextLogElement::createBlock() { - auto priority_datatype = std::make_shared( DataTypeEnum8::Values { @@ -47,7 +46,6 @@ Block TextLogElement::createBlock() {std::make_shared(), "os_thread_id"}, {std::move(priority_datatype), "level"}, - {std::make_shared(), "query_id"}, {std::make_shared(), "logger_name"}, {std::make_shared(), "message"}, @@ -69,13 +67,11 @@ void TextLogElement::appendToBlock(Block & block) const columns[i++]->insert(event_time); columns[i++]->insert(microseconds); - // Thread info columns[i++]->insertData(thread_name.data(), thread_name.size()); columns[i++]->insert(thread_number); columns[i++]->insert(os_thread_id); columns[i++]->insert(level); - columns[i++]->insert(query_id); columns[i++]->insert(logger_name); columns[i++]->insert(message); diff --git a/dbms/src/Interpreters/TextLog.h b/dbms/src/Interpreters/TextLog.h index f56017b13bc..31ce514c340 100644 --- a/dbms/src/Interpreters/TextLog.h +++ b/dbms/src/Interpreters/TextLog.h @@ -8,7 +8,6 @@ using Poco::Message; struct TextLogElement { - time_t event_date{}; time_t event_time{}; UInt32 microseconds; From daa7fc154fd4a4de01e5625efb2e1a1df8485431 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Mon, 22 Jul 2019 19:21:34 +0300 Subject: [PATCH 0238/1165] better includes --- dbms/src/Interpreters/TextLog.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/dbms/src/Interpreters/TextLog.cpp b/dbms/src/Interpreters/TextLog.cpp index 5eb19958ab4..884cc4568af 100644 --- a/dbms/src/Interpreters/TextLog.cpp +++ b/dbms/src/Interpreters/TextLog.cpp @@ -1,18 +1,10 @@ #include #include -#include -#include -#include #include #include #include #include -#include -#include -#include -#include #include -#include #include namespace DB From fa2610e0961500800ae2da14a7c0f98e03afd8c3 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Mon, 22 Jul 2019 19:46:42 +0300 Subject: [PATCH 0239/1165] Fix CAST from LowCardinality(Nullable). --- dbms/src/Columns/ColumnLowCardinality.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Columns/ColumnLowCardinality.cpp b/dbms/src/Columns/ColumnLowCardinality.cpp index 47433942c51..1dbb3f8574f 100644 --- a/dbms/src/Columns/ColumnLowCardinality.cpp +++ b/dbms/src/Columns/ColumnLowCardinality.cpp @@ -614,7 +614,7 @@ bool ColumnLowCardinality::Index::containsDefault() const { bool contains = false; - auto check_contains_default = [&](auto & x) + auto check_contains_default = [&](auto x) { using CurIndexType = decltype(x); auto & data = getPositionsData(); From 467b654318dc32e9c912536cf605f433b3dedc56 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Mon, 22 Jul 2019 22:03:16 +0300 Subject: [PATCH 0240/1165] Update CMakeLists.txt --- dbms/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/CMakeLists.txt b/dbms/CMakeLists.txt index dced3ed7b93..ee7fba8328d 100644 --- a/dbms/CMakeLists.txt +++ b/dbms/CMakeLists.txt @@ -291,7 +291,7 @@ if (NOT USE_INTERNAL_LZ4_LIBRARY) target_include_directories(dbms SYSTEM BEFORE PRIVATE ${LZ4_INCLUDE_DIR}) endif () -if(ZSTD_LIBRARY) +if (ZSTD_LIBRARY) target_link_libraries(dbms PRIVATE ${ZSTD_LIBRARY}) endif() if (NOT USE_INTERNAL_ZSTD_LIBRARY AND ZSTD_INCLUDE_DIR) From 4858b067f5edf19df833efd901e588e89e04677b Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Mon, 22 Jul 2019 22:04:19 +0300 Subject: [PATCH 0241/1165] Update Defines.h --- dbms/src/Core/Defines.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Core/Defines.h b/dbms/src/Core/Defines.h index 5cd6326f445..c83aa984fad 100644 --- a/dbms/src/Core/Defines.h +++ b/dbms/src/Core/Defines.h @@ -141,8 +141,8 @@ #define DBMS_DISTRIBUTED_SENDS_MAGIC_NUMBER 0xCAFECABE #if !__has_include() -# define ASAN_UNPOISON_MEMORY_REGION(a,b) -# define ASAN_POISON_MEMORY_REGION(a,b) +# define ASAN_UNPOISON_MEMORY_REGION(a, b) +# define ASAN_POISON_MEMORY_REGION(a, b) #endif /// A macro for suppressing warnings about unused variables or function results. From eaa3cb557a9853eaccdb486485d9f187a4613acc Mon Sep 17 00:00:00 2001 From: chertus Date: Mon, 22 Jul 2019 22:21:07 +0300 Subject: [PATCH 0242/1165] move prefer_alias_to_column_name logic out of parser --- dbms/src/Interpreters/QueryAliasesVisitor.cpp | 17 ++++++++++++++++- dbms/src/Interpreters/QueryAliasesVisitor.h | 3 ++- dbms/src/Parsers/ExpressionElementParsers.cpp | 1 - dbms/src/Parsers/ExpressionElementParsers.h | 7 +++---- dbms/src/Parsers/ExpressionListParsers.cpp | 6 +++--- dbms/src/Parsers/ExpressionListParsers.h | 11 +++++------ dbms/src/Parsers/ParserSelectQuery.cpp | 2 +- 7 files changed, 30 insertions(+), 17 deletions(-) diff --git a/dbms/src/Interpreters/QueryAliasesVisitor.cpp b/dbms/src/Interpreters/QueryAliasesVisitor.cpp index f9257870583..98069396d81 100644 --- a/dbms/src/Interpreters/QueryAliasesVisitor.cpp +++ b/dbms/src/Interpreters/QueryAliasesVisitor.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -41,12 +42,25 @@ void QueryAliasesMatcher::visit(ASTPtr & ast, Data & data) { if (auto * s = ast->as()) visit(*s, ast, data); + else if (auto * q = ast->as()) + visit(*q, ast, data); else if (auto * aj = ast->as()) visit(*aj, ast, data); else visitOther(ast, data); } +void QueryAliasesMatcher::visit(const ASTSelectQuery & select, const ASTPtr &, Data &) +{ + ASTPtr with = select.with(); + if (!with) + return; + + for (auto & child : with->children) + if (auto * ast_with_alias = dynamic_cast(child.get())) + ast_with_alias->prefer_alias_to_column_name = true; +} + /// The top-level aliases in the ARRAY JOIN section have a special meaning, we will not add them /// (skip the expression list itself and its children). void QueryAliasesMatcher::visit(const ASTArrayJoin &, const ASTPtr & ast, Data & data) @@ -83,11 +97,12 @@ void QueryAliasesMatcher::visit(ASTSubquery & subquery, const ASTPtr & ast, Data while (aliases.count(alias)); subquery.setAlias(alias); - subquery.prefer_alias_to_column_name = true; aliases[alias] = ast; } else visitOther(ast, data); + + subquery.prefer_alias_to_column_name = true; } void QueryAliasesMatcher::visitOther(const ASTPtr & ast, Data & data) diff --git a/dbms/src/Interpreters/QueryAliasesVisitor.h b/dbms/src/Interpreters/QueryAliasesVisitor.h index 458acce66f6..c4e297965c3 100644 --- a/dbms/src/Interpreters/QueryAliasesVisitor.h +++ b/dbms/src/Interpreters/QueryAliasesVisitor.h @@ -6,7 +6,7 @@ namespace DB { -class ASTSelectWithUnionQuery; +class ASTSelectQuery; class ASTSubquery; struct ASTTableExpression; struct ASTArrayJoin; @@ -26,6 +26,7 @@ public: static bool needChildVisit(ASTPtr & node, const ASTPtr & child); private: + static void visit(const ASTSelectQuery & select, const ASTPtr & ast, Data & data); static void visit(ASTSubquery & subquery, const ASTPtr & ast, Data & data); static void visit(const ASTArrayJoin &, const ASTPtr & ast, Data & data); static void visitOther(const ASTPtr & ast, Data & data); diff --git a/dbms/src/Parsers/ExpressionElementParsers.cpp b/dbms/src/Parsers/ExpressionElementParsers.cpp index 8cd017f0710..33c95cdf1aa 100644 --- a/dbms/src/Parsers/ExpressionElementParsers.cpp +++ b/dbms/src/Parsers/ExpressionElementParsers.cpp @@ -1337,7 +1337,6 @@ bool ParserWithOptionalAlias::parseImpl(Pos & pos, ASTPtr & node, Expected & exp if (auto * ast_with_alias = dynamic_cast(node.get())) { getIdentifierName(alias_node, ast_with_alias->alias); - ast_with_alias->prefer_alias_to_column_name = prefer_alias_to_column_name; } else { diff --git a/dbms/src/Parsers/ExpressionElementParsers.h b/dbms/src/Parsers/ExpressionElementParsers.h index dca82f72f12..9a87a78a5a3 100644 --- a/dbms/src/Parsers/ExpressionElementParsers.h +++ b/dbms/src/Parsers/ExpressionElementParsers.h @@ -274,13 +274,12 @@ protected: class ParserWithOptionalAlias : public IParserBase { public: - ParserWithOptionalAlias(ParserPtr && elem_parser_, bool allow_alias_without_as_keyword_, bool prefer_alias_to_column_name_ = false) - : elem_parser(std::move(elem_parser_)), allow_alias_without_as_keyword(allow_alias_without_as_keyword_), - prefer_alias_to_column_name(prefer_alias_to_column_name_) {} + ParserWithOptionalAlias(ParserPtr && elem_parser_, bool allow_alias_without_as_keyword_) + : elem_parser(std::move(elem_parser_)), allow_alias_without_as_keyword(allow_alias_without_as_keyword_) + {} protected: ParserPtr elem_parser; bool allow_alias_without_as_keyword; - bool prefer_alias_to_column_name; const char * getName() const { return "element of expression with optional alias"; } bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected); diff --git a/dbms/src/Parsers/ExpressionListParsers.cpp b/dbms/src/Parsers/ExpressionListParsers.cpp index b948a22ce2a..4c8ef64b804 100644 --- a/dbms/src/Parsers/ExpressionListParsers.cpp +++ b/dbms/src/Parsers/ExpressionListParsers.cpp @@ -522,9 +522,9 @@ bool ParserTupleElementExpression::parseImpl(Pos & pos, ASTPtr & node, Expected } -ParserExpressionWithOptionalAlias::ParserExpressionWithOptionalAlias(bool allow_alias_without_as_keyword, bool prefer_alias_to_column_name) +ParserExpressionWithOptionalAlias::ParserExpressionWithOptionalAlias(bool allow_alias_without_as_keyword) : impl(std::make_unique(std::make_unique(), - allow_alias_without_as_keyword, prefer_alias_to_column_name)) + allow_alias_without_as_keyword)) { } @@ -532,7 +532,7 @@ ParserExpressionWithOptionalAlias::ParserExpressionWithOptionalAlias(bool allow_ bool ParserExpressionList::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) { return ParserList( - std::make_unique(allow_alias_without_as_keyword, prefer_alias_to_column_name), + std::make_unique(allow_alias_without_as_keyword), std::make_unique(TokenType::Comma)) .parse(pos, node, expected); } diff --git a/dbms/src/Parsers/ExpressionListParsers.h b/dbms/src/Parsers/ExpressionListParsers.h index 28a5bb5b2b9..f33965a9d05 100644 --- a/dbms/src/Parsers/ExpressionListParsers.h +++ b/dbms/src/Parsers/ExpressionListParsers.h @@ -322,7 +322,7 @@ using ParserExpression = ParserLambdaExpression; class ParserExpressionWithOptionalAlias : public IParserBase { public: - ParserExpressionWithOptionalAlias(bool allow_alias_without_as_keyword, bool prefer_alias_to_column_name_ = false); + ParserExpressionWithOptionalAlias(bool allow_alias_without_as_keyword); protected: ParserPtr impl; @@ -339,12 +339,11 @@ protected: class ParserExpressionList : public IParserBase { public: - ParserExpressionList(bool allow_alias_without_as_keyword_, bool prefer_alias_to_column_name_ = false) - : allow_alias_without_as_keyword(allow_alias_without_as_keyword_), prefer_alias_to_column_name(prefer_alias_to_column_name_) {} + ParserExpressionList(bool allow_alias_without_as_keyword_) + : allow_alias_without_as_keyword(allow_alias_without_as_keyword_) {} protected: bool allow_alias_without_as_keyword; - bool prefer_alias_to_column_name; const char * getName() const { return "list of expressions"; } bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected); @@ -354,8 +353,8 @@ protected: class ParserNotEmptyExpressionList : public IParserBase { public: - ParserNotEmptyExpressionList(bool allow_alias_without_as_keyword, bool prefer_alias_to_column_name = false) - : nested_parser(allow_alias_without_as_keyword, prefer_alias_to_column_name) {} + ParserNotEmptyExpressionList(bool allow_alias_without_as_keyword) + : nested_parser(allow_alias_without_as_keyword) {} private: ParserExpressionList nested_parser; protected: diff --git a/dbms/src/Parsers/ParserSelectQuery.cpp b/dbms/src/Parsers/ParserSelectQuery.cpp index 644d63788cb..afef7842ef6 100644 --- a/dbms/src/Parsers/ParserSelectQuery.cpp +++ b/dbms/src/Parsers/ParserSelectQuery.cpp @@ -44,7 +44,7 @@ bool ParserSelectQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) ParserKeyword s_offset("OFFSET"); ParserNotEmptyExpressionList exp_list(false); - ParserNotEmptyExpressionList exp_list_for_with_clause(false, true); /// Set prefer_alias_to_column_name for each alias. + ParserNotEmptyExpressionList exp_list_for_with_clause(false); ParserNotEmptyExpressionList exp_list_for_select_clause(true); /// Allows aliases without AS keyword. ParserExpressionWithOptionalAlias exp_elem(false); ParserOrderByExpressionList order_list; From 96d0a066d9f8f10e0937c998b06479df18b96b8f Mon Sep 17 00:00:00 2001 From: Alexander Tokmakov Date: Mon, 22 Jul 2019 23:13:27 +0300 Subject: [PATCH 0243/1165] rename format_csv_unquoted_null_literal_as_null to input_format_csv_unquoted_null_literal_as_null --- dbms/src/Core/Settings.h | 2 +- dbms/src/DataTypes/DataTypeNullable.h | 2 +- dbms/src/Formats/FormatFactory.cpp | 2 +- dbms/tests/queries/0_stateless/00301_csv.sh | 2 +- docs/en/interfaces/formats.md | 2 +- docs/en/operations/settings/settings.md | 2 +- docs/ru/interfaces/formats.md | 2 +- docs/ru/operations/settings/settings.md | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dbms/src/Core/Settings.h b/dbms/src/Core/Settings.h index 2098aa34a8c..a9a444e89ac 100644 --- a/dbms/src/Core/Settings.h +++ b/dbms/src/Core/Settings.h @@ -299,7 +299,7 @@ struct Settings : public SettingsCollection M(SettingChar, format_csv_delimiter, ',', "The character to be considered as a delimiter in CSV data. If setting with a string, a string has to have a length of 1.") \ M(SettingBool, format_csv_allow_single_quotes, 1, "If it is set to true, allow strings in single quotes.") \ M(SettingBool, format_csv_allow_double_quotes, 1, "If it is set to true, allow strings in double quotes.") \ - M(SettingBool, format_csv_unquoted_null_literal_as_null, false, "Consider unquoted NULL literal as \N") \ + M(SettingBool, input_format_csv_unquoted_null_literal_as_null, false, "Consider unquoted NULL literal as \N") \ \ M(SettingDateTimeInputFormat, date_time_input_format, FormatSettings::DateTimeInputFormat::Basic, "Method to read DateTime from text input formats. Possible values: 'basic' and 'best_effort'.") \ M(SettingBool, log_profile_events, true, "Log query performance statistics into the query_log and query_thread_log.") \ diff --git a/dbms/src/DataTypes/DataTypeNullable.h b/dbms/src/DataTypes/DataTypeNullable.h index 6a9308af69f..5bacdb39ff4 100644 --- a/dbms/src/DataTypes/DataTypeNullable.h +++ b/dbms/src/DataTypes/DataTypeNullable.h @@ -62,7 +62,7 @@ public: * 2. empty string (without quotes) * 3. NULL * We support all of them (however, second variant is supported by CSVRowInputStream, not by deserializeTextCSV). - * (see also input_format_defaults_for_omitted_fields and format_csv_unquoted_null_literal_as_null settings) + * (see also input_format_defaults_for_omitted_fields and input_format_csv_unquoted_null_literal_as_null settings) * In CSV, non-NULL string value, starting with \N characters, must be placed in quotes, to avoid ambiguity. */ void deserializeTextCSV(IColumn & column, ReadBuffer & istr, const FormatSettings & settings) const override; diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index b1c4b861162..3dfcc84eb4d 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -41,7 +41,7 @@ static FormatSettings getInputFormatSetting(const Settings & settings) format_settings.csv.delimiter = settings.format_csv_delimiter; format_settings.csv.allow_single_quotes = settings.format_csv_allow_single_quotes; format_settings.csv.allow_double_quotes = settings.format_csv_allow_double_quotes; - format_settings.csv.unquoted_null_literal_as_null = settings.format_csv_unquoted_null_literal_as_null; + format_settings.csv.unquoted_null_literal_as_null = settings.input_format_csv_unquoted_null_literal_as_null; format_settings.csv.empty_as_default = settings.input_format_defaults_for_omitted_fields; format_settings.csv.null_as_default = settings.input_format_null_as_default; format_settings.values.interpret_expressions = settings.input_format_values_interpret_expressions; diff --git a/dbms/tests/queries/0_stateless/00301_csv.sh b/dbms/tests/queries/0_stateless/00301_csv.sh index 8ed2a2ca814..6e72c31b870 100755 --- a/dbms/tests/queries/0_stateless/00301_csv.sh +++ b/dbms/tests/queries/0_stateless/00301_csv.sh @@ -34,7 +34,7 @@ $CLICKHOUSE_CLIENT --query="CREATE TABLE csv_null (t Nullable(DateTime('Europe/M echo 'NULL, NULL "2016-01-01 01:02:03",NUL -"2016-01-02 01:02:03",Nhello' | $CLICKHOUSE_CLIENT --format_csv_unquoted_null_literal_as_null=1 --query="INSERT INTO csv_null FORMAT CSV"; +"2016-01-02 01:02:03",Nhello' | $CLICKHOUSE_CLIENT --input_format_csv_unquoted_null_literal_as_null=1 --query="INSERT INTO csv_null FORMAT CSV"; $CLICKHOUSE_CLIENT --query="SELECT * FROM csv_null ORDER BY s NULLS LAST"; $CLICKHOUSE_CLIENT --query="DROP TABLE csv_null"; diff --git a/docs/en/interfaces/formats.md b/docs/en/interfaces/formats.md index 7a93d0614a9..8c9badaa02f 100644 --- a/docs/en/interfaces/formats.md +++ b/docs/en/interfaces/formats.md @@ -173,7 +173,7 @@ Empty unquoted input values are replaced with default values for the respective [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#session_settings-input_format_defaults_for_omitted_fields) is enabled. -`NULL` is formatted as `\N` or `NULL` or an empty unquoted string (see settings [format_csv_unquoted_null_literal_as_null](../operations/settings/settings.md#settings-format_csv_unquoted_null_literal_as_null) and [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#settings-input_format_defaults_for_omitted_fields)). +`NULL` is formatted as `\N` or `NULL` or an empty unquoted string (see settings [input_format_csv_unquoted_null_literal_as_null](../operations/settings/settings.md#settings-input_format_csv_unquoted_null_literal_as_null) and [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#settings-input_format_defaults_for_omitted_fields)). The CSV format supports the output of totals and extremes the same way as `TabSeparated`. diff --git a/docs/en/operations/settings/settings.md b/docs/en/operations/settings/settings.md index 7de2d86120b..3eac7ab5950 100644 --- a/docs/en/operations/settings/settings.md +++ b/docs/en/operations/settings/settings.md @@ -694,7 +694,7 @@ If the value is true, integers appear in quotes when using JSON\* Int64 and UInt The character interpreted as a delimiter in the CSV data. By default, the delimiter is `,`. -## format_csv_unquoted_null_literal_as_null {#settings-format_csv_unquoted_null_literal_as_null} +## input_format_csv_unquoted_null_literal_as_null {#settings-input_format_csv_unquoted_null_literal_as_null} For CSV input format enables or disables parsing of unquoted `NULL` as literal (synonym for `\N`). diff --git a/docs/ru/interfaces/formats.md b/docs/ru/interfaces/formats.md index 24cf6bea9ed..14d6408b7e7 100644 --- a/docs/ru/interfaces/formats.md +++ b/docs/ru/interfaces/formats.md @@ -165,7 +165,7 @@ clickhouse-client --format_csv_delimiter="|" --query="INSERT INTO test.csv FORMA При парсинге, все значения могут парситься как в кавычках, так и без кавычек. Поддерживаются как двойные, так и одинарные кавычки. Строки также могут быть без кавычек. В этом случае они парсятся до символа-разделителя или перевода строки (CR или LF). В нарушение RFC, в случае парсинга строк не в кавычках, начальные и конечные пробелы и табы игнорируются. В качестве перевода строки, поддерживаются как Unix (LF), так и Windows (CR LF) и Mac OS Classic (LF CR) варианты. -`NULL` форматируется в виде `\N` или `NULL` или пустой неэкранированной строки (см. настройки [format_csv_unquoted_null_literal_as_null](../operations/settings/settings.md#settings-format_csv_unquoted_null_literal_as_null) и [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#settings-input_format_defaults_for_omitted_fields)). +`NULL` форматируется в виде `\N` или `NULL` или пустой неэкранированной строки (см. настройки [input_format_csv_unquoted_null_literal_as_null](../operations/settings/settings.md#settings-input_format_csv_unquoted_null_literal_as_null) и [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#settings-input_format_defaults_for_omitted_fields)). Если установлена настройка [input_format_defaults_for_omitted_fields = 1](../operations/settings/settings.md#session_settings-input_format_defaults_for_omitted_fields) и тип столбца не `Nullable(T)`, то пустые значения без кавычек заменяются значениями по умолчанию для типа данных столбца. diff --git a/docs/ru/operations/settings/settings.md b/docs/ru/operations/settings/settings.md index 1c0a9c0ac24..92c546c288c 100644 --- a/docs/ru/operations/settings/settings.md +++ b/docs/ru/operations/settings/settings.md @@ -608,7 +608,7 @@ load_balancing = first_or_random Символ, интерпретируемый как разделитель в данных формата CSV. По умолчанию — `,`. -## format_csv_unquoted_null_literal_as_null {#settings-format_csv_unquoted_null_literal_as_null} +## input_format_csv_unquoted_null_literal_as_null {#settings-input_format_csv_unquoted_null_literal_as_null} Для формата CSV включает или выключает парсинг неэкранированной строки `NULL` как литерала (синоним для `\N`) From b282c6160d2b21e17097d6eb6e5f0963421edbd0 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 23 Jul 2019 02:41:06 +0300 Subject: [PATCH 0244/1165] Added "fastops" as submodule --- .gitmodules | 3 +++ CMakeLists.txt | 1 + contrib/CMakeLists.txt | 4 ++++ contrib/fastops | 1 + contrib/fastops-cmake/CMakeLists.txt | 19 +++++++++++++++++++ dbms/src/Functions/config_functions.h.in | 1 + 6 files changed, 29 insertions(+) create mode 160000 contrib/fastops create mode 100644 contrib/fastops-cmake/CMakeLists.txt diff --git a/.gitmodules b/.gitmodules index 567772bad60..847abf7d931 100644 --- a/.gitmodules +++ b/.gitmodules @@ -100,3 +100,6 @@ [submodule "contrib/mimalloc"] path = contrib/mimalloc url = https://github.com/ClickHouse-Extras/mimalloc +[submodule "contrib/fastops"] + path = contrib/fastops + url = https://github.com/ClickHouse-Extras/fastops diff --git a/CMakeLists.txt b/CMakeLists.txt index a2cc5f15ac8..af85c774d39 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -462,6 +462,7 @@ include (cmake/find_hyperscan.cmake) include (cmake/find_mimalloc.cmake) include (cmake/find_simdjson.cmake) include (cmake/find_rapidjson.cmake) +include (cmake/find_fastops.cmake) find_contrib_lib(cityhash) find_contrib_lib(farmhash) diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 2cc8ae37806..c478311d77a 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -330,3 +330,7 @@ endif() if (USE_MIMALLOC) add_subdirectory (mimalloc) endif() + +if (USE_FASTOPS) + add_subdirectory (fastops-cmake) +endif() diff --git a/contrib/fastops b/contrib/fastops new file mode 160000 index 00000000000..30f16c1dcb7 --- /dev/null +++ b/contrib/fastops @@ -0,0 +1 @@ +Subproject commit 30f16c1dcb799d483fabc0f45aaf44fa0fed097e diff --git a/contrib/fastops-cmake/CMakeLists.txt b/contrib/fastops-cmake/CMakeLists.txt new file mode 100644 index 00000000000..0269d5603c2 --- /dev/null +++ b/contrib/fastops-cmake/CMakeLists.txt @@ -0,0 +1,19 @@ +set(LIBRARY_DIR ${ClickHouse_SOURCE_DIR}/contrib/fastops) + +set(SRCS "") + +if(HAVE_AVX) + set (SRCS ${SRCS} ${LIBRARY_DIR}/fastops/avx/ops_avx.cpp) + set_source_files_properties(${LIBRARY_DIR}/fastops/avx/ops_avx.cpp PROPERTIES COMPILE_FLAGS "-mavx -DNO_AVX2") +endif() + +if(HAVE_AVX2) + set (SRCS ${SRCS} ${LIBRARY_DIR}/fastops/avx2/ops_avx2.cpp) + set_source_files_properties(${LIBRARY_DIR}/fastops/avx2/ops_avx2.cpp PROPERTIES COMPILE_FLAGS "-mavx2 -mfma") +endif() + +set (SRCS ${SRCS} ${LIBRARY_DIR}/fastops/plain/ops_plain.cpp ${LIBRARY_DIR}/fastops/core/avx_id.cpp ${LIBRARY_DIR}/fastops/fastops.cpp) + +add_library(fastops ${SRCS}) + +target_include_directories(fastops SYSTEM PUBLIC "${LIBRARY_DIR}") diff --git a/dbms/src/Functions/config_functions.h.in b/dbms/src/Functions/config_functions.h.in index 7d395741b78..28891bec4f0 100644 --- a/dbms/src/Functions/config_functions.h.in +++ b/dbms/src/Functions/config_functions.h.in @@ -9,3 +9,4 @@ #cmakedefine01 USE_SIMDJSON #cmakedefine01 USE_RAPIDJSON #cmakedefine01 USE_H3 +#cmakedefine01 USE_FASTOPS From a652a8bb6c34d08053fb467fd5cd0d188a71d7e6 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 23 Jul 2019 03:04:04 +0300 Subject: [PATCH 0245/1165] Disabled query profiler by default #4247 --- dbms/src/Core/Settings.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Core/Settings.h b/dbms/src/Core/Settings.h index 06c82101956..27e06ffec10 100644 --- a/dbms/src/Core/Settings.h +++ b/dbms/src/Core/Settings.h @@ -221,8 +221,8 @@ struct Settings : public SettingsCollection M(SettingBool, empty_result_for_aggregation_by_empty_set, false, "Return empty result when aggregating without keys on empty set.") \ M(SettingBool, allow_distributed_ddl, true, "If it is set to true, then a user is allowed to executed distributed DDL queries.") \ M(SettingUInt64, odbc_max_field_size, 1024, "Max size of filed can be read from ODBC dictionary. Long strings are truncated.") \ - M(SettingUInt64, query_profiler_real_time_period_ns, 500000000, "Period for real clock timer of query profiler (in nanoseconds). Set 0 value to turn off real clock query profiler") \ - M(SettingUInt64, query_profiler_cpu_time_period_ns, 500000000, "Period for CPU clock timer of query profiler (in nanoseconds). Set 0 value to turn off CPU clock query profiler") \ + M(SettingUInt64, query_profiler_real_time_period_ns, 0, "Period for real clock timer of query profiler (in nanoseconds). Set 0 value to turn off real clock query profiler") \ + M(SettingUInt64, query_profiler_cpu_time_period_ns, 0, "Period for CPU clock timer of query profiler (in nanoseconds). Set 0 value to turn off CPU clock query profiler") \ \ \ /** Limits during query execution are part of the settings. \ From 8e7a17528f8f12a172b4be1bfe1ebb607c337b76 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Tue, 23 Jul 2019 09:11:09 +0300 Subject: [PATCH 0246/1165] DOCAPI-7553: CHECK TABLE for MergeTree docs update. --- docs/en/query_language/misc.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/en/query_language/misc.md b/docs/en/query_language/misc.md index 46feeed8c6f..964b847e4fe 100644 --- a/docs/en/query_language/misc.md +++ b/docs/en/query_language/misc.md @@ -32,15 +32,16 @@ The query response contains the `result` column with a single row. The row has a - 0 - The data in the table is corrupted. - 1 - The data maintains integrity. -The `CHECK TABLE` query is only supported for the following table engines: +The `CHECK TABLE` query works for the following table engines: - [Log](../operations/table_engines/log.md) - [TinyLog](../operations/table_engines/tinylog.md) - [StripeLog](../operations/table_engines/stripelog.md) +- [MergeTree](../operations/table_engines/mergetree.md) -These engines do not provide automatic data recovery on failure. Use the `CHECK TABLE` query to track data loss in a timely manner. +The `*Log` engines do not provide automatic data recovery on failure. Use the `CHECK TABLE` query to track data loss in a timely manner. -To avoid data loss use the [MergeTree](../operations/table_engines/mergetree.md) family tables. +For the `MergeTree` family engines the `CHECK TABLE` query shows a check status for every individual table data part at the local server. **If the data is corrupted** @@ -57,7 +58,7 @@ If the table is corrupted, you can copy the non-corrupted data to another table. DESC|DESCRIBE TABLE [db.]table [INTO OUTFILE filename] [FORMAT format] ``` -Returns the following `String` type columns: +Returns the following `String` type columns: - `name` — Column name. - `type`— Column type. From 1e35f8776099d77a338d2ab9729be83bb986a931 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Tue, 23 Jul 2019 10:57:32 +0300 Subject: [PATCH 0247/1165] Fix CAST from LowCardinality(Nullable). --- dbms/src/Functions/FunctionsConversion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Functions/FunctionsConversion.h b/dbms/src/Functions/FunctionsConversion.h index 909cf5c2ef1..7d1d277752f 100644 --- a/dbms/src/Functions/FunctionsConversion.h +++ b/dbms/src/Functions/FunctionsConversion.h @@ -2018,7 +2018,7 @@ private: { /// Conversion from Nullable to non-Nullable. - return [wrapper] (Block & block, const ColumnNumbers & arguments, const size_t result, size_t input_rows_count) + return [wrapper, skip_not_null_check] (Block & block, const ColumnNumbers & arguments, const size_t result, size_t input_rows_count) { Block tmp_block = createBlockWithNestedColumns(block, arguments, result); From a1152f99aeb4a110734097dd81054396987cc493 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Tue, 23 Jul 2019 10:10:06 +0300 Subject: [PATCH 0248/1165] switching to sha256_password after handshake in order to use PHP client without SSL --- dbms/src/Core/MySQLProtocol.h | 8 +++++- .../clients/php-mysqlnd/Dockerfile | 1 + .../clients/php-mysqlnd/test.php | 3 --- .../clients/php-mysqlnd/test_ssl.php | 27 +++++++++++++++++++ .../integration/test_mysql_protocol/test.py | 4 +++ 5 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 dbms/tests/integration/test_mysql_protocol/clients/php-mysqlnd/test_ssl.php diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index 3d908971601..d06949285fa 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -34,6 +34,7 @@ const size_t SSL_REQUEST_PAYLOAD_SIZE = 32; namespace Authentication { + const String Native = "mysql_native_password"; const String SHA256 = "sha256_password"; /// Caching SHA2 plugin is not used because it would be possible to authenticate knowing hash from users.xml. } @@ -285,7 +286,12 @@ public: result.append(1, auth_plugin_data.size()); result.append(10, 0x0); result.append(auth_plugin_data.substr(AUTH_PLUGIN_DATA_PART_1_LENGTH, auth_plugin_data.size() - AUTH_PLUGIN_DATA_PART_1_LENGTH)); - result.append(Authentication::SHA256); + + // A workaround for PHP mysqlnd extension bug which occurs when sha256_password is used as a default authentication plugin. + // Instead of using client response for mysql_native_password plugin, the server will always generate authentication method mismatch + // and switch to sha256_password to simulate that mysql_native_password is used as a default plugin. + result.append(Authentication::Native); + result.append(1, 0x0); return result; } diff --git a/dbms/tests/integration/test_mysql_protocol/clients/php-mysqlnd/Dockerfile b/dbms/tests/integration/test_mysql_protocol/clients/php-mysqlnd/Dockerfile index 85e256dfed6..76125702076 100644 --- a/dbms/tests/integration/test_mysql_protocol/clients/php-mysqlnd/Dockerfile +++ b/dbms/tests/integration/test_mysql_protocol/clients/php-mysqlnd/Dockerfile @@ -3,5 +3,6 @@ FROM php:7.3-cli COPY ./client.crt client.crt COPY ./client.key client.key COPY ./test.php test.php +COPY ./test_ssl.php test_ssl.php RUN docker-php-ext-install pdo pdo_mysql diff --git a/dbms/tests/integration/test_mysql_protocol/clients/php-mysqlnd/test.php b/dbms/tests/integration/test_mysql_protocol/clients/php-mysqlnd/test.php index 86354381835..dc5b55ad1d5 100644 --- a/dbms/tests/integration/test_mysql_protocol/clients/php-mysqlnd/test.php +++ b/dbms/tests/integration/test_mysql_protocol/clients/php-mysqlnd/test.php @@ -12,9 +12,6 @@ $options = [ PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, PDO::MYSQL_ATTR_DIRECT_QUERY => true, - PDO::MYSQL_ATTR_SSL_CERT => "client.crt", - PDO::MYSQL_ATTR_SSL_KEY => "client.key", - PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => 0, ]; $pdo = new PDO($dsn, $user, $pass, $options); diff --git a/dbms/tests/integration/test_mysql_protocol/clients/php-mysqlnd/test_ssl.php b/dbms/tests/integration/test_mysql_protocol/clients/php-mysqlnd/test_ssl.php new file mode 100644 index 00000000000..86354381835 --- /dev/null +++ b/dbms/tests/integration/test_mysql_protocol/clients/php-mysqlnd/test_ssl.php @@ -0,0 +1,27 @@ + PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + PDO::ATTR_EMULATE_PREPARES => false, + PDO::MYSQL_ATTR_DIRECT_QUERY => true, + PDO::MYSQL_ATTR_SSL_CERT => "client.crt", + PDO::MYSQL_ATTR_SSL_KEY => "client.key", + PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => 0, +]; +$pdo = new PDO($dsn, $user, $pass, $options); + +$stmt = $pdo->query("SELECT name FROM tables WHERE name = 'tables'"); + +foreach ($stmt as $row) +{ + echo $row["name"] . "\n"; +} +?> diff --git a/dbms/tests/integration/test_mysql_protocol/test.py b/dbms/tests/integration/test_mysql_protocol/test.py index f0c696b4dc7..4a8d6f0b608 100644 --- a/dbms/tests/integration/test_mysql_protocol/test.py +++ b/dbms/tests/integration/test_mysql_protocol/test.py @@ -152,3 +152,7 @@ def test_php_client(server_address, php_container): code, (stdout, stderr) = php_container.exec_run('php -f test.php {host} {port} default 123 '.format(host=server_address, port=server_port), demux=True) assert code == 0 assert stdout == 'tables\n' + + code, (stdout, stderr) = php_container.exec_run('php -f test_ssl.php {host} {port} default 123 '.format(host=server_address, port=server_port), demux=True) + assert code == 0 + assert stdout == 'tables\n' From 1feb20d9e01b17876e768c8db2672f9d28e4eac9 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Tue, 23 Jul 2019 11:01:08 +0300 Subject: [PATCH 0249/1165] DOCAPI-7460: The histogram function docs. --- .../agg_functions/parametric_functions.md | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/docs/en/query_language/agg_functions/parametric_functions.md b/docs/en/query_language/agg_functions/parametric_functions.md index c6a9694ed0c..cefc9e6777f 100644 --- a/docs/en/query_language/agg_functions/parametric_functions.md +++ b/docs/en/query_language/agg_functions/parametric_functions.md @@ -2,6 +2,42 @@ Some aggregate functions can accept not only argument columns (used for compression), but a set of parameters – constants for initialization. The syntax is two pairs of brackets instead of one. The first is for parameters, and the second is for arguments. +## histogram + +Calculates a histogram. + +``` +histogram(number_of_bins)(values) +``` + +**Parameters** + +`number_of_bins` — Number of bins for the histogram. +`values` — [Expression](../syntax.md#expressions) resulting in a data sample. + +**Returned values** + +- [Array](../../data_types/array.md) of [Tuples](../../data_types/tuple.md) of the following format: + + ``` + [(lower_1, upper_1, height_1), ... (lower_N, upper_N, height_N)] + ``` + + - `lower` — Lower bound of the bin. + - `upper` — Upper bound of the bin. + - `height` — Calculated height of the bin. + +**Example** + +```sql +SELECT histogram(5)(number + 1) FROM (SELECT * FROM system.numbers LIMIT 20) +``` +```text +┌─histogram(5)(plus(number, 1))───────────────────────────────────────────┐ +│ [(1,4.5,4),(4.5,8.5,4),(8.5,12.75,4.125),(12.75,17,4.625),(17,20,3.25)] │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + ## sequenceMatch(pattern)(time, cond1, cond2, ...) Pattern matching for event chains. From 221ab6a04f32b3be40cf80c123b8b67d5609fd01 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Tue, 23 Jul 2019 11:18:09 +0300 Subject: [PATCH 0250/1165] DOCAPI-7460: Link fix. --- docs/en/query_language/agg_functions/parametric_functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/query_language/agg_functions/parametric_functions.md b/docs/en/query_language/agg_functions/parametric_functions.md index cefc9e6777f..da6052545dc 100644 --- a/docs/en/query_language/agg_functions/parametric_functions.md +++ b/docs/en/query_language/agg_functions/parametric_functions.md @@ -13,7 +13,7 @@ histogram(number_of_bins)(values) **Parameters** `number_of_bins` — Number of bins for the histogram. -`values` — [Expression](../syntax.md#expressions) resulting in a data sample. +`values` — [Expression](../syntax.md#syntax-expressions) resulting in a data sample. **Returned values** From 8c71c109a65b93fe90678050799182089e3d026b Mon Sep 17 00:00:00 2001 From: robot-clickhouse Date: Tue, 23 Jul 2019 11:20:19 +0300 Subject: [PATCH 0251/1165] Auto version update to [19.12.1.889] [54424] --- dbms/cmake/version.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dbms/cmake/version.cmake b/dbms/cmake/version.cmake index 5714b5207b8..66f3f2a3ef4 100644 --- a/dbms/cmake/version.cmake +++ b/dbms/cmake/version.cmake @@ -3,9 +3,9 @@ set(VERSION_REVISION 54424) set(VERSION_MAJOR 19) set(VERSION_MINOR 12) set(VERSION_PATCH 1) -set(VERSION_GITHASH a584f0ca6cb5df9b0d9baf1e2e1eaa7d12a20a44) -set(VERSION_DESCRIBE v19.12.1.1-prestable) -set(VERSION_STRING 19.12.1.1) +set(VERSION_GITHASH adfc36917222bdb03eba069f0cad0f4f5b8f1c94) +set(VERSION_DESCRIBE v19.12.1.889-prestable) +set(VERSION_STRING 19.12.1.889) # end of autochange set(VERSION_EXTRA "" CACHE STRING "") From 58e03ad7b9fa54b069be71ebbdef206488100f38 Mon Sep 17 00:00:00 2001 From: robot-clickhouse Date: Tue, 23 Jul 2019 11:20:52 +0300 Subject: [PATCH 0252/1165] Auto version update to [19.13.1.1] [54425] --- dbms/cmake/version.cmake | 8 ++++---- debian/changelog | 4 ++-- docker/client/Dockerfile | 2 +- docker/server/Dockerfile | 2 +- docker/test/Dockerfile | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dbms/cmake/version.cmake b/dbms/cmake/version.cmake index 66f3f2a3ef4..d4c7b376b89 100644 --- a/dbms/cmake/version.cmake +++ b/dbms/cmake/version.cmake @@ -1,11 +1,11 @@ # This strings autochanged from release_lib.sh: -set(VERSION_REVISION 54424) +set(VERSION_REVISION 54425) set(VERSION_MAJOR 19) -set(VERSION_MINOR 12) +set(VERSION_MINOR 13) set(VERSION_PATCH 1) set(VERSION_GITHASH adfc36917222bdb03eba069f0cad0f4f5b8f1c94) -set(VERSION_DESCRIBE v19.12.1.889-prestable) -set(VERSION_STRING 19.12.1.889) +set(VERSION_DESCRIBE v19.13.1.1-prestable) +set(VERSION_STRING 19.13.1.1) # end of autochange set(VERSION_EXTRA "" CACHE STRING "") diff --git a/debian/changelog b/debian/changelog index 6abe0effc06..f1db1b81185 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -clickhouse (19.12.1.1) unstable; urgency=low +clickhouse (19.13.1.1) unstable; urgency=low * Modified source code - -- clickhouse-release Wed, 10 Jul 2019 22:57:50 +0300 + -- clickhouse-release Tue, 23 Jul 2019 11:20:49 +0300 diff --git a/docker/client/Dockerfile b/docker/client/Dockerfile index 1afc097aafd..68cdf3f0204 100644 --- a/docker/client/Dockerfile +++ b/docker/client/Dockerfile @@ -1,7 +1,7 @@ FROM ubuntu:18.04 ARG repository="deb http://repo.yandex.ru/clickhouse/deb/stable/ main/" -ARG version=19.12.1.* +ARG version=19.13.1.* RUN apt-get update \ && apt-get install --yes --no-install-recommends \ diff --git a/docker/server/Dockerfile b/docker/server/Dockerfile index fed4295b76c..934c1921a67 100644 --- a/docker/server/Dockerfile +++ b/docker/server/Dockerfile @@ -1,7 +1,7 @@ FROM ubuntu:18.04 ARG repository="deb http://repo.yandex.ru/clickhouse/deb/stable/ main/" -ARG version=19.12.1.* +ARG version=19.13.1.* ARG gosu_ver=1.10 RUN apt-get update \ diff --git a/docker/test/Dockerfile b/docker/test/Dockerfile index 488a2554483..5c2bd25b48c 100644 --- a/docker/test/Dockerfile +++ b/docker/test/Dockerfile @@ -1,7 +1,7 @@ FROM ubuntu:18.04 ARG repository="deb http://repo.yandex.ru/clickhouse/deb/stable/ main/" -ARG version=19.12.1.* +ARG version=19.13.1.* RUN apt-get update && \ apt-get install -y apt-transport-https dirmngr && \ From 61412e7f7492ef08b6efb963f9e64401f0073285 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Tue, 23 Jul 2019 11:22:38 +0300 Subject: [PATCH 0253/1165] changes after review + update config + resolve build fail --- dbms/src/Interpreters/TextLog.cpp | 16 ++++++++-------- dbms/tests/config/text_log.xml | 7 +++++++ docker/test/stateful/Dockerfile | 1 + docker/test/stateful_with_coverage/run.sh | 1 + docker/test/stateless/Dockerfile | 1 + docker/test/stateless_with_coverage/run.sh | 1 + libs/libloggers/loggers/OwnSplitChannel.cpp | 2 +- 7 files changed, 20 insertions(+), 9 deletions(-) create mode 100644 dbms/tests/config/text_log.xml diff --git a/dbms/src/Interpreters/TextLog.cpp b/dbms/src/Interpreters/TextLog.cpp index 884cc4568af..a6d21524c29 100644 --- a/dbms/src/Interpreters/TextLog.cpp +++ b/dbms/src/Interpreters/TextLog.cpp @@ -17,14 +17,14 @@ Block TextLogElement::createBlock() auto priority_datatype = std::make_shared( DataTypeEnum8::Values { - {"FATAL", static_cast(Message::PRIO_FATAL)}, - {"CRITICAL", static_cast(Message::PRIO_CRITICAL)}, - {"ERROR", static_cast(Message::PRIO_ERROR)}, - {"WARNING", static_cast(Message::PRIO_WARNING)}, - {"NOTICE", static_cast(Message::PRIO_NOTICE)}, - {"INFORMATION", static_cast(Message::PRIO_INFORMATION)}, - {"DEBUG", static_cast(Message::PRIO_DEBUG)}, - {"TRACE", static_cast(Message::PRIO_TRACE)} + {"Fatal", static_cast(Message::PRIO_FATAL)}, + {"Critical", static_cast(Message::PRIO_CRITICAL)}, + {"Error", static_cast(Message::PRIO_ERROR)}, + {"Warning", static_cast(Message::PRIO_WARNING)}, + {"Notice", static_cast(Message::PRIO_NOTICE)}, + {"Information", static_cast(Message::PRIO_INFORMATION)}, + {"Debug", static_cast(Message::PRIO_DEBUG)}, + {"Trace", static_cast(Message::PRIO_TRACE)} }); return diff --git a/dbms/tests/config/text_log.xml b/dbms/tests/config/text_log.xml new file mode 100644 index 00000000000..3699a23578c --- /dev/null +++ b/dbms/tests/config/text_log.xml @@ -0,0 +1,7 @@ + + + system + text_log
+ 7500 +
+
diff --git a/docker/test/stateful/Dockerfile b/docker/test/stateful/Dockerfile index 466578c8b98..516d63fa330 100644 --- a/docker/test/stateful/Dockerfile +++ b/docker/test/stateful/Dockerfile @@ -19,6 +19,7 @@ CMD dpkg -i package_folder/clickhouse-common-static_*.deb; \ ln -s /usr/share/clickhouse-test/config/zookeeper.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/listen.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/part_log.xml /etc/clickhouse-server/config.d/; \ + ln -s /usr/share/clickhouse-test/config/text_log.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/log_queries.xml /etc/clickhouse-server/users.d/; \ ln -s /usr/share/clickhouse-test/config/readonly.xml /etc/clickhouse-server/users.d/; \ ln -s /usr/share/clickhouse-test/config/ints_dictionary.xml /etc/clickhouse-server/; \ diff --git a/docker/test/stateful_with_coverage/run.sh b/docker/test/stateful_with_coverage/run.sh index 6ec0bfa155a..6253a07c745 100755 --- a/docker/test/stateful_with_coverage/run.sh +++ b/docker/test/stateful_with_coverage/run.sh @@ -45,6 +45,7 @@ chmod 777 -R /var/log/clickhouse-server/ ln -s /usr/share/clickhouse-test/config/zookeeper.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/listen.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/part_log.xml /etc/clickhouse-server/config.d/; \ + ln -s /usr/share/clickhouse-test/config/text_log.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/log_queries.xml /etc/clickhouse-server/users.d/; \ ln -s /usr/share/clickhouse-test/config/readonly.xml /etc/clickhouse-server/users.d/; \ ln -s /usr/share/clickhouse-test/config/ints_dictionary.xml /etc/clickhouse-server/; \ diff --git a/docker/test/stateless/Dockerfile b/docker/test/stateless/Dockerfile index e2cd5eee933..eea48c3c032 100644 --- a/docker/test/stateless/Dockerfile +++ b/docker/test/stateless/Dockerfile @@ -39,6 +39,7 @@ CMD dpkg -i package_folder/clickhouse-common-static_*.deb; \ ln -s /usr/share/clickhouse-test/config/zookeeper.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/listen.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/part_log.xml /etc/clickhouse-server/config.d/; \ + ln -s /usr/share/clickhouse-test/config/text_log.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/query_masking_rules.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/log_queries.xml /etc/clickhouse-server/users.d/; \ ln -s /usr/share/clickhouse-test/config/readonly.xml /etc/clickhouse-server/users.d/; \ diff --git a/docker/test/stateless_with_coverage/run.sh b/docker/test/stateless_with_coverage/run.sh index 50082337757..5d63f9f49d0 100755 --- a/docker/test/stateless_with_coverage/run.sh +++ b/docker/test/stateless_with_coverage/run.sh @@ -47,6 +47,7 @@ chmod 777 -R /var/log/clickhouse-server/ ln -s /usr/share/clickhouse-test/config/zookeeper.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/listen.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/part_log.xml /etc/clickhouse-server/config.d/; \ + ln -s /usr/share/clickhouse-test/config/text_log.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/log_queries.xml /etc/clickhouse-server/users.d/; \ ln -s /usr/share/clickhouse-test/config/readonly.xml /etc/clickhouse-server/users.d/; \ ln -s /usr/share/clickhouse-test/config/ints_dictionary.xml /etc/clickhouse-server/; \ diff --git a/libs/libloggers/loggers/OwnSplitChannel.cpp b/libs/libloggers/loggers/OwnSplitChannel.cpp index c9f8f5e8bb5..926cf06d09a 100644 --- a/libs/libloggers/loggers/OwnSplitChannel.cpp +++ b/libs/libloggers/loggers/OwnSplitChannel.cpp @@ -63,7 +63,7 @@ void OwnSplitChannel::log(const Poco::Message & msg) elem.thread_name = getThreadName(); elem.thread_number = msg_ext.thread_number; - elem.os_thread_id = msg.getOsTid(); + elem.os_thread_id = CurrentThread::get().os_thread_id; elem.query_id = msg_ext.query_id; From b0ee2a4ce07a1bcd32a93ca405d8b6bd9b38736b Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Tue, 23 Jul 2019 12:10:00 +0300 Subject: [PATCH 0254/1165] system flush logs added --- .../0_stateless/00974_text_log_table_not_empty.reference | 2 +- .../queries/0_stateless/00974_text_log_table_not_empty.sql | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference index 56a6051ca2b..d00491fd7e5 100644 --- a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference +++ b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference @@ -1 +1 @@ -1 \ No newline at end of file +1 diff --git a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql index 26bf82d62a5..9097dea4897 100644 --- a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql +++ b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql @@ -1,2 +1,4 @@ SELECT count() > 0 -FROM system.text_log \ No newline at end of file +FROM system.text_log + +SYSTEM FLUSH LOGS From 0d484869f8ae3d760c028bc33c7c344272709486 Mon Sep 17 00:00:00 2001 From: Ivan Lezhankin Date: Mon, 22 Jul 2019 17:14:01 +0300 Subject: [PATCH 0255/1165] Fix build --- contrib/librdkafka-cmake/config.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/librdkafka-cmake/config.h b/contrib/librdkafka-cmake/config.h index c8043f8b7dd..22244cd6e06 100644 --- a/contrib/librdkafka-cmake/config.h +++ b/contrib/librdkafka-cmake/config.h @@ -16,7 +16,7 @@ #define MKL_APP_NAME "librdkafka" #define MKL_APP_DESC_ONELINE "The Apache Kafka C/C++ library" // distro -//#define SOLIB_EXT ".so" +#define SOLIB_EXT ".so" // gcc //#define WITH_GCC 1 // gxx @@ -48,9 +48,9 @@ // parseversion #define MKL_APP_VERSION "0.11.4" // libdl -//#define WITH_LIBDL 1 +#define WITH_LIBDL 1 // WITH_PLUGINS -//#define WITH_PLUGINS 1 +#define WITH_PLUGINS 1 // zlib #define WITH_ZLIB 1 // zstd From 8e8ebf9c441d8408c7698d5e1a6fb1fa1572e48d Mon Sep 17 00:00:00 2001 From: proller Date: Tue, 23 Jul 2019 12:32:08 +0300 Subject: [PATCH 0256/1165] Try fix -Wsign-compare --- contrib/libunwind | 2 +- dbms/src/IO/ReadBufferAIO.cpp | 5 +---- dbms/src/IO/WriteBufferAIO.cpp | 5 +---- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/contrib/libunwind b/contrib/libunwind index 17a48fbfa79..ec86b1c6a2c 160000 --- a/contrib/libunwind +++ b/contrib/libunwind @@ -1 +1 @@ -Subproject commit 17a48fbfa7913ee889960a698516bd3ba51d63ee +Subproject commit ec86b1c6a2c6b8ba316f429db9a6d4122dd12710 diff --git a/dbms/src/IO/ReadBufferAIO.cpp b/dbms/src/IO/ReadBufferAIO.cpp index eccebf854f0..50845330587 100644 --- a/dbms/src/IO/ReadBufferAIO.cpp +++ b/dbms/src/IO/ReadBufferAIO.cpp @@ -254,12 +254,9 @@ void ReadBufferAIO::prepare() /// Region of the disk from which we want to read data. const off_t region_begin = first_unread_pos_in_file; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wsign-compare" - if ((requested_byte_count > std::numeric_limits::max()) || + if ((requested_byte_count > static_cast(std::numeric_limits::max())) || (first_unread_pos_in_file > (std::numeric_limits::max() - static_cast(requested_byte_count)))) throw Exception("An overflow occurred during file operation", ErrorCodes::LOGICAL_ERROR); -#pragma GCC diagnostic pop const off_t region_end = first_unread_pos_in_file + requested_byte_count; diff --git a/dbms/src/IO/WriteBufferAIO.cpp b/dbms/src/IO/WriteBufferAIO.cpp index dcceff96d02..a558768c64a 100644 --- a/dbms/src/IO/WriteBufferAIO.cpp +++ b/dbms/src/IO/WriteBufferAIO.cpp @@ -274,12 +274,9 @@ void WriteBufferAIO::prepare() /// Region of the disk in which we want to write data. const off_t region_begin = pos_in_file; -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wsign-compare" - if ((flush_buffer.offset() > std::numeric_limits::max()) || + if ((flush_buffer.offset() > static_cast(std::numeric_limits::max())) || (pos_in_file > (std::numeric_limits::max() - static_cast(flush_buffer.offset())))) throw Exception("An overflow occurred during file operation", ErrorCodes::LOGICAL_ERROR); -#pragma GCC diagnostic pop const off_t region_end = pos_in_file + flush_buffer.offset(); const size_t region_size = region_end - region_begin; From 2da5b3e6c2cfb4d30592f70157a6cd19ce9ece80 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Tue, 23 Jul 2019 12:32:47 +0300 Subject: [PATCH 0257/1165] DOCAPI-7553: Clarifications. --- docs/en/query_language/misc.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/query_language/misc.md b/docs/en/query_language/misc.md index 964b847e4fe..c3e7e598547 100644 --- a/docs/en/query_language/misc.md +++ b/docs/en/query_language/misc.md @@ -32,12 +32,12 @@ The query response contains the `result` column with a single row. The row has a - 0 - The data in the table is corrupted. - 1 - The data maintains integrity. -The `CHECK TABLE` query works for the following table engines: +The `CHECK TABLE` query supports the following table engines: - [Log](../operations/table_engines/log.md) - [TinyLog](../operations/table_engines/tinylog.md) - [StripeLog](../operations/table_engines/stripelog.md) -- [MergeTree](../operations/table_engines/mergetree.md) +- [MergeTree family](../operations/table_engines/mergetree.md) The `*Log` engines do not provide automatic data recovery on failure. Use the `CHECK TABLE` query to track data loss in a timely manner. From 6ff1dce79a3851ac5ad151966d70f219dea62c13 Mon Sep 17 00:00:00 2001 From: alesapin Date: Tue, 23 Jul 2019 12:46:54 +0300 Subject: [PATCH 0258/1165] Backquote key in debsign --- utils/release/push_packages | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/release/push_packages b/utils/release/push_packages index d432136a5bd..c2ab47b6e85 100755 --- a/utils/release/push_packages +++ b/utils/release/push_packages @@ -107,7 +107,7 @@ class SSHConnection(object): def debsign(path, gpg_passphrase, gpg_sec_key_path, gpg_pub_key_path, gpg_user): try: with GpgKey(gpg_sec_key_path, gpg_pub_key_path): - cmd = ('debsign -k {key} -p"gpg --verbose --no-use-agent --batch ' + cmd = ('debsign -k \'{key}\' -p"gpg --verbose --no-use-agent --batch ' '--no-tty --passphrase {passphrase}" {path}/*.changes').format( key=gpg_user, passphrase=gpg_passphrase, path=path) logging.info("Build debsign cmd '%s'", cmd) From bb1ddf67e15bb23dc3c94546147b5b856edf4ed6 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Tue, 23 Jul 2019 12:53:33 +0300 Subject: [PATCH 0259/1165] DOCAPI-6888: EN review and RU translation of the toDecimal*Or* funcions docs. (#5916) * Review of EN version. * DOCAPI-6888: RU translation of the toDecimal*Or* functions docs. --- .../functions/type_conversion_functions.md | 40 +++---- .../functions/type_conversion_functions.md | 111 ++++++++++++++++-- 2 files changed, 120 insertions(+), 31 deletions(-) diff --git a/docs/en/query_language/functions/type_conversion_functions.md b/docs/en/query_language/functions/type_conversion_functions.md index 2e1a07327a1..198925832d4 100644 --- a/docs/en/query_language/functions/type_conversion_functions.md +++ b/docs/en/query_language/functions/type_conversion_functions.md @@ -15,29 +15,29 @@ ## toDecimal32(value, S), toDecimal64(value, S), toDecimal128(value, S) -Converts `value` to [Decimal](../../data_types/decimal.md) of precision `S`. The `value` can be a number or a string. The `S` (scale) parameter specifies the number of decimal places. +Converts `value` to the [Decimal](../../data_types/decimal.md) data type with precision of `S`. The `value` can be a number or a string. The `S` (scale) parameter specifies the number of decimal places. ## toDecimal(32|64|128)OrNull -Converts an input string to the value of [Nullable(Decimal(P,S))](../../data_types/decimal.md) data type. This family of functions include: +Converts an input string to a [Nullable(Decimal(P,S))](../../data_types/decimal.md) data type value. This family of functions include: -- `toDecimal32OrNull(expr, S)` — Results with `Nullable(Decimal32(S))` data type. -- `toDecimal64OrNull(expr, S)` — Results with `Nullable(Decimal64(S))` data type. -- `toDecimal128OrNull(expr, S)` — Results with `Nullable(Decimal128(S))` data type. +- `toDecimal32OrNull(expr, S)` — Results in `Nullable(Decimal32(S))` data type. +- `toDecimal64OrNull(expr, S)` — Results in `Nullable(Decimal64(S))` data type. +- `toDecimal128OrNull(expr, S)` — Results in `Nullable(Decimal128(S))` data type. -These functions should be used instead of `toDecimal*()` functions, if you prefer to get the `NULL` value instead of exception, when input value parsing error. +These functions should be used instead of `toDecimal*()` functions, if you prefer to get a `NULL` value instead of an exception in the event of an input value parsing error. **Parameters** -- `expr` — [Expression](../syntax.md#syntax-expressions), returning a value of the [String](../../data_types/string.md) data type. ClickHouse expects the textual representation of the decimal number. For example, "1.111". +- `expr` — [Expression](../syntax.md#syntax-expressions), returns a value in the [String](../../data_types/string.md) data type. ClickHouse expects the textual representation of the decimal number. For example, `'1.111'`. - `S` — Scale, the number of decimal places in the resulting value. **Returned value** -The value of `Nullable(Decimal(P,S))` data type. `P` equals to numeric part of the function name. For example, for the `toDecimal32OrNull` function `P = 32`. The value contains: +A value in the `Nullable(Decimal(P,S))` data type. The value contains: -- Number with `S` decimal places, if ClickHouse could interpret input string as a number. -- `NULL`, if ClickHouse couldn't interpret input string as a number or if the input number contains more decimal places then `S`. +- Number with `S` decimal places, if ClickHouse interprets the input string as a number. +- `NULL`, if ClickHouse can't interpret the input string as a number or if the input number contains more than `S` decimal places. **Examples** @@ -63,23 +63,23 @@ SELECT toDecimal32OrNull(toString(-1.111), 2) AS val, toTypeName(val) Converts an input value to the [Decimal(P,S)](../../data_types/decimal.md) data type. This family of functions include: -- `toDecimal32OrZero( expr, S)` — Results with `Decimal32(S)` data type. -- `toDecimal64OrZero( expr, S)` — Results with `Decimal64(S)` data type. -- `toDecimal128OrZero( expr, S)` — Results with `Decimal128(S)` data type. +- `toDecimal32OrZero( expr, S)` — Results in `Decimal32(S)` data type. +- `toDecimal64OrZero( expr, S)` — Results in `Decimal64(S)` data type. +- `toDecimal128OrZero( expr, S)` — Results in `Decimal128(S)` data type. -These functions should be used instead of `toDecimal*()` functions, if you prefer to get the `0` value instead of exception, when input value parsing error. +These functions should be used instead of `toDecimal*()` functions, if you prefer to get a `0` value instead of an exception in the event of an input value parsing error. **Parameters** -- `expr` — [Expression](../syntax.md#syntax-expressions), returning a value of the [String](../../data_types/string.md) data type. ClickHouse expects the textual representation of the decimal number. For example, `'1.111'`. +- `expr` — [Expression](../syntax.md#syntax-expressions), returns a value in the [String](../../data_types/string.md) data type. ClickHouse expects the textual representation of the decimal number. For example, `'1.111'`. - `S` — Scale, the number of decimal places in the resulting value. **Returned value** -The value of `Nullable(Decimal(P,S))` data type. `P` equals to numeric part of the function name. For example, for the `toDecimal32OrZero` function `P = 32`. The value contains: +A value in the `Nullable(Decimal(P,S))` data type. The value contains: -- Number with `S` decimal places, if ClickHouse could interpret input string as a number. -- 0 with `S` decimal places, if ClickHouse couldn't interpret input string as a number or if the input number contains more decimal places then `S`. +- Number with `S` decimal places, if ClickHouse interprets the input string as a number. +- 0 with `S` decimal places, if ClickHouse can't interpret the input string as a number or if the input number contains more than `S` decimal places. **Example** @@ -139,10 +139,6 @@ SELECT Also see the `toUnixTimestamp` function. -## toDecimal32(value, S), toDecimal64(value, S), toDecimal128(value, S) - -Converts `value` to [Decimal](../../data_types/decimal.md) of precision `S`. The `value` can be a number or a string. The `S` (scale) parameter specifies the number of decimal places. - ## toFixedString(s, N) Converts a String type argument to a FixedString(N) type (a string with fixed length N). N must be a constant. diff --git a/docs/ru/query_language/functions/type_conversion_functions.md b/docs/ru/query_language/functions/type_conversion_functions.md index 498cb90ad98..5e25d767e08 100644 --- a/docs/ru/query_language/functions/type_conversion_functions.md +++ b/docs/ru/query_language/functions/type_conversion_functions.md @@ -1,4 +1,3 @@ - # Функции преобразования типов ## toUInt8, toUInt16, toUInt32, toUInt64 @@ -7,15 +6,106 @@ ## toFloat32, toFloat64 -## toUInt8OrZero, toUInt16OrZero, toUInt32OrZero, toUInt64OrZero, toInt8OrZero, toInt16OrZero, toInt32OrZero, toInt64OrZero, toFloat32OrZero, toFloat64OrZero - ## toDate, toDateTime +## toUInt8OrZero, toUInt16OrZero, toUInt32OrZero, toUInt64OrZero, toInt8OrZero, toInt16OrZero, toInt32OrZero, toInt64OrZero, toFloat32OrZero, toFloat64OrZero + +## toUInt8OrNull, toUInt16OrNull, toUInt32OrNull, toUInt64OrNull, toInt8OrNull, toInt16OrNull, toInt32OrNull, toInt64OrNull, toFloat32OrNull, toFloat64OrNull, toDateOrNull, toDateTimeOrNull + ## toDecimal32(value, S), toDecimal64(value, S), toDecimal128(value, S) -Приводит строку или число value к типу [Decimal](../../data_types/decimal.md) указанной точности. -Параметр S (scale) определяет число десятичных знаков после запятой. + +Преобразует тип `value` в тип [Decimal](../../data_types/decimal.md), имеющий точность `S`. `value` может быть числом или строкой. Параметр `S` (scale) устанавливает количество десятичных знаков. + +## toDecimal(32|64|128)OrNull + +Преобразует входную строку в значение с типом данных [Nullable (Decimal (P, S))](../../data_types/decimal.md). Семейство функций включает в себя: + +- `toDecimal32OrNull(expr, S)` — Возвращает значение типа `Nullable(Decimal32(S))`. +- `toDecimal64OrNull(expr, S)` — Возвращает значение типа `Nullable(Decimal64(S))`. +- `toDecimal128OrNull(expr, S)` — Возвращает значение типа `Nullable(Decimal128(S))`. + +Эти функции следует использовать вместо функций `toDecimal*()`, если при ошибке обработки входного значения вы хотите получать `NULL` вместо исключения. + +**Параметры** + +- `expr` — [выражение](../syntax.md#syntax-expressions), возвращающее значение типа [String](../../data_types/string.md). ClickHouse ожидает текстовое представление десятичного числа. Например, `'1.111'`. +- `S` — количество десятичных знаков в результирующем значении. + +**Возвращаемое значение** + +Значение типа `Nullable(Decimal(P,S))`. Значение содержит: + +- Число с `S` десятичными знаками, если ClickHouse распознал число во входной строке. +- `NULL`, если ClickHouse не смог распознать число во входной строке или входное число содержит больше чем `S` десятичных знаков. + +**Примеры** + +```sql +SELECT toDecimal32OrNull(toString(-1.111), 5) AS val, toTypeName(val) +``` + +```text +┌──────val─┬─toTypeName(toDecimal32OrNull(toString(-1.111), 5))─┐ +│ -1.11100 │ Nullable(Decimal(9, 5)) │ +└──────────┴────────────────────────────────────────────────────┘ +``` + +```sql +SELECT toDecimal32OrNull(toString(-1.111), 2) AS val, toTypeName(val) +``` + +```text +┌──val─┬─toTypeName(toDecimal32OrNull(toString(-1.111), 2))─┐ +│ ᴺᵁᴸᴸ │ Nullable(Decimal(9, 2)) │ +└──────┴────────────────────────────────────────────────────┘ +``` + +## toDecimal(32|64|128)OrZero + +Преобразует тип входного значения в [Decimal (P, S)](../../data_types/decimal.md). Семейство функций включает в себя: + +- `toDecimal32OrZero( expr, S)` — возвращает значение типа `Decimal32(S)`. +- `toDecimal64OrZero( expr, S)` — возвращает значение типа `Decimal64(S)`. +- `toDecimal128OrZero( expr, S)` — возвращает значение типа `Decimal128(S)`. + +Эти функции следует использовать вместо функций `toDecimal*()`, если при ошибке обработки входного значения вы хотите получать `0` вместо исключения. + +**Параметры** + +- `expr` — [выражение](../syntax.md#syntax-expressions), возвращающее значение типа [String](../../data_types/string.md). ClickHouse ожидает текстовое представление десятичного числа. Например, `'1.111'`. +- `S` — количество десятичных знаков в результирующем значении. + +**Возвращаемое значение** + +Значение типа `Nullable(Decimal(P,S))`. `P` равно числовой части имени функции. Например, для функции `toDecimal32OrZero`, `P = 32`. Значение содержит: + +- Число с `S` десятичными знаками, если ClickHouse распознал число во входной строке. +- 0 c `S` десятичными знаками, если ClickHouse не смог распознать число во входной строке или входное число содержит больше чем `S` десятичных знаков. + +**Пример** + +```sql +SELECT toDecimal32OrZero(toString(-1.111), 5) AS val, toTypeName(val) +``` + +```text +┌──────val─┬─toTypeName(toDecimal32OrZero(toString(-1.111), 5))─┐ +│ -1.11100 │ Decimal(9, 5) │ +└──────────┴────────────────────────────────────────────────────┘ +``` + +```sql +SELECT toDecimal32OrZero(toString(-1.111), 2) AS val, toTypeName(val) +``` + +```text +┌──val─┬─toTypeName(toDecimal32OrZero(toString(-1.111), 2))─┐ +│ 0.00 │ Decimal(9, 2) │ +└──────┴────────────────────────────────────────────────────┘ +``` ## toString + Функции преобразования между числами, строками (но не фиксированными строками), датами и датами-с-временем. Все эти функции принимают один аргумент. @@ -39,7 +129,7 @@ YYYY-MM-DD hh:mm:ss Дополнительно, функция toString от аргумента типа DateTime может принимать второй аргумент String - имя тайм-зоны. Пример: `Asia/Yekaterinburg` В этом случае, форматирование времени производится согласно указанной тайм-зоне. -``` sql +```sql SELECT now() AS now_local, toString(now(), 'Asia/Yekaterinburg') AS now_yekat @@ -54,15 +144,17 @@ SELECT Также смотрите функцию `toUnixTimestamp`. ## toFixedString(s, N) + Преобразует аргумент типа String в тип FixedString(N) (строку фиксированной длины N). N должно быть константой. Если строка имеет меньше байт, чем N, то она дополняется нулевыми байтами справа. Если строка имеет больше байт, чем N - кидается исключение. ## toStringCutToZero(s) + Принимает аргумент типа String или FixedString. Возвращает String, вырезая содержимое строки до первого найденного нулевого байта. Пример: -``` sql +```sql SELECT toFixedString('foo', 8) AS s, toStringCutToZero(s) AS s_cut ``` @@ -72,7 +164,7 @@ SELECT toFixedString('foo', 8) AS s, toStringCutToZero(s) AS s_cut └───────────────┴───────┘ ``` -``` sql +```sql SELECT toFixedString('foo\0bar', 8) AS s, toStringCutToZero(s) AS s_cut ``` @@ -89,6 +181,7 @@ SELECT toFixedString('foo\0bar', 8) AS s, toStringCutToZero(s) AS s_cut ## reinterpretAsFloat32, reinterpretAsFloat64 ## reinterpretAsDate, reinterpretAsDateTime + Функции принимают строку и интерпретируют байты, расположенные в начале строки, как число в host order (little endian). Если строка имеет недостаточную длину, то функции работают так, как будто строка дополнена необходимым количеством нулевых байт. Если строка длиннее, чем нужно, то лишние байты игнорируются. Дата интерпретируется, как число дней с начала unix-эпохи, а дата-с-временем - как число секунд с начала unix-эпохи. ## reinterpretAsString @@ -100,7 +193,7 @@ SELECT toFixedString('foo\0bar', 8) AS s, toStringCutToZero(s) AS s_cut Пример: -``` sql +```sql SELECT '2016-06-15 23:00:00' AS timestamp, CAST(timestamp AS DateTime) AS datetime, From cb882d61bbedb82be186a08117d942b3564d61bb Mon Sep 17 00:00:00 2001 From: proller Date: Tue, 23 Jul 2019 12:54:15 +0300 Subject: [PATCH 0260/1165] Freebsd fix --- dbms/src/Common/QueryProfiler.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index 9832b64ee8b..aedab2a9eff 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -78,7 +78,13 @@ QueryProfilerBase::QueryProfilerBase(const Int32 thread_id, const struct sigevent sev; sev.sigev_notify = SIGEV_THREAD_ID; sev.sigev_signo = pause_signal; + +#if defined(__FreeBSD__) + sev._sigev_un._threadid = thread_id; +#else sev._sigev_un._tid = thread_id; +#endif + if (timer_create(clock_type, &sev, &timer_id)) throwFromErrno("Failed to create thread timer", ErrorCodes::CANNOT_CREATE_TIMER); From 4b690d752b19ffa2f64da8b20708bf5ea1099d0e Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Tue, 23 Jul 2019 13:01:18 +0300 Subject: [PATCH 0261/1165] Replace YouTube link with human-readable one https://www.youtube.com/c/ClickHouseDB --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3de9abdc333..25dccdf16e4 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ClickHouse is an open-source column-oriented database management system that all * [Official website](https://clickhouse.yandex/) has quick high-level overview of ClickHouse on main page. * [Tutorial](https://clickhouse.yandex/tutorial.html) shows how to set up and query small ClickHouse cluster. * [Documentation](https://clickhouse.yandex/docs/en/) provides more in-depth information. -* [YouTube channel](https://www.youtube.com/channel/UChtmrD-dsdpspr42P_PyRAw) has a lot of content about ClickHouse in video format. +* [YouTube channel](https://www.youtube.com/c/ClickHouseDB) has a lot of content about ClickHouse in video format. * [Blog](https://clickhouse.yandex/blog/en/) contains various ClickHouse-related articles, as well as announces and reports about events. * [Contacts](https://clickhouse.yandex/#contacts) can help to get your questions answered if there are any. * You can also [fill this form](https://forms.yandex.com/surveys/meet-yandex-clickhouse-team/) to meet Yandex ClickHouse team in person. From aee4497ada134b77893dcfc0225e723992c2a455 Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Tue, 23 Jul 2019 13:02:19 +0300 Subject: [PATCH 0262/1165] Replace YouTube link with human-readable one https://www.youtube.com/c/ClickHouseDB --- website/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/index.html b/website/index.html index 9b799638c26..57d67fc0f3b 100644 --- a/website/index.html +++ b/website/index.html @@ -444,7 +444,7 @@ clickhouse-client rel="external nofollow" target="_blank">English or in Russian. -
  • Watch video content on Watch video content on YouTube channel.
  • Follow official Date: Tue, 23 Jul 2019 13:04:26 +0300 Subject: [PATCH 0263/1165] Added test with LowCardinality(Nullable) to not-Nullable cast. --- .../0_stateless/00974_low_cardinality_cast.reference | 4 ++++ .../queries/0_stateless/00974_low_cardinality_cast.sql | 6 ++++++ 2 files changed, 10 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00974_low_cardinality_cast.reference create mode 100644 dbms/tests/queries/0_stateless/00974_low_cardinality_cast.sql diff --git a/dbms/tests/queries/0_stateless/00974_low_cardinality_cast.reference b/dbms/tests/queries/0_stateless/00974_low_cardinality_cast.reference new file mode 100644 index 00000000000..5c576f5dee6 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_low_cardinality_cast.reference @@ -0,0 +1,4 @@ +Hello +\N +Hello +Hello diff --git a/dbms/tests/queries/0_stateless/00974_low_cardinality_cast.sql b/dbms/tests/queries/0_stateless/00974_low_cardinality_cast.sql new file mode 100644 index 00000000000..e369a8c169e --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_low_cardinality_cast.sql @@ -0,0 +1,6 @@ +SELECT CAST('Hello' AS LowCardinality(Nullable(String))); +SELECT CAST(Null AS LowCardinality(Nullable(String))); +SELECT CAST(CAST('Hello' AS LowCardinality(Nullable(String))) AS String); +SELECT CAST(CAST(Null AS LowCardinality(Nullable(String))) AS String); -- { serverError 349 } +SELECT CAST(CAST('Hello' AS Nullable(String)) AS String); +SELECT CAST(CAST(Null AS Nullable(String)) AS String); -- { serverError 349 } From cab6307e247e9074376e8c072782822b97ff3231 Mon Sep 17 00:00:00 2001 From: Ivan Lezhankin Date: Tue, 23 Jul 2019 13:07:40 +0300 Subject: [PATCH 0264/1165] Fix build --- contrib/librdkafka-cmake/config.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/librdkafka-cmake/config.h b/contrib/librdkafka-cmake/config.h index 22244cd6e06..78b9bc613c3 100644 --- a/contrib/librdkafka-cmake/config.h +++ b/contrib/librdkafka-cmake/config.h @@ -63,6 +63,8 @@ #define WITH_SSL 1 // WITH_SASL_SCRAM #define WITH_SASL_SCRAM 1 +// WITH_SASL_OAUTHBEARER +#define WITH_SASL_OAUTHBEARER 1 // crc32chw #if !defined(__PPC__) #define WITH_CRC32C_HW 1 From b01f54ade1af9627aa09628851950cd45a70b9a4 Mon Sep 17 00:00:00 2001 From: tai Date: Tue, 23 Jul 2019 14:18:44 +0800 Subject: [PATCH 0265/1165] ISSUE-5695: support push down predicate to final subquery --- dbms/src/Core/Settings.h | 3 +- .../PredicateExpressionsOptimizer.cpp | 5 +- .../PredicateExpressionsOptimizer.h | 4 ++ .../00974_final_predicate_push_down.reference | 50 +++++++++++++++++++ .../00974_final_predicate_push_down.sql | 17 +++++++ 5 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00974_final_predicate_push_down.reference create mode 100644 dbms/tests/queries/0_stateless/00974_final_predicate_push_down.sql diff --git a/dbms/src/Core/Settings.h b/dbms/src/Core/Settings.h index 4df07df60f6..e55e58e9d28 100644 --- a/dbms/src/Core/Settings.h +++ b/dbms/src/Core/Settings.h @@ -336,7 +336,8 @@ struct Settings : public SettingsCollection \ /** Obsolete settings that do nothing but left for compatibility reasons. Remove each one after half a year of obsolescence. */ \ \ - M(SettingBool, allow_experimental_low_cardinality_type, true, "Obsolete setting, does nothing. Will be removed after 2019-08-13") + M(SettingBool, allow_experimental_low_cardinality_type, true, "Obsolete setting, does nothing. Will be removed after 2019-08-13") \ + M(SettingBool, allow_push_predicate_to_final_subquery, 1, "Allow push predicate to final subquery.") DECLARE_SETTINGS_COLLECTION(LIST_OF_SETTINGS) diff --git a/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp b/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp index b6e6545e475..5e0d11212dc 100644 --- a/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp +++ b/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp @@ -138,7 +138,10 @@ bool PredicateExpressionsOptimizer::allowPushDown( const std::vector & dependencies, OptimizeKind & optimize_kind) { - if (!subquery || subquery->final() || subquery->limitBy() || subquery->limitLength() || subquery->with()) + if (!subquery || + (!settings.allow_push_predicate_to_final_subquery && subquery->final()) || + subquery->limitBy() || subquery->limitLength() || + subquery->with()) return false; else { diff --git a/dbms/src/Interpreters/PredicateExpressionsOptimizer.h b/dbms/src/Interpreters/PredicateExpressionsOptimizer.h index b7e3cd430fc..89d2bfcfbf0 100644 --- a/dbms/src/Interpreters/PredicateExpressionsOptimizer.h +++ b/dbms/src/Interpreters/PredicateExpressionsOptimizer.h @@ -37,6 +37,9 @@ class PredicateExpressionsOptimizer const UInt64 max_expanded_ast_elements; const String count_distinct_implementation; + /// for final PredicatePushOptimizer + const bool allow_push_predicate_to_final_subquery; + /// for PredicateExpressionsOptimizer const bool enable_optimize_predicate_expression; const bool join_use_nulls; @@ -46,6 +49,7 @@ class PredicateExpressionsOptimizer : max_ast_depth(settings.max_ast_depth), max_expanded_ast_elements(settings.max_expanded_ast_elements), count_distinct_implementation(settings.count_distinct_implementation), + allow_push_predicate_to_final_subquery(settings.allow_push_predicate_to_final_subquery), enable_optimize_predicate_expression(settings.enable_optimize_predicate_expression), join_use_nulls(settings.join_use_nulls) {} diff --git a/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.reference b/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.reference new file mode 100644 index 00000000000..55b5763f76b --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.reference @@ -0,0 +1,50 @@ +{ + "meta": + [ + { + "name": "COUNT()", + "type": "UInt64" + } + ], + + "data": + [ + { + "COUNT()": "1" + } + ], + + "rows": 1, + + "statistics": + { + "elapsed": 0.000780393, + "rows_read": 4, + "bytes_read": 16 + } +} +{ + "meta": + [ + { + "name": "COUNT()", + "type": "UInt64" + } + ], + + "data": + [ + { + "COUNT()": "1" + } + ], + + "rows": 1, + + "statistics": + { + "elapsed": 0.000687364, + "rows_read": 2, + "bytes_read": 8 + } +} diff --git a/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.sql b/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.sql new file mode 100644 index 00000000000..76b39b09acb --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.sql @@ -0,0 +1,17 @@ +DROP TABLE IF EXISTS test_00974; + +CREATE TABLE test_00974 +( + date Date, + x Int32, + ver UInt64 +) +ENGINE = ReplacingMergeTree(date, x, 4096); + +INSERT INTO test_00974 VALUES ('2019-07-23', 1, 1), ('2019-07-23', 1, 2); +INSERT INTO test_00974 VALUES ('2019-07-23', 2, 1), ('2019-07-23', 2, 2); + +SELECT COUNT() FROM (SELECT * FROM test_00974 FINAL) where x = 1 SETTINGS allow_push_predicate_to_final_subquery = 0 FORMAT JSON ; +SELECT COUNT() FROM (SELECT * FROM test_00974 FINAL) where x = 1 SETTINGS allow_push_predicate_to_final_subquery = 1 FORMAT JSON ; + +DROP TABLE test_00974; From aef0e2c0a387e26645fca340e6ec7fc332562149 Mon Sep 17 00:00:00 2001 From: Alex Krash Date: Tue, 23 Jul 2019 13:32:32 +0300 Subject: [PATCH 0266/1165] Document "WITH" section for SELECT (#5894) --- docs/en/query_language/select.md | 94 +++++++++++++++++++++++++++----- docs/ru/query_language/select.md | 92 ++++++++++++++++++++++++++----- 2 files changed, 158 insertions(+), 28 deletions(-) diff --git a/docs/en/query_language/select.md b/docs/en/query_language/select.md index b2d17bed674..bf0cf060a1a 100644 --- a/docs/en/query_language/select.md +++ b/docs/en/query_language/select.md @@ -3,21 +3,22 @@ `SELECT` performs data retrieval. ``` sql +[WITH expr_list|(subquery)] SELECT [DISTINCT] expr_list - [FROM [db.]table | (subquery) | table_function] [FINAL] - [SAMPLE sample_coeff] - [ARRAY JOIN ...] - [GLOBAL] [ANY|ALL] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER] JOIN (subquery)|table USING columns_list - [PREWHERE expr] - [WHERE expr] - [GROUP BY expr_list] [WITH TOTALS] - [HAVING expr] - [ORDER BY expr_list] - [LIMIT [n, ]m] - [UNION ALL ...] - [INTO OUTFILE filename] - [FORMAT format] - [LIMIT [offset_value, ]n BY columns] +[FROM [db.]table | (subquery) | table_function] [FINAL] +[SAMPLE sample_coeff] +[ARRAY JOIN ...] +[GLOBAL] [ANY|ALL] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER] JOIN (subquery)|table USING columns_list +[PREWHERE expr] +[WHERE expr] +[GROUP BY expr_list] [WITH TOTALS] +[HAVING expr] +[ORDER BY expr_list] +[LIMIT [n, ]m] +[UNION ALL ...] +[INTO OUTFILE filename] +[FORMAT format] +[LIMIT [offset_value, ]n BY columns] ``` All the clauses are optional, except for the required list of expressions immediately after SELECT. @@ -26,6 +27,71 @@ The clauses below are described in almost the same order as in the query executi If the query omits the `DISTINCT`, `GROUP BY` and `ORDER BY` clauses and the `IN` and `JOIN` subqueries, the query will be completely stream processed, using O(1) amount of RAM. Otherwise, the query might consume a lot of RAM if the appropriate restrictions are not specified: `max_memory_usage`, `max_rows_to_group_by`, `max_rows_to_sort`, `max_rows_in_distinct`, `max_bytes_in_distinct`, `max_rows_in_set`, `max_bytes_in_set`, `max_rows_in_join`, `max_bytes_in_join`, `max_bytes_before_external_sort`, `max_bytes_before_external_group_by`. For more information, see the section "Settings". It is possible to use external sorting (saving temporary tables to a disk) and external aggregation. `The system does not have "merge join"`. +### WITH Clause +This section provides support for Common Table Expressions ([CTE](https://en.wikipedia.org/wiki/Hierarchical_and_recursive_queries_in_SQL)), with some limitations: +1. Recursive queries are not supported +2. When subquery is used inside WITH section, it's result should be scalar with exactly one row +3. Expression's results are not available in subqueries +Results of WITH clause expressions can be used inside SELECT clause. + +Example 1: Using constant expression as "variable" +``` +WITH '2019-08-01 15:23:00' as ts_upper_bound +SELECT * +FROM hits +WHERE + EventDate = toDate(ts_upper_bound) AND + EventTime <= ts_upper_bound +``` + +Example 2: Evicting sum(bytes) expression result from SELECT clause column list +``` +WITH sum(bytes) as s +SELECT + formatReadableSize(s), + table +FROM system.parts +GROUP BY table +ORDER BY s +``` + +Example 3: Using results of scalar subquery +``` +/* this example would return TOP 10 of most huge tables */ +WITH + ( + SELECT sum(bytes) + FROM system.parts + WHERE active + ) AS total_disk_usage +SELECT + (sum(bytes) / total_disk_usage) * 100 AS table_disk_usage, + table +FROM system.parts +GROUP BY table +ORDER BY table_disk_usage DESC +LIMIT 10 +``` + +Example 4: Re-using expression in subquery +As a workaround for current limitation for expression usage in subqueries, you may duplicate it. +``` +WITH ['hello'] AS hello +SELECT + hello, + * +FROM +( + WITH ['hello'] AS hello + SELECT hello +) + +┌─hello─────┬─hello─────┐ +│ ['hello'] │ ['hello'] │ +└───────────┴───────────┘ +``` + + ### FROM Clause If the FROM clause is omitted, data will be read from the `system.one` table. diff --git a/docs/ru/query_language/select.md b/docs/ru/query_language/select.md index 614c56ee44e..6aa3f1e145b 100644 --- a/docs/ru/query_language/select.md +++ b/docs/ru/query_language/select.md @@ -3,21 +3,22 @@ `SELECT` осуществляет выборку данных. ```sql +[WITH expr_list|(subquery)] SELECT [DISTINCT] expr_list - [FROM [db.]table | (subquery) | table_function] [FINAL] - [SAMPLE sample_coeff] - [ARRAY JOIN ...] - [GLOBAL] [ANY|ALL] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER] JOIN (subquery)|table USING columns_list - [PREWHERE expr] - [WHERE expr] - [GROUP BY expr_list] [WITH TOTALS] - [HAVING expr] - [ORDER BY expr_list] - [LIMIT [n, ]m] - [UNION ALL ...] - [INTO OUTFILE filename] - [FORMAT format] - [LIMIT [offset_value, ]n BY columns] +[FROM [db.]table | (subquery) | table_function] [FINAL] +[SAMPLE sample_coeff] +[ARRAY JOIN ...] +[GLOBAL] [ANY|ALL] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER] JOIN (subquery)|table USING columns_list +[PREWHERE expr] +[WHERE expr] +[GROUP BY expr_list] [WITH TOTALS] +[HAVING expr] +[ORDER BY expr_list] +[LIMIT [n, ]m] +[UNION ALL ...] +[INTO OUTFILE filename] +[FORMAT format] +[LIMIT [offset_value, ]n BY columns] ``` Все секции, кроме списка выражений сразу после SELECT, являются необязательными. @@ -26,6 +27,69 @@ SELECT [DISTINCT] expr_list Если в запросе отсутствуют секции `DISTINCT`, `GROUP BY`, `ORDER BY`, подзапросы в `IN` и `JOIN`, то запрос будет обработан полностью потоково, с использованием O(1) количества оперативки. Иначе запрос может съесть много оперативки, если не указаны подходящие ограничения `max_memory_usage`, `max_rows_to_group_by`, `max_rows_to_sort`, `max_rows_in_distinct`, `max_bytes_in_distinct`, `max_rows_in_set`, `max_bytes_in_set`, `max_rows_in_join`, `max_bytes_in_join`, `max_bytes_before_external_sort`, `max_bytes_before_external_group_by`. Подробнее смотрите в разделе "Настройки". Присутствует возможность использовать внешнюю сортировку (с сохранением временных данных на диск) и внешнюю агрегацию. `Merge join` в системе нет. +### Секция WITH +Данная секция представляет собой [CTE](https://ru.wikipedia.org/wiki/Иерархические_и_рекурсивные_запросы_в_SQL), с рядом ограничений: +1. Рекурсивные запросы не поддерживаются +2. Если в качестве выражения используется подзапрос, то результат должен содержать ровно одну строку +3. Результаты выражений нельзя переиспользовать во вложенных запросах +В дальнейшем, результаты выражений можно использовать в секции SELECT. + +Пример 1: Использование константного выражения как "переменной" +``` +WITH '2019-08-01 15:23:00' as ts_upper_bound +SELECT * +FROM hits +WHERE + EventDate = toDate(ts_upper_bound) AND + EventTime <= ts_upper_bound +``` + +Пример 2: Выкидывание выражения sum(bytes) из списка колонок в SELECT +``` +WITH sum(bytes) as s +SELECT + formatReadableSize(s), + table +FROM system.parts +GROUP BY table +ORDER BY s +``` + +Пример 3: Использование результатов скалярного подзапроса +``` +/* запрос покажет TOP 10 самых больших таблиц */ +WITH + ( + SELECT sum(bytes) + FROM system.parts + WHERE active + ) AS total_disk_usage +SELECT + (sum(bytes) / total_disk_usage) * 100 AS table_disk_usage, + table +FROM system.parts +GROUP BY table +ORDER BY table_disk_usage DESC +LIMIT 10 +``` + +Пример 4: Переиспользование выражения +В настоящий момент, переиспользование выражения из секции WITH внутри подзапроса возможно только через дублирование. +``` +WITH ['hello'] AS hello +SELECT + hello, + * +FROM +( + WITH ['hello'] AS hello + SELECT hello +) + +┌─hello─────┬─hello─────┐ +│ ['hello'] │ ['hello'] │ +└───────────┴───────────┘ +``` ### Секция FROM From 35b57699b0382e0c0bd7371399651db857cc3f35 Mon Sep 17 00:00:00 2001 From: Alexander Tokmakov Date: Tue, 23 Jul 2019 02:19:32 +0300 Subject: [PATCH 0267/1165] better error message --- dbms/src/DataTypes/DataTypeNullable.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/dbms/src/DataTypes/DataTypeNullable.cpp b/dbms/src/DataTypes/DataTypeNullable.cpp index fbeb115b787..44df56b3d3a 100644 --- a/dbms/src/DataTypes/DataTypeNullable.cpp +++ b/dbms/src/DataTypes/DataTypeNullable.cpp @@ -314,12 +314,26 @@ void DataTypeNullable::deserializeTextCSV(IColumn & column, ReadBuffer & istr, c ConcatReadBuffer buf(prepend, istr); nested_data_type->deserializeAsTextCSV(nested, buf, settings); - /// Check if all extracted characters was read by nested parser and update buffer position + /// Check if all extracted characters were read by nested parser and update buffer position if (null_prefix_len < buf.count()) istr.position() = buf.position(); else if (null_prefix_len > buf.count()) - throw DB::Exception("Some characters were extracted from buffer, but nested parser did not read them", - ErrorCodes::LOGICAL_ERROR); + { + /// It can happen only if there is an unquoted string instead of a number + /// or if someone uses 'U' or 'L' as delimiter in CSV. + /// In the first case we cannot continue reading anyway. The second case seems to be unlikely. + if (settings.csv.delimiter == 'U' || settings.csv.delimiter == 'L') + throw DB::Exception("Enabled setting input_format_csv_unquoted_null_literal_as_null may not work correctly " + "with format_csv_delimiter = 'U' or 'L' for large input.", ErrorCodes::CANNOT_READ_ALL_DATA); + WriteBufferFromOwnString parsed_value; + nested_data_type->serializeAsTextCSV(nested, nested.size() - 1, parsed_value, settings); + throw DB::Exception("Error while parsing \"" + std::string(null_literal, null_prefix_len) + + std::string(istr.position(), std::min(size_t{10}, istr.available())) + "\" as " + getName() + + " at position " + std::to_string(istr.count()) + ": expected \"NULL\" or " + nested_data_type->getName() + + ", got \"" + std::string(null_literal, buf.count()) + "\", which was deserialized as \"" + + parsed_value.str() + "\". It seems that input data is ill-formatted.", + ErrorCodes::CANNOT_READ_ALL_DATA); + } } }; From 23dba8d025004bba4bf1740a029625a644f83fbf Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Tue, 23 Jul 2019 13:50:43 +0300 Subject: [PATCH 0268/1165] better test --- .../0_stateless/00974_text_log_table_not_empty.reference | 1 + .../0_stateless/00974_text_log_table_not_empty.sql | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference index d00491fd7e5..6ed281c757a 100644 --- a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference +++ b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference @@ -1 +1,2 @@ 1 +1 diff --git a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql index 9097dea4897..c6f1f536a53 100644 --- a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql +++ b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql @@ -1,4 +1,6 @@ -SELECT count() > 0 -FROM system.text_log +SELECT 1; -SYSTEM FLUSH LOGS +SYSTEM FLUSH LOGS; + +SELECT count() > 0 +FROM system.text_log; From 24725b62a8f552da81a9936732b16d63e939ff71 Mon Sep 17 00:00:00 2001 From: proller Date: Tue, 23 Jul 2019 14:03:35 +0300 Subject: [PATCH 0269/1165] Add missing libs --- contrib/brotli-cmake/CMakeLists.txt | 1 + contrib/double-conversion-cmake/CMakeLists.txt | 1 - contrib/h3-cmake/CMakeLists.txt | 1 + contrib/librdkafka-cmake/CMakeLists.txt | 4 ++-- contrib/libunwind-cmake/CMakeLists.txt | 1 + contrib/libxml2-cmake/CMakeLists.txt | 2 +- contrib/mariadb-connector-c-cmake/CMakeLists.txt | 2 ++ contrib/unixodbc-cmake/CMakeLists.txt | 1 + 8 files changed, 9 insertions(+), 4 deletions(-) diff --git a/contrib/brotli-cmake/CMakeLists.txt b/contrib/brotli-cmake/CMakeLists.txt index 00fea50fc43..9bc6d3d89e7 100644 --- a/contrib/brotli-cmake/CMakeLists.txt +++ b/contrib/brotli-cmake/CMakeLists.txt @@ -31,3 +31,4 @@ set(SRCS add_library(brotli ${SRCS}) target_include_directories(brotli PUBLIC ${BROTLI_SOURCE_DIR}/include) +target_link_libraries(brotli PRIVATE m) diff --git a/contrib/double-conversion-cmake/CMakeLists.txt b/contrib/double-conversion-cmake/CMakeLists.txt index f91b0fb74c1..8b808b8de9a 100644 --- a/contrib/double-conversion-cmake/CMakeLists.txt +++ b/contrib/double-conversion-cmake/CMakeLists.txt @@ -11,4 +11,3 @@ ${LIBRARY_DIR}/double-conversion/fixed-dtoa.cc ${LIBRARY_DIR}/double-conversion/strtod.cc) target_include_directories(double-conversion SYSTEM PUBLIC "${LIBRARY_DIR}") - diff --git a/contrib/h3-cmake/CMakeLists.txt b/contrib/h3-cmake/CMakeLists.txt index 5df0a205a34..951e5e83bdc 100644 --- a/contrib/h3-cmake/CMakeLists.txt +++ b/contrib/h3-cmake/CMakeLists.txt @@ -25,3 +25,4 @@ add_library(h3 ${SRCS}) target_include_directories(h3 SYSTEM PUBLIC ${H3_SOURCE_DIR}/include) target_include_directories(h3 SYSTEM PUBLIC ${H3_BINARY_DIR}/include) target_compile_definitions(h3 PRIVATE H3_HAVE_VLA) +target_link_libraries(h3 PRIVATE m) diff --git a/contrib/librdkafka-cmake/CMakeLists.txt b/contrib/librdkafka-cmake/CMakeLists.txt index 54149d0db6f..d060994ef05 100644 --- a/contrib/librdkafka-cmake/CMakeLists.txt +++ b/contrib/librdkafka-cmake/CMakeLists.txt @@ -61,7 +61,7 @@ add_library(rdkafka ${SRCS}) target_include_directories(rdkafka SYSTEM PUBLIC include) target_include_directories(rdkafka SYSTEM PUBLIC ${RDKAFKA_SOURCE_DIR}) # Because weird logic with "include_next" is used. target_include_directories(rdkafka SYSTEM PRIVATE ${ZSTD_INCLUDE_DIR}/common) # Because wrong path to "zstd_errors.h" is used. -target_link_libraries(rdkafka PUBLIC ${ZLIB_LIBRARIES} ${ZSTD_LIBRARY} ${LZ4_LIBRARY} ${LIBGSASL_LIBRARY}) +target_link_libraries(rdkafka PRIVATE ${ZLIB_LIBRARIES} ${ZSTD_LIBRARY} ${LZ4_LIBRARY} ${LIBGSASL_LIBRARY} Threads::Threads) if(OPENSSL_SSL_LIBRARY AND OPENSSL_CRYPTO_LIBRARY) - target_link_libraries(rdkafka PUBLIC ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY}) + target_link_libraries(rdkafka PRIVATE ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY}) endif() diff --git a/contrib/libunwind-cmake/CMakeLists.txt b/contrib/libunwind-cmake/CMakeLists.txt index 3d4cd319089..993323d56c0 100644 --- a/contrib/libunwind-cmake/CMakeLists.txt +++ b/contrib/libunwind-cmake/CMakeLists.txt @@ -29,3 +29,4 @@ add_library(unwind_static ${LIBUNWIND_SOURCES}) target_include_directories(unwind_static PUBLIC ${LIBUNWIND_SOURCE_DIR}/include) target_compile_definitions(unwind_static PRIVATE -D_LIBUNWIND_NO_HEAP=1 -D_DEBUG -D_LIBUNWIND_IS_NATIVE_ONLY) target_compile_options(unwind_static PRIVATE -fno-exceptions -funwind-tables -fno-sanitize=all -nostdinc++ -fno-rtti) +target_link_libraries(unwind_static PRIVATE Threads::Threads ${CMAKE_DL_LIBS}) diff --git a/contrib/libxml2-cmake/CMakeLists.txt b/contrib/libxml2-cmake/CMakeLists.txt index 8783fca774e..827ed8fefd8 100644 --- a/contrib/libxml2-cmake/CMakeLists.txt +++ b/contrib/libxml2-cmake/CMakeLists.txt @@ -52,7 +52,7 @@ set(SRCS ) add_library(libxml2 ${SRCS}) -target_link_libraries(libxml2 ${ZLIB_LIBRARIES}) +target_link_libraries(libxml2 PRIVATE ${ZLIB_LIBRARIES} m ${CMAKE_DL_LIBS}) target_include_directories(libxml2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/linux_x86_64/include) target_include_directories(libxml2 PUBLIC ${LIBXML2_SOURCE_DIR}/include) diff --git a/contrib/mariadb-connector-c-cmake/CMakeLists.txt b/contrib/mariadb-connector-c-cmake/CMakeLists.txt index 1c9b7a5ec9c..f9bd2490fba 100644 --- a/contrib/mariadb-connector-c-cmake/CMakeLists.txt +++ b/contrib/mariadb-connector-c-cmake/CMakeLists.txt @@ -60,6 +60,8 @@ endif() add_library(mysqlclient ${SRCS}) +target_link_libraries(mysqlclient PRIVATE ${CMAKE_DL_LIBS} m Threads::Threads) + if(OPENSSL_LIBRARIES) target_link_libraries(mysqlclient PRIVATE ${OPENSSL_LIBRARIES}) target_compile_definitions(mysqlclient PRIVATE -D HAVE_OPENSSL -D HAVE_TLS) diff --git a/contrib/unixodbc-cmake/CMakeLists.txt b/contrib/unixodbc-cmake/CMakeLists.txt index 1715747191c..98c1e2268cc 100644 --- a/contrib/unixodbc-cmake/CMakeLists.txt +++ b/contrib/unixodbc-cmake/CMakeLists.txt @@ -32,6 +32,7 @@ target_include_directories(ltdl PUBLIC ${ODBC_SOURCE_DIR}/libltdl/libltdl) target_compile_definitions(ltdl PRIVATE -DHAVE_CONFIG_H -DLTDL -DLTDLOPEN=libltdlc) target_compile_options(ltdl PRIVATE -Wno-constant-logical-operand -Wno-unknown-warning-option -O2) +target_link_libraries(ltdl PRIVATE ${CMAKE_DL_LIBS}) set(SRCS From 2d895c4fe63f850bbb8298e53d8d7a88f09a998d Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 23 Jul 2019 15:46:58 +0300 Subject: [PATCH 0270/1165] Changed symbolizeTrace to symbolizeAddress --- dbms/src/Functions/FunctionsIntrospection.cpp | 2 +- dbms/src/Functions/FunctionsIntrospection.h | 69 +++++++------------ libs/libcommon/src/StackTrace.cpp | 2 +- 3 files changed, 27 insertions(+), 46 deletions(-) diff --git a/dbms/src/Functions/FunctionsIntrospection.cpp b/dbms/src/Functions/FunctionsIntrospection.cpp index 7dedc1daae3..0452e1a9f1f 100644 --- a/dbms/src/Functions/FunctionsIntrospection.cpp +++ b/dbms/src/Functions/FunctionsIntrospection.cpp @@ -6,7 +6,7 @@ namespace DB void registerFunctionsIntrospection(FunctionFactory & factory) { - factory.registerFunction(); + factory.registerFunction(); } } diff --git a/dbms/src/Functions/FunctionsIntrospection.h b/dbms/src/Functions/FunctionsIntrospection.h index d7ca1d37efa..081616d8c0c 100644 --- a/dbms/src/Functions/FunctionsIntrospection.h +++ b/dbms/src/Functions/FunctionsIntrospection.h @@ -1,15 +1,15 @@ #pragma once -#include +#include +#include #include -#include -#include -#include +#include #include #include #include #include + namespace DB { @@ -21,13 +21,13 @@ namespace ErrorCodes extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; } -class FunctionSymbolizeTrace : public IFunction +class FunctionSymbolizeAddress : public IFunction { public: - static constexpr auto name = "symbolizeTrace"; + static constexpr auto name = "symbolizeAddress"; static FunctionPtr create(const Context &) { - return std::make_shared(); + return std::make_shared(); } String getName() const override @@ -44,20 +44,13 @@ public: { if (arguments.size() != 1) throw Exception("Function " + getName() + " needs exactly one argument; passed " - + toString(arguments.size()) + ".", - ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); + + toString(arguments.size()) + ".", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); - const auto array_type = checkAndGetDataType(arguments[0].type.get()); + const auto & type = arguments[0].type; - if (!array_type) - throw Exception("The only argument for function " + getName() + " must be array. Found " - + arguments[0].type->getName() + " instead.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); - - DataTypePtr nested_type = array_type->getNestedType(); - - if (!WhichDataType(nested_type).isUInt64()) - throw Exception("The only argument for function " + getName() + " must be array of UInt64. Found " - + arguments[0].type->getName() + " instead.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); + if (!WhichDataType(type.get()).isUInt64()) + throw Exception("The only argument for function " + getName() + " must be UInt64. Found " + + type->getName() + " instead.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); return std::make_shared(); } @@ -67,37 +60,25 @@ public: return true; } - void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) override + void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override { - const ColumnPtr column = block.getByPosition(arguments[0]).column; - const ColumnArray * column_array = checkAndGetColumn(column.get()); + const ColumnPtr & column = block.getByPosition(arguments[0]).column; + const ColumnUInt64 * column_concrete = checkAndGetColumn(column.get()); - if (!column_array) - throw Exception("Illegal column " + block.getByPosition(arguments[0]).column->getName() + " of argument of function " + getName(), - ErrorCodes::ILLEGAL_COLUMN); - - const ColumnPtr data_ptr = column_array->getDataPtr(); - const ColumnVector * data_vector = checkAndGetColumn>(&*data_ptr); - - const typename ColumnVector::Container & data = data_vector->getData(); - const ColumnArray::Offsets & offsets = column_array->getOffsets(); + if (!column_concrete) + throw Exception("Illegal column " + column->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN); + const typename ColumnVector::Container & data = column_concrete->getData(); auto result_column = ColumnString::create(); - StackTrace::Frames frames; - size_t current_offset = 0; - for (size_t i = 0; i < offsets.size(); ++i) + for (size_t i = 0; i < input_rows_count; ++i) { - size_t current_size = 0; - for (; current_size < frames.size() && current_offset + current_size < offsets[i]; ++current_size) - { - frames[current_size] = reinterpret_cast(data[current_offset + current_size]); - } - - std::string backtrace = StackTrace(frames.begin(), frames.begin() + current_size).toString(); - result_column->insertDataWithTerminatingZero(backtrace.c_str(), backtrace.length() + 1); - - current_offset = offsets[i]; + void * addr = unalignedLoad(&data[i]); + Dl_info info; + if (0 == dladdr(addr, &info) && info.dli_sname) + result_column->insertDataWithTerminatingZero(info.dli_sname, strlen(info.dli_sname) + 1); + else + result_column->insertDefault(); } block.getByPosition(result).column = std::move(result_column); diff --git a/libs/libcommon/src/StackTrace.cpp b/libs/libcommon/src/StackTrace.cpp index 8aea884d004..8323a737fdf 100644 --- a/libs/libcommon/src/StackTrace.cpp +++ b/libs/libcommon/src/StackTrace.cpp @@ -208,7 +208,7 @@ size_t StackTrace::getSize() const return size; } -const StackTrace::Frames& StackTrace::getFrames() const +const StackTrace::Frames & StackTrace::getFrames() const { return frames; } From 97103b9067ae7dd072cb52611b306e68a8e04936 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 23 Jul 2019 15:55:13 +0300 Subject: [PATCH 0271/1165] Every function in its own file --- dbms/src/Functions/FunctionsIntrospection.cpp | 12 ------------ dbms/src/Functions/registerFunctions.cpp | 3 ++- ...FunctionsIntrospection.h => symbolizeAddress.cpp} | 8 ++++++-- 3 files changed, 8 insertions(+), 15 deletions(-) delete mode 100644 dbms/src/Functions/FunctionsIntrospection.cpp rename dbms/src/Functions/{FunctionsIntrospection.h => symbolizeAddress.cpp} (94%) diff --git a/dbms/src/Functions/FunctionsIntrospection.cpp b/dbms/src/Functions/FunctionsIntrospection.cpp deleted file mode 100644 index 0452e1a9f1f..00000000000 --- a/dbms/src/Functions/FunctionsIntrospection.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include - -namespace DB -{ - -void registerFunctionsIntrospection(FunctionFactory & factory) -{ - factory.registerFunction(); -} - -} diff --git a/dbms/src/Functions/registerFunctions.cpp b/dbms/src/Functions/registerFunctions.cpp index a1c75aaf33a..178f085e1ad 100644 --- a/dbms/src/Functions/registerFunctions.cpp +++ b/dbms/src/Functions/registerFunctions.cpp @@ -40,6 +40,7 @@ void registerFunctionsIntrospection(FunctionFactory &); void registerFunctionsNull(FunctionFactory &); void registerFunctionsFindCluster(FunctionFactory &); void registerFunctionsJSON(FunctionFactory &); +void registerFunctionSymbolizeAddress(FunctionFactory &); void registerFunctions() { @@ -75,10 +76,10 @@ void registerFunctions() registerFunctionsVisitParam(factory); registerFunctionsMath(factory); registerFunctionsGeo(factory); - registerFunctionsIntrospection(factory); registerFunctionsNull(factory); registerFunctionsFindCluster(factory); registerFunctionsJSON(factory); + registerFunctionSymbolizeAddress(factory); } } diff --git a/dbms/src/Functions/FunctionsIntrospection.h b/dbms/src/Functions/symbolizeAddress.cpp similarity index 94% rename from dbms/src/Functions/FunctionsIntrospection.h rename to dbms/src/Functions/symbolizeAddress.cpp index 081616d8c0c..e49a4147a58 100644 --- a/dbms/src/Functions/FunctionsIntrospection.h +++ b/dbms/src/Functions/symbolizeAddress.cpp @@ -1,5 +1,3 @@ -#pragma once - #include #include #include @@ -7,6 +5,7 @@ #include #include #include +#include #include @@ -85,4 +84,9 @@ public: } }; +void registerFunctionSymbolizeAddress(FunctionFactory & factory) +{ + factory.registerFunction(); +} + } From 398a280f23d96c277439f69cf55c07bbc6d41b5e Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 23 Jul 2019 16:16:51 +0300 Subject: [PATCH 0272/1165] Fixed error --- dbms/src/Functions/symbolizeAddress.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Functions/symbolizeAddress.cpp b/dbms/src/Functions/symbolizeAddress.cpp index e49a4147a58..65e7fa25b3b 100644 --- a/dbms/src/Functions/symbolizeAddress.cpp +++ b/dbms/src/Functions/symbolizeAddress.cpp @@ -74,7 +74,7 @@ public: { void * addr = unalignedLoad(&data[i]); Dl_info info; - if (0 == dladdr(addr, &info) && info.dli_sname) + if (dladdr(addr, &info) && info.dli_sname) result_column->insertDataWithTerminatingZero(info.dli_sname, strlen(info.dli_sname) + 1); else result_column->insertDefault(); From bd3173bac2259ce1a51a46bee44073e32f62a612 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 23 Jul 2019 16:17:56 +0300 Subject: [PATCH 0273/1165] Added comment --- dbms/src/Functions/symbolizeAddress.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dbms/src/Functions/symbolizeAddress.cpp b/dbms/src/Functions/symbolizeAddress.cpp index 65e7fa25b3b..2d55d463652 100644 --- a/dbms/src/Functions/symbolizeAddress.cpp +++ b/dbms/src/Functions/symbolizeAddress.cpp @@ -74,6 +74,8 @@ public: { void * addr = unalignedLoad(&data[i]); Dl_info info; + /// This is unsafe. The function dladdr may loop infinitely. + /// Reproduce with query: SELECT DISTINCT symbolizeAddress(number) FROM system.numbers if (dladdr(addr, &info) && info.dli_sname) result_column->insertDataWithTerminatingZero(info.dli_sname, strlen(info.dli_sname) + 1); else From 0755d1e4b33bdcb69fe62fcafc32e529a33d6bcd Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 23 Jul 2019 16:34:22 +0300 Subject: [PATCH 0274/1165] Added demangling to function symbolizeAddress --- dbms/src/Functions/symbolizeAddress.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dbms/src/Functions/symbolizeAddress.cpp b/dbms/src/Functions/symbolizeAddress.cpp index 2d55d463652..3c39155e8b4 100644 --- a/dbms/src/Functions/symbolizeAddress.cpp +++ b/dbms/src/Functions/symbolizeAddress.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -74,10 +75,15 @@ public: { void * addr = unalignedLoad(&data[i]); Dl_info info; + /// This is unsafe. The function dladdr may loop infinitely. /// Reproduce with query: SELECT DISTINCT symbolizeAddress(number) FROM system.numbers if (dladdr(addr, &info) && info.dli_sname) - result_column->insertDataWithTerminatingZero(info.dli_sname, strlen(info.dli_sname) + 1); + { + int demangling_status = 0; + std::string demangled_name = demangle(info.dli_sname, demangling_status); + result_column->insertDataWithTerminatingZero(demangled_name.data(), demangled_name.size() + 1); + } else result_column->insertDefault(); } From 87c7186feb13d8384465c759177289f6fd0d4472 Mon Sep 17 00:00:00 2001 From: Alexander Tokmakov Date: Tue, 23 Jul 2019 16:37:52 +0300 Subject: [PATCH 0275/1165] better test --- .../queries/0_stateless/00301_csv.reference | 5 ++++- dbms/tests/queries/0_stateless/00301_csv.sh | 21 +++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00301_csv.reference b/dbms/tests/queries/0_stateless/00301_csv.reference index a808d5b5daf..92cb50c0727 100644 --- a/dbms/tests/queries/0_stateless/00301_csv.reference +++ b/dbms/tests/queries/0_stateless/00301_csv.reference @@ -4,7 +4,10 @@ Hello "world" 789 2016-01-03 Hello\n world 100 2016-01-04 default 1 2019-06-19 default-eof 1 2019-06-19 -0000-00-00 00:00:00 +0 1 42 2019-07-22 +1 world 3 2019-07-23 +2 Hello 123 2019-06-19 +3 Hello 42 2019-06-19 2016-01-01 01:02:03 1 2016-01-02 01:02:03 2 2017-08-15 13:15:01 3 diff --git a/dbms/tests/queries/0_stateless/00301_csv.sh b/dbms/tests/queries/0_stateless/00301_csv.sh index 6e72c31b870..3ecc87e5bc1 100755 --- a/dbms/tests/queries/0_stateless/00301_csv.sh +++ b/dbms/tests/queries/0_stateless/00301_csv.sh @@ -17,6 +17,17 @@ Hello "world", 789 ,2016-01-03 $CLICKHOUSE_CLIENT --query="SELECT * FROM csv ORDER BY d"; $CLICKHOUSE_CLIENT --query="DROP TABLE csv"; + +$CLICKHOUSE_CLIENT --query="CREATE TABLE csv (i Int8, s String DEFAULT 'Hello', n UInt64 DEFAULT 42, d Date DEFAULT '2019-06-19') ENGINE = Memory"; +echo '\N, 1, \N, "2019-07-22" +1, world, 3, "2019-07-23" +2, \N, 123, \N +3, \N, \N, \N' | $CLICKHOUSE_CLIENT --input_format_null_as_default=1 --query="INSERT INTO csv FORMAT CSV"; + +$CLICKHOUSE_CLIENT --query="SELECT * FROM csv ORDER BY i"; +$CLICKHOUSE_CLIENT --query="DROP TABLE csv"; + + $CLICKHOUSE_CLIENT --query="CREATE TABLE csv (t DateTime('Europe/Moscow'), s String) ENGINE = Memory"; echo '"2016-01-01 01:02:03","1" @@ -24,17 +35,15 @@ echo '"2016-01-01 01:02:03","1" 1502792101,"3" 99999,"4"' | $CLICKHOUSE_CLIENT --query="INSERT INTO csv FORMAT CSV"; -echo '\N, \N' | $CLICKHOUSE_CLIENT --input_format_null_as_default=1 --query="INSERT INTO csv FORMAT CSV"; - $CLICKHOUSE_CLIENT --query="SELECT * FROM csv ORDER BY s"; $CLICKHOUSE_CLIENT --query="DROP TABLE csv"; -$CLICKHOUSE_CLIENT --query="CREATE TABLE csv_null (t Nullable(DateTime('Europe/Moscow')), s Nullable(String)) ENGINE = Memory"; +$CLICKHOUSE_CLIENT --query="CREATE TABLE csv (t Nullable(DateTime('Europe/Moscow')), s Nullable(String)) ENGINE = Memory"; echo 'NULL, NULL "2016-01-01 01:02:03",NUL -"2016-01-02 01:02:03",Nhello' | $CLICKHOUSE_CLIENT --input_format_csv_unquoted_null_literal_as_null=1 --query="INSERT INTO csv_null FORMAT CSV"; +"2016-01-02 01:02:03",Nhello' | $CLICKHOUSE_CLIENT --input_format_csv_unquoted_null_literal_as_null=1 --query="INSERT INTO csv FORMAT CSV"; -$CLICKHOUSE_CLIENT --query="SELECT * FROM csv_null ORDER BY s NULLS LAST"; -$CLICKHOUSE_CLIENT --query="DROP TABLE csv_null"; +$CLICKHOUSE_CLIENT --query="SELECT * FROM csv ORDER BY s NULLS LAST"; +$CLICKHOUSE_CLIENT --query="DROP TABLE csv"; From 24cc9f9c1ef5876a5f678638f4e88356b90dabba Mon Sep 17 00:00:00 2001 From: filimonov <1549571+filimonov@users.noreply.github.com> Date: Tue, 23 Jul 2019 15:50:07 +0200 Subject: [PATCH 0276/1165] default for enable_optimize_predicate_expression was changed --- docs/ru/operations/settings/settings.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/operations/settings/settings.md b/docs/ru/operations/settings/settings.md index e5e4bad1fa6..86c16e92da3 100644 --- a/docs/ru/operations/settings/settings.md +++ b/docs/ru/operations/settings/settings.md @@ -31,7 +31,7 @@ ClickHouse применяет настройку в тех случаях, ко - 0 — выключена. - 1 — включена. -Значение по умолчанию: 0. +Значение по умолчанию: 1. **Использование** From 1dc6e1710243e75c9c5ac4705180a7621d988b3d Mon Sep 17 00:00:00 2001 From: filimonov <1549571+filimonov@users.noreply.github.com> Date: Tue, 23 Jul 2019 15:51:11 +0200 Subject: [PATCH 0277/1165] eng version --- docs/en/operations/settings/settings.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/operations/settings/settings.md b/docs/en/operations/settings/settings.md index 63648d95b77..1c97cb134e2 100644 --- a/docs/en/operations/settings/settings.md +++ b/docs/en/operations/settings/settings.md @@ -32,7 +32,7 @@ Possible values: - 0 — Disabled. - 1 — Enabled. -Default value: 0. +Default value: 1. **Usage** From 4f91e3e4b710791ed6e278b5cc010fd7c9ba3937 Mon Sep 17 00:00:00 2001 From: Vitaly Baranov Date: Tue, 23 Jul 2019 16:51:22 +0300 Subject: [PATCH 0278/1165] Fix protobuf format tests. --- .../00825_protobuf_format_input.insh | 8 +-- .../00825_protobuf_format_input.sh | 58 +++++++-------- .../00825_protobuf_format_output.sh | 70 +++++++++---------- .../ProtobufDelimitedMessagesSerializer.cpp | 20 +++--- 4 files changed, 78 insertions(+), 78 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00825_protobuf_format_input.insh b/dbms/tests/queries/0_stateless/00825_protobuf_format_input.insh index d615f6e4e6d..7aed4487a56 100644 --- a/dbms/tests/queries/0_stateless/00825_protobuf_format_input.insh +++ b/dbms/tests/queries/0_stateless/00825_protobuf_format_input.insh @@ -1,4 +1,4 @@ -echo -ne '\xf3\x01\x0a\x24\x61\x37\x35\x32\x32\x31\x35\x38\x2d\x33\x64\x34\x31\x2d\x34\x62\x37\x37\x2d\x61\x64\x36\x39\x2d\x36\x63\x35\x39\x38\x65\x65\x35\x35\x63\x34\x39\x12\x04\x49\x76\x61\x6e\x1a\x06\x50\x65\x74\x72\x6f\x76\x20\x01\x28\xaf\x1f\x32\x03\x70\x6e\x67\x3a\x0c\x2b\x37\x34\x39\x35\x31\x32\x33\x34\x35\x36\x37\x40\x01\x4d\xfc\xd0\x30\x5c\x50\x26\x58\x09\x62\x09\x59\x65\x73\x74\x65\x72\x64\x61\x79\x62\x07\x46\x6c\x6f\x77\x65\x72\x73\x6a\x04\xff\x01\x00\x00\x72\x06\x4d\x6f\x73\x63\x6f\x77\x7a\x08\x4b\x03\x5f\x42\x72\x7d\x16\x42\x81\x01\x1f\x85\xeb\x51\xb8\x1e\x09\x40\x89\x01\x33\x33\x33\x33\x33\xc3\x6a\x40\x95\x01\xcd\xcc\xcc\x3d\x9d\x01\x9a\x99\xb9\x40\xa0\x01\x80\xc4\xd7\x8d\x7f\xaa\x01\x0c\x0a\x05\x6d\x65\x74\x65\x72\x15\x00\x00\x80\x3f\xaa\x01\x11\x0a\x0a\x63\x65\x6e\x74\x69\x6d\x65\x74\x65\x72\x15\x0a\xd7\x23\x3c\xaa\x01\x10\x0a\x09\x6b\x69\x6c\x6f\x6d\x65\x74\x65\x72\x15\x00\x00\x7a\x44\xb2\x01\x10\x0a\x0e\xa2\x06\x0b\x0a\x09\x08\xf4\x03\x12\x04\xf5\x03\xf6\x03\x7e\x0a\x24\x63\x36\x39\x34\x61\x64\x38\x61\x2d\x66\x37\x31\x34\x2d\x34\x65\x61\x33\x2d\x39\x30\x37\x64\x2d\x66\x64\x35\x34\x66\x62\x32\x35\x64\x39\x62\x35\x12\x07\x4e\x61\x74\x61\x6c\x69\x61\x1a\x08\x53\x6f\x6b\x6f\x6c\x6f\x76\x61\x28\xa6\x3f\x32\x03\x6a\x70\x67\x50\x1a\x58\x0b\x6a\x04\x64\xc8\x01\x32\x72\x08\x50\x6c\x79\x6d\x6f\x75\x74\x68\x7a\x08\x6a\x9d\x49\x42\x46\x8c\x84\xc0\x81\x01\x6e\x86\x1b\xf0\xf9\x21\x09\x40\x95\x01\x42\x60\xe5\x3b\x9d\x01\xcd\xcc\xac\x40\xa0\x01\xff\xff\xa9\xce\x93\x8c\x09\xc0\x01\x0a\x24\x61\x37\x64\x61\x31\x61\x61\x36\x2d\x66\x34\x32\x35\x2d\x34\x37\x38\x39\x2d\x38\x39\x34\x37\x2d\x62\x30\x33\x34\x37\x38\x36\x65\x64\x33\x37\x34\x12\x06\x56\x61\x73\x69\x6c\x79\x1a\x07\x53\x69\x64\x6f\x72\x6f\x76\x20\x01\x28\xfb\x48\x32\x03\x62\x6d\x70\x3a\x0d\x2b\x34\x34\x32\x30\x31\x32\x33\x34\x35\x36\x37\x38\x40\x01\x4d\x50\xe0\x27\x5c\x50\x17\x58\x04\x62\x05\x53\x75\x6e\x6e\x79\x6a\x05\xfa\x01\xf4\x01\x0a\x72\x08\x4d\x75\x72\x6d\x61\x6e\x73\x6b\x7a\x08\xfd\xf0\x89\x42\xc8\x4c\x04\x42\x81\x01\x11\x2d\x44\x54\xfb\x21\x09\x40\x89\x01\x00\x00\x00\xe8\x76\x48\x37\x42\x95\x01\x00\x00\x48\x44\x9d\x01\xcd\xcc\x4c\xc0\xa0\x01\x80\xd4\x9f\x93\x01\xaa\x01\x0c\x0a\x05\x70\x6f\x75\x6e\x64\x15\x00\x00\x80\x41\xb2\x01\x0a\x0a\x08\xa2\x06\x05\x0a\x03\x08\xf7\x03' | $CLICKHOUSE_CLIENT --query="INSERT INTO table_00825 FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format:Person'" -echo -ne '\xb3\x01\x12\x05\x46\x72\x69\x64\x61\x28\x99\xe1\xf3\xd1\x0b\x52\x08\x45\x72\x6d\x61\x6b\x6f\x76\x61\x72\x0c\x00\x00\xdc\x42\x00\x00\x52\x43\x00\x00\x94\x42\x79\x48\xce\x3d\x51\x00\x00\x00\x00\xc8\x02\x14\xc2\x05\x08\x00\x00\x80\x44\x00\x00\x80\x49\x9a\x06\x02\x4b\x42\x9a\x06\x02\x4d\x42\xa1\x06\x00\x00\x00\x00\x00\x00\xe0\x3f\xa8\x06\x2a\xa8\x06\xa8\xff\xff\xff\xff\xff\xff\xff\xff\x01\xb0\x06\x01\xbd\x06\x25\x06\x49\x40\xfa\x06\x02\x34\x30\x90\x08\xe2\x08\xe1\x08\x89\xe6\x6e\xdd\x01\x00\x00\x00\xb0\x09\xc3\x19\xd0\x0c\xb7\x02\xe2\x12\x24\x32\x30\x66\x63\x64\x39\x35\x61\x2d\x33\x33\x32\x64\x2d\x34\x31\x64\x62\x2d\x61\x39\x65\x63\x2d\x31\x36\x31\x66\x36\x34\x34\x64\x30\x35\x39\x63\xa0\x38\xbc\x05\xaa\x38\x02\xbd\x05\xb4\x01\x08\x01\x12\x06\x49\x73\x6f\x6c\x64\x65\x52\x07\x4c\x61\x76\x72\x6f\x76\x61\x72\x0c\x00\x00\x7f\x43\x00\x00\x00\x00\x00\x00\x7f\x43\xaa\x01\x03\x61\x62\x63\xc8\x02\x32\xc2\x05\x08\x00\x00\x00\x41\x00\x00\x80\x3f\x9a\x06\x04\x42\x79\x74\x65\x9a\x06\x03\x42\x69\x74\xa1\x06\x00\x00\x00\x00\x00\x00\x12\x40\xa8\x06\x1a\xa8\x06\xb0\xff\xff\xff\xff\xff\xff\xff\xff\x01\xb0\x06\x01\xbd\x06\xf9\x0f\x49\x40\xc2\x06\x01\x2c\xfa\x06\x02\x33\x32\x90\x08\x78\xe1\x08\x39\x4e\x2b\xfe\xe4\xf5\xff\xff\xb0\x09\xe8\x30\xd8\x12\x01\xe2\x12\x24\x37\x63\x66\x61\x36\x38\x35\x36\x2d\x61\x35\x34\x61\x2d\x34\x37\x38\x36\x2d\x62\x38\x65\x35\x2d\x37\x34\x35\x31\x35\x39\x64\x35\x32\x32\x37\x38\xa0\x38\xbe\x05\xc2\x3e\x05\x15\x00\x00\xb6\x42' | $CLICKHOUSE_CLIENT --query="INSERT INTO table_00825 FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format:AltPerson'" -echo -ne '\xa5\x02\x0a\x24\x61\x61\x30\x65\x35\x61\x30\x36\x2d\x63\x61\x62\x32\x2d\x34\x30\x33\x34\x2d\x61\x36\x61\x32\x2d\x34\x38\x65\x38\x32\x62\x39\x31\x36\x36\x34\x65\x12\x06\x4c\x65\x6f\x6e\x69\x64\x1a\x08\x4b\x69\x72\x69\x6c\x6c\x6f\x76\x22\x04\x6d\x61\x6c\x65\x2a\x0a\x31\x39\x38\x33\x2d\x30\x36\x2d\x32\x34\x3a\x0c\x2b\x37\x34\x39\x35\x30\x32\x37\x35\x38\x36\x34\x42\x01\x31\x4a\x13\x32\x30\x31\x39\x2d\x30\x32\x2d\x30\x34\x20\x30\x39\x3a\x34\x35\x3a\x30\x30\x52\x02\x33\x35\x5a\x06\x63\x61\x6e\x63\x65\x72\x62\x07\x37\x20\x72\x69\x6e\x67\x73\x62\x08\x45\x61\x73\x74\x73\x69\x64\x65\x62\x0b\x4c\x61\x73\x74\x20\x48\x75\x72\x72\x61\x68\x6a\x01\x30\x6a\x01\x30\x6a\x03\x32\x35\x35\x72\x09\x53\x61\x6e\x20\x44\x69\x65\x67\x6f\x7a\x09\x33\x32\x2e\x38\x32\x33\x39\x34\x33\x7a\x0b\x2d\x31\x31\x37\x2e\x30\x38\x31\x33\x32\x37\x82\x01\x09\x33\x2e\x31\x34\x31\x35\x39\x32\x37\x8a\x01\x08\x31\x35\x30\x30\x30\x30\x30\x30\x92\x01\x06\x31\x38\x36\x2e\x37\x35\x9a\x01\x04\x2d\x32\x2e\x31\xa2\x01\x0b\x32\x30\x36\x35\x39\x38\x32\x39\x33\x33\x31\xaa\x01\x18\x0a\x06\x6d\x69\x6e\x75\x74\x65\x0a\x04\x68\x6f\x75\x72\x12\x02\x36\x30\x12\x04\x33\x36\x30\x30\xb2\x01\x08\x0a\x06\x12\x04\x31\x38\x30\x30' | $CLICKHOUSE_CLIENT --query="INSERT INTO table_00825 FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format:StrPerson'" -echo -ne '\xdd\x01\x0a\x24\x33\x66\x61\x65\x65\x30\x36\x34\x2d\x63\x34\x66\x37\x2d\x34\x64\x33\x34\x2d\x62\x36\x66\x33\x2d\x38\x64\x38\x31\x63\x32\x62\x36\x61\x31\x35\x64\x12\x04\x4e\x69\x63\x6b\x1a\x0a\x4b\x6f\x6c\x65\x73\x6e\x69\x6b\x6f\x76\x20\x01\x28\xda\x52\x32\x03\x62\x6d\x70\x3a\x0c\x34\x31\x32\x2d\x36\x38\x37\x2d\x35\x30\x30\x37\x40\x01\x4d\x2f\x27\xf2\x5b\x50\x14\x58\x09\x62\x06\x48\x61\x76\x61\x6e\x61\x68\x80\x01\x68\x00\x68\x80\x01\x72\x0a\x50\x69\x74\x74\x73\x62\x75\x72\x67\x68\x7a\x08\x9b\x11\x22\x42\x1f\xe6\x9f\xc2\x81\x01\x28\x2d\x44\x54\xfb\x21\x09\x40\x89\x01\x00\x00\x00\xe8\x76\x48\x27\x42\x95\x01\x00\x00\x43\x44\x9d\x01\x66\x66\x92\x41\xa0\x01\xce\xdf\xb8\xba\x01\xab\x01\x0d\xcd\xcc\xe2\x41\x0d\xcd\xcc\x4c\x3e\x0d\x00\x00\x80\x3f\x12\x05\x6f\x75\x6e\x63\x65\x12\x05\x63\x61\x72\x61\x74\x12\x04\x67\x72\x61\x6d\xac\x01\xb3\x01\x0b\xa2\x06\x05\x0b\x08\x96\x4a\x0c\x0c\xb4\x01' | $CLICKHOUSE_CLIENT --query="INSERT INTO table_00825 FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format_syntax2:Syntax2Person'" +echo -ne '\xf3\x01\x0a\x24\x61\x37\x35\x32\x32\x31\x35\x38\x2d\x33\x64\x34\x31\x2d\x34\x62\x37\x37\x2d\x61\x64\x36\x39\x2d\x36\x63\x35\x39\x38\x65\x65\x35\x35\x63\x34\x39\x12\x04\x49\x76\x61\x6e\x1a\x06\x50\x65\x74\x72\x6f\x76\x20\x01\x28\xaf\x1f\x32\x03\x70\x6e\x67\x3a\x0c\x2b\x37\x34\x39\x35\x31\x32\x33\x34\x35\x36\x37\x40\x01\x4d\xfc\xd0\x30\x5c\x50\x26\x58\x09\x62\x09\x59\x65\x73\x74\x65\x72\x64\x61\x79\x62\x07\x46\x6c\x6f\x77\x65\x72\x73\x6a\x04\xff\x01\x00\x00\x72\x06\x4d\x6f\x73\x63\x6f\x77\x7a\x08\x4b\x03\x5f\x42\x72\x7d\x16\x42\x81\x01\x1f\x85\xeb\x51\xb8\x1e\x09\x40\x89\x01\x33\x33\x33\x33\x33\xc3\x6a\x40\x95\x01\xcd\xcc\xcc\x3d\x9d\x01\x9a\x99\xb9\x40\xa0\x01\x80\xc4\xd7\x8d\x7f\xaa\x01\x0c\x0a\x05\x6d\x65\x74\x65\x72\x15\x00\x00\x80\x3f\xaa\x01\x11\x0a\x0a\x63\x65\x6e\x74\x69\x6d\x65\x74\x65\x72\x15\x0a\xd7\x23\x3c\xaa\x01\x10\x0a\x09\x6b\x69\x6c\x6f\x6d\x65\x74\x65\x72\x15\x00\x00\x7a\x44\xb2\x01\x10\x0a\x0e\xa2\x06\x0b\x0a\x09\x08\xf4\x03\x12\x04\xf5\x03\xf6\x03\x7e\x0a\x24\x63\x36\x39\x34\x61\x64\x38\x61\x2d\x66\x37\x31\x34\x2d\x34\x65\x61\x33\x2d\x39\x30\x37\x64\x2d\x66\x64\x35\x34\x66\x62\x32\x35\x64\x39\x62\x35\x12\x07\x4e\x61\x74\x61\x6c\x69\x61\x1a\x08\x53\x6f\x6b\x6f\x6c\x6f\x76\x61\x28\xa6\x3f\x32\x03\x6a\x70\x67\x50\x1a\x58\x0b\x6a\x04\x64\xc8\x01\x32\x72\x08\x50\x6c\x79\x6d\x6f\x75\x74\x68\x7a\x08\x6a\x9d\x49\x42\x46\x8c\x84\xc0\x81\x01\x6e\x86\x1b\xf0\xf9\x21\x09\x40\x95\x01\x42\x60\xe5\x3b\x9d\x01\xcd\xcc\xac\x40\xa0\x01\xff\xff\xa9\xce\x93\x8c\x09\xc0\x01\x0a\x24\x61\x37\x64\x61\x31\x61\x61\x36\x2d\x66\x34\x32\x35\x2d\x34\x37\x38\x39\x2d\x38\x39\x34\x37\x2d\x62\x30\x33\x34\x37\x38\x36\x65\x64\x33\x37\x34\x12\x06\x56\x61\x73\x69\x6c\x79\x1a\x07\x53\x69\x64\x6f\x72\x6f\x76\x20\x01\x28\xfb\x48\x32\x03\x62\x6d\x70\x3a\x0d\x2b\x34\x34\x32\x30\x31\x32\x33\x34\x35\x36\x37\x38\x40\x01\x4d\x50\xe0\x27\x5c\x50\x17\x58\x04\x62\x05\x53\x75\x6e\x6e\x79\x6a\x05\xfa\x01\xf4\x01\x0a\x72\x08\x4d\x75\x72\x6d\x61\x6e\x73\x6b\x7a\x08\xfd\xf0\x89\x42\xc8\x4c\x04\x42\x81\x01\x11\x2d\x44\x54\xfb\x21\x09\x40\x89\x01\x00\x00\x00\xe8\x76\x48\x37\x42\x95\x01\x00\x00\x48\x44\x9d\x01\xcd\xcc\x4c\xc0\xa0\x01\x80\xd4\x9f\x93\x01\xaa\x01\x0c\x0a\x05\x70\x6f\x75\x6e\x64\x15\x00\x00\x80\x41\xb2\x01\x0a\x0a\x08\xa2\x06\x05\x0a\x03\x08\xf7\x03' | $CLICKHOUSE_CLIENT --query="INSERT INTO in_persons_00825 FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format:Person'" +echo -ne '\xb3\x01\x12\x05\x46\x72\x69\x64\x61\x28\x99\xe1\xf3\xd1\x0b\x52\x08\x45\x72\x6d\x61\x6b\x6f\x76\x61\x72\x0c\x00\x00\xdc\x42\x00\x00\x52\x43\x00\x00\x94\x42\x79\x48\xce\x3d\x51\x00\x00\x00\x00\xc8\x02\x14\xc2\x05\x08\x00\x00\x80\x44\x00\x00\x80\x49\x9a\x06\x02\x4b\x42\x9a\x06\x02\x4d\x42\xa1\x06\x00\x00\x00\x00\x00\x00\xe0\x3f\xa8\x06\x2a\xa8\x06\xa8\xff\xff\xff\xff\xff\xff\xff\xff\x01\xb0\x06\x01\xbd\x06\x25\x06\x49\x40\xfa\x06\x02\x34\x30\x90\x08\xe2\x08\xe1\x08\x89\xe6\x6e\xdd\x01\x00\x00\x00\xb0\x09\xc3\x19\xd0\x0c\xb7\x02\xe2\x12\x24\x32\x30\x66\x63\x64\x39\x35\x61\x2d\x33\x33\x32\x64\x2d\x34\x31\x64\x62\x2d\x61\x39\x65\x63\x2d\x31\x36\x31\x66\x36\x34\x34\x64\x30\x35\x39\x63\xa0\x38\xbc\x05\xaa\x38\x02\xbd\x05\xb4\x01\x08\x01\x12\x06\x49\x73\x6f\x6c\x64\x65\x52\x07\x4c\x61\x76\x72\x6f\x76\x61\x72\x0c\x00\x00\x7f\x43\x00\x00\x00\x00\x00\x00\x7f\x43\xaa\x01\x03\x61\x62\x63\xc8\x02\x32\xc2\x05\x08\x00\x00\x00\x41\x00\x00\x80\x3f\x9a\x06\x04\x42\x79\x74\x65\x9a\x06\x03\x42\x69\x74\xa1\x06\x00\x00\x00\x00\x00\x00\x12\x40\xa8\x06\x1a\xa8\x06\xb0\xff\xff\xff\xff\xff\xff\xff\xff\x01\xb0\x06\x01\xbd\x06\xf9\x0f\x49\x40\xc2\x06\x01\x2c\xfa\x06\x02\x33\x32\x90\x08\x78\xe1\x08\x39\x4e\x2b\xfe\xe4\xf5\xff\xff\xb0\x09\xe8\x30\xd8\x12\x01\xe2\x12\x24\x37\x63\x66\x61\x36\x38\x35\x36\x2d\x61\x35\x34\x61\x2d\x34\x37\x38\x36\x2d\x62\x38\x65\x35\x2d\x37\x34\x35\x31\x35\x39\x64\x35\x32\x32\x37\x38\xa0\x38\xbe\x05\xc2\x3e\x05\x15\x00\x00\xb6\x42' | $CLICKHOUSE_CLIENT --query="INSERT INTO in_persons_00825 FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format:AltPerson'" +echo -ne '\xa5\x02\x0a\x24\x61\x61\x30\x65\x35\x61\x30\x36\x2d\x63\x61\x62\x32\x2d\x34\x30\x33\x34\x2d\x61\x36\x61\x32\x2d\x34\x38\x65\x38\x32\x62\x39\x31\x36\x36\x34\x65\x12\x06\x4c\x65\x6f\x6e\x69\x64\x1a\x08\x4b\x69\x72\x69\x6c\x6c\x6f\x76\x22\x04\x6d\x61\x6c\x65\x2a\x0a\x31\x39\x38\x33\x2d\x30\x36\x2d\x32\x34\x3a\x0c\x2b\x37\x34\x39\x35\x30\x32\x37\x35\x38\x36\x34\x42\x01\x31\x4a\x13\x32\x30\x31\x39\x2d\x30\x32\x2d\x30\x34\x20\x30\x39\x3a\x34\x35\x3a\x30\x30\x52\x02\x33\x35\x5a\x06\x63\x61\x6e\x63\x65\x72\x62\x07\x37\x20\x72\x69\x6e\x67\x73\x62\x08\x45\x61\x73\x74\x73\x69\x64\x65\x62\x0b\x4c\x61\x73\x74\x20\x48\x75\x72\x72\x61\x68\x6a\x01\x30\x6a\x01\x30\x6a\x03\x32\x35\x35\x72\x09\x53\x61\x6e\x20\x44\x69\x65\x67\x6f\x7a\x09\x33\x32\x2e\x38\x32\x33\x39\x34\x33\x7a\x0b\x2d\x31\x31\x37\x2e\x30\x38\x31\x33\x32\x37\x82\x01\x09\x33\x2e\x31\x34\x31\x35\x39\x32\x37\x8a\x01\x08\x31\x35\x30\x30\x30\x30\x30\x30\x92\x01\x06\x31\x38\x36\x2e\x37\x35\x9a\x01\x04\x2d\x32\x2e\x31\xa2\x01\x0b\x32\x30\x36\x35\x39\x38\x32\x39\x33\x33\x31\xaa\x01\x18\x0a\x06\x6d\x69\x6e\x75\x74\x65\x0a\x04\x68\x6f\x75\x72\x12\x02\x36\x30\x12\x04\x33\x36\x30\x30\xb2\x01\x08\x0a\x06\x12\x04\x31\x38\x30\x30' | $CLICKHOUSE_CLIENT --query="INSERT INTO in_persons_00825 FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format:StrPerson'" +echo -ne '\xdd\x01\x0a\x24\x33\x66\x61\x65\x65\x30\x36\x34\x2d\x63\x34\x66\x37\x2d\x34\x64\x33\x34\x2d\x62\x36\x66\x33\x2d\x38\x64\x38\x31\x63\x32\x62\x36\x61\x31\x35\x64\x12\x04\x4e\x69\x63\x6b\x1a\x0a\x4b\x6f\x6c\x65\x73\x6e\x69\x6b\x6f\x76\x20\x01\x28\xda\x52\x32\x03\x62\x6d\x70\x3a\x0c\x34\x31\x32\x2d\x36\x38\x37\x2d\x35\x30\x30\x37\x40\x01\x4d\x2f\x27\xf2\x5b\x50\x14\x58\x09\x62\x06\x48\x61\x76\x61\x6e\x61\x68\x80\x01\x68\x00\x68\x80\x01\x72\x0a\x50\x69\x74\x74\x73\x62\x75\x72\x67\x68\x7a\x08\x9b\x11\x22\x42\x1f\xe6\x9f\xc2\x81\x01\x28\x2d\x44\x54\xfb\x21\x09\x40\x89\x01\x00\x00\x00\xe8\x76\x48\x27\x42\x95\x01\x00\x00\x43\x44\x9d\x01\x66\x66\x92\x41\xa0\x01\xce\xdf\xb8\xba\x01\xab\x01\x0d\xcd\xcc\xe2\x41\x0d\xcd\xcc\x4c\x3e\x0d\x00\x00\x80\x3f\x12\x05\x6f\x75\x6e\x63\x65\x12\x05\x63\x61\x72\x61\x74\x12\x04\x67\x72\x61\x6d\xac\x01\xb3\x01\x0b\xa2\x06\x05\x0b\x08\x96\x4a\x0c\x0c\xb4\x01' | $CLICKHOUSE_CLIENT --query="INSERT INTO in_persons_00825 FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format_syntax2:Syntax2Person'" diff --git a/dbms/tests/queries/0_stateless/00825_protobuf_format_input.sh b/dbms/tests/queries/0_stateless/00825_protobuf_format_input.sh index d56864e0b0e..a2efad352aa 100755 --- a/dbms/tests/queries/0_stateless/00825_protobuf_format_input.sh +++ b/dbms/tests/queries/0_stateless/00825_protobuf_format_input.sh @@ -7,34 +7,34 @@ set -e -o pipefail # Run the client. $CLICKHOUSE_CLIENT --multiquery <<'EOF' -DROP TABLE IF EXISTS table_00825; +DROP TABLE IF EXISTS in_persons_00825; -CREATE TABLE table_00825 (uuid UUID, - name String, - surname String, - gender Enum8('male'=1, 'female'=0), - birthDate Date, - photo Nullable(String), - phoneNumber Nullable(FixedString(13)), - isOnline UInt8, - visitTime Nullable(DateTime), - age UInt8, - zodiacSign Enum16('aries'=321, 'taurus'=420, 'gemini'=521, 'cancer'=621, 'leo'=723, 'virgo'=823, - 'libra'=923, 'scorpius'=1023, 'sagittarius'=1122, 'capricorn'=1222, 'aquarius'=120, - 'pisces'=219), - songs Array(String), - color Array(UInt8), - hometown LowCardinality(String), - location Array(Decimal32(6)), - pi Nullable(Float64), - lotteryWin Nullable(Decimal64(2)), - someRatio Float32, - temperature Decimal32(1), - randomBigNumber Int64, - measureUnits Nested (unit String, coef Float32), - nestiness_a_b_c_d Nullable(UInt32), - `nestiness_a_B.c_E` Array(UInt32) - ) ENGINE = MergeTree ORDER BY tuple(); +CREATE TABLE in_persons_00825 (uuid UUID, + name String, + surname String, + gender Enum8('male'=1, 'female'=0), + birthDate Date, + photo Nullable(String), + phoneNumber Nullable(FixedString(13)), + isOnline UInt8, + visitTime Nullable(DateTime), + age UInt8, + zodiacSign Enum16('aries'=321, 'taurus'=420, 'gemini'=521, 'cancer'=621, 'leo'=723, 'virgo'=823, + 'libra'=923, 'scorpius'=1023, 'sagittarius'=1122, 'capricorn'=1222, 'aquarius'=120, + 'pisces'=219), + songs Array(String), + color Array(UInt8), + hometown LowCardinality(String), + location Array(Decimal32(6)), + pi Nullable(Float64), + lotteryWin Nullable(Decimal64(2)), + someRatio Float32, + temperature Decimal32(1), + randomBigNumber Int64, + measureUnits Nested (unit String, coef Float32), + nestiness_a_b_c_d Nullable(UInt32), + `nestiness_a_B.c_E` Array(UInt32) + ) ENGINE = MergeTree ORDER BY tuple(); EOF # To generate the file 00825_protobuf_format_input.insh use the following commands: @@ -42,6 +42,6 @@ EOF # build/utils/test-data-generator/ProtobufDelimitedMessagesSerializer source $CURDIR/00825_protobuf_format_input.insh -$CLICKHOUSE_CLIENT --query "SELECT * FROM table_00825 ORDER BY uuid;" +$CLICKHOUSE_CLIENT --query "SELECT * FROM in_persons_00825 ORDER BY uuid;" -$CLICKHOUSE_CLIENT --query "DROP TABLE IF EXISTS table_00825;" +$CLICKHOUSE_CLIENT --query "DROP TABLE IF EXISTS in_persons_00825;" diff --git a/dbms/tests/queries/0_stateless/00825_protobuf_format_output.sh b/dbms/tests/queries/0_stateless/00825_protobuf_format_output.sh index 3fd2a5abd18..0b2e51cbfbf 100755 --- a/dbms/tests/queries/0_stateless/00825_protobuf_format_output.sh +++ b/dbms/tests/queries/0_stateless/00825_protobuf_format_output.sh @@ -11,46 +11,46 @@ set -e -o pipefail # Run the client. $CLICKHOUSE_CLIENT --multiquery <'; -SELECT * FROM table_00825 ORDER BY name FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format:AltPerson'; +SELECT * FROM out_persons_00825 ORDER BY name FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format:AltPerson'; SELECT 'STRINGS->'; -SELECT * FROM table_00825 ORDER BY name FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format:StrPerson'; +SELECT * FROM out_persons_00825 ORDER BY name FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format:StrPerson'; SELECT 'SYNTAX2->'; -SELECT * FROM table_00825 ORDER BY name FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format_syntax2:Syntax2Person'; +SELECT * FROM out_persons_00825 ORDER BY name FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format_syntax2:Syntax2Person'; -DROP TABLE IF EXISTS table_00825; +DROP TABLE IF EXISTS out_persons_00825; EOF diff --git a/utils/test-data-generator/ProtobufDelimitedMessagesSerializer.cpp b/utils/test-data-generator/ProtobufDelimitedMessagesSerializer.cpp index 4acb8aae9b2..92ed44dc28b 100644 --- a/utils/test-data-generator/ProtobufDelimitedMessagesSerializer.cpp +++ b/utils/test-data-generator/ProtobufDelimitedMessagesSerializer.cpp @@ -9,7 +9,7 @@ #include "00825_protobuf_format_syntax2.pb.h" -void writeInsertQueryCommand(std::ostream & out, const std::string & format_schema, std::stringstream & delimited_messages) +void writeInsertDataQueryForInputTest(std::stringstream & delimited_messages, const std::string & table_name, const std::string & format_schema, std::ostream & out) { out << "echo -ne '"; std::string bytes = delimited_messages.str(); @@ -20,12 +20,12 @@ void writeInsertQueryCommand(std::ostream & out, const std::string & format_sche sprintf(buf, "\\x%02x", static_cast(c)); out << buf; } - out << "' | $CLICKHOUSE_CLIENT --query=\"INSERT INTO test.table FORMAT Protobuf" + out << "' | $CLICKHOUSE_CLIENT --query=\"INSERT INTO " << table_name << " FORMAT Protobuf" " SETTINGS format_schema = '$CURDIR/" << format_schema << "'\"" << std::endl; } -void writeInputInsertQueries(std::ostream & out) +void writeInsertDataQueriesForInputTest(std::ostream & out) { std::stringstream ss; { @@ -125,7 +125,7 @@ void writeInputInsertQueries(std::ostream & out) google::protobuf::util::SerializeDelimitedToOstream(person, &ss); } - writeInsertQueryCommand(out, "00825_protobuf_format:Person", ss); + writeInsertDataQueryForInputTest(ss, "in_persons_00825", "00825_protobuf_format:Person", out); { AltPerson person; @@ -189,7 +189,7 @@ void writeInputInsertQueries(std::ostream & out) google::protobuf::util::SerializeDelimitedToOstream(person, &ss); } - writeInsertQueryCommand(out, "00825_protobuf_format:AltPerson", ss); + writeInsertDataQueryForInputTest(ss, "in_persons_00825", "00825_protobuf_format:AltPerson", out); { StrPerson person; @@ -225,7 +225,7 @@ void writeInputInsertQueries(std::ostream & out) google::protobuf::util::SerializeDelimitedToOstream(person, &ss); } - writeInsertQueryCommand(out, "00825_protobuf_format:StrPerson", ss); + writeInsertDataQueryForInputTest(ss, "in_persons_00825", "00825_protobuf_format:StrPerson", out); { Syntax2Person person; @@ -262,11 +262,11 @@ void writeInputInsertQueries(std::ostream & out) google::protobuf::util::SerializeDelimitedToOstream(person, &ss); } - writeInsertQueryCommand(out, "00825_protobuf_format_syntax2:Syntax2Person", ss); + writeInsertDataQueryForInputTest(ss, "in_persons_00825", "00825_protobuf_format_syntax2:Syntax2Person", out); } -void writeOutputReference(std::ostream & out) +void writeReferenceForOutputTest(std::ostream & out) { { Person person; @@ -676,7 +676,7 @@ int main(int argc, char ** argv) { std::string output_dir; parseCommandLine(argc, argv, output_dir); - writeFile(output_dir + "/00825_protobuf_format_input.insh", writeInputInsertQueries); - writeFile(output_dir + "/00825_protobuf_format_output.reference", writeOutputReference); + writeFile(output_dir + "/00825_protobuf_format_input.insh", writeInsertDataQueriesForInputTest); + writeFile(output_dir + "/00825_protobuf_format_output.reference", writeReferenceForOutputTest); return 0; } From 4d43cf2a8d3dd2d38fa208918301995aee9d5222 Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Mon, 22 Jul 2019 17:00:44 +0300 Subject: [PATCH 0279/1165] config exception when not corresponding root names --- dbms/src/Common/Config/ConfigProcessor.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dbms/src/Common/Config/ConfigProcessor.cpp b/dbms/src/Common/Config/ConfigProcessor.cpp index 04c8bf15c03..80da7008ac5 100644 --- a/dbms/src/Common/Config/ConfigProcessor.cpp +++ b/dbms/src/Common/Config/ConfigProcessor.cpp @@ -210,7 +210,13 @@ void ConfigProcessor::mergeRecursive(XMLDocumentPtr config, Node * config_root, void ConfigProcessor::merge(XMLDocumentPtr config, XMLDocumentPtr with) { - mergeRecursive(config, getRootNode(&*config), getRootNode(&*with)); + Node * config_root = getRootNode(&*config); + const Node * with_root = getRootNode(&*with); + + if (config_root->nodeName() != with_root->nodeName()) + throw Poco::Exception("Root element doesn't have the corresponding root element as the config file. It must be <" + config_root->nodeName() + ">"); + + mergeRecursive(config, config_root, with_root); } std::string ConfigProcessor::layerFromHost() From 13ef987361e64a51fd7e1f2caedef7faa5939a43 Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Tue, 23 Jul 2019 13:31:20 +0300 Subject: [PATCH 0280/1165] Git commit fixes --- dbms/src/Common/Config/ConfigProcessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Common/Config/ConfigProcessor.cpp b/dbms/src/Common/Config/ConfigProcessor.cpp index 80da7008ac5..6b90ab23075 100644 --- a/dbms/src/Common/Config/ConfigProcessor.cpp +++ b/dbms/src/Common/Config/ConfigProcessor.cpp @@ -211,7 +211,7 @@ void ConfigProcessor::mergeRecursive(XMLDocumentPtr config, Node * config_root, void ConfigProcessor::merge(XMLDocumentPtr config, XMLDocumentPtr with) { Node * config_root = getRootNode(&*config); - const Node * with_root = getRootNode(&*with); + Node * with_root = getRootNode(&*with); if (config_root->nodeName() != with_root->nodeName()) throw Poco::Exception("Root element doesn't have the corresponding root element as the config file. It must be <" + config_root->nodeName() + ">"); From 4bee54cd93824a5b69d163f58eb169a39329d96f Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Tue, 23 Jul 2019 16:40:16 +0300 Subject: [PATCH 0281/1165] integration test added --- .../configs/config.d/bad.xml | 4 + .../configs/config.xml | 415 ++++++++++++++++++ .../configs/users.xml | 130 ++++++ .../test_config_corresponding_root/test.py | 22 + 4 files changed, 571 insertions(+) create mode 100644 dbms/tests/integration/test_config_corresponding_root/configs/config.d/bad.xml create mode 100644 dbms/tests/integration/test_config_corresponding_root/configs/config.xml create mode 100644 dbms/tests/integration/test_config_corresponding_root/configs/users.xml create mode 100644 dbms/tests/integration/test_config_corresponding_root/test.py diff --git a/dbms/tests/integration/test_config_corresponding_root/configs/config.d/bad.xml b/dbms/tests/integration/test_config_corresponding_root/configs/config.d/bad.xml new file mode 100644 index 00000000000..9398be257eb --- /dev/null +++ b/dbms/tests/integration/test_config_corresponding_root/configs/config.d/bad.xml @@ -0,0 +1,4 @@ + + + + diff --git a/dbms/tests/integration/test_config_corresponding_root/configs/config.xml b/dbms/tests/integration/test_config_corresponding_root/configs/config.xml new file mode 100644 index 00000000000..154ebf6c35e --- /dev/null +++ b/dbms/tests/integration/test_config_corresponding_root/configs/config.xml @@ -0,0 +1,415 @@ + + + + + + trace + /var/log/clickhouse-server/clickhouse-server.log + /var/log/clickhouse-server/clickhouse-server.err.log + 1000M + 10 + + + + 8123 + 9000 + + + + + + + + + /etc/clickhouse-server/server.crt + /etc/clickhouse-server/server.key + + /etc/clickhouse-server/dhparam.pem + none + true + true + sslv2,sslv3 + true + + + + true + true + sslv2,sslv3 + true + + + + RejectCertificateHandler + + + + + + + + + 9009 + + + + + + + + + + + + + + + + + + + + 4096 + 3 + + + 100 + + + + + + 8589934592 + + + 5368709120 + + + + /var/lib/clickhouse/ + + + /var/lib/clickhouse/tmp/ + + + /var/lib/clickhouse/user_files/ + + + users.xml + + + default + + + + + + default + + + + + + + + + false + + + + + + + + localhost + 9000 + + + + + + + localhost + 9000 + + + + + localhost + 9000 + + + + + + + localhost + 9440 + 1 + + + + + + + localhost + 9000 + + + + + localhost + 1 + + + + + + + + + + + + + + + + + 3600 + + + + 3600 + + + 60 + + + + + + + + + + system + query_log
    + + toYYYYMM(event_date) + + 7500 +
    + + + + system + query_thread_log
    + toYYYYMM(event_date) + 7500 +
    + + + + + + + + + + + + + + + *_dictionary.xml + + + + + + + + + + /clickhouse/task_queue/ddl + + + + + + + + + + + + + + + + click_cost + any + + 0 + 3600 + + + 86400 + 60 + + + + max + + 0 + 60 + + + 3600 + 300 + + + 86400 + 3600 + + + + + + /var/lib/clickhouse/format_schemas/ + + + +
    diff --git a/dbms/tests/integration/test_config_corresponding_root/configs/users.xml b/dbms/tests/integration/test_config_corresponding_root/configs/users.xml new file mode 100644 index 00000000000..24b8f628c3a --- /dev/null +++ b/dbms/tests/integration/test_config_corresponding_root/configs/users.xml @@ -0,0 +1,130 @@ + + + + + + + + 10000000000 + + + 0 + + + random + + + + + 1 + + + + + + + + + + + + + ::/0 + + + + default + + + default + + + + + + + a = 1 + + + + + a + b < 1 or c - d > 5 + + + + + c = 1 + + + + + + + + + + + + + + + + + 3600 + + + 0 + 0 + 0 + 0 + 0 + + + + diff --git a/dbms/tests/integration/test_config_corresponding_root/test.py b/dbms/tests/integration/test_config_corresponding_root/test.py new file mode 100644 index 00000000000..c29f0b53c3a --- /dev/null +++ b/dbms/tests/integration/test_config_corresponding_root/test.py @@ -0,0 +1,22 @@ +import os +import pytest + +from helpers.cluster import ClickHouseCluster + +SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) +config_dir = os.path.join(SCRIPT_DIR, './configs') + +cluster = ClickHouseCluster(__file__) +node = cluster.add_instance('node', config_dir = config_dir) +caught_exception = "" + +@pytest.fixture(scope="module") +def start_cluster(): + global caught_exception + try: + cluster.start() + except Exception as e: + caught_exception = str(e) + +def test_work(start_cluster): + assert caught_exception.find("Root element doesn't have the corresponding root element as the config file.") != -1 From 2068e1f0e0cc74dae27115e70c44891743f18033 Mon Sep 17 00:00:00 2001 From: Vitaly Baranov Date: Tue, 23 Jul 2019 16:34:05 +0300 Subject: [PATCH 0282/1165] Add more protobuf IO tests. --- .../0_stateless/00825_protobuf_format.proto | 6 +++ .../00825_protobuf_format_input.insh | 1 + .../00825_protobuf_format_input.reference | 3 ++ .../00825_protobuf_format_input.sh | 5 ++ .../00825_protobuf_format_output.reference | Bin 2412 -> 2433 bytes .../00825_protobuf_format_output.sh | 7 +++ .../ProtobufDelimitedMessagesSerializer.cpp | 46 ++++++++++++++++++ 7 files changed, 68 insertions(+) diff --git a/dbms/tests/queries/0_stateless/00825_protobuf_format.proto b/dbms/tests/queries/0_stateless/00825_protobuf_format.proto index b588619f488..0d9bdd83ccd 100644 --- a/dbms/tests/queries/0_stateless/00825_protobuf_format.proto +++ b/dbms/tests/queries/0_stateless/00825_protobuf_format.proto @@ -143,3 +143,9 @@ message StrPerson { MeasureUnits measureUnits = 21; NestinessA nestiness_a = 22; }; + +message NumberAndSquare +{ + uint32 number = 1; + uint64 square = 2; +}; diff --git a/dbms/tests/queries/0_stateless/00825_protobuf_format_input.insh b/dbms/tests/queries/0_stateless/00825_protobuf_format_input.insh index 7aed4487a56..39a2f17c98f 100644 --- a/dbms/tests/queries/0_stateless/00825_protobuf_format_input.insh +++ b/dbms/tests/queries/0_stateless/00825_protobuf_format_input.insh @@ -2,3 +2,4 @@ echo -ne '\xf3\x01\x0a\x24\x61\x37\x35\x32\x32\x31\x35\x38\x2d\x33\x64\x34\x31\x echo -ne '\xb3\x01\x12\x05\x46\x72\x69\x64\x61\x28\x99\xe1\xf3\xd1\x0b\x52\x08\x45\x72\x6d\x61\x6b\x6f\x76\x61\x72\x0c\x00\x00\xdc\x42\x00\x00\x52\x43\x00\x00\x94\x42\x79\x48\xce\x3d\x51\x00\x00\x00\x00\xc8\x02\x14\xc2\x05\x08\x00\x00\x80\x44\x00\x00\x80\x49\x9a\x06\x02\x4b\x42\x9a\x06\x02\x4d\x42\xa1\x06\x00\x00\x00\x00\x00\x00\xe0\x3f\xa8\x06\x2a\xa8\x06\xa8\xff\xff\xff\xff\xff\xff\xff\xff\x01\xb0\x06\x01\xbd\x06\x25\x06\x49\x40\xfa\x06\x02\x34\x30\x90\x08\xe2\x08\xe1\x08\x89\xe6\x6e\xdd\x01\x00\x00\x00\xb0\x09\xc3\x19\xd0\x0c\xb7\x02\xe2\x12\x24\x32\x30\x66\x63\x64\x39\x35\x61\x2d\x33\x33\x32\x64\x2d\x34\x31\x64\x62\x2d\x61\x39\x65\x63\x2d\x31\x36\x31\x66\x36\x34\x34\x64\x30\x35\x39\x63\xa0\x38\xbc\x05\xaa\x38\x02\xbd\x05\xb4\x01\x08\x01\x12\x06\x49\x73\x6f\x6c\x64\x65\x52\x07\x4c\x61\x76\x72\x6f\x76\x61\x72\x0c\x00\x00\x7f\x43\x00\x00\x00\x00\x00\x00\x7f\x43\xaa\x01\x03\x61\x62\x63\xc8\x02\x32\xc2\x05\x08\x00\x00\x00\x41\x00\x00\x80\x3f\x9a\x06\x04\x42\x79\x74\x65\x9a\x06\x03\x42\x69\x74\xa1\x06\x00\x00\x00\x00\x00\x00\x12\x40\xa8\x06\x1a\xa8\x06\xb0\xff\xff\xff\xff\xff\xff\xff\xff\x01\xb0\x06\x01\xbd\x06\xf9\x0f\x49\x40\xc2\x06\x01\x2c\xfa\x06\x02\x33\x32\x90\x08\x78\xe1\x08\x39\x4e\x2b\xfe\xe4\xf5\xff\xff\xb0\x09\xe8\x30\xd8\x12\x01\xe2\x12\x24\x37\x63\x66\x61\x36\x38\x35\x36\x2d\x61\x35\x34\x61\x2d\x34\x37\x38\x36\x2d\x62\x38\x65\x35\x2d\x37\x34\x35\x31\x35\x39\x64\x35\x32\x32\x37\x38\xa0\x38\xbe\x05\xc2\x3e\x05\x15\x00\x00\xb6\x42' | $CLICKHOUSE_CLIENT --query="INSERT INTO in_persons_00825 FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format:AltPerson'" echo -ne '\xa5\x02\x0a\x24\x61\x61\x30\x65\x35\x61\x30\x36\x2d\x63\x61\x62\x32\x2d\x34\x30\x33\x34\x2d\x61\x36\x61\x32\x2d\x34\x38\x65\x38\x32\x62\x39\x31\x36\x36\x34\x65\x12\x06\x4c\x65\x6f\x6e\x69\x64\x1a\x08\x4b\x69\x72\x69\x6c\x6c\x6f\x76\x22\x04\x6d\x61\x6c\x65\x2a\x0a\x31\x39\x38\x33\x2d\x30\x36\x2d\x32\x34\x3a\x0c\x2b\x37\x34\x39\x35\x30\x32\x37\x35\x38\x36\x34\x42\x01\x31\x4a\x13\x32\x30\x31\x39\x2d\x30\x32\x2d\x30\x34\x20\x30\x39\x3a\x34\x35\x3a\x30\x30\x52\x02\x33\x35\x5a\x06\x63\x61\x6e\x63\x65\x72\x62\x07\x37\x20\x72\x69\x6e\x67\x73\x62\x08\x45\x61\x73\x74\x73\x69\x64\x65\x62\x0b\x4c\x61\x73\x74\x20\x48\x75\x72\x72\x61\x68\x6a\x01\x30\x6a\x01\x30\x6a\x03\x32\x35\x35\x72\x09\x53\x61\x6e\x20\x44\x69\x65\x67\x6f\x7a\x09\x33\x32\x2e\x38\x32\x33\x39\x34\x33\x7a\x0b\x2d\x31\x31\x37\x2e\x30\x38\x31\x33\x32\x37\x82\x01\x09\x33\x2e\x31\x34\x31\x35\x39\x32\x37\x8a\x01\x08\x31\x35\x30\x30\x30\x30\x30\x30\x92\x01\x06\x31\x38\x36\x2e\x37\x35\x9a\x01\x04\x2d\x32\x2e\x31\xa2\x01\x0b\x32\x30\x36\x35\x39\x38\x32\x39\x33\x33\x31\xaa\x01\x18\x0a\x06\x6d\x69\x6e\x75\x74\x65\x0a\x04\x68\x6f\x75\x72\x12\x02\x36\x30\x12\x04\x33\x36\x30\x30\xb2\x01\x08\x0a\x06\x12\x04\x31\x38\x30\x30' | $CLICKHOUSE_CLIENT --query="INSERT INTO in_persons_00825 FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format:StrPerson'" echo -ne '\xdd\x01\x0a\x24\x33\x66\x61\x65\x65\x30\x36\x34\x2d\x63\x34\x66\x37\x2d\x34\x64\x33\x34\x2d\x62\x36\x66\x33\x2d\x38\x64\x38\x31\x63\x32\x62\x36\x61\x31\x35\x64\x12\x04\x4e\x69\x63\x6b\x1a\x0a\x4b\x6f\x6c\x65\x73\x6e\x69\x6b\x6f\x76\x20\x01\x28\xda\x52\x32\x03\x62\x6d\x70\x3a\x0c\x34\x31\x32\x2d\x36\x38\x37\x2d\x35\x30\x30\x37\x40\x01\x4d\x2f\x27\xf2\x5b\x50\x14\x58\x09\x62\x06\x48\x61\x76\x61\x6e\x61\x68\x80\x01\x68\x00\x68\x80\x01\x72\x0a\x50\x69\x74\x74\x73\x62\x75\x72\x67\x68\x7a\x08\x9b\x11\x22\x42\x1f\xe6\x9f\xc2\x81\x01\x28\x2d\x44\x54\xfb\x21\x09\x40\x89\x01\x00\x00\x00\xe8\x76\x48\x27\x42\x95\x01\x00\x00\x43\x44\x9d\x01\x66\x66\x92\x41\xa0\x01\xce\xdf\xb8\xba\x01\xab\x01\x0d\xcd\xcc\xe2\x41\x0d\xcd\xcc\x4c\x3e\x0d\x00\x00\x80\x3f\x12\x05\x6f\x75\x6e\x63\x65\x12\x05\x63\x61\x72\x61\x74\x12\x04\x67\x72\x61\x6d\xac\x01\xb3\x01\x0b\xa2\x06\x05\x0b\x08\x96\x4a\x0c\x0c\xb4\x01' | $CLICKHOUSE_CLIENT --query="INSERT INTO in_persons_00825 FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format_syntax2:Syntax2Person'" +echo -ne '\x04\x08\x02\x10\x04\x00\x04\x08\x03\x10\x09' | $CLICKHOUSE_CLIENT --query="INSERT INTO in_squares_00825 FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format:NumberAndSquare'" diff --git a/dbms/tests/queries/0_stateless/00825_protobuf_format_input.reference b/dbms/tests/queries/0_stateless/00825_protobuf_format_input.reference index e374ff0bcf6..884cc74c4e5 100644 --- a/dbms/tests/queries/0_stateless/00825_protobuf_format_input.reference +++ b/dbms/tests/queries/0_stateless/00825_protobuf_format_input.reference @@ -5,3 +5,6 @@ aa0e5a06-cab2-4034-a6a2-48e82b91664e Leonid Kirillov male 1983-06-24 \N +7495027 a7522158-3d41-4b77-ad69-6c598ee55c49 Ivan Petrov male 1980-12-29 png +74951234567\0 1 2019-01-05 18:45:00 38 capricorn ['Yesterday','Flowers'] [255,0,0] Moscow [55.753216,37.622504] 3.14 214.10 0.1 5.8 17060000000 ['meter','centimeter','kilometer'] [1,0.01,1000] 500 [501,502] 3faee064-c4f7-4d34-b6f3-8d81c2b6a15d Nick Kolesnikov male 1998-12-26 bmp 412-687-5007\0 1 2018-11-19 05:59:59 20 capricorn ['Havana'] [128,0,128] Pittsburgh [40.517192,-79.949456] 3.1415926535898 50000000000.00 780 18.3 195500007 ['ounce','carat','gram'] [28.35,0.2,1] 9494 [] 7cfa6856-a54a-4786-b8e5-745159d52278 Isolde Lavrova female 1987-02-09 \N \N 1 \N 32 aquarius [] [255,0,255] [26.000000,-80.000000] 3.1415998935699463 \N 4.5 25.0 -11111111111111 ['Byte','Bit'] [8,1] 702 [] +0 0 +2 4 +3 9 diff --git a/dbms/tests/queries/0_stateless/00825_protobuf_format_input.sh b/dbms/tests/queries/0_stateless/00825_protobuf_format_input.sh index a2efad352aa..d28b70bb002 100755 --- a/dbms/tests/queries/0_stateless/00825_protobuf_format_input.sh +++ b/dbms/tests/queries/0_stateless/00825_protobuf_format_input.sh @@ -8,6 +8,7 @@ set -e -o pipefail # Run the client. $CLICKHOUSE_CLIENT --multiquery <<'EOF' DROP TABLE IF EXISTS in_persons_00825; +DROP TABLE IF EXISTS in_squares_00825; CREATE TABLE in_persons_00825 (uuid UUID, name String, @@ -35,6 +36,8 @@ CREATE TABLE in_persons_00825 (uuid UUID, nestiness_a_b_c_d Nullable(UInt32), `nestiness_a_B.c_E` Array(UInt32) ) ENGINE = MergeTree ORDER BY tuple(); + +CREATE TABLE in_squares_00825 (number UInt32, square UInt32) ENGINE = MergeTree ORDER BY tuple(); EOF # To generate the file 00825_protobuf_format_input.insh use the following commands: @@ -43,5 +46,7 @@ EOF source $CURDIR/00825_protobuf_format_input.insh $CLICKHOUSE_CLIENT --query "SELECT * FROM in_persons_00825 ORDER BY uuid;" +$CLICKHOUSE_CLIENT --query "SELECT * FROM in_squares_00825 ORDER BY number;" $CLICKHOUSE_CLIENT --query "DROP TABLE IF EXISTS in_persons_00825;" +$CLICKHOUSE_CLIENT --query "DROP TABLE IF EXISTS in_squares_00825;" diff --git a/dbms/tests/queries/0_stateless/00825_protobuf_format_output.reference b/dbms/tests/queries/0_stateless/00825_protobuf_format_output.reference index 7387762c8eca06137abeb8a845076e51de64580f..9d20d778ff6ac82cc23b20eed6ed833bb628fcb8 100644 GIT binary patch delta 29 kcmaDO)F`|mhf_2-Fw`-~HCWe'; @@ -51,6 +55,9 @@ SELECT 'STRINGS->'; SELECT * FROM out_persons_00825 ORDER BY name FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format:StrPerson'; SELECT 'SYNTAX2->'; SELECT * FROM out_persons_00825 ORDER BY name FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format_syntax2:Syntax2Person'; +SELECT 'SQUARES->'; +SELECT * FROM out_squares_00825 ORDER BY number FORMAT Protobuf SETTINGS format_schema = '$CURDIR/00825_protobuf_format:NumberAndSquare'; DROP TABLE IF EXISTS out_persons_00825; +DROP TABLE IF EXISTS out_squares_00825; EOF diff --git a/utils/test-data-generator/ProtobufDelimitedMessagesSerializer.cpp b/utils/test-data-generator/ProtobufDelimitedMessagesSerializer.cpp index 92ed44dc28b..c956dea8712 100644 --- a/utils/test-data-generator/ProtobufDelimitedMessagesSerializer.cpp +++ b/utils/test-data-generator/ProtobufDelimitedMessagesSerializer.cpp @@ -263,6 +263,29 @@ void writeInsertDataQueriesForInputTest(std::ostream & out) } writeInsertDataQueryForInputTest(ss, "in_persons_00825", "00825_protobuf_format_syntax2:Syntax2Person", out); + + { + NumberAndSquare ns; + ns.set_number(2); + ns.set_square(4); + google::protobuf::util::SerializeDelimitedToOstream(ns, &ss); + } + + { + NumberAndSquare ns; + ns.set_number(0); + ns.set_square(0); + google::protobuf::util::SerializeDelimitedToOstream(ns, &ss); + } + + { + NumberAndSquare ns; + ns.set_number(3); + ns.set_square(9); + google::protobuf::util::SerializeDelimitedToOstream(ns, &ss); + } + + writeInsertDataQueryForInputTest(ss, "in_squares_00825", "00825_protobuf_format:NumberAndSquare", out); } @@ -637,6 +660,29 @@ void writeReferenceForOutputTest(std::ostream & out) person.mutable_nestiness()->mutable_a()->mutable_b()->mutable_c()->set_d(503); google::protobuf::util::SerializeDelimitedToOstream(person, &out); } + + out << "SQUARES->" << std::endl; + + { + NumberAndSquare ns; + ns.set_number(0); + ns.set_square(0); + google::protobuf::util::SerializeDelimitedToOstream(ns, &out); + } + + { + NumberAndSquare ns; + ns.set_number(2); + ns.set_square(4); + google::protobuf::util::SerializeDelimitedToOstream(ns, &out); + } + + { + NumberAndSquare ns; + ns.set_number(3); + ns.set_square(9); + google::protobuf::util::SerializeDelimitedToOstream(ns, &out); + } } From 746066be48ebc90972fc050aefc582d87decc76c Mon Sep 17 00:00:00 2001 From: Vitaly Baranov Date: Tue, 23 Jul 2019 17:02:15 +0300 Subject: [PATCH 0283/1165] Remove excessive `throw` in a correct case. --- dbms/src/Formats/ProtobufReader.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/dbms/src/Formats/ProtobufReader.cpp b/dbms/src/Formats/ProtobufReader.cpp index ac45c1d94ee..669fd37406e 100644 --- a/dbms/src/Formats/ProtobufReader.cpp +++ b/dbms/src/Formats/ProtobufReader.cpp @@ -68,8 +68,6 @@ bool ProtobufReader::SimpleReader::startMessage() if (unlikely(in.eof())) return false; size_t size_of_message = readVarint(); - if (size_of_message == 0) - throwUnknownFormat(); current_message_end = cursor + size_of_message; root_message_end = current_message_end; } From 1b00e99334323b4a0ae7ef2e6655d131a42ae3f0 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 23 Jul 2019 17:30:14 +0300 Subject: [PATCH 0284/1165] Fixed error with initialization of query profiler --- dbms/src/Interpreters/ThreadStatusExt.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dbms/src/Interpreters/ThreadStatusExt.cpp b/dbms/src/Interpreters/ThreadStatusExt.cpp index c1fcf72667b..e5e9b92507c 100644 --- a/dbms/src/Interpreters/ThreadStatusExt.cpp +++ b/dbms/src/Interpreters/ThreadStatusExt.cpp @@ -41,8 +41,6 @@ void ThreadStatus::attachQueryContext(Context & query_context_) if (!thread_group->global_context) thread_group->global_context = global_context; } - - initQueryProfiler(); } void CurrentThread::defaultThreadDeleter() @@ -124,6 +122,7 @@ void ThreadStatus::attachQuery(const ThreadGroupStatusPtr & thread_group_, bool #endif initPerformanceCounters(); + initQueryProfiler(); thread_state = ThreadState::AttachedToQuery; } @@ -155,7 +154,7 @@ void ThreadStatus::finalizePerformanceCounters() void ThreadStatus::initQueryProfiler() { /// query profilers are useless without trace collector - if (!global_context->hasTraceCollector()) + if (!global_context || !global_context->hasTraceCollector()) return; const auto & settings = query_context->getSettingsRef(); From 752eccf2eb30476851b04bdf9f916c64a5a7584d Mon Sep 17 00:00:00 2001 From: dimarub2000 Date: Tue, 23 Jul 2019 17:41:41 +0300 Subject: [PATCH 0285/1165] changes after review --- dbms/src/Common/Config/ConfigProcessor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Common/Config/ConfigProcessor.cpp b/dbms/src/Common/Config/ConfigProcessor.cpp index 6b90ab23075..acf58abfbb4 100644 --- a/dbms/src/Common/Config/ConfigProcessor.cpp +++ b/dbms/src/Common/Config/ConfigProcessor.cpp @@ -210,8 +210,8 @@ void ConfigProcessor::mergeRecursive(XMLDocumentPtr config, Node * config_root, void ConfigProcessor::merge(XMLDocumentPtr config, XMLDocumentPtr with) { - Node * config_root = getRootNode(&*config); - Node * with_root = getRootNode(&*with); + Node * config_root = getRootNode(config.get()); + Node * with_root = getRootNode(with.get()); if (config_root->nodeName() != with_root->nodeName()) throw Poco::Exception("Root element doesn't have the corresponding root element as the config file. It must be <" + config_root->nodeName() + ">"); From 811e3ab241b60d3b78ec5e5f424dee95ed7eaa8e Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Tue, 23 Jul 2019 17:50:38 +0300 Subject: [PATCH 0286/1165] style check --- dbms/src/Interpreters/Context.cpp | 6 +++--- dbms/src/Interpreters/Context.h | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index ab84fbc7364..6ae6bcb6d5b 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -1702,14 +1702,14 @@ std::shared_ptr Context::getTextLog() return shared->system_logs->text_log; } - - + + std::shared_ptr Context::getTraceLog() { auto lock = getLock(); if (!shared->system_logs || !shared->system_logs->trace_log) - return nullptr; + return {}; return shared->system_logs->trace_log; } diff --git a/dbms/src/Interpreters/Context.h b/dbms/src/Interpreters/Context.h index 3aa1422ffaa..2c5e0511efa 100644 --- a/dbms/src/Interpreters/Context.h +++ b/dbms/src/Interpreters/Context.h @@ -429,7 +429,6 @@ public: std::shared_ptr getQueryLog(); std::shared_ptr getQueryThreadLog(); std::shared_ptr getTextLog(); - std::shared_ptr getTraceLog(); /// Returns an object used to log opertaions with parts if it possible. From 1913bfa27664a8e586885032dca243954655a095 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 23 Jul 2019 17:59:29 +0300 Subject: [PATCH 0287/1165] Added cache for symbolizeAddress function --- dbms/src/Functions/symbolizeAddress.cpp | 30 ++++++++++++++++++------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/dbms/src/Functions/symbolizeAddress.cpp b/dbms/src/Functions/symbolizeAddress.cpp index 3c39155e8b4..d196899939a 100644 --- a/dbms/src/Functions/symbolizeAddress.cpp +++ b/dbms/src/Functions/symbolizeAddress.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include #include #include @@ -71,21 +73,33 @@ public: const typename ColumnVector::Container & data = column_concrete->getData(); auto result_column = ColumnString::create(); + std::unordered_map cache; + for (size_t i = 0; i < input_rows_count; ++i) { void * addr = unalignedLoad(&data[i]); - Dl_info info; - /// This is unsafe. The function dladdr may loop infinitely. - /// Reproduce with query: SELECT DISTINCT symbolizeAddress(number) FROM system.numbers - if (dladdr(addr, &info) && info.dli_sname) + if (auto it = cache.find(addr); it != cache.end()) { - int demangling_status = 0; - std::string demangled_name = demangle(info.dli_sname, demangling_status); - result_column->insertDataWithTerminatingZero(demangled_name.data(), demangled_name.size() + 1); + result_column->insertDataWithTerminatingZero(it->second.data(), it->second.size() + 1); } else - result_column->insertDefault(); + { + /// This is extremely slow. + Dl_info info; + if (dladdr(addr, &info) && info.dli_sname) + { + int demangling_status = 0; + std::string demangled_name = demangle(info.dli_sname, demangling_status); + result_column->insertDataWithTerminatingZero(demangled_name.data(), demangled_name.size() + 1); + cache.emplace(addr, demangled_name); + } + else + { + cache.emplace(addr, std::string()); + result_column->insertDefault(); + } + } } block.getByPosition(result).column = std::move(result_column); From 6e458a6a6863a89d55d4fb0a667c57f0c37d0da2 Mon Sep 17 00:00:00 2001 From: alesapin Date: Tue, 23 Jul 2019 18:27:36 +0300 Subject: [PATCH 0288/1165] Fix secondary indices write with adaptive granularity --- .../MergeTree/MergedBlockOutputStream.cpp | 10 ++-- .../MergeTree/MergedBlockOutputStream.h | 1 + ...tive_granularity_secondary_index.reference | 2 + ...4_adaptive_granularity_secondary_index.sql | 56 +++++++++++++++++++ 4 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00974_adaptive_granularity_secondary_index.reference create mode 100644 dbms/tests/queries/0_stateless/00974_adaptive_granularity_secondary_index.sql diff --git a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp index 8b38f1ff32e..5ed783c034f 100644 --- a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp @@ -381,18 +381,18 @@ void MergedBlockOutputStream::writeImpl(const Block & block, const IColumn::Perm } rows_count += rows; - { /// Creating block for update Block indices_update_block(skip_indexes_columns); + size_t skip_index_current_mark = 0; + /// Filling and writing skip indices like in IMergedBlockOutputStream::writeColumn for (size_t i = 0; i < storage.skip_indices.size(); ++i) { const auto index = storage.skip_indices[i]; auto & stream = *skip_indices_streams[i]; size_t prev_pos = 0; - - size_t skip_index_current_mark = 0; + skip_index_current_mark = skip_index_mark; while (prev_pos < rows) { UInt64 limit = 0; @@ -417,6 +417,8 @@ void MergedBlockOutputStream::writeImpl(const Block & block, const IColumn::Perm /// to be compatible with normal .mrk2 file format if (storage.canUseAdaptiveGranularity()) writeIntBinary(1UL, stream.marks); + + ++skip_index_current_mark; } } @@ -435,9 +437,9 @@ void MergedBlockOutputStream::writeImpl(const Block & block, const IColumn::Perm } } prev_pos = pos; - ++skip_index_current_mark; } } + skip_index_mark = skip_index_current_mark; } { diff --git a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.h b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.h index 467660413b3..3acb01c3c0a 100644 --- a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.h +++ b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.h @@ -68,6 +68,7 @@ private: String part_path; size_t rows_count = 0; + size_t skip_index_mark = 0; std::unique_ptr index_file_stream; std::unique_ptr index_stream; diff --git a/dbms/tests/queries/0_stateless/00974_adaptive_granularity_secondary_index.reference b/dbms/tests/queries/0_stateless/00974_adaptive_granularity_secondary_index.reference new file mode 100644 index 00000000000..5878ba47225 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_adaptive_granularity_secondary_index.reference @@ -0,0 +1,2 @@ +1000 +1000 diff --git a/dbms/tests/queries/0_stateless/00974_adaptive_granularity_secondary_index.sql b/dbms/tests/queries/0_stateless/00974_adaptive_granularity_secondary_index.sql new file mode 100644 index 00000000000..fe43237ccbb --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_adaptive_granularity_secondary_index.sql @@ -0,0 +1,56 @@ +SET allow_experimental_data_skipping_indices = 1; + +DROP TABLE IF EXISTS indexed_table; + +CREATE TABLE indexed_table +( + `tm` DateTime, + `log_message` String, + INDEX log_message log_message TYPE tokenbf_v1(4096, 2, 0) GRANULARITY 1 +) +ENGINE = MergeTree +ORDER BY (tm) +SETTINGS index_granularity_bytes = 50; + +INSERT INTO indexed_table SELECT toDateTime('2019-05-27 10:00:00') + number % 100, 'h' FROM numbers(1000); + +INSERT INTO indexed_table +SELECT + toDateTime('2019-05-27 10:00:00') + number % 100, + concat('hhhhhhhhhhhhhhhhhhhhhhhhh', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'yyyyyyyyyyyyyyyyyyyyyyyyyy', reinterpretAsString(rand())) +FROM numbers(1000); + +OPTIMIZE TABLE indexed_table FINAL; + +SELECT COUNT() FROM indexed_table WHERE log_message like '%x%'; + +DROP TABLE IF EXISTS indexed_table; + +DROP TABLE IF EXISTS another_indexed_table; + +CREATE TABLE another_indexed_table +( + `tm` DateTime, + `log_message` String, + INDEX log_message log_message TYPE tokenbf_v1(4096, 2, 0) GRANULARITY 1 +) +ENGINE = MergeTree +ORDER BY (tm) +SETTINGS index_granularity_bytes = 50, + vertical_merge_algorithm_min_rows_to_activate=0, + vertical_merge_algorithm_min_columns_to_activate=0; + + +INSERT INTO another_indexed_table SELECT toDateTime('2019-05-27 10:00:00') + number % 100, 'h' FROM numbers(1000); + +INSERT INTO another_indexed_table +SELECT + toDateTime('2019-05-27 10:00:00') + number % 100, + concat('hhhhhhhhhhhhhhhhhhhhhhhhh', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'yyyyyyyyyyyyyyyyyyyyyyyyyy', reinterpretAsString(rand())) + FROM numbers(1000); + +OPTIMIZE TABLE another_indexed_table FINAL; + +SELECT COUNT() FROM another_indexed_table WHERE log_message like '%x%'; + +DROP TABLE IF EXISTS another_indexed_table; From e8ef13edfa2624aac5a8f1d6ff679ac2968f9ade Mon Sep 17 00:00:00 2001 From: Ivan Lezhankin Date: Tue, 23 Jul 2019 20:34:57 +0300 Subject: [PATCH 0289/1165] Check background_task_handle --- dbms/src/Storages/MergeTree/MergeTreeBlockOutputStream.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dbms/src/Storages/MergeTree/MergeTreeBlockOutputStream.cpp b/dbms/src/Storages/MergeTree/MergeTreeBlockOutputStream.cpp index f5b656a9364..6aa9b07df73 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeBlockOutputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeBlockOutputStream.cpp @@ -27,7 +27,8 @@ void MergeTreeBlockOutputStream::write(const Block & block) PartLog::addNewPart(storage.global_context, part, watch.elapsed()); /// Initiate async merge - it will be done if it's good time for merge and if there are space in 'background_pool'. - storage.background_task_handle->wake(); + if (storage.background_task_handle) + storage.background_task_handle->wake(); } } From 3a1bc23370156f3bbf7544cbf02da5f8197f3f92 Mon Sep 17 00:00:00 2001 From: proller Date: Tue, 23 Jul 2019 20:42:48 +0300 Subject: [PATCH 0290/1165] Fix double-conversion include for copy-headers --- cmake/print_include_directories.cmake | 3 +++ contrib/double-conversion-cmake/CMakeLists.txt | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cmake/print_include_directories.cmake b/cmake/print_include_directories.cmake index 05be8f909ee..b39ca866148 100644 --- a/cmake/print_include_directories.cmake +++ b/cmake/print_include_directories.cmake @@ -16,6 +16,9 @@ list(APPEND dirs ${dirs1}) get_property (dirs1 TARGET roaring PROPERTY INCLUDE_DIRECTORIES) list(APPEND dirs ${dirs1}) +get_property (dirs1 TARGET double-conversion PROPERTY INCLUDE_DIRECTORIES) +list(APPEND dirs ${dirs1}) + if (USE_INTERNAL_BOOST_LIBRARY) get_property (dirs1 TARGET ${Boost_PROGRAM_OPTIONS_LIBRARY} PROPERTY INCLUDE_DIRECTORIES) list(APPEND dirs ${dirs1}) diff --git a/contrib/double-conversion-cmake/CMakeLists.txt b/contrib/double-conversion-cmake/CMakeLists.txt index 8b808b8de9a..0690731e1b1 100644 --- a/contrib/double-conversion-cmake/CMakeLists.txt +++ b/contrib/double-conversion-cmake/CMakeLists.txt @@ -10,4 +10,4 @@ ${LIBRARY_DIR}/double-conversion/fast-dtoa.cc ${LIBRARY_DIR}/double-conversion/fixed-dtoa.cc ${LIBRARY_DIR}/double-conversion/strtod.cc) -target_include_directories(double-conversion SYSTEM PUBLIC "${LIBRARY_DIR}") +target_include_directories(double-conversion SYSTEM BEFORE PUBLIC "${LIBRARY_DIR}") From 02fb67dc8af7da7e85399fe67bdb3917a3563b70 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 23 Jul 2019 21:45:54 +0300 Subject: [PATCH 0291/1165] Simple protection from too frequent profiler signals --- dbms/src/Common/QueryProfiler.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index 9832b64ee8b..b98d57a1d3b 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -20,8 +20,13 @@ namespace /// Thus upper bound on query_id length should be introduced to avoid buffer overflow in signal handler. constexpr size_t QUERY_ID_MAX_LEN = 1024; - void writeTraceInfo(TimerType timer_type, int /* sig */, siginfo_t * /* info */, void * context) + void writeTraceInfo(TimerType timer_type, int /* sig */, siginfo_t * info, void * context) { + /// Quickly drop if signal handler is called too frequently. + /// Otherwise we may end up infinitelly processing signals instead of doing any useful work. + if (info && info->si_overrun > 0) + return; + constexpr size_t buf_size = sizeof(char) + // TraceCollector stop flag 8 * sizeof(char) + // maximum VarUInt length for string size QUERY_ID_MAX_LEN * sizeof(char) + // maximum query_id length From 60c4eaedb8f23f9c0030e245128cc378d2f8445c Mon Sep 17 00:00:00 2001 From: proller Date: Tue, 23 Jul 2019 22:23:57 +0300 Subject: [PATCH 0292/1165] Fix zlib link --- dbms/src/Functions/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/dbms/src/Functions/CMakeLists.txt b/dbms/src/Functions/CMakeLists.txt index 13b294197cf..5b8bfca2cd6 100644 --- a/dbms/src/Functions/CMakeLists.txt +++ b/dbms/src/Functions/CMakeLists.txt @@ -22,6 +22,7 @@ target_link_libraries(clickhouse_functions ${BASE64_LIBRARY} PRIVATE + ${ZLIB_LIBRARIES} ${Boost_FILESYSTEM_LIBRARY} ) From 9da1b0089c5867536a0d113d1a36e45395ac108b Mon Sep 17 00:00:00 2001 From: chertus Date: Tue, 23 Jul 2019 22:49:15 +0300 Subject: [PATCH 0293/1165] visitor for JOIN ON keys extraction --- .../Interpreters/CollectJoinOnKeysVisitor.h | 147 ++++++++++++++++++ dbms/src/Interpreters/InDepthNodeVisitor.h | 16 +- dbms/src/Interpreters/SyntaxAnalyzer.cpp | 125 +-------------- 3 files changed, 166 insertions(+), 122 deletions(-) create mode 100644 dbms/src/Interpreters/CollectJoinOnKeysVisitor.h diff --git a/dbms/src/Interpreters/CollectJoinOnKeysVisitor.h b/dbms/src/Interpreters/CollectJoinOnKeysVisitor.h new file mode 100644 index 00000000000..aacfbe507a1 --- /dev/null +++ b/dbms/src/Interpreters/CollectJoinOnKeysVisitor.h @@ -0,0 +1,147 @@ +#pragma once + +#include +#include + +#include +#include + +namespace DB +{ + +namespace ErrorCodes +{ + extern const int INVALID_JOIN_ON_EXPRESSION; +} + + +class CollectJoinOnKeysMatcher +{ +public: + using Visitor = ConstInDepthNodeVisitor; + + struct Data + { + AnalyzedJoin & analyzed_join; + bool has_some = false; + }; + + static void visit(const ASTPtr & ast, Data & data) + { + if (auto * func = ast->as()) + visit(*func, ast, data); + } + + static bool needChildVisit(const ASTPtr & node, const ASTPtr &) + { + if (auto * func = node->as()) + if (func->name == "equals") + return false; + return true; + } + +private: + static void visit(const ASTFunction & func, const ASTPtr & ast, Data & data) + { + if (func.name == "and") + return; /// go into children + + if (func.name == "equals") + { + ASTPtr left = func.arguments->children.at(0)->clone(); + ASTPtr right = func.arguments->children.at(1)->clone(); + addColumnsFromEqualsExpr(ast, left, right, data); + return; + } + + throwSyntaxException("Expected equals expression, got " + queryToString(ast) + "."); + } + + static void getIdentifiers(const ASTPtr & ast, std::vector & out) + { + if (const auto * ident = ast->as()) + { + if (IdentifierSemantic::getColumnName(*ident)) + out.push_back(ident); + return; + } + + for (const auto & child : ast->children) + getIdentifiers(child, out); + } + + static void addColumnsFromEqualsExpr(const ASTPtr & expr, ASTPtr left_ast, ASTPtr right_ast, Data & data) + { + std::vector left_identifiers; + std::vector right_identifiers; + + getIdentifiers(left_ast, left_identifiers); + getIdentifiers(right_ast, right_identifiers); + + size_t left_idents_table = checkSameTable(left_identifiers); + size_t right_idents_table = checkSameTable(right_identifiers); + + if (left_idents_table && left_idents_table == right_idents_table) + { + auto left_name = queryToString(*left_identifiers[0]); + auto right_name = queryToString(*right_identifiers[0]); + + throwSyntaxException("In expression " + queryToString(expr) + " columns " + left_name + " and " + right_name + + " are from the same table but from different arguments of equal function."); + } + + if (left_idents_table == 1 || right_idents_table == 2) + data.analyzed_join.addOnKeys(left_ast, right_ast); + else if (left_idents_table == 2 || right_idents_table == 1) + data.analyzed_join.addOnKeys(right_ast, left_ast); + else + { + /// Default variant when all identifiers may be from any table. + data.analyzed_join.addOnKeys(left_ast, right_ast); /// FIXME + } + + data.has_some = true; + } + + static size_t checkSameTable(std::vector & identifiers) + { + size_t table_number = 0; + const ASTIdentifier * detected = nullptr; + + for (const auto & identifier : identifiers) + { + /// It's set in TranslateQualifiedNamesVisitor + size_t membership = IdentifierSemantic::getMembership(*identifier); + if (membership && table_number == 0) + { + table_number = membership; + detected = identifier; + } + + if (membership && membership != table_number) + { + throw Exception("Invalid columns in JOIN ON section. Columns " + + detected->getAliasOrColumnName() + " and " + identifier->getAliasOrColumnName() + + " are from different tables.", ErrorCodes::INVALID_JOIN_ON_EXPRESSION); + } + } + + identifiers.clear(); + if (detected) + identifiers.push_back(detected); + return table_number; + } + + [[noreturn]] static void throwSyntaxException(const String & msg) + { + throw Exception("Invalid expression for JOIN ON. " + msg + + " Supported syntax: JOIN ON Expr([table.]column, ...) = Expr([table.]column, ...) " + "[AND Expr([table.]column, ...) = Expr([table.]column, ...) ...]", + ErrorCodes::INVALID_JOIN_ON_EXPRESSION); + } +}; + +/// Parse JOIN ON expression and collect ASTs for joined columns. +using CollectJoinOnKeysVisitor = CollectJoinOnKeysMatcher::Visitor; + +} diff --git a/dbms/src/Interpreters/InDepthNodeVisitor.h b/dbms/src/Interpreters/InDepthNodeVisitor.h index 7706a1fdd34..6ed19da2e94 100644 --- a/dbms/src/Interpreters/InDepthNodeVisitor.h +++ b/dbms/src/Interpreters/InDepthNodeVisitor.h @@ -10,19 +10,19 @@ namespace DB /// Visits AST tree in depth, call functions for nodes according to Matcher type data. /// You need to define Data, visit() and needChildVisit() in Matcher class. -template -class InDepthNodeVisitor +template +class InDepthNodeVisitorTemplate { public: using Data = typename Matcher::Data; - InDepthNodeVisitor(Data & data_, std::ostream * ostr_ = nullptr) + InDepthNodeVisitorTemplate(Data & data_, std::ostream * ostr_ = nullptr) : data(data_), visit_depth(0), ostr(ostr_) {} - void visit(ASTPtr & ast) + void visit(T & ast) { DumpASTNode dump(*ast, ostr, visit_depth, typeid(Matcher).name()); @@ -40,7 +40,7 @@ private: size_t visit_depth; std::ostream * ostr; - void visitChildren(ASTPtr & ast) + void visitChildren(T & ast) { for (auto & child : ast->children) if (Matcher::needChildVisit(ast, child)) @@ -48,6 +48,12 @@ private: } }; +template +using InDepthNodeVisitor = InDepthNodeVisitorTemplate; + +template +using ConstInDepthNodeVisitor = InDepthNodeVisitorTemplate; + /// Simple matcher for one node type without complex traversal logic. template class OneTypeMatcher diff --git a/dbms/src/Interpreters/SyntaxAnalyzer.cpp b/dbms/src/Interpreters/SyntaxAnalyzer.cpp index 83cacc94692..c70b4e21363 100644 --- a/dbms/src/Interpreters/SyntaxAnalyzer.cpp +++ b/dbms/src/Interpreters/SyntaxAnalyzer.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -21,7 +22,6 @@ #include #include #include -#include #include @@ -481,126 +481,11 @@ void getArrayJoinedColumns(ASTPtr & query, SyntaxAnalyzerResult & result, const } } - -[[noreturn]] static void throwSyntaxException(const String & msg) -{ - throw Exception("Invalid expression for JOIN ON. " + msg + " Supported syntax: JOIN ON Expr([table.]column, ...) = Expr([table.]column, ...) " - "[AND Expr([table.]column, ...) = Expr([table.]column, ...) ...]", ErrorCodes::INVALID_JOIN_ON_EXPRESSION); -}; - - -/// Parse JOIN ON expression and collect ASTs for joined columns. -void collectJoinedColumnsFromJoinOnExpr(AnalyzedJoin & analyzed_join, const ASTTableJoin & table_join) -{ - if (!table_join.on_expression) - return; - - /// Stores examples of columns which are only from one table. - struct TableBelonging - { - const ASTIdentifier * example_only_from_left = nullptr; - const ASTIdentifier * example_only_from_right = nullptr; - }; - - /// Check all identifiers in ast and decide their possible table belonging. - /// Throws if there are two identifiers definitely from different tables. - std::function get_table_belonging; - get_table_belonging = [&](const ASTPtr & ast) -> TableBelonging - { - if (IdentifierSemantic::getColumnName(ast)) - { - const auto * identifier = ast->as(); - - /// It's set in TranslateQualifiedNamesVisitor - size_t membership = IdentifierSemantic::getMembership(*identifier); - switch (membership) - { - case 1: return {identifier, nullptr}; - case 2: return {nullptr, identifier}; - default: - break; - } - - return {}; - } - - TableBelonging table_belonging; - for (const auto & child : ast->children) - { - auto children_belonging = get_table_belonging(child); - if (!table_belonging.example_only_from_left) - table_belonging.example_only_from_left = children_belonging.example_only_from_left; - if (!table_belonging.example_only_from_right) - table_belonging.example_only_from_right = children_belonging.example_only_from_right; - } - - if (table_belonging.example_only_from_left && table_belonging.example_only_from_right) - throw Exception("Invalid columns in JOIN ON section. Columns " - + table_belonging.example_only_from_left->getAliasOrColumnName() + " and " - + table_belonging.example_only_from_right->getAliasOrColumnName() - + " are from different tables.", ErrorCodes::INVALID_JOIN_ON_EXPRESSION); - - return table_belonging; - }; - - /// For equal expression find out corresponding table for each part, translate qualified names and add asts to join keys. - auto add_columns_from_equals_expr = [&](const ASTPtr & expr) - { - const auto * func_equals = expr->as(); - if (!func_equals || func_equals->name != "equals") - throwSyntaxException("Expected equals expression, got " + queryToString(expr) + "."); - - ASTPtr left_ast = func_equals->arguments->children.at(0)->clone(); - ASTPtr right_ast = func_equals->arguments->children.at(1)->clone(); - - auto left_table_belonging = get_table_belonging(left_ast); - auto right_table_belonging = get_table_belonging(right_ast); - - bool can_be_left_part_from_left_table = left_table_belonging.example_only_from_right == nullptr; - bool can_be_left_part_from_right_table = left_table_belonging.example_only_from_left == nullptr; - bool can_be_right_part_from_left_table = right_table_belonging.example_only_from_right == nullptr; - bool can_be_right_part_from_right_table = right_table_belonging.example_only_from_left == nullptr; - - /// Default variant when all identifiers may be from any table. - if (can_be_left_part_from_left_table && can_be_right_part_from_right_table) - analyzed_join.addOnKeys(left_ast, right_ast); - else if (can_be_left_part_from_right_table && can_be_right_part_from_left_table) - analyzed_join.addOnKeys(right_ast, left_ast); - else - { - auto * left_example = left_table_belonging.example_only_from_left ? - left_table_belonging.example_only_from_left : - left_table_belonging.example_only_from_right; - - auto * right_example = right_table_belonging.example_only_from_left ? - right_table_belonging.example_only_from_left : - right_table_belonging.example_only_from_right; - - auto left_name = queryToString(*left_example); - auto right_name = queryToString(*right_example); - auto expr_name = queryToString(expr); - - throwSyntaxException("In expression " + expr_name + " columns " + left_name + " and " + right_name - + " are from the same table but from different arguments of equal function."); - } - }; - - const auto * func = table_join.on_expression->as(); - if (func && func->name == "and") - { - for (const auto & expr : func->arguments->children) - add_columns_from_equals_expr(expr); - } - else - add_columns_from_equals_expr(table_join.on_expression); -} - /// Find the columns that are obtained by JOIN. void collectJoinedColumns(AnalyzedJoin & analyzed_join, const ASTSelectQuery & select_query, const NameSet & source_columns, const String & current_database, bool join_use_nulls) { const ASTTablesInSelectQueryElement * node = select_query.join(); - if (!node) return; @@ -619,7 +504,13 @@ void collectJoinedColumns(AnalyzedJoin & analyzed_join, const ASTSelectQuery & s name = joined_table_name.getQualifiedNamePrefix() + name; } else if (table_join.on_expression) - collectJoinedColumnsFromJoinOnExpr(analyzed_join, table_join); + { + CollectJoinOnKeysVisitor::Data data{analyzed_join}; + CollectJoinOnKeysVisitor(data).visit(table_join.on_expression); + if (!data.has_some) + throw Exception("Cannot get JOIN keys from JOIN ON section: " + queryToString(table_join.on_expression), + ErrorCodes::INVALID_JOIN_ON_EXPRESSION); + } bool make_nullable = join_use_nulls && isLeftOrFull(table_join.kind); From a3f6b704338c1ef8e40ff35dcb35edaab73b48a3 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 23 Jul 2019 23:07:33 +0300 Subject: [PATCH 0294/1165] Fixed warning from PVS-Studio --- dbms/src/Interpreters/ThreadStatusExt.cpp | 6 ++---- dbms/src/Interpreters/TraceLog.h | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/dbms/src/Interpreters/ThreadStatusExt.cpp b/dbms/src/Interpreters/ThreadStatusExt.cpp index e5e9b92507c..8c46a3ba08f 100644 --- a/dbms/src/Interpreters/ThreadStatusExt.cpp +++ b/dbms/src/Interpreters/ThreadStatusExt.cpp @@ -162,14 +162,12 @@ void ThreadStatus::initQueryProfiler() if (settings.query_profiler_real_time_period_ns > 0) query_profiler_real = std::make_unique( /* thread_id */ os_thread_id, - /* period */ static_cast(settings.query_profiler_real_time_period_ns) - ); + /* period */ static_cast(settings.query_profiler_real_time_period_ns)); if (settings.query_profiler_cpu_time_period_ns > 0) query_profiler_cpu = std::make_unique( /* thread_id */ os_thread_id, - /* period */ static_cast(settings.query_profiler_cpu_time_period_ns) - ); + /* period */ static_cast(settings.query_profiler_cpu_time_period_ns)); } void ThreadStatus::finalizeQueryProfiler() diff --git a/dbms/src/Interpreters/TraceLog.h b/dbms/src/Interpreters/TraceLog.h index d5b38b69440..7a28e30f50c 100644 --- a/dbms/src/Interpreters/TraceLog.h +++ b/dbms/src/Interpreters/TraceLog.h @@ -15,7 +15,7 @@ struct TraceLogElement static const TimerDataType::Values timer_values; time_t event_time{}; - TimerType timer_type; + TimerType timer_type{}; String query_id{}; Array trace{}; From 99be894ead0ec7f6a10e94bcbb3a2006302bd884 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 03:23:21 +0300 Subject: [PATCH 0295/1165] Mitigate segfault in libunwind #6124 --- contrib/libunwind | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/libunwind b/contrib/libunwind index 17a48fbfa79..36df74d804e 160000 --- a/contrib/libunwind +++ b/contrib/libunwind @@ -1 +1 @@ -Subproject commit 17a48fbfa7913ee889960a698516bd3ba51d63ee +Subproject commit 36df74d804e03bf5fa4bdd2bfafde8662ad28129 From dc068859505054a40e6ec946d959490320607662 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 03:42:55 +0300 Subject: [PATCH 0296/1165] Addition to prev. revision --- contrib/libunwind | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/libunwind b/contrib/libunwind index 36df74d804e..5afe6d87ae9 160000 --- a/contrib/libunwind +++ b/contrib/libunwind @@ -1 +1 @@ -Subproject commit 36df74d804e03bf5fa4bdd2bfafde8662ad28129 +Subproject commit 5afe6d87ae9e66485c7fcb106d2f7c2c0359c8f6 From 378fff29900affb1fdd1ff42f5e6687f931f210e Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 03:46:37 +0300 Subject: [PATCH 0297/1165] Lower bound on profiler period --- dbms/src/Common/QueryProfiler.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index b98d57a1d3b..f700295d7a4 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -61,10 +61,14 @@ namespace ErrorCodes } template -QueryProfilerBase::QueryProfilerBase(const Int32 thread_id, const int clock_type, const UInt32 period, const int pause_signal) +QueryProfilerBase::QueryProfilerBase(const Int32 thread_id, const int clock_type, UInt32 period, const int pause_signal) : log(&Logger::get("QueryProfiler")) , pause_signal(pause_signal) { + /// Too high frequency can introduce infinite busy loop of signal handlers. We will limit maximum frequency (with 1000 signals per second). + if (period < 1000000) + period = 1000000; + struct sigaction sa{}; sa.sa_sigaction = ProfilerImpl::signalHandler; sa.sa_flags = SA_SIGINFO | SA_RESTART; From 36746d85ddbb0c6e5879fec7e699a5b6f15cdde4 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 03:47:17 +0300 Subject: [PATCH 0298/1165] Better cache for symbolizeAddress function --- dbms/src/Functions/symbolizeAddress.cpp | 49 +++++++++++---------- libs/libcommon/include/common/SimpleCache.h | 8 +++- 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/dbms/src/Functions/symbolizeAddress.cpp b/dbms/src/Functions/symbolizeAddress.cpp index d196899939a..1096a8924b3 100644 --- a/dbms/src/Functions/symbolizeAddress.cpp +++ b/dbms/src/Functions/symbolizeAddress.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +63,23 @@ public: return true; } + static std::string addressToSymbol(UInt64 uint_address) + { + void * addr = unalignedLoad(&uint_address); + + /// This is extremely slow. + Dl_info info; + if (dladdr(addr, &info) && info.dli_sname) + { + int demangling_status = 0; + return demangle(info.dli_sname, demangling_status); + } + else + { + return {}; + } + } + void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override { const ColumnPtr & column = block.getByPosition(arguments[0]).column; @@ -73,36 +91,19 @@ public: const typename ColumnVector::Container & data = column_concrete->getData(); auto result_column = ColumnString::create(); - std::unordered_map cache; + static SimpleCache func_cached; for (size_t i = 0; i < input_rows_count; ++i) { - void * addr = unalignedLoad(&data[i]); - - if (auto it = cache.find(addr); it != cache.end()) - { - result_column->insertDataWithTerminatingZero(it->second.data(), it->second.size() + 1); - } - else - { - /// This is extremely slow. - Dl_info info; - if (dladdr(addr, &info) && info.dli_sname) - { - int demangling_status = 0; - std::string demangled_name = demangle(info.dli_sname, demangling_status); - result_column->insertDataWithTerminatingZero(demangled_name.data(), demangled_name.size() + 1); - cache.emplace(addr, demangled_name); - } - else - { - cache.emplace(addr, std::string()); - result_column->insertDefault(); - } - } + std::string symbol = func_cached(data[i]); + result_column->insertDataWithTerminatingZero(symbol.data(), symbol.size() + 1); } block.getByPosition(result).column = std::move(result_column); + + /// Do not let our cache to grow indefinitely (simply drop it) + if (func_cached.size() > 1000000) + func_cached.drop(); } }; diff --git a/libs/libcommon/include/common/SimpleCache.h b/libs/libcommon/include/common/SimpleCache.h index 2cf4348d0d7..57247de696a 100644 --- a/libs/libcommon/include/common/SimpleCache.h +++ b/libs/libcommon/include/common/SimpleCache.h @@ -26,7 +26,7 @@ private: using Result = typename function_traits::result; std::map cache; - std::mutex mutex; + mutable std::mutex mutex; public: template @@ -66,6 +66,12 @@ public: } } + size_t size() const + { + std::lock_guard lock(mutex); + return cache.size(); + } + void drop() { std::lock_guard lock(mutex); From 33ee957b5ca63b2ea5778a05daefcbd3e2b6b33c Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 03:49:14 +0300 Subject: [PATCH 0299/1165] Addition to prev. revision --- dbms/src/Common/QueryProfiler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Common/QueryProfiler.h b/dbms/src/Common/QueryProfiler.h index d4e92f25a17..80e38637053 100644 --- a/dbms/src/Common/QueryProfiler.h +++ b/dbms/src/Common/QueryProfiler.h @@ -34,7 +34,7 @@ template class QueryProfilerBase { public: - QueryProfilerBase(const Int32 thread_id, const int clock_type, const UInt32 period, const int pause_signal = SIGALRM); + QueryProfilerBase(const Int32 thread_id, const int clock_type, UInt32 period, const int pause_signal = SIGALRM); ~QueryProfilerBase(); From c97a4e1133c6874ecfcbfbb95d7ce8ef4b7a425b Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 04:04:46 +0300 Subject: [PATCH 0300/1165] Added a test --- .../queries/0_stateless/00974_query_profiler.reference | 4 ++++ .../tests/queries/0_stateless/00974_query_profiler.sql | 10 ++++++++++ 2 files changed, 14 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00974_query_profiler.reference create mode 100644 dbms/tests/queries/0_stateless/00974_query_profiler.sql diff --git a/dbms/tests/queries/0_stateless/00974_query_profiler.reference b/dbms/tests/queries/0_stateless/00974_query_profiler.reference new file mode 100644 index 00000000000..e37cf5f7642 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_query_profiler.reference @@ -0,0 +1,4 @@ +0 0 +1 +1000000000 0 +1 diff --git a/dbms/tests/queries/0_stateless/00974_query_profiler.sql b/dbms/tests/queries/0_stateless/00974_query_profiler.sql new file mode 100644 index 00000000000..9ea297ff626 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_query_profiler.sql @@ -0,0 +1,10 @@ +SET query_profiler_real_time_period_ns = 100000000; +SELECT sleep(0.5), ignore('test real time query profiler'); +SYSTEM FLUSH LOGS; +WITH symbolizeAddress(arrayJoin(trace)) AS symbol SELECT count() > 0 FROM system.trace_log t WHERE event_date >= yesterday() AND query_id = (SELECT query_id FROM system.query_log WHERE event_date >= yesterday() AND query LIKE '%test real time query profiler%' ORDER BY event_time DESC LIMIT 1) AND symbol LIKE '%FunctionSleep%'; + +SET query_profiler_real_time_period_ns = 0; +SET query_profiler_cpu_time_period_ns = 100000000; +SELECT count(), ignore('test cpu time query profiler') FROM numbers(1000000000); +SYSTEM FLUSH LOGS; +WITH symbolizeAddress(arrayJoin(trace)) AS symbol SELECT count() > 0 FROM system.trace_log t WHERE event_date >= yesterday() AND query_id = (SELECT query_id FROM system.query_log WHERE event_date >= yesterday() AND query LIKE '%test cpu time query profiler%' ORDER BY event_time DESC LIMIT 1) AND symbol LIKE '%Numbers%'; From 72d543f3cf2ce3cd03a36dfbfa9f1002b05e9073 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 04:11:46 +0300 Subject: [PATCH 0301/1165] Updated test --- dbms/tests/queries/0_stateless/00974_query_profiler.sql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dbms/tests/queries/0_stateless/00974_query_profiler.sql b/dbms/tests/queries/0_stateless/00974_query_profiler.sql index 9ea297ff626..b3d70bc6ac3 100644 --- a/dbms/tests/queries/0_stateless/00974_query_profiler.sql +++ b/dbms/tests/queries/0_stateless/00974_query_profiler.sql @@ -1,10 +1,14 @@ SET query_profiler_real_time_period_ns = 100000000; +SET log_queries = 1; SELECT sleep(0.5), ignore('test real time query profiler'); +SET log_queries = 0; SYSTEM FLUSH LOGS; WITH symbolizeAddress(arrayJoin(trace)) AS symbol SELECT count() > 0 FROM system.trace_log t WHERE event_date >= yesterday() AND query_id = (SELECT query_id FROM system.query_log WHERE event_date >= yesterday() AND query LIKE '%test real time query profiler%' ORDER BY event_time DESC LIMIT 1) AND symbol LIKE '%FunctionSleep%'; SET query_profiler_real_time_period_ns = 0; SET query_profiler_cpu_time_period_ns = 100000000; +SET log_queries = 1; SELECT count(), ignore('test cpu time query profiler') FROM numbers(1000000000); +SET log_queries = 0; SYSTEM FLUSH LOGS; WITH symbolizeAddress(arrayJoin(trace)) AS symbol SELECT count() > 0 FROM system.trace_log t WHERE event_date >= yesterday() AND query_id = (SELECT query_id FROM system.query_log WHERE event_date >= yesterday() AND query LIKE '%test cpu time query profiler%' ORDER BY event_time DESC LIMIT 1) AND symbol LIKE '%Numbers%'; From b9105e131fc0d4a7eaeb33294782cc73f7c249ae Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 05:02:10 +0300 Subject: [PATCH 0302/1165] Avoid deadlock in TraceCollector --- dbms/src/Common/ErrorCodes.cpp | 1 + dbms/src/Common/QueryProfiler.cpp | 29 ++++++++++++++++++++++++++++- dbms/src/Common/TraceCollector.cpp | 20 ++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/dbms/src/Common/ErrorCodes.cpp b/dbms/src/Common/ErrorCodes.cpp index c472a336d73..e8ee16c5670 100644 --- a/dbms/src/Common/ErrorCodes.cpp +++ b/dbms/src/Common/ErrorCodes.cpp @@ -437,6 +437,7 @@ namespace ErrorCodes extern const int CANNOT_CREATE_TIMER = 460; extern const int CANNOT_SET_TIMER_PERIOD = 461; extern const int CANNOT_DELETE_TIMER = 462; + extern const int CANNOT_FCNTL = 463; extern const int KEEPER_EXCEPTION = 999; extern const int POCO_EXCEPTION = 1000; diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index f700295d7a4..48a385e300c 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -16,6 +16,33 @@ extern LazyPipe trace_pipe; namespace { + /** Write to file descriptor but drop the data if write would block or fail. + * To use within signal handler. Motivating example: a signal handler invoked during execution of malloc + * should not block because some mutex (or even worse - a spinlock) may be held. + */ + class WriteBufferDiscardOnFailure : public WriteBufferFromFileDescriptor + { + protected: + void nextImpl() override + { + size_t bytes_written = 0; + while (bytes_written != offset()) + { + ssize_t res = ::write(fd, working_buffer.begin() + bytes_written, offset() - bytes_written); + + if ((-1 == res || 0 == res) && errno != EINTR) + break; /// Discard + + if (res > 0) + bytes_written += res; + } + } + + public: + using WriteBufferFromFileDescriptor::WriteBufferFromFileDescriptor; + ~WriteBufferDiscardOnFailure() override {} + }; + /// Normally query_id is a UUID (string with a fixed length) but user can provide custom query_id. /// Thus upper bound on query_id length should be introduced to avoid buffer overflow in signal handler. constexpr size_t QUERY_ID_MAX_LEN = 1024; @@ -33,7 +60,7 @@ namespace sizeof(StackTrace) + // collected stack trace sizeof(TimerType); // timer type char buffer[buf_size]; - WriteBufferFromFileDescriptor out(trace_pipe.fds_rw[1], buf_size, buffer); + WriteBufferDiscardOnFailure out(trace_pipe.fds_rw[1], buf_size, buffer); StringRef query_id = CurrentThread::getQueryId(); query_id.size = std::min(query_id.size, QUERY_ID_MAX_LEN); diff --git a/dbms/src/Common/TraceCollector.cpp b/dbms/src/Common/TraceCollector.cpp index 293e4c38e97..b6b0a7cfa85 100644 --- a/dbms/src/Common/TraceCollector.cpp +++ b/dbms/src/Common/TraceCollector.cpp @@ -12,6 +12,10 @@ #include #include +#include +#include + + namespace DB { @@ -21,6 +25,7 @@ namespace ErrorCodes { extern const int NULL_POINTER_DEREFERENCE; extern const int THREAD_IS_NOT_JOINABLE; + extern const int CANNOT_FCNTL; } TraceCollector::TraceCollector(std::shared_ptr & trace_log) @@ -31,6 +36,21 @@ TraceCollector::TraceCollector(std::shared_ptr & trace_log) throw Exception("Invalid trace log pointer passed", ErrorCodes::NULL_POINTER_DEREFERENCE); trace_pipe.open(); + + /** Turn write end of pipe to non-blocking mode to avoid deadlocks + * when QueryProfiler is invoked under locks and TraceCollector cannot pull data from pipe. + */ + int flags = fcntl(trace_pipe.fds_rw[1], F_GETFL, 0); + if (-1 == fcntl(trace_pipe.fds_rw[1], F_SETFL, flags | O_NONBLOCK)) + throwFromErrno("Cannot set non-blocking mode of pipe", ErrorCodes::CANNOT_FCNTL); + + /** Increase pipe size to avoid slowdown during fine-grained trace collection. + */ + int pipe_size = fcntl(trace_pipe.fds_rw[1], F_GETPIPE_SZ); + for (errno = 0; errno != EPERM && pipe_size <= 1048576; pipe_size *= 2) + if (-1 == fcntl(trace_pipe.fds_rw[1], F_SETPIPE_SZ, pipe_size) && errno != EPERM) + throwFromErrno("Cannot increase pipe capacity to " + toString(pipe_size), ErrorCodes::CANNOT_FCNTL); + thread = ThreadFromGlobalPool(&TraceCollector::run, this); } From 56bb2956cd41434bba7345144441c9fd1a40066d Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 05:07:16 +0300 Subject: [PATCH 0303/1165] Addition to prev. revision --- dbms/src/Common/TraceCollector.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dbms/src/Common/TraceCollector.cpp b/dbms/src/Common/TraceCollector.cpp index b6b0a7cfa85..680eefad5da 100644 --- a/dbms/src/Common/TraceCollector.cpp +++ b/dbms/src/Common/TraceCollector.cpp @@ -41,12 +41,16 @@ TraceCollector::TraceCollector(std::shared_ptr & trace_log) * when QueryProfiler is invoked under locks and TraceCollector cannot pull data from pipe. */ int flags = fcntl(trace_pipe.fds_rw[1], F_GETFL, 0); + if (-1 == flags) + throwFromErrno("Cannot get file status flags of pipe", ErrorCodes::CANNOT_FCNTL); if (-1 == fcntl(trace_pipe.fds_rw[1], F_SETFL, flags | O_NONBLOCK)) throwFromErrno("Cannot set non-blocking mode of pipe", ErrorCodes::CANNOT_FCNTL); /** Increase pipe size to avoid slowdown during fine-grained trace collection. */ int pipe_size = fcntl(trace_pipe.fds_rw[1], F_GETPIPE_SZ); + if (-1 == pipe_size) + throwFromErrno("Cannot get pipe capacity", ErrorCodes::CANNOT_FCNTL); for (errno = 0; errno != EPERM && pipe_size <= 1048576; pipe_size *= 2) if (-1 == fcntl(trace_pipe.fds_rw[1], F_SETPIPE_SZ, pipe_size) && errno != EPERM) throwFromErrno("Cannot increase pipe capacity to " + toString(pipe_size), ErrorCodes::CANNOT_FCNTL); From fd97c01f783d03ed1b0c42718112b97a8efdd828 Mon Sep 17 00:00:00 2001 From: alesapin Date: Wed, 24 Jul 2019 10:59:20 +0300 Subject: [PATCH 0304/1165] Fix test --- .../00974_adaptive_granularity_secondary_index.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00974_adaptive_granularity_secondary_index.sql b/dbms/tests/queries/0_stateless/00974_adaptive_granularity_secondary_index.sql index fe43237ccbb..328ec86f060 100644 --- a/dbms/tests/queries/0_stateless/00974_adaptive_granularity_secondary_index.sql +++ b/dbms/tests/queries/0_stateless/00974_adaptive_granularity_secondary_index.sql @@ -17,7 +17,7 @@ INSERT INTO indexed_table SELECT toDateTime('2019-05-27 10:00:00') + number % 10 INSERT INTO indexed_table SELECT toDateTime('2019-05-27 10:00:00') + number % 100, - concat('hhhhhhhhhhhhhhhhhhhhhhhhh', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'yyyyyyyyyyyyyyyyyyyyyyyyyy', reinterpretAsString(rand())) + concat('hhhhhhhhhhhhhhhhhhhhhhhhh', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'yyyyyyyyyyyyyyyyyyyyyyyyyy', toString(rand())) FROM numbers(1000); OPTIMIZE TABLE indexed_table FINAL; @@ -46,7 +46,7 @@ INSERT INTO another_indexed_table SELECT toDateTime('2019-05-27 10:00:00') + num INSERT INTO another_indexed_table SELECT toDateTime('2019-05-27 10:00:00') + number % 100, - concat('hhhhhhhhhhhhhhhhhhhhhhhhh', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'yyyyyyyyyyyyyyyyyyyyyyyyyy', reinterpretAsString(rand())) + concat('hhhhhhhhhhhhhhhhhhhhhhhhh', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'yyyyyyyyyyyyyyyyyyyyyyyyyy', toString(rand())) FROM numbers(1000); OPTIMIZE TABLE another_indexed_table FINAL; From 38607af95fd82c08d8d08e8c441f8fd4ee19c2f5 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Wed, 24 Jul 2019 11:26:23 +0300 Subject: [PATCH 0305/1165] nothing interesting --- dbms/src/Interpreters/TextLog.h | 1 - 1 file changed, 1 deletion(-) diff --git a/dbms/src/Interpreters/TextLog.h b/dbms/src/Interpreters/TextLog.h index 31ce514c340..34f40ffe5f1 100644 --- a/dbms/src/Interpreters/TextLog.h +++ b/dbms/src/Interpreters/TextLog.h @@ -34,5 +34,4 @@ class TextLog : public SystemLog using SystemLog::SystemLog; }; - } From e382089c7fe4e4a3a587ea097f43b413fa192bff Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Wed, 24 Jul 2019 11:41:31 +0300 Subject: [PATCH 0306/1165] better test --- .../0_stateless/00974_text_log_table_not_empty.reference | 2 +- .../0_stateless/00974_text_log_table_not_empty.sql | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference index 6ed281c757a..0cc5d717d83 100644 --- a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference +++ b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference @@ -1,2 +1,2 @@ -1 +6103 1 diff --git a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql index c6f1f536a53..ee1469d968e 100644 --- a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql +++ b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql @@ -1,6 +1,9 @@ -SELECT 1; +SELECT 6103; SYSTEM FLUSH LOGS; -SELECT count() > 0 -FROM system.text_log; +SELECT count(query) > 0 +FROM system.text_log AS natural +INNER JOIN system.query_log USING (query_id) +WHERE query = 'SELECT 6103' + From b14356ba113da999dc8923d77e32d877e058dd6f Mon Sep 17 00:00:00 2001 From: Ivan Lezhankin Date: Wed, 24 Jul 2019 12:53:51 +0300 Subject: [PATCH 0307/1165] Try to debug failing kafka test. --- dbms/tests/integration/test_storage_kafka/test.py | 1 + 1 file changed, 1 insertion(+) diff --git a/dbms/tests/integration/test_storage_kafka/test.py b/dbms/tests/integration/test_storage_kafka/test.py index 3f38b068a22..c2bdade170f 100644 --- a/dbms/tests/integration/test_storage_kafka/test.py +++ b/dbms/tests/integration/test_storage_kafka/test.py @@ -174,6 +174,7 @@ def test_kafka_settings_new_syntax(kafka_cluster): result += instance.query('SELECT * FROM test.kafka') if kafka_check_result(result): break + print result kafka_check_result(result, True) From db9f0cfba19093a2e11bb0fe76b8b7696158522a Mon Sep 17 00:00:00 2001 From: alesapin Date: Wed, 24 Jul 2019 14:10:34 +0300 Subject: [PATCH 0308/1165] Add empty text_log file --- dbms/tests/config/text_log.xml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 dbms/tests/config/text_log.xml diff --git a/dbms/tests/config/text_log.xml b/dbms/tests/config/text_log.xml new file mode 100644 index 00000000000..7e62283a83c --- /dev/null +++ b/dbms/tests/config/text_log.xml @@ -0,0 +1,2 @@ + + From d3ff30cb5bbdfc7b4c26f736ef7867d818383d7d Mon Sep 17 00:00:00 2001 From: Vitaly Baranov Date: Wed, 24 Jul 2019 14:41:49 +0300 Subject: [PATCH 0309/1165] Use better approach to check offsets in protobuf messages. --- dbms/src/DataTypes/DataTypeArray.cpp | 2 +- dbms/src/Formats/ProtobufReader.cpp | 172 +++++++++--------- dbms/src/Formats/ProtobufReader.h | 32 +--- dbms/src/Formats/ProtobufRowInputStream.cpp | 4 +- .../Formats/Impl/ProtobufRowInputFormat.cpp | 4 +- 5 files changed, 102 insertions(+), 112 deletions(-) diff --git a/dbms/src/DataTypes/DataTypeArray.cpp b/dbms/src/DataTypes/DataTypeArray.cpp index 82de731f4ad..7b5de251a0d 100644 --- a/dbms/src/DataTypes/DataTypeArray.cpp +++ b/dbms/src/DataTypes/DataTypeArray.cpp @@ -462,7 +462,7 @@ void DataTypeArray::deserializeProtobuf(IColumn & column, ProtobufReader & proto bool nested_row_added; do nested->deserializeProtobuf(nested_column, protobuf, true, nested_row_added); - while (nested_row_added && protobuf.maybeCanReadValue()); + while (nested_row_added && protobuf.canReadMoreValues()); if (allow_add_row) { offsets.emplace_back(nested_column.size()); diff --git a/dbms/src/Formats/ProtobufReader.cpp b/dbms/src/Formats/ProtobufReader.cpp index 669fd37406e..5ef39315f5f 100644 --- a/dbms/src/Formats/ProtobufReader.cpp +++ b/dbms/src/Formats/ProtobufReader.cpp @@ -34,19 +34,18 @@ namespace BITS32 = 5, }; - // The following should be always true: - // REACHED_END < any cursor position < min(END_OF_VARINT, END_OF_GROUP) + // The following condition must always be true: + // any_cursor_position < min(END_OF_VARINT, END_OF_GROUP) // This inequation helps to check conditions in SimpleReader. constexpr UInt64 END_OF_VARINT = static_cast(-1); constexpr UInt64 END_OF_GROUP = static_cast(-2); Int64 decodeZigZag(UInt64 n) { return static_cast((n >> 1) ^ (~(n & 1) + 1)); } -} - -[[noreturn]] void ProtobufReader::SimpleReader::throwUnknownFormat() -{ - throw Exception("Protobuf messages are corrupted or don't match the provided schema. Please note that Protobuf stream is length-delimited: every message is prefixed by its length in varint.", ErrorCodes::UNKNOWN_PROTOBUF_FORMAT); + [[noreturn]] void throwUnknownFormat() + { + throw Exception("Protobuf messages are corrupted or don't match the provided schema. Please note that Protobuf stream is length-delimited: every message is prefixed by its length in varint.", ErrorCodes::UNKNOWN_PROTOBUF_FORMAT); + } } @@ -54,92 +53,103 @@ namespace // Knows nothing about protobuf schemas, just provides useful functions to deserialize data. ProtobufReader::SimpleReader::SimpleReader(ReadBuffer & in_) : in(in_) - , cursor(1 /* We starts at cursor == 1 to keep any cursor value > REACHED_END, this allows to simplify conditions */) - , current_message_end(REACHED_END) - , field_end(REACHED_END) + , cursor(0) + , current_message_level(0) + , current_message_end(0) + , field_end(0) + , last_string_pos(-1) { } bool ProtobufReader::SimpleReader::startMessage() { - if ((current_message_end == REACHED_END) && parent_message_ends.empty()) - { - // Start reading a root message. - if (unlikely(in.eof())) - return false; - size_t size_of_message = readVarint(); - current_message_end = cursor + size_of_message; - root_message_end = current_message_end; - } - else - { - // Start reading a nested message which is located inside a length-delimited field - // of another message.s - parent_message_ends.emplace_back(current_message_end); - current_message_end = field_end; - } - field_end = REACHED_END; + // Start reading a root message. + assert(!current_message_level); + if (unlikely(in.eof())) + return false; + size_t size_of_message = readVarint(); + current_message_end = cursor + size_of_message; + ++current_message_level; + field_end = cursor; return true; } -void ProtobufReader::SimpleReader::endMessage() +void ProtobufReader::SimpleReader::endMessage(bool ignore_errors) { - if (current_message_end != REACHED_END) + if (!current_message_level) + return; + + UInt64 root_message_end = (current_message_level == 1) ? current_message_end : parent_message_ends.front(); + if (cursor != root_message_end) { - if (current_message_end == END_OF_GROUP) - ignoreGroup(); - else if (cursor < current_message_end) - ignore(current_message_end - cursor); - else if (unlikely(cursor > current_message_end)) - { - if (!parent_message_ends.empty()) - throwUnknownFormat(); - moveCursorBackward(cursor - current_message_end); - } - current_message_end = REACHED_END; + if (cursor < root_message_end) + ignore(root_message_end - cursor); + else if (ignore_errors) + moveCursorBackward(cursor - root_message_end); + else + throwUnknownFormat(); } - field_end = REACHED_END; - if (!parent_message_ends.empty()) - { - current_message_end = parent_message_ends.back(); - parent_message_ends.pop_back(); - } + current_message_level = 0; + parent_message_ends.clear(); } -void ProtobufReader::SimpleReader::endRootMessage() +void ProtobufReader::SimpleReader::startNestedMessage() { - UInt64 message_end = parent_message_ends.empty() ? current_message_end : parent_message_ends.front(); - if (message_end != REACHED_END) + assert(current_message_level >= 1); + // Start reading a nested message which is located inside a length-delimited field + // of another message. + parent_message_ends.emplace_back(current_message_end); + current_message_end = field_end; + ++current_message_level; + field_end = cursor; +} + +void ProtobufReader::SimpleReader::endNestedMessage() +{ + assert(current_message_level >= 2); + if (cursor != current_message_end) { - if (cursor < message_end) - ignore(message_end - cursor); - else if (unlikely(cursor > message_end)) - moveCursorBackward(cursor - message_end); + if (current_message_end == END_OF_GROUP) + { + ignoreGroup(); + current_message_end = cursor; + } + else if (cursor < current_message_end) + ignore(current_message_end - cursor); + else + throwUnknownFormat(); } - parent_message_ends.clear(); - current_message_end = REACHED_END; - field_end = REACHED_END; + + --current_message_level; + current_message_end = parent_message_ends.back(); + parent_message_ends.pop_back(); + field_end = cursor; } bool ProtobufReader::SimpleReader::readFieldNumber(UInt32 & field_number) { - if (field_end != REACHED_END) + assert(current_message_level); + if (field_end != cursor) { if (field_end == END_OF_VARINT) + { ignoreVarint(); + field_end = cursor; + } else if (field_end == END_OF_GROUP) + { ignoreGroup(); + field_end = cursor; + } else if (cursor < field_end) ignore(field_end - cursor); - field_end = REACHED_END; + else + throwUnknownFormat(); } if (cursor >= current_message_end) - { - current_message_end = REACHED_END; return false; - } UInt64 varint = readVarint(); if (unlikely(varint & (static_cast(0xFFFFFFFF) << 32))) @@ -149,6 +159,11 @@ bool ProtobufReader::SimpleReader::readFieldNumber(UInt32 & field_number) WireType wire_type = static_cast(key & 0x07); switch (wire_type) { + case BITS32: + { + field_end = cursor + 4; + return true; + } case BITS64: { field_end = cursor + 8; @@ -174,29 +189,20 @@ bool ProtobufReader::SimpleReader::readFieldNumber(UInt32 & field_number) { if (current_message_end != END_OF_GROUP) throwUnknownFormat(); - current_message_end = REACHED_END; + current_message_end = cursor; return false; } - case BITS32: - { - field_end = cursor + 4; - return true; - } } throwUnknownFormat(); - __builtin_unreachable(); } bool ProtobufReader::SimpleReader::readUInt(UInt64 & value) { if (unlikely(cursor >= field_end)) - { - field_end = REACHED_END; return false; - } value = readVarint(); - if ((field_end == END_OF_VARINT) || (cursor >= field_end)) - field_end = REACHED_END; + if (field_end == END_OF_VARINT) + field_end = cursor; return true; } @@ -222,25 +228,22 @@ template bool ProtobufReader::SimpleReader::readFixed(T & value) { if (unlikely(cursor >= field_end)) - { - field_end = REACHED_END; return false; - } readBinary(&value, sizeof(T)); - if (cursor >= field_end) - field_end = REACHED_END; return true; } bool ProtobufReader::SimpleReader::readStringInto(PaddedPODArray & str) { + if (unlikely(cursor == last_string_pos)) + return false; /// We don't want to read the same empty string again. + last_string_pos = cursor; if (unlikely(cursor > field_end)) - return false; + throwUnknownFormat(); size_t length = field_end - cursor; size_t old_size = str.size(); str.resize(old_size + length); readBinary(reinterpret_cast(str.data() + old_size), length); - field_end = REACHED_END; return true; } @@ -297,7 +300,6 @@ UInt64 ProtobufReader::SimpleReader::continueReadingVarint(UInt64 first_byte) #undef PROTOBUF_READER_READ_VARINT_BYTE throwUnknownFormat(); - __builtin_unreachable(); } void ProtobufReader::SimpleReader::ignoreVarint() @@ -1081,9 +1083,9 @@ bool ProtobufReader::startMessage() return true; } -void ProtobufReader::endMessage() +void ProtobufReader::endMessage(bool try_ignore_errors) { - simple_reader.endRootMessage(); + simple_reader.endMessage(try_ignore_errors); current_message = nullptr; current_converter = nullptr; } @@ -1100,7 +1102,7 @@ bool ProtobufReader::readColumnIndex(size_t & column_index) current_converter = nullptr; return false; } - simple_reader.endMessage(); + simple_reader.endNestedMessage(); current_field_index = current_message->index_in_parent; current_message = current_message->parent; continue; @@ -1130,7 +1132,7 @@ bool ProtobufReader::readColumnIndex(size_t & column_index) if (field->nested_message) { - simple_reader.startMessage(); + simple_reader.startNestedMessage(); current_message = field->nested_message.get(); current_field_index = 0; continue; diff --git a/dbms/src/Formats/ProtobufReader.h b/dbms/src/Formats/ProtobufReader.h index 41088e54ac3..bc5b1fc4b6c 100644 --- a/dbms/src/Formats/ProtobufReader.h +++ b/dbms/src/Formats/ProtobufReader.h @@ -42,7 +42,7 @@ public: bool startMessage(); /// Ends reading a message. - void endMessage(); + void endMessage(bool ignore_errors = false); /// Reads the column index. /// The function returns false if there are no more columns to read (call endMessage() in this case). @@ -79,9 +79,8 @@ public: bool readAggregateFunction(const AggregateFunctionPtr & function, AggregateDataPtr place, Arena & arena) { return current_converter->readAggregateFunction(function, place, arena); } - /// When it returns false there is no more values left and from now on all the read() functions will return false - /// until readColumnIndex() is called. When it returns true it's unclear. - bool ALWAYS_INLINE maybeCanReadValue() const { return simple_reader.maybeCanReadValue(); } + /// Call it after calling one of the read*() function to determine if there are more values available for reading. + bool ALWAYS_INLINE canReadMoreValues() const { return simple_reader.canReadMoreValues(); } private: class SimpleReader @@ -89,8 +88,9 @@ private: public: SimpleReader(ReadBuffer & in_); bool startMessage(); - void endMessage(); - void endRootMessage(); + void endMessage(bool ignore_errors); + void startNestedMessage(); + void endNestedMessage(); bool readFieldNumber(UInt32 & field_number); bool readInt(Int64 & value); bool readSInt(Int64 & value); @@ -98,15 +98,7 @@ private: template bool readFixed(T & value); bool readStringInto(PaddedPODArray & str); - bool ALWAYS_INLINE maybeCanReadValue() const - { - if (field_end == REACHED_END) - return false; - if (cursor < root_message_end) - return true; - - throwUnknownFormat(); - } + bool ALWAYS_INLINE canReadMoreValues() const { return cursor < field_end; } private: void readBinary(void * data, size_t size); @@ -128,17 +120,13 @@ private: void ignoreVarint(); void ignoreGroup(); - [[noreturn]] static void throwUnknownFormat(); - - static constexpr UInt64 REACHED_END = 0; - ReadBuffer & in; UInt64 cursor; - std::vector parent_message_ends; + size_t current_message_level; UInt64 current_message_end; + std::vector parent_message_ends; UInt64 field_end; - - UInt64 root_message_end; + UInt64 last_string_pos; }; class IConverter diff --git a/dbms/src/Formats/ProtobufRowInputStream.cpp b/dbms/src/Formats/ProtobufRowInputStream.cpp index 1c4193b9f1a..799b53c9d6e 100644 --- a/dbms/src/Formats/ProtobufRowInputStream.cpp +++ b/dbms/src/Formats/ProtobufRowInputStream.cpp @@ -43,7 +43,7 @@ bool ProtobufRowInputStream::read(MutableColumns & columns, RowReadExtension & e read_columns[column_index] = true; allow_add_row = false; } - } while (reader.maybeCanReadValue()); + } while (reader.canReadMoreValues()); } // Fill non-visited columns with the default values. @@ -62,7 +62,7 @@ bool ProtobufRowInputStream::allowSyncAfterError() const void ProtobufRowInputStream::syncAfterError() { - reader.endMessage(); + reader.endMessage(true); } diff --git a/dbms/src/Processors/Formats/Impl/ProtobufRowInputFormat.cpp b/dbms/src/Processors/Formats/Impl/ProtobufRowInputFormat.cpp index a2f3a47def3..1dcebc2959b 100644 --- a/dbms/src/Processors/Formats/Impl/ProtobufRowInputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/ProtobufRowInputFormat.cpp @@ -43,7 +43,7 @@ bool ProtobufRowInputFormat::readRow(MutableColumns & columns, RowReadExtension read_columns[column_index] = true; allow_add_row = false; } - } while (reader.maybeCanReadValue()); + } while (reader.canReadMoreValues()); } // Fill non-visited columns with the default values. @@ -62,7 +62,7 @@ bool ProtobufRowInputFormat::allowSyncAfterError() const void ProtobufRowInputFormat::syncAfterError() { - reader.endMessage(); + reader.endMessage(true); } From 96df26a4d2367ca58c8044fb1642c6806445939c Mon Sep 17 00:00:00 2001 From: Vitaly Baranov Date: Wed, 24 Jul 2019 14:46:50 +0300 Subject: [PATCH 0310/1165] Add test for reloading a dictionary after fail by timer. --- .../dictionaries/dictionary_preset_file.xml | 17 ++++++++++ .../integration/test_dictionaries/test.py | 31 ++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_file.xml b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_file.xml index 14b82305b4d..d04d0be3f90 100644 --- a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_file.xml +++ b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_file.xml @@ -33,4 +33,21 @@ + + + no_file_2 + + + /etc/clickhouse-server/config.d/dictionary_preset_no_file_2.txt + TabSeparated + + + 1 + + key + aInt32 + 0 + + + diff --git a/dbms/tests/integration/test_dictionaries/test.py b/dbms/tests/integration/test_dictionaries/test.py index dfb27cd2ed7..251fe7f31ee 100644 --- a/dbms/tests/integration/test_dictionaries/test.py +++ b/dbms/tests/integration/test_dictionaries/test.py @@ -294,7 +294,7 @@ def test_reload_after_loading(started_cluster): assert query("SELECT dictGetInt32('cmd', 'a', toUInt64(7))") == "83\n" -def test_reload_after_fail(started_cluster): +def test_reload_after_fail_by_system_reload(started_cluster): query = instance.query # dictionaries_lazy_load == false, so this dictionary is not loaded. @@ -321,3 +321,32 @@ def test_reload_after_fail(started_cluster): query("SYSTEM RELOAD DICTIONARY 'no_file'") query("SELECT dictGetInt32('no_file', 'a', toUInt64(9))") == "10\n" assert get_status("no_file") == "LOADED" + + +def test_reload_after_fail_by_timer(started_cluster): + query = instance.query + + # dictionaries_lazy_load == false, so this dictionary is not loaded. + assert get_status("no_file_2") == "NOT_LOADED" + + # We expect an error because the file source doesn't exist. + expected_error = "No such file" + assert expected_error in instance.query_and_get_error("SELECT dictGetInt32('no_file_2', 'a', toUInt64(9))") + assert get_status("no_file_2") == "FAILED" + + # Passed time should not change anything now, the status is still FAILED. + time.sleep(6); + assert expected_error in instance.query_and_get_error("SELECT dictGetInt32('no_file_2', 'a', toUInt64(9))") + assert get_status("no_file_2") == "FAILED" + + # Creating the file source makes the dictionary able to load. + instance.copy_file_to_container(os.path.join(SCRIPT_DIR, "configs/dictionaries/dictionary_preset_file.txt"), "/etc/clickhouse-server/config.d/dictionary_preset_no_file_2.txt") + time.sleep(6); + query("SELECT dictGetInt32('no_file_2', 'a', toUInt64(9))") == "10\n" + assert get_status("no_file_2") == "LOADED" + + # Removing the file source should not spoil the loaded dictionary. + instance.exec_in_container("rm /etc/clickhouse-server/config.d/dictionary_preset_no_file_2.txt") + time.sleep(6); + query("SELECT dictGetInt32('no_file_2', 'a', toUInt64(9))") == "10\n" + assert get_status("no_file_2") == "LOADED" From df14bd6142c48be849b169f7994e7c3143b969b8 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Wed, 24 Jul 2019 15:02:58 +0300 Subject: [PATCH 0311/1165] test with sleep --- .../0_stateless/00974_text_log_table_not_empty.reference | 1 + .../queries/0_stateless/00974_text_log_table_not_empty.sql | 2 ++ 2 files changed, 3 insertions(+) diff --git a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference index 0cc5d717d83..0c56a79a1c5 100644 --- a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference +++ b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference @@ -1,2 +1,3 @@ 6103 +0 1 diff --git a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql index ee1469d968e..8cf62c9cdbb 100644 --- a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql +++ b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql @@ -1,5 +1,7 @@ SELECT 6103; +SELECT sleep(1); + SYSTEM FLUSH LOGS; SELECT count(query) > 0 From 95fdc8a96b6eaa7f357746d37f03f81c3b456dd9 Mon Sep 17 00:00:00 2001 From: akuzm <36882414+akuzm@users.noreply.github.com> Date: Wed, 24 Jul 2019 15:04:18 +0300 Subject: [PATCH 0312/1165] Add a test case for #4402. (#6129) Turns out it's easy to reproduce using the `hits` table, so we can add a case to stateful tests. --- .../queries/1_stateful/00153_aggregate_arena_race.reference | 0 dbms/tests/queries/1_stateful/00153_aggregate_arena_race.sql | 2 ++ 2 files changed, 2 insertions(+) create mode 100644 dbms/tests/queries/1_stateful/00153_aggregate_arena_race.reference create mode 100644 dbms/tests/queries/1_stateful/00153_aggregate_arena_race.sql diff --git a/dbms/tests/queries/1_stateful/00153_aggregate_arena_race.reference b/dbms/tests/queries/1_stateful/00153_aggregate_arena_race.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dbms/tests/queries/1_stateful/00153_aggregate_arena_race.sql b/dbms/tests/queries/1_stateful/00153_aggregate_arena_race.sql new file mode 100644 index 00000000000..239b5ad0aa5 --- /dev/null +++ b/dbms/tests/queries/1_stateful/00153_aggregate_arena_race.sql @@ -0,0 +1,2 @@ +create temporary table dest00153 (`s` AggregateFunction(groupUniqArray, String)) engine Memory; +insert into dest00153 select groupUniqArrayState(RefererDomain) from test.hits group by URLDomain; From 67b8f0c7895e7da51224dd85974b4253dec50544 Mon Sep 17 00:00:00 2001 From: Bakhtiyor Ruziev Date: Wed, 24 Jul 2019 14:29:06 +0300 Subject: [PATCH 0313/1165] Add regression test for #5192 fix --- .../00974_full_outer_join.reference | 5 +++++ .../0_stateless/00974_full_outer_join.sql | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00974_full_outer_join.reference create mode 100644 dbms/tests/queries/0_stateless/00974_full_outer_join.sql diff --git a/dbms/tests/queries/0_stateless/00974_full_outer_join.reference b/dbms/tests/queries/0_stateless/00974_full_outer_join.reference new file mode 100644 index 00000000000..82c1bd051d3 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_full_outer_join.reference @@ -0,0 +1,5 @@ +2015-12-01 0 0 +2015-12-02 1 1 +2015-12-03 0 2 +2015-12-04 0 3 +2015-12-05 0 4 diff --git a/dbms/tests/queries/0_stateless/00974_full_outer_join.sql b/dbms/tests/queries/0_stateless/00974_full_outer_join.sql new file mode 100644 index 00000000000..fda9d70e444 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_full_outer_join.sql @@ -0,0 +1,20 @@ +SELECT + q0.dt, + q0.cnt, + q0.cnt2 +FROM +( + SELECT + toDate(addDays(toDate('2015-12-01'), number)) AS dt, + sum(number) AS cnt + FROM numbers(2) + GROUP BY dt +) AS q0 +ALL FULL OUTER JOIN +( + SELECT + toDate(addDays(toDate('2015-12-01'), number)) AS dt, + sum(number) AS cnt2 + FROM numbers(5) + GROUP BY dt +) AS q1 ON q0.dt = q1.dt From 3d706ec20e2895f42c204a64dc348dddc6857677 Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Wed, 24 Jul 2019 17:23:57 +0300 Subject: [PATCH 0314/1165] support 'order by' optimiation with simple monotonic functions --- .../Interpreters/InterpreterSelectQuery.cpp | 153 +++++++++++++----- .../src/Interpreters/InterpreterSelectQuery.h | 3 +- .../MergeTree/MergeTreeDataSelectExecutor.cpp | 4 + dbms/src/Storages/SelectQueryInfo.h | 5 +- 4 files changed, 126 insertions(+), 39 deletions(-) diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.cpp b/dbms/src/Interpreters/InterpreterSelectQuery.cpp index a352e625d94..f33ac980fb3 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSelectQuery.cpp @@ -52,6 +52,7 @@ #include #include +#include #include #include #include @@ -534,13 +535,19 @@ InterpreterSelectQuery::analyzeExpressions(QueryProcessingStage::Enum from_stage } } - /// If there is aggregation, we execute expressions in SELECT and ORDER BY on the initiating server, otherwise on the source servers. query_analyzer->appendSelect(chain, dry_run || (res.need_aggregate ? !res.second_stage : !res.first_stage)); res.selected_columns = chain.getLastStep().required_output; - res.has_order_by = query_analyzer->appendOrderBy(chain, dry_run || (res.need_aggregate ? !res.second_stage : !res.first_stage)); - res.before_order_and_select = chain.getLastActions(); + res.before_select = chain.getLastActions(); chain.addStep(); + /// If there is aggregation, we execute expressions in SELECT and ORDER BY on the initiating server, otherwise on the source servers. + if (query_analyzer->appendOrderBy(chain, dry_run || (res.need_aggregate ? !res.second_stage : !res.first_stage))) + { + res.has_order_by = true; + res.before_order = chain.getLastActions(); + chain.addStep(); + } + if (query_analyzer->appendLimitBy(chain, dry_run || !res.second_stage)) { res.has_limit_by = true; @@ -646,6 +653,86 @@ static UInt64 getLimitForSorting(const ASTSelectQuery & query, const Context & c return 0; } + +static SortingInfoPtr optimizeSortingWithPK(const MergeTreeData & merge_tree, const ASTSelectQuery & query, + const Context & context, const NamesAndTypesList & required_columns) +{ + if (!merge_tree.hasSortingKey()) + return {}; + + auto order_descr = getSortDescription(query); + SortDescription prefix_order_descr; + int read_direction = order_descr.at(0).direction; + + const auto & sorting_key_columns = merge_tree.getSortingKeyColumns(); + size_t prefix_size = std::min(order_descr.size(), sorting_key_columns.size()); + + auto order_by_expr = query.orderBy(); + auto syntax_result = SyntaxAnalyzer(context).analyze(order_by_expr, required_columns); + for (size_t i = 0; i < prefix_size; ++i) + { + /// Read in pk order in case of exact match with order key element + /// or in some simple cases when order key element is wrapped into monotonic function. + int current_direction = order_descr[i].direction; + if (order_descr[i].column_name == sorting_key_columns[i] && current_direction == read_direction) + prefix_order_descr.push_back(order_descr[i]); + else + { + const auto & ast = query.orderBy()->children[0]; + auto actions = ExpressionAnalyzer(ast->children.at(0), syntax_result, context).getActions(false); + + const auto & input_columns = actions->getRequiredColumnsWithTypes(); + if (input_columns.size() != 1 || input_columns.front().name != sorting_key_columns[i]) + break; + + bool first = true; + for (const auto & action : actions->getActions()) + { + if (action.type != ExpressionAction::APPLY_FUNCTION) + continue; + + if (!first) + { + current_direction = 0; + break; + } + else + first = false; + + const auto & func = *action.function_base; + if (!func.hasInformationAboutMonotonicity()) + { + current_direction = 0; + break; + } + + auto monotonicity = func.getMonotonicityForRange(*input_columns.front().type, {}, {}); + if (!monotonicity.is_monotonic) + { + current_direction = 0; + break; + } + else if (!monotonicity.is_positive) + current_direction *= -1; + } + + if (!current_direction || (i > 0 && current_direction != read_direction)) + break; + + if (i == 0) + read_direction = current_direction; + + prefix_order_descr.push_back(order_descr[i]); + } + } + + if (prefix_order_descr.empty()) + return {}; + + return std::make_shared(std::move(prefix_order_descr), read_direction); +} + + template void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputStreamPtr & prepared_input, bool dry_run) { @@ -704,38 +791,6 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS } SortingInfoPtr sorting_info; - if (settings.optimize_pk_order && storage && query.orderBy() && !query.groupBy() && !query.final()) - { - auto optimize_pk_order = [&](const auto & merge_tree) -> SortingInfoPtr - { - if (!merge_tree.hasSortingKey()) - return {}; - - auto order_descr = getSortDescription(query); - const auto & sorting_key_columns = merge_tree.getSortingKeyColumns(); - SortDescription prefix_order_descr; - - int direction = order_descr.at(0).direction; - size_t prefix_size = std::min(order_descr.size(), sorting_key_columns.size()); - - for (size_t i = 0; i < prefix_size; ++i) - { - if (order_descr[i].column_name != sorting_key_columns[i] - || order_descr[i].direction != direction) - break; - prefix_order_descr.push_back(order_descr[i]); - } - - if (prefix_order_descr.empty()) - return {}; - - return std::make_shared(std::move(prefix_order_descr), direction); - }; - - if (const MergeTreeData * merge_tree_data = dynamic_cast(storage.get())) - sorting_info = optimize_pk_order(*merge_tree_data); - } - if (dry_run) { if constexpr (pipeline_with_processors) @@ -748,6 +803,14 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS if (storage && expressions.filter_info && expressions.prewhere_info) throw Exception("PREWHERE is not supported if the table is filtered by row-level security expression", ErrorCodes::ILLEGAL_PREWHERE); + if (settings.optimize_pk_order && storage && query.orderBy() && !query.groupBy() && !query.final()) + { + if (const MergeTreeData * merge_tree_data = dynamic_cast(storage.get())) + sorting_info = optimizeSortingWithPK(*merge_tree_data, query,context, expressions.before_order->getSampleBlock().getNamesAndTypesList()); + if (sorting_info) + sorting_info->setActions(expressions.before_order); + } + if (expressions.prewhere_info) { if constexpr (pipeline_with_processors) @@ -784,6 +847,14 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS if (storage && expressions.filter_info && expressions.prewhere_info) throw Exception("PREWHERE is not supported if the table is filtered by row-level security expression", ErrorCodes::ILLEGAL_PREWHERE); + if (settings.optimize_pk_order && storage && query.orderBy() && !query.groupBy() && !query.final()) + { + if (const MergeTreeData * merge_tree_data = dynamic_cast(storage.get())) + sorting_info = optimizeSortingWithPK(*merge_tree_data, query, context, expressions.before_order->getSampleBlock().getNamesAndTypesList()); + if (sorting_info) + sorting_info->setActions(expressions.before_order); + } + /** Read the data from Storage. from_stage - to what stage the request was completed in Storage. */ executeFetchColumns(from_stage, pipeline, sorting_info, expressions.prewhere_info, expressions.columns_to_remove_after_prewhere); @@ -891,7 +962,7 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS executeAggregation(pipeline, expressions.before_aggregation, aggregate_overflow_row, aggregate_final); else { - executeExpression(pipeline, expressions.before_order_and_select); + executeExpression(pipeline, expressions.before_select); executeDistinct(pipeline, true, expressions.selected_columns); } @@ -903,7 +974,11 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS if (!expressions.second_stage && !expressions.need_aggregate && !expressions.has_having) { if (expressions.has_order_by) + { + if (!query_info.sorting_info) // Otherwise we have executed expressions while reading + executeExpression(pipeline, expressions.before_order); executeOrder(pipeline, query_info.sorting_info); + } if (expressions.has_order_by && query.limitLength()) executeDistinct(pipeline, false, expressions.selected_columns); @@ -957,7 +1032,7 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS else if (expressions.has_having) executeHaving(pipeline, expressions.before_having); - executeExpression(pipeline, expressions.before_order_and_select); + executeExpression(pipeline, expressions.before_select); executeDistinct(pipeline, true, expressions.selected_columns); need_second_distinct_pass = query.distinct && pipeline.hasMixedStreams(); @@ -994,6 +1069,10 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS * but there is no aggregation, then on the remote servers ORDER BY was made * - therefore, we merge the sorted streams from remote servers. */ + + if (!query_info.sorting_info) // Otherwise we have executed them while reading + executeExpression(pipeline, expressions.before_order); + if (!expressions.first_stage && !expressions.need_aggregate && !(query.group_by_with_totals && !aggregate_final)) executeMergeSorted(pipeline); else /// Otherwise, just sort. diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.h b/dbms/src/Interpreters/InterpreterSelectQuery.h index f6f3c0baf19..aaed7ce0a45 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.h +++ b/dbms/src/Interpreters/InterpreterSelectQuery.h @@ -152,7 +152,8 @@ private: ExpressionActionsPtr before_where; ExpressionActionsPtr before_aggregation; ExpressionActionsPtr before_having; - ExpressionActionsPtr before_order_and_select; + ExpressionActionsPtr before_order; + ExpressionActionsPtr before_select; ExpressionActionsPtr before_limit_by; ExpressionActionsPtr final_projection; diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index 1c9373004c8..22b97184d53 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -973,6 +973,10 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsPKOrd streams_per_thread.push_back(source_stream); } + if (sorting_info->actions && !sorting_info->actions->getActions().empty()) + for (auto & stream : streams_per_thread) + stream = std::make_shared(stream, sorting_info->actions); + if (streams_per_thread.size() > 1) streams.push_back(std::make_shared( streams_per_thread, sorting_info->prefix_order_descr, max_block_size)); diff --git a/dbms/src/Storages/SelectQueryInfo.h b/dbms/src/Storages/SelectQueryInfo.h index e5de8a1cece..56bbaff86a7 100644 --- a/dbms/src/Storages/SelectQueryInfo.h +++ b/dbms/src/Storages/SelectQueryInfo.h @@ -38,9 +38,12 @@ struct SortingInfo { SortDescription prefix_order_descr; int direction; + ExpressionActionsPtr actions; - SortingInfo(const SortDescription prefix_order_descr_, int direction_) + SortingInfo(const SortDescription & prefix_order_descr_, int direction_) : prefix_order_descr(prefix_order_descr_), direction(direction_) {} + + void setActions(const ExpressionActionsPtr & actions_) { actions = actions_; } }; using PrewhereInfoPtr = std::shared_ptr; From d95c6e1bc480123dc761cf34a479ba48af27bf02 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 18:26:23 +0300 Subject: [PATCH 0315/1165] Attempt to solve signal safety of libunwind with solution from Fedor Korotkiy --- dbms/programs/main.cpp | 7 +++ libs/libcommon/CMakeLists.txt | 2 + libs/libcommon/include/common/phdr_cache.h | 10 ++++ libs/libcommon/src/phdr_cache.cpp | 70 ++++++++++++++++++++++ 4 files changed, 89 insertions(+) create mode 100644 libs/libcommon/include/common/phdr_cache.h create mode 100644 libs/libcommon/src/phdr_cache.cpp diff --git a/dbms/programs/main.cpp b/dbms/programs/main.cpp index afb0ad3d6c2..27053147a65 100644 --- a/dbms/programs/main.cpp +++ b/dbms/programs/main.cpp @@ -20,6 +20,9 @@ #include +#include + + /// Universal executable for various clickhouse applications #if ENABLE_CLICKHOUSE_SERVER || !defined(ENABLE_CLICKHOUSE_SERVER) int mainEntryClickHouseServer(int argc, char ** argv); @@ -144,6 +147,10 @@ int main(int argc_, char ** argv_) /// It is needed because LLVM library clobbers it. std::set_new_handler(nullptr); + /// PHDR cache is required for query profiler to work reliably + /// It also speed up exception handling, but exceptions from dynamically loaded libraries (dlopen) won't work. + enablePHDRCache(); + #if USE_EMBEDDED_COMPILER if (argc_ >= 2 && 0 == strcmp(argv_[1], "-cc1")) return mainEntryClickHouseClang(argc_, argv_); diff --git a/libs/libcommon/CMakeLists.txt b/libs/libcommon/CMakeLists.txt index eb77f43a37f..8ebd9bddc8d 100644 --- a/libs/libcommon/CMakeLists.txt +++ b/libs/libcommon/CMakeLists.txt @@ -25,6 +25,7 @@ add_library (common src/argsToConfig.cpp src/StackTrace.cpp src/Pipe.cpp + src/phdr_cache.cpp include/common/SimpleCache.h include/common/StackTrace.h @@ -51,6 +52,7 @@ add_library (common include/common/getThreadNumber.h include/common/sleep.h include/common/SimpleCache.h + include/common/phdr_cache.h include/ext/bit_cast.h include/ext/collection_cast.h diff --git a/libs/libcommon/include/common/phdr_cache.h b/libs/libcommon/include/common/phdr_cache.h new file mode 100644 index 00000000000..76c28f7713a --- /dev/null +++ b/libs/libcommon/include/common/phdr_cache.h @@ -0,0 +1,10 @@ +#pragma once + +/// This code was developed by Fedor Korotkiy (prime@yandex-team.ru) for YT product in Yandex. + +//! Collects all dl_phdr_info items and caches them in a static array. +//! Also rewrites dl_iterate_phdr with a lockless version which consults the above cache +//! thus eliminating scalability bottleneck in C++ exception unwinding. +//! As a drawback, this only works if no dynamic object loading/unloading happens after this point. +//! This function is not thread-safe; the caller must guarantee that no concurrent unwinding takes place. +void enablePHDRCache(); diff --git a/libs/libcommon/src/phdr_cache.cpp b/libs/libcommon/src/phdr_cache.cpp new file mode 100644 index 00000000000..292d71ceead --- /dev/null +++ b/libs/libcommon/src/phdr_cache.cpp @@ -0,0 +1,70 @@ +/// This code was developed by Fedor Korotkiy (prime@yandex-team.ru) for YT product in Yandex. + +#include +#include +#include +#include +#include +#include + +namespace +{ + +// This is adapted from +// https://github.com/scylladb/seastar/blob/master/core/exception_hacks.hh +// https://github.com/scylladb/seastar/blob/master/core/exception_hacks.cc + +using DLIterateFunction = int (*) (int (*callback) (dl_phdr_info * info, size_t size, void * data), void * data); + +DLIterateFunction getOriginalDLIteratePHDR() +{ + void * func = dlsym(RTLD_NEXT, "dl_iterate_phdr"); + if (!func) + throw std::runtime_error("Cannot find dl_iterate_phdr function with dlsym"); + return reinterpret_cast(func); +} + +// Never destroyed to avoid races with static destructors. +using PHDRCache = std::vector; +PHDRCache * phdr_cache; + +} + + +extern "C" +#ifndef __clang__ +[[gnu::visibility("default")]] +[[gnu::externally_visible]] +#endif +int dl_iterate_phdr(int (*callback) (dl_phdr_info * info, size_t size, void * data), void * data) +{ + if (!phdr_cache) + { + // Cache is not yet populated, pass through to the original function. + return getOriginalDLIteratePHDR()(callback, data); + } + + int result = 0; + for (auto & info : *phdr_cache) + { + result = callback(&info, offsetof(dl_phdr_info, dlpi_adds), data); + if (result != 0) + break; + } + return result; +} + + +void enablePHDRCache() +{ +#if defined(__linux__) + // Fill out ELF header cache for access without locking. + // This assumes no dynamic object loading/unloading after this point + phdr_cache = new PHDRCache; + getOriginalDLIteratePHDR()([] (dl_phdr_info * info, size_t /*size*/, void * /*data*/) + { + phdr_cache->push_back(*info); + return 0; + }, nullptr); +#endif +} From cc7fe5fb8d9dc840baf493b2875f59b1113c2309 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 18:27:37 +0300 Subject: [PATCH 0316/1165] Addition to prev. revision --- libs/libcommon/src/phdr_cache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/libcommon/src/phdr_cache.cpp b/libs/libcommon/src/phdr_cache.cpp index 292d71ceead..6e31ff2e633 100644 --- a/libs/libcommon/src/phdr_cache.cpp +++ b/libs/libcommon/src/phdr_cache.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include namespace { From 30d319fc7728601d4f7b60b776e909bc13b89a4c Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov Date: Wed, 24 Jul 2019 16:08:08 +0300 Subject: [PATCH 0317/1165] Update zlib-ng to fix a ThreadSanitizer warning. --- contrib/zlib-ng | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/zlib-ng b/contrib/zlib-ng index 9173b89d467..cb43e7fa08e 160000 --- a/contrib/zlib-ng +++ b/contrib/zlib-ng @@ -1 +1 @@ -Subproject commit 9173b89d46799582d20a30578e0aa9788bc7d6e1 +Subproject commit cb43e7fa08ec29fd76d84e3bb35258a0f0bf3df3 From 796dfeb44e276cc94944ae6e6e5f6e6fec0efb0c Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 18:35:19 +0300 Subject: [PATCH 0318/1165] Better PHDR cache --- libs/libcommon/src/phdr_cache.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/libs/libcommon/src/phdr_cache.cpp b/libs/libcommon/src/phdr_cache.cpp index 6e31ff2e633..c27d42d40b5 100644 --- a/libs/libcommon/src/phdr_cache.cpp +++ b/libs/libcommon/src/phdr_cache.cpp @@ -2,11 +2,11 @@ #include #include -#include -#include +#include #include #include + namespace { @@ -24,9 +24,11 @@ DLIterateFunction getOriginalDLIteratePHDR() return reinterpret_cast(func); } -// Never destroyed to avoid races with static destructors. -using PHDRCache = std::vector; -PHDRCache * phdr_cache; + +constexpr size_t phdr_cache_max_size = 128; +size_t phdr_cache_size = 0; +using PHDRCache = std::array; +PHDRCache phdr_cache; } @@ -38,16 +40,16 @@ extern "C" #endif int dl_iterate_phdr(int (*callback) (dl_phdr_info * info, size_t size, void * data), void * data) { - if (!phdr_cache) + if (0 == phdr_cache_size) { // Cache is not yet populated, pass through to the original function. return getOriginalDLIteratePHDR()(callback, data); } int result = 0; - for (auto & info : *phdr_cache) + for (size_t i = 0; i < phdr_cache_size; ++i) { - result = callback(&info, offsetof(dl_phdr_info, dlpi_adds), data); + result = callback(&phdr_cache[i], offsetof(dl_phdr_info, dlpi_adds), data); if (result != 0) break; } @@ -60,10 +62,12 @@ void enablePHDRCache() #if defined(__linux__) // Fill out ELF header cache for access without locking. // This assumes no dynamic object loading/unloading after this point - phdr_cache = new PHDRCache; getOriginalDLIteratePHDR()([] (dl_phdr_info * info, size_t /*size*/, void * /*data*/) { - phdr_cache->push_back(*info); + if (phdr_cache_size >= phdr_cache_max_size) + throw std::runtime_error("phdr_cache_max_size is not enough to accomodate the result of dl_iterate_phdr. You must recompile the code."); + phdr_cache[phdr_cache_size] = *info; + ++phdr_cache_size; return 0; }, nullptr); #endif From b3123df58ec6cf1832a00fe3006fbc1af49f6c97 Mon Sep 17 00:00:00 2001 From: chertus Date: Wed, 24 Jul 2019 18:37:37 +0300 Subject: [PATCH 0319/1165] use source and joined columns to detect JOIN ON right and left keys --- .../Interpreters/CollectJoinOnKeysVisitor.h | 80 +++++++++++++++---- dbms/src/Interpreters/SyntaxAnalyzer.cpp | 13 ++- .../TranslateQualifiedNamesVisitor.h | 2 +- .../00800_low_cardinality_join.sql | 19 ++--- .../0_stateless/00974_fix_join_on.reference | 28 +++++++ .../queries/0_stateless/00974_fix_join_on.sql | 61 ++++++++++++++ 6 files changed, 172 insertions(+), 31 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00974_fix_join_on.reference create mode 100644 dbms/tests/queries/0_stateless/00974_fix_join_on.sql diff --git a/dbms/src/Interpreters/CollectJoinOnKeysVisitor.h b/dbms/src/Interpreters/CollectJoinOnKeysVisitor.h index aacfbe507a1..1857bc88cf4 100644 --- a/dbms/src/Interpreters/CollectJoinOnKeysVisitor.h +++ b/dbms/src/Interpreters/CollectJoinOnKeysVisitor.h @@ -4,14 +4,18 @@ #include #include +#include #include + namespace DB { namespace ErrorCodes { extern const int INVALID_JOIN_ON_EXPRESSION; + extern const int AMBIGUOUS_COLUMN_NAME; + extern const int LOGICAL_ERROR; } @@ -23,6 +27,9 @@ public: struct Data { AnalyzedJoin & analyzed_join; + const NameSet & source_columns; + const NameSet & joined_columns; + const Aliases & aliases; bool has_some = false; }; @@ -50,7 +57,7 @@ private: { ASTPtr left = func.arguments->children.at(0)->clone(); ASTPtr right = func.arguments->children.at(1)->clone(); - addColumnsFromEqualsExpr(ast, left, right, data); + addJoinKeys(ast, left, right, data); return; } @@ -70,7 +77,7 @@ private: getIdentifiers(child, out); } - static void addColumnsFromEqualsExpr(const ASTPtr & expr, ASTPtr left_ast, ASTPtr right_ast, Data & data) + static void addJoinKeys(const ASTPtr & expr, ASTPtr left_ast, ASTPtr right_ast, Data & data) { std::vector left_identifiers; std::vector right_identifiers; @@ -78,8 +85,8 @@ private: getIdentifiers(left_ast, left_identifiers); getIdentifiers(right_ast, right_identifiers); - size_t left_idents_table = checkSameTable(left_identifiers); - size_t right_idents_table = checkSameTable(right_identifiers); + size_t left_idents_table = getTableForIdentifiers(left_identifiers, data); + size_t right_idents_table = getTableForIdentifiers(right_identifiers, data); if (left_idents_table && left_idents_table == right_idents_table) { @@ -95,40 +102,79 @@ private: else if (left_idents_table == 2 || right_idents_table == 1) data.analyzed_join.addOnKeys(right_ast, left_ast); else - { - /// Default variant when all identifiers may be from any table. - data.analyzed_join.addOnKeys(left_ast, right_ast); /// FIXME - } + throw Exception("Cannot detect left and right JOIN keys. JOIN ON section is ambiguous.", + ErrorCodes::AMBIGUOUS_COLUMN_NAME); data.has_some = true; } - static size_t checkSameTable(std::vector & identifiers) + static const ASTIdentifier * unrollAliases(const ASTIdentifier * identifier, const Aliases & aliases) + { + UInt32 max_attempts = 100; + for (auto it = aliases.find(identifier->name); it != aliases.end();) + { + const ASTIdentifier * parent = identifier; + identifier = it->second->as(); + if (!identifier) + break; /// not a column alias + if (identifier == parent) + break; /// alias to itself with the same name: 'a as a' + if (identifier->compound()) + break; /// not an alias. Break to prevent cycle through short names: 'a as b, t1.b as a' + + it = aliases.find(identifier->name); + if (!max_attempts--) + throw Exception("Cannot unroll aliases for '" + identifier->name + "'", ErrorCodes::LOGICAL_ERROR); + } + + return identifier; + } + + /// @returns 1 if identifiers belongs to left table, 2 for right table and 0 if unknown. Throws on table mix. + /// Place detected identifier into identifiers[0] if any. + static size_t getTableForIdentifiers(std::vector & identifiers, const Data & data) { size_t table_number = 0; - const ASTIdentifier * detected = nullptr; - for (const auto & identifier : identifiers) + for (auto & ident : identifiers) { - /// It's set in TranslateQualifiedNamesVisitor + const ASTIdentifier * identifier = unrollAliases(ident, data.aliases); + if (!identifier) + continue; + + /// Column name could be cropped to a short form in TranslateQualifiedNamesVisitor. + /// In this case it saves membership in IdentifierSemantic. size_t membership = IdentifierSemantic::getMembership(*identifier); + + if (!membership) + { + const String & name = identifier->name; + bool in_left_table = data.source_columns.count(name); + bool in_right_table = data.joined_columns.count(name); + + if (in_left_table && in_right_table) + throw Exception("Column '" + name + "' is ambiguous", ErrorCodes::AMBIGUOUS_COLUMN_NAME); + + if (in_left_table) + membership = 1; + if (in_right_table) + membership = 2; + } + if (membership && table_number == 0) { table_number = membership; - detected = identifier; + std::swap(ident, identifiers[0]); /// move first detected identifier to the first position } if (membership && membership != table_number) { throw Exception("Invalid columns in JOIN ON section. Columns " - + detected->getAliasOrColumnName() + " and " + identifier->getAliasOrColumnName() + + identifiers[0]->getAliasOrColumnName() + " and " + ident->getAliasOrColumnName() + " are from different tables.", ErrorCodes::INVALID_JOIN_ON_EXPRESSION); } } - identifiers.clear(); - if (detected) - identifiers.push_back(detected); return table_number; } diff --git a/dbms/src/Interpreters/SyntaxAnalyzer.cpp b/dbms/src/Interpreters/SyntaxAnalyzer.cpp index c70b4e21363..04102f5ae15 100644 --- a/dbms/src/Interpreters/SyntaxAnalyzer.cpp +++ b/dbms/src/Interpreters/SyntaxAnalyzer.cpp @@ -482,8 +482,8 @@ void getArrayJoinedColumns(ASTPtr & query, SyntaxAnalyzerResult & result, const } /// Find the columns that are obtained by JOIN. -void collectJoinedColumns(AnalyzedJoin & analyzed_join, const ASTSelectQuery & select_query, - const NameSet & source_columns, const String & current_database, bool join_use_nulls) +void collectJoinedColumns(AnalyzedJoin & analyzed_join, const ASTSelectQuery & select_query, const NameSet & source_columns, + const Aliases & aliases, const String & current_database, bool join_use_nulls) { const ASTTablesInSelectQueryElement * node = select_query.join(); if (!node) @@ -505,7 +505,11 @@ void collectJoinedColumns(AnalyzedJoin & analyzed_join, const ASTSelectQuery & s } else if (table_join.on_expression) { - CollectJoinOnKeysVisitor::Data data{analyzed_join}; + NameSet joined_columns; + for (const auto & col : analyzed_join.columns_from_joined_table) + joined_columns.insert(col.original_name); + + CollectJoinOnKeysVisitor::Data data{analyzed_join, source_columns, joined_columns, aliases}; CollectJoinOnKeysVisitor(data).visit(table_join.on_expression); if (!data.has_some) throw Exception("Cannot get JOIN keys from JOIN ON section: " + queryToString(table_join.on_expression), @@ -662,7 +666,8 @@ SyntaxAnalyzerResultPtr SyntaxAnalyzer::analyze( /// Push the predicate expression down to the subqueries. result.rewrite_subqueries = PredicateExpressionsOptimizer(select_query, settings, context).optimize(); - collectJoinedColumns(result.analyzed_join, *select_query, source_columns_set, context.getCurrentDatabase(), settings.join_use_nulls); + collectJoinedColumns(result.analyzed_join, *select_query, source_columns_set, result.aliases, + context.getCurrentDatabase(), settings.join_use_nulls); } return std::make_shared(result); diff --git a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.h b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.h index f1eaa3c9993..346c39b3344 100644 --- a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.h +++ b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.h @@ -24,7 +24,7 @@ public: struct Data { - NameSet source_columns; + const NameSet source_columns; const std::vector & tables; std::unordered_set join_using_columns; bool has_columns; diff --git a/dbms/tests/queries/0_stateless/00800_low_cardinality_join.sql b/dbms/tests/queries/0_stateless/00800_low_cardinality_join.sql index 07ad6d54624..9734b1ef31c 100644 --- a/dbms/tests/queries/0_stateless/00800_low_cardinality_join.sql +++ b/dbms/tests/queries/0_stateless/00800_low_cardinality_join.sql @@ -8,15 +8,16 @@ select * from (select toLowCardinality(toNullable(dummy)) as val from system.one select * from (select toLowCardinality(dummy) as val from system.one) any left join (select toLowCardinality(toNullable(dummy)) as val from system.one) using val; select * from (select toLowCardinality(toNullable(dummy)) as val from system.one) any left join (select toLowCardinality(toNullable(dummy)) as val from system.one) using val; select '-'; -select * from (select dummy as val from system.one) any left join (select dummy as val from system.one) on val + 0 = val * 1; -select * from (select toLowCardinality(dummy) as val from system.one) any left join (select dummy as val from system.one) on val + 0 = val * 1; -select * from (select dummy as val from system.one) any left join (select toLowCardinality(dummy) as val from system.one) on val + 0 = val * 1; -select * from (select toLowCardinality(dummy) as val from system.one) any left join (select toLowCardinality(dummy) as val from system.one) on val + 0 = val * 1; -select * from (select toLowCardinality(toNullable(dummy)) as val from system.one) any left join (select dummy as val from system.one) on val + 0 = val * 1; -select * from (select dummy as val from system.one) any left join (select toLowCardinality(toNullable(dummy)) as val from system.one) on val + 0 = val * 1; -select * from (select toLowCardinality(toNullable(dummy)) as val from system.one) any left join (select toLowCardinality(dummy) as val from system.one) on val + 0 = val * 1; -select * from (select toLowCardinality(dummy) as val from system.one) any left join (select toLowCardinality(toNullable(dummy)) as val from system.one) on val + 0 = val * 1; -select * from (select toLowCardinality(toNullable(dummy)) as val from system.one) any left join (select toLowCardinality(toNullable(dummy)) as val from system.one) on val + 0 = val * 1; +select * from (select dummy as val from system.one) any left join (select dummy as val from system.one) on val + 0 = val * 1; -- { serverError 352 } +select * from (select dummy as val from system.one) any left join (select dummy as rval from system.one) on val + 0 = rval * 1; +select * from (select toLowCardinality(dummy) as val from system.one) any left join (select dummy as rval from system.one) on val + 0 = rval * 1; +select * from (select dummy as val from system.one) any left join (select toLowCardinality(dummy) as rval from system.one) on val + 0 = rval * 1; +select * from (select toLowCardinality(dummy) as val from system.one) any left join (select toLowCardinality(dummy) as rval from system.one) on val + 0 = rval * 1; +select * from (select toLowCardinality(toNullable(dummy)) as val from system.one) any left join (select dummy as rval from system.one) on val + 0 = rval * 1; +select * from (select dummy as val from system.one) any left join (select toLowCardinality(toNullable(dummy)) as rval from system.one) on val + 0 = rval * 1; +select * from (select toLowCardinality(toNullable(dummy)) as val from system.one) any left join (select toLowCardinality(dummy) as rval from system.one) on val + 0 = rval * 1; +select * from (select toLowCardinality(dummy) as val from system.one) any left join (select toLowCardinality(toNullable(dummy)) as rval from system.one) on val + 0 = rval * 1; +select * from (select toLowCardinality(toNullable(dummy)) as val from system.one) any left join (select toLowCardinality(toNullable(dummy)) as rval from system.one) on val + 0 = rval * 1; select '-'; select * from (select number as l from system.numbers limit 3) any left join (select number as r from system.numbers limit 3) on l + 1 = r * 1; select * from (select toLowCardinality(number) as l from system.numbers limit 3) any left join (select number as r from system.numbers limit 3) on l + 1 = r * 1; diff --git a/dbms/tests/queries/0_stateless/00974_fix_join_on.reference b/dbms/tests/queries/0_stateless/00974_fix_join_on.reference new file mode 100644 index 00000000000..1d0b18e4f96 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_fix_join_on.reference @@ -0,0 +1,28 @@ +2 y 2 w +2 y 2 w +2 2 +2 2 +y w +y w +2 2 +2 2 +y w +y w +y y +y y +y y +y y +2 y 2 w +2 y 2 w +2 2 +2 2 +y w +y w +2 2 +2 2 +y w +y w +y y +y y +y y +y y diff --git a/dbms/tests/queries/0_stateless/00974_fix_join_on.sql b/dbms/tests/queries/0_stateless/00974_fix_join_on.sql new file mode 100644 index 00000000000..1a3126f981d --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_fix_join_on.sql @@ -0,0 +1,61 @@ +use test; + +drop table if exists t1; +drop table if exists t2; + +create table t1 (a UInt32, b String) engine = Memory; +create table t2 (c UInt32, d String) engine = Memory; + +insert into t1 values (1, 'x'), (2, 'y'), (3, 'z'); +insert into t2 values (2, 'w'), (4, 'y'); + +set enable_optimize_predicate_expression = 0; +select * from t1 join t2 on a = c; +select * from t1 join t2 on c = a; + +select t1.a, t2.c from t1 join t2 on a = c; +select t1.a, t2.c from t1 join t2 on c = a; +select t1.b, t2.d from t1 join t2 on a = c; +select t1.b, t2.d from t1 join t2 on c = a; + +select a, c from t1 join t2 on a = c; +select a, c from t1 join t2 on c = a; +select b, d from t1 join t2 on a = c; +select b, d from t1 join t2 on c = a; + +select b as a, d as c from t1 join t2 on a = c; +select b as a, d as c from t1 join t2 on c = a; +select b as c, d as a from t1 join t2 on a = c; +select b as c, d as a from t1 join t2 on c = a; + +-- TODO +-- select t1.a as a, t2.c as c from t1 join t2 on a = c; +-- select t1.a as a, t2.c as c from t1 join t2 on c = a; +-- select t1.a as c, t2.c as a from t1 join t2 on a = c; +-- select t1.a as c, t2.c as a from t1 join t2 on c = a; +-- +-- select t1.a as c, t2.c as a from t1 join t2 on t1.a = t2.c; +-- select t1.a as c, t2.c as a from t1 join t2 on t2.c = t1.a; + +set enable_optimize_predicate_expression = 1; + +select * from t1 join t2 on a = c; +select * from t1 join t2 on c = a; + +select t1.a, t2.c from t1 join t2 on a = c; +select t1.a, t2.c from t1 join t2 on c = a; +select t1.b, t2.d from t1 join t2 on a = c; +select t1.b, t2.d from t1 join t2 on c = a; + +select a, c from t1 join t2 on a = c; +select a, c from t1 join t2 on c = a; +select b, d from t1 join t2 on a = c; +select b, d from t1 join t2 on c = a; + +select b as a, d as c from t1 join t2 on a = c; +select b as a, d as c from t1 join t2 on c = a; +select b as c, d as a from t1 join t2 on a = c; +select b as c, d as a from t1 join t2 on c = a; + +drop table t1; +drop table t2; From 7d8e9658827239a750f22b0d1dba9a5abcb8a210 Mon Sep 17 00:00:00 2001 From: proller Date: Wed, 24 Jul 2019 19:58:37 +0300 Subject: [PATCH 0320/1165] Fix includes for arcadia --- dbms/src/Formats/ParquetBlockInputStream.cpp | 3 +-- dbms/src/Formats/ParquetBlockOutputStream.cpp | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/dbms/src/Formats/ParquetBlockInputStream.cpp b/dbms/src/Formats/ParquetBlockInputStream.cpp index deba953bab4..6b5b29e1e11 100644 --- a/dbms/src/Formats/ParquetBlockInputStream.cpp +++ b/dbms/src/Formats/ParquetBlockInputStream.cpp @@ -1,6 +1,5 @@ -#include "config_formats.h" +#include "ParquetBlockInputStream.h" #if USE_PARQUET -# include "ParquetBlockInputStream.h" # include # include diff --git a/dbms/src/Formats/ParquetBlockOutputStream.cpp b/dbms/src/Formats/ParquetBlockOutputStream.cpp index f03aa181bc3..6b595962437 100644 --- a/dbms/src/Formats/ParquetBlockOutputStream.cpp +++ b/dbms/src/Formats/ParquetBlockOutputStream.cpp @@ -1,6 +1,5 @@ -#include "config_formats.h" +#include "ParquetBlockOutputStream.h" #if USE_PARQUET -# include "ParquetBlockOutputStream.h" // TODO: clean includes # include From c8a274f2ed95127da3a216107ff771fe30b7ae3f Mon Sep 17 00:00:00 2001 From: proller Date: Wed, 24 Jul 2019 20:09:14 +0300 Subject: [PATCH 0321/1165] Fix includes for arcadia --- dbms/src/Formats/ParquetBlockInputStream.cpp | 2 +- dbms/src/Formats/ParquetBlockOutputStream.cpp | 2 +- dbms/src/Formats/ProtobufColumnMatcher.cpp | 5 +---- dbms/src/Formats/ProtobufRowInputStream.cpp | 4 +--- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/dbms/src/Formats/ParquetBlockInputStream.cpp b/dbms/src/Formats/ParquetBlockInputStream.cpp index 6b5b29e1e11..e75d5e1d455 100644 --- a/dbms/src/Formats/ParquetBlockInputStream.cpp +++ b/dbms/src/Formats/ParquetBlockInputStream.cpp @@ -1,6 +1,6 @@ #include "ParquetBlockInputStream.h" -#if USE_PARQUET +#if USE_PARQUET # include # include # include diff --git a/dbms/src/Formats/ParquetBlockOutputStream.cpp b/dbms/src/Formats/ParquetBlockOutputStream.cpp index 6b595962437..b0d4cd7818c 100644 --- a/dbms/src/Formats/ParquetBlockOutputStream.cpp +++ b/dbms/src/Formats/ParquetBlockOutputStream.cpp @@ -1,6 +1,6 @@ #include "ParquetBlockOutputStream.h" -#if USE_PARQUET +#if USE_PARQUET // TODO: clean includes # include # include diff --git a/dbms/src/Formats/ProtobufColumnMatcher.cpp b/dbms/src/Formats/ProtobufColumnMatcher.cpp index 317b6388ea5..ed9bd27bb34 100644 --- a/dbms/src/Formats/ProtobufColumnMatcher.cpp +++ b/dbms/src/Formats/ProtobufColumnMatcher.cpp @@ -1,8 +1,5 @@ -#include "config_formats.h" -#if USE_PROTOBUF - #include "ProtobufColumnMatcher.h" - +#if USE_PROTOBUF #include #include #include diff --git a/dbms/src/Formats/ProtobufRowInputStream.cpp b/dbms/src/Formats/ProtobufRowInputStream.cpp index 1c4193b9f1a..ff5717c1bca 100644 --- a/dbms/src/Formats/ProtobufRowInputStream.cpp +++ b/dbms/src/Formats/ProtobufRowInputStream.cpp @@ -1,8 +1,6 @@ -#include "config_formats.h" -#if USE_PROTOBUF - #include "ProtobufRowInputStream.h" +#if USE_PROTOBUF #include #include #include From a734231d425e2ade6cc1421a5c88f27510f26291 Mon Sep 17 00:00:00 2001 From: proller Date: Wed, 24 Jul 2019 20:49:02 +0300 Subject: [PATCH 0322/1165] Fix includes for arcadia --- dbms/src/Common/MiAllocator.cpp | 4 +--- dbms/src/Common/MiAllocator.h | 7 +++---- dbms/src/Formats/CapnProtoRowInputStream.cpp | 4 +--- dbms/src/IO/ReadBufferFromHDFS.cpp | 4 +--- dbms/src/IO/ReadBufferFromHDFS.h | 2 ++ 5 files changed, 8 insertions(+), 13 deletions(-) diff --git a/dbms/src/Common/MiAllocator.cpp b/dbms/src/Common/MiAllocator.cpp index cafa6c135f7..04e61a5de16 100644 --- a/dbms/src/Common/MiAllocator.cpp +++ b/dbms/src/Common/MiAllocator.cpp @@ -1,8 +1,6 @@ -#include +#include "MiAllocator.h" #if USE_MIMALLOC - -#include "MiAllocator.h" #include #include diff --git a/dbms/src/Common/MiAllocator.h b/dbms/src/Common/MiAllocator.h index 48cfc6f9ab4..127be82434b 100644 --- a/dbms/src/Common/MiAllocator.h +++ b/dbms/src/Common/MiAllocator.h @@ -2,10 +2,7 @@ #include -#if !USE_MIMALLOC -#error "do not include this file until USE_MIMALLOC is set to 1" -#endif - +#if USE_MIMALLOC #include namespace DB @@ -26,3 +23,5 @@ struct MiAllocator }; } + +#endif diff --git a/dbms/src/Formats/CapnProtoRowInputStream.cpp b/dbms/src/Formats/CapnProtoRowInputStream.cpp index 96c3c5fded3..89d652ebb12 100644 --- a/dbms/src/Formats/CapnProtoRowInputStream.cpp +++ b/dbms/src/Formats/CapnProtoRowInputStream.cpp @@ -1,8 +1,6 @@ -#include "config_formats.h" -#if USE_CAPNP - #include "CapnProtoRowInputStream.h" +#if USE_CAPNP #include #include #include diff --git a/dbms/src/IO/ReadBufferFromHDFS.cpp b/dbms/src/IO/ReadBufferFromHDFS.cpp index daedd9b0481..9c44048d4ce 100644 --- a/dbms/src/IO/ReadBufferFromHDFS.cpp +++ b/dbms/src/IO/ReadBufferFromHDFS.cpp @@ -1,8 +1,6 @@ -#include +#include "ReadBufferFromHDFS.h" #if USE_HDFS - -#include #include #include #include diff --git a/dbms/src/IO/ReadBufferFromHDFS.h b/dbms/src/IO/ReadBufferFromHDFS.h index 81a1d4b75dc..6d00c8b2310 100644 --- a/dbms/src/IO/ReadBufferFromHDFS.h +++ b/dbms/src/IO/ReadBufferFromHDFS.h @@ -1,5 +1,7 @@ #pragma once +#include + #if USE_HDFS #include #include From 58d579e7e2ee4a3861fb21da91e65b609f6900fd Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 24 Jul 2019 21:00:09 +0300 Subject: [PATCH 0323/1165] Use IInputFormat and IOutputFormat by default. --- dbms/src/Formats/FormatFactory.cpp | 70 +++++++++---------- dbms/src/Formats/FormatFactory.h | 18 +++-- dbms/src/Processors/Formats/IOutputFormat.h | 11 +++ dbms/src/Processors/Formats/IRowInputFormat.h | 5 ++ .../Formats/InputStreamFromInputFormat.h | 58 +++++++++++++++ .../Formats/OutputStreamToOutputFormat.cpp | 34 +++++++++ .../Formats/OutputStreamToOutputFormat.h | 38 ++++++++++ 7 files changed, 192 insertions(+), 42 deletions(-) create mode 100644 dbms/src/Processors/Formats/InputStreamFromInputFormat.h create mode 100644 dbms/src/Processors/Formats/OutputStreamToOutputFormat.cpp create mode 100644 dbms/src/Processors/Formats/OutputStreamToOutputFormat.h diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 4fae140abee..5f1e2f25605 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include namespace DB @@ -18,14 +20,14 @@ namespace ErrorCodes extern const int FORMAT_IS_NOT_SUITABLE_FOR_OUTPUT; } - -const FormatFactory::Creators & FormatFactory::getCreators(const String & name) const -{ - auto it = dict.find(name); - if (dict.end() != it) - return it->second; - throw Exception("Unknown format " + name, ErrorCodes::UNKNOWN_FORMAT); -} +// +//const FormatFactory::Creators & FormatFactory::getCreators(const String & name) const +//{ +// auto it = dict.find(name); +// if (dict.end() != it) +// return it->second; +// throw Exception("Unknown format " + name, ErrorCodes::UNKNOWN_FORMAT); +//} const FormatFactory::ProcessorCreators & FormatFactory::getProcessorCreators(const String & name) const { @@ -81,36 +83,30 @@ BlockInputStreamPtr FormatFactory::getInput( UInt64 rows_portion_size, ReadCallback callback) const { - const auto & input_getter = getCreators(name).first; - if (!input_getter) - throw Exception("Format " + name + " is not suitable for input", ErrorCodes::FORMAT_IS_NOT_SUITABLE_FOR_INPUT); - - const Settings & settings = context.getSettingsRef(); - FormatSettings format_settings = getInputFormatSetting(settings); - - return input_getter( - buf, sample, context, max_block_size, rows_portion_size, callback ? callback : ReadCallback(), format_settings); + auto format = getInputFormat(name, buf, sample, context, max_block_size, rows_portion_size, std::move(callback)); + return std::make_shared(std::move(format)); } BlockOutputStreamPtr FormatFactory::getOutput(const String & name, WriteBuffer & buf, const Block & sample, const Context & context) const { - const auto & output_getter = getCreators(name).second; - if (!output_getter) - throw Exception("Format " + name + " is not suitable for output", ErrorCodes::FORMAT_IS_NOT_SUITABLE_FOR_OUTPUT); - - const Settings & settings = context.getSettingsRef(); - FormatSettings format_settings = getOutputFormatSetting(settings); + auto format = getOutputFormat(name, buf, sample, context); /** Materialization is needed, because formats can use the functions `IDataType`, * which only work with full columns. */ - return std::make_shared( - output_getter(buf, sample, context, format_settings), sample); + return std::make_shared(std::make_shared(format)); } -InputFormatPtr FormatFactory::getInputFormat(const String & name, ReadBuffer & buf, const Block & sample, const Context & context, UInt64 max_block_size) const +InputFormatPtr FormatFactory::getInputFormat( + const String & name, + ReadBuffer & buf, + const Block & sample, + const Context & context, + UInt64 max_block_size, + UInt64 rows_portion_size, + ReadCallback callback) const { const auto & input_getter = getProcessorCreators(name).first; if (!input_getter) @@ -123,6 +119,8 @@ InputFormatPtr FormatFactory::getInputFormat(const String & name, ReadBuffer & b params.max_block_size = max_block_size; params.allow_errors_num = format_settings.input_allow_errors_num; params.allow_errors_ratio = format_settings.input_allow_errors_ratio; + params.rows_portion_size = rows_portion_size; + params.callback = std::move(callback); return input_getter(buf, sample, context, params, format_settings); } @@ -144,20 +142,20 @@ OutputFormatPtr FormatFactory::getOutputFormat(const String & name, WriteBuffer } -void FormatFactory::registerInputFormat(const String & name, InputCreator input_creator) +void FormatFactory::registerInputFormat(const String & /*name*/, InputCreator /*input_creator*/) { - auto & target = dict[name].first; - if (target) - throw Exception("FormatFactory: Input format " + name + " is already registered", ErrorCodes::LOGICAL_ERROR); - target = std::move(input_creator); +// auto & target = dict[name].first; +// if (target) +// throw Exception("FormatFactory: Input format " + name + " is already registered", ErrorCodes::LOGICAL_ERROR); +// target = std::move(input_creator); } -void FormatFactory::registerOutputFormat(const String & name, OutputCreator output_creator) +void FormatFactory::registerOutputFormat(const String & /*name*/, OutputCreator /*output_creator*/) { - auto & target = dict[name].second; - if (target) - throw Exception("FormatFactory: Output format " + name + " is already registered", ErrorCodes::LOGICAL_ERROR); - target = std::move(output_creator); +// auto & target = dict[name].second; +// if (target) +// throw Exception("FormatFactory: Output format " + name + " is already registered", ErrorCodes::LOGICAL_ERROR); +// target = std::move(output_creator); } void FormatFactory::registerInputFormatProcessor(const String & name, InputProcessorCreator input_creator) diff --git a/dbms/src/Formats/FormatFactory.h b/dbms/src/Formats/FormatFactory.h index 5cc1fcecb93..23fd71aa9ad 100644 --- a/dbms/src/Formats/FormatFactory.h +++ b/dbms/src/Formats/FormatFactory.h @@ -89,8 +89,14 @@ public: BlockOutputStreamPtr getOutput(const String & name, WriteBuffer & buf, const Block & sample, const Context & context) const; - InputFormatPtr getInputFormat(const String & name, ReadBuffer & buf, - const Block & sample, const Context & context, UInt64 max_block_size) const; + InputFormatPtr getInputFormat( + const String & name, + ReadBuffer & buf, + const Block & sample, + const Context & context, + UInt64 max_block_size, + UInt64 rows_portion_size = 0, + ReadCallback callback = {}) const; OutputFormatPtr getOutputFormat(const String & name, WriteBuffer & buf, const Block & sample, const Context & context) const; @@ -102,19 +108,19 @@ public: void registerInputFormatProcessor(const String & name, InputProcessorCreator input_creator); void registerOutputFormatProcessor(const String & name, OutputProcessorCreator output_creator); - const FormatsDictionary & getAllFormats() const + const FormatProcessorsDictionary & getAllFormats() const { - return dict; + return processors_dict; } private: - FormatsDictionary dict; + /// FormatsDictionary dict; FormatProcessorsDictionary processors_dict; FormatFactory(); friend class ext::singleton; - const Creators & getCreators(const String & name) const; + //const Creators & getCreators(const String & name) const; const ProcessorCreators & getProcessorCreators(const String & name) const; }; diff --git a/dbms/src/Processors/Formats/IOutputFormat.h b/dbms/src/Processors/Formats/IOutputFormat.h index 280f64593b7..55555717070 100644 --- a/dbms/src/Processors/Formats/IOutputFormat.h +++ b/dbms/src/Processors/Formats/IOutputFormat.h @@ -58,6 +58,17 @@ public: virtual std::string getContentType() const { return "text/plain; charset=UTF-8"; } InputPort & getPort(PortKind kind) { return *std::next(inputs.begin(), kind); } + +public: + /// Compatible to IBlockOutputStream interface + + void write(const Block & block) { consume(Chunk(block.getColumns(), block.rows())); } + + void writePrefix() {} + void writeSuffix() { finalize(); } + + void setTotals(const Block & totals) { consume(Chunk(totals.getColumns(), totals.rows())); } + void setExtremes(const Block & extremes) { consume(Chunk(extremes.getColumns(), extremes.rows())); } }; } diff --git a/dbms/src/Processors/Formats/IRowInputFormat.h b/dbms/src/Processors/Formats/IRowInputFormat.h index 9d0ee7cb0c9..b574af8c39a 100644 --- a/dbms/src/Processors/Formats/IRowInputFormat.h +++ b/dbms/src/Processors/Formats/IRowInputFormat.h @@ -23,6 +23,11 @@ struct RowInputFormatParams UInt64 allow_errors_num; Float64 allow_errors_ratio; + + UInt64 rows_portion_size; + + using ReadCallback = std::function; + ReadCallback callback; }; ///Row oriented input format: reads data row by row. diff --git a/dbms/src/Processors/Formats/InputStreamFromInputFormat.h b/dbms/src/Processors/Formats/InputStreamFromInputFormat.h new file mode 100644 index 00000000000..445f45068d4 --- /dev/null +++ b/dbms/src/Processors/Formats/InputStreamFromInputFormat.h @@ -0,0 +1,58 @@ +#pragma once +#include +#include + +namespace DB +{ + +class IInputFormat; +using InputFormatPtr = std::shared_ptr; + +class InputStreamFromInputFormat : public IBlockInputStream +{ +public: + explicit InputStreamFromInputFormat(InputFormatPtr input_format_) + : input_format(std::move(input_format_)) + , port(input_format->getPort().getHeader()) + { + connect(input_format->getPort(), port); + } + + String getName() const override { return input_format->getName(); } + Block getHeader() const override { return input_format->getPort().getHeader(); } + +protected: + + Block readImpl() override + { + while (true) + { + auto status = input_format->prepare(); + + switch (status) + { + case IProcessor::Status::Ready: + input_format->work(); + break; + + case IProcessor::Status::Finished: + return {}; + + case IProcessor::Status::PortFull: + return input_format->getPort().getHeader().cloneWithColumns(port.pull().detachColumns()); + + case IProcessor::Status::NeedData: + case IProcessor::Status::Async: + case IProcessor::Status::Wait: + case IProcessor::Status::ExpandPipeline: + throw Exception("Source processor returned status " + IProcessor::statusToName(status), ErrorCodes::LOGICAL_ERROR); + } + } + } + +private: + InputFormatPtr input_format; + InputPort port; +}; + +} diff --git a/dbms/src/Processors/Formats/OutputStreamToOutputFormat.cpp b/dbms/src/Processors/Formats/OutputStreamToOutputFormat.cpp new file mode 100644 index 00000000000..153972fc65d --- /dev/null +++ b/dbms/src/Processors/Formats/OutputStreamToOutputFormat.cpp @@ -0,0 +1,34 @@ +#include +#include + +namespace DB +{ + +Block OutputStreamToOutputFormat::getHeader() const +{ + return output_format->getPort(IOutputFormat::PortKind::Main).getHeader(); +} + +void OutputStreamToOutputFormat::write(const Block & block) +{ + output_format->write(block); +} + +void OutputStreamToOutputFormat::writePrefix() { output_format->writePrefix(); } +void OutputStreamToOutputFormat::writeSuffix() { output_format->writeSuffix(); } + +void OutputStreamToOutputFormat::flush() { output_format->flush(); } + +void OutputStreamToOutputFormat::setRowsBeforeLimit(size_t rows_before_limit) +{ + output_format->setRowsBeforeLimit(rows_before_limit); +} + +void OutputStreamToOutputFormat::setTotals(const Block & totals) { output_format->setTotals(totals); } +void OutputStreamToOutputFormat::setExtremes(const Block & extremes) { output_format->setExtremes(extremes); } + +void OutputStreamToOutputFormat::onProgress(const Progress & progress) { output_format->onProgress(progress); } + +std::string OutputStreamToOutputFormat::getContentType() const { return output_format->getContentType(); } + +} diff --git a/dbms/src/Processors/Formats/OutputStreamToOutputFormat.h b/dbms/src/Processors/Formats/OutputStreamToOutputFormat.h new file mode 100644 index 00000000000..350486f9b41 --- /dev/null +++ b/dbms/src/Processors/Formats/OutputStreamToOutputFormat.h @@ -0,0 +1,38 @@ +#pragma once +#include + +namespace DB +{ + + +class IOutputFormat; + +using OutputFormatPtr = std::shared_ptr; + +class OutputStreamToOutputFormat : public IBlockOutputStream +{ +public: + explicit OutputStreamToOutputFormat(OutputFormatPtr output_format_) : output_format(std::move(output_format_)) {} + + Block getHeader() const override; + + void write(const Block & block) override; + + void writePrefix() override; + void writeSuffix() override; + + void flush() override; + + void setRowsBeforeLimit(size_t rows_before_limit) override; + void setTotals(const Block & totals) override; + void setExtremes(const Block & extremes) override; + + void onProgress(const Progress & progress) override; + + std::string getContentType() const override; + +private: + OutputFormatPtr output_format; +}; + +} From 16de323bbea40f1a134b9d80a82e9209d517b2e4 Mon Sep 17 00:00:00 2001 From: proller Date: Wed, 24 Jul 2019 21:04:26 +0300 Subject: [PATCH 0324/1165] Freebsd fix --- cmake/print_include_directories.cmake | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cmake/print_include_directories.cmake b/cmake/print_include_directories.cmake index b39ca866148..fe5e9e8e6e9 100644 --- a/cmake/print_include_directories.cmake +++ b/cmake/print_include_directories.cmake @@ -16,10 +16,12 @@ list(APPEND dirs ${dirs1}) get_property (dirs1 TARGET roaring PROPERTY INCLUDE_DIRECTORIES) list(APPEND dirs ${dirs1}) -get_property (dirs1 TARGET double-conversion PROPERTY INCLUDE_DIRECTORIES) -list(APPEND dirs ${dirs1}) +if (TARGET double-conversion) + get_property (dirs1 TARGET double-conversion PROPERTY INCLUDE_DIRECTORIES) + list(APPEND dirs ${dirs1}) +endif () -if (USE_INTERNAL_BOOST_LIBRARY) +if (TARGET ${Boost_PROGRAM_OPTIONS_LIBRARY}) get_property (dirs1 TARGET ${Boost_PROGRAM_OPTIONS_LIBRARY} PROPERTY INCLUDE_DIRECTORIES) list(APPEND dirs ${dirs1}) endif () From 9de5b0d21c5ccfda5905f9bcfd87f95ac0e32cea Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 21:07:24 +0300 Subject: [PATCH 0325/1165] Fixed error in test --- dbms/tests/queries/0_stateless/00971_query_id_in_logs.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dbms/tests/queries/0_stateless/00971_query_id_in_logs.sh b/dbms/tests/queries/0_stateless/00971_query_id_in_logs.sh index a4ef7671f48..83c72be265c 100755 --- a/dbms/tests/queries/0_stateless/00971_query_id_in_logs.sh +++ b/dbms/tests/queries/0_stateless/00971_query_id_in_logs.sh @@ -1,9 +1,11 @@ #!/usr/bin/env bash +CLICKHOUSE_CLIENT_SERVER_LOGS_LEVEL=trace + CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) . $CURDIR/../shell_config.sh set -e # No log lines without query id -$CLICKHOUSE_CLIENT --send_logs_level=trace --query_id=hello --query="SELECT count() FROM numbers(10)" 2>&1 | grep -vF ' {hello} ' | grep -P '<\w+>' ||: +$CLICKHOUSE_CLIENT --query_id=hello --query="SELECT count() FROM numbers(10)" 2>&1 | grep -vF ' {hello} ' | grep -P '<\w+>' ||: From 6cec39ce9641cbb142a0d5fe7d52a9ef07145d7e Mon Sep 17 00:00:00 2001 From: proller Date: Wed, 24 Jul 2019 21:35:45 +0300 Subject: [PATCH 0326/1165] Arcadia fixes --- dbms/src/Formats/ProtobufReader.h | 2 +- dbms/src/Formats/ProtobufWriter.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Formats/ProtobufReader.h b/dbms/src/Formats/ProtobufReader.h index 41088e54ac3..9c5fdfb5fe4 100644 --- a/dbms/src/Formats/ProtobufReader.h +++ b/dbms/src/Formats/ProtobufReader.h @@ -9,7 +9,7 @@ #if USE_PROTOBUF #include -#include +#include "ProtobufColumnMatcher.h" #include #include diff --git a/dbms/src/Formats/ProtobufWriter.h b/dbms/src/Formats/ProtobufWriter.h index d133a8b1214..f11fbcbc391 100644 --- a/dbms/src/Formats/ProtobufWriter.h +++ b/dbms/src/Formats/ProtobufWriter.h @@ -7,7 +7,7 @@ #include "config_formats.h" #if USE_PROTOBUF -#include +#include "ProtobufColumnMatcher.h" #include #include #include From f031d064b6a0eb3c6c647c67c93b6bedc7e5a432 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 22:03:26 +0300 Subject: [PATCH 0327/1165] Don't drop all traces if frequency is too high --- dbms/src/Common/QueryProfiler.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index 48a385e300c..5237a7d142b 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -47,11 +47,17 @@ namespace /// Thus upper bound on query_id length should be introduced to avoid buffer overflow in signal handler. constexpr size_t QUERY_ID_MAX_LEN = 1024; + thread_local size_t write_trace_iteration = 0; + void writeTraceInfo(TimerType timer_type, int /* sig */, siginfo_t * info, void * context) { /// Quickly drop if signal handler is called too frequently. /// Otherwise we may end up infinitelly processing signals instead of doing any useful work. - if (info && info->si_overrun > 0) + ++write_trace_iteration; + if (info + && info->si_overrun > 0 + /// But pass with some frequency to avoid drop of all traces. + && write_trace_iteration % info->si_overrun != 0) return; constexpr size_t buf_size = sizeof(char) + // TraceCollector stop flag From 6e8258fa2fa262212d8a783e0a68713137f6ba01 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 22:04:07 +0300 Subject: [PATCH 0328/1165] Added ProfileEvent for dropped traces due to pipe full --- dbms/src/Common/QueryProfiler.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index 48a385e300c..98fbf36b9d6 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -9,6 +9,12 @@ #include #include + +namespace ProfileEvents +{ + extern const Event QueryProfilerCannotWriteTrace; +} + namespace DB { @@ -31,7 +37,10 @@ namespace ssize_t res = ::write(fd, working_buffer.begin() + bytes_written, offset() - bytes_written); if ((-1 == res || 0 == res) && errno != EINTR) + { + ProfileEvents::increment(ProfileEvents::QueryProfilerCannotWriteTrace); break; /// Discard + } if (res > 0) bytes_written += res; From d9976abe18600719022ee121f2c196616b9301ff Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 22:19:29 +0300 Subject: [PATCH 0329/1165] Added ProfileEvents for signal handler overruns --- dbms/src/Common/ProfileEvents.cpp | 3 +++ dbms/src/Common/QueryProfiler.cpp | 17 +++++++++++++---- dbms/src/Common/TraceCollector.cpp | 6 ++++-- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/dbms/src/Common/ProfileEvents.cpp b/dbms/src/Common/ProfileEvents.cpp index 7059e02d76c..277aafa9eb8 100644 --- a/dbms/src/Common/ProfileEvents.cpp +++ b/dbms/src/Common/ProfileEvents.cpp @@ -171,6 +171,9 @@ M(OSReadChars, "Number of bytes read from filesystem, including page cache.") \ M(OSWriteChars, "Number of bytes written to filesystem, including page cache.") \ M(CreatedHTTPConnections, "Total amount of created HTTP connections (closed or opened).") \ + \ + M(QueryProfilerCannotWriteTrace, "Number of stack traces dropped by query profiler because pipe is full or cannot write to pipe.") \ + M(QueryProfilerSignalOverruns, "Number of times we drop processing of a signal due to overrun plus the number of signals that OS has not delivered due to overrun.") \ namespace ProfileEvents { diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index d9266e9b763..ef12d14320a 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -13,6 +13,7 @@ namespace ProfileEvents { extern const Event QueryProfilerCannotWriteTrace; + extern const Event QueryProfilerSignalOverruns; } namespace DB @@ -63,11 +64,19 @@ namespace /// Quickly drop if signal handler is called too frequently. /// Otherwise we may end up infinitelly processing signals instead of doing any useful work. ++write_trace_iteration; - if (info - && info->si_overrun > 0 + if (info && info->si_overrun > 0) + { /// But pass with some frequency to avoid drop of all traces. - && write_trace_iteration % info->si_overrun != 0) - return; + if (write_trace_iteration % info->si_overrun == 0) + { + ProfileEvents::increment(ProfileEvents::QueryProfilerSignalOverruns, info->si_overrun); + } + else + { + ProfileEvents::increment(ProfileEvents::QueryProfilerSignalOverruns, info->si_overrun + 1); + return; + } + } constexpr size_t buf_size = sizeof(char) + // TraceCollector stop flag 8 * sizeof(char) + // maximum VarUInt length for string size diff --git a/dbms/src/Common/TraceCollector.cpp b/dbms/src/Common/TraceCollector.cpp index 680eefad5da..20e4b0a481e 100644 --- a/dbms/src/Common/TraceCollector.cpp +++ b/dbms/src/Common/TraceCollector.cpp @@ -52,8 +52,10 @@ TraceCollector::TraceCollector(std::shared_ptr & trace_log) if (-1 == pipe_size) throwFromErrno("Cannot get pipe capacity", ErrorCodes::CANNOT_FCNTL); for (errno = 0; errno != EPERM && pipe_size <= 1048576; pipe_size *= 2) - if (-1 == fcntl(trace_pipe.fds_rw[1], F_SETPIPE_SZ, pipe_size) && errno != EPERM) - throwFromErrno("Cannot increase pipe capacity to " + toString(pipe_size), ErrorCodes::CANNOT_FCNTL); + if (-1 == fcntl(trace_pipe.fds_rw[1], F_SETPIPE_SZ, pipe_size * 2) && errno != EPERM) + throwFromErrno("Cannot increase pipe capacity to " + toString(pipe_size * 2), ErrorCodes::CANNOT_FCNTL); + + LOG_TRACE(log, "Pipe capacity is " << formatReadableSizeWithBinarySuffix(pipe_size)); thread = ThreadFromGlobalPool(&TraceCollector::run, this); } From 4b93b459359692eb0d531a3cc2c289e8d3cb7b85 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 22:22:42 +0300 Subject: [PATCH 0330/1165] Update settings description --- dbms/src/Core/Settings.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Core/Settings.h b/dbms/src/Core/Settings.h index 27e06ffec10..833282bba3c 100644 --- a/dbms/src/Core/Settings.h +++ b/dbms/src/Core/Settings.h @@ -221,8 +221,8 @@ struct Settings : public SettingsCollection M(SettingBool, empty_result_for_aggregation_by_empty_set, false, "Return empty result when aggregating without keys on empty set.") \ M(SettingBool, allow_distributed_ddl, true, "If it is set to true, then a user is allowed to executed distributed DDL queries.") \ M(SettingUInt64, odbc_max_field_size, 1024, "Max size of filed can be read from ODBC dictionary. Long strings are truncated.") \ - M(SettingUInt64, query_profiler_real_time_period_ns, 0, "Period for real clock timer of query profiler (in nanoseconds). Set 0 value to turn off real clock query profiler") \ - M(SettingUInt64, query_profiler_cpu_time_period_ns, 0, "Period for CPU clock timer of query profiler (in nanoseconds). Set 0 value to turn off CPU clock query profiler") \ + M(SettingUInt64, query_profiler_real_time_period_ns, 0, "Highly experimental. Period for real clock timer of query profiler (in nanoseconds). Set 0 value to turn off real clock query profiler. Recommended value is at least 10000000 (100 times a second) for single queries or 1000000000 (once a second) for cluster-wide profiling.") \ + M(SettingUInt64, query_profiler_cpu_time_period_ns, 0, "Highly experimental. Period for CPU clock timer of query profiler (in nanoseconds). Set 0 value to turn off CPU clock query profiler. Recommended value is at least 10000000 (100 times a second) for single queries or 1000000000 (once a second) for cluster-wide profiling.") \ \ \ /** Limits during query execution are part of the settings. \ From cfb20661980106b2b0c46fd7b80a9484791f2ff9 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 23:10:23 +0300 Subject: [PATCH 0331/1165] Added information about thread number to trace log --- dbms/src/Common/QueryProfiler.cpp | 6 +++++- dbms/src/Common/TraceCollector.cpp | 9 ++++++--- dbms/src/Interpreters/TraceLog.cpp | 4 +++- dbms/src/Interpreters/TraceLog.h | 1 + 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index ef12d14320a..d9ec571eaa2 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -82,13 +82,16 @@ namespace 8 * sizeof(char) + // maximum VarUInt length for string size QUERY_ID_MAX_LEN * sizeof(char) + // maximum query_id length sizeof(StackTrace) + // collected stack trace - sizeof(TimerType); // timer type + sizeof(TimerType) + // timer type + sizeof(UInt32); // thread_number char buffer[buf_size]; WriteBufferDiscardOnFailure out(trace_pipe.fds_rw[1], buf_size, buffer); StringRef query_id = CurrentThread::getQueryId(); query_id.size = std::min(query_id.size, QUERY_ID_MAX_LEN); + UInt32 thread_number = CurrentThread::get().thread_number; + const auto signal_context = *reinterpret_cast(context); const StackTrace stack_trace(signal_context); @@ -96,6 +99,7 @@ namespace writeStringBinary(query_id, out); writePODBinary(stack_trace, out); writePODBinary(timer_type, out); + writePODBinary(thread_number, out); out.next(); } diff --git a/dbms/src/Common/TraceCollector.cpp b/dbms/src/Common/TraceCollector.cpp index 20e4b0a481e..e66a580289d 100644 --- a/dbms/src/Common/TraceCollector.cpp +++ b/dbms/src/Common/TraceCollector.cpp @@ -48,14 +48,15 @@ TraceCollector::TraceCollector(std::shared_ptr & trace_log) /** Increase pipe size to avoid slowdown during fine-grained trace collection. */ + constexpr int max_pipe_capacity_to_set = 1048576; int pipe_size = fcntl(trace_pipe.fds_rw[1], F_GETPIPE_SZ); if (-1 == pipe_size) throwFromErrno("Cannot get pipe capacity", ErrorCodes::CANNOT_FCNTL); - for (errno = 0; errno != EPERM && pipe_size <= 1048576; pipe_size *= 2) + for (errno = 0; errno != EPERM && pipe_size < max_pipe_capacity_to_set; pipe_size *= 2) if (-1 == fcntl(trace_pipe.fds_rw[1], F_SETPIPE_SZ, pipe_size * 2) && errno != EPERM) throwFromErrno("Cannot increase pipe capacity to " + toString(pipe_size * 2), ErrorCodes::CANNOT_FCNTL); - LOG_TRACE(log, "Pipe capacity is " << formatReadableSizeWithBinarySuffix(pipe_size)); + LOG_TRACE(log, "Pipe capacity is " << formatReadableSizeWithBinarySuffix(std::min(pipe_size, max_pipe_capacity_to_set))); thread = ThreadFromGlobalPool(&TraceCollector::run, this); } @@ -104,10 +105,12 @@ void TraceCollector::run() std::string query_id; StackTrace stack_trace(NoCapture{}); TimerType timer_type; + UInt32 thread_number; readStringBinary(query_id, in); readPODBinary(stack_trace, in); readPODBinary(timer_type, in); + readPODBinary(thread_number, in); const auto size = stack_trace.getSize(); const auto & frames = stack_trace.getFrames(); @@ -117,7 +120,7 @@ void TraceCollector::run() for (size_t i = 0; i < size; i++) trace.emplace_back(UInt64(reinterpret_cast(frames[i]))); - TraceLogElement element{std::time(nullptr), timer_type, query_id, trace}; + TraceLogElement element{std::time(nullptr), timer_type, thread_number, query_id, trace}; trace_log->add(element); } diff --git a/dbms/src/Interpreters/TraceLog.cpp b/dbms/src/Interpreters/TraceLog.cpp index c5583476e99..7340391c6d2 100644 --- a/dbms/src/Interpreters/TraceLog.cpp +++ b/dbms/src/Interpreters/TraceLog.cpp @@ -21,12 +21,13 @@ Block TraceLogElement::createBlock() {std::make_shared(), "event_date"}, {std::make_shared(), "event_time"}, {std::make_shared(timer_values), "timer_type"}, + {std::make_shared(), "thread_number"}, {std::make_shared(), "query_id"}, {std::make_shared(std::make_shared()), "trace"} }; } -void TraceLogElement::appendToBlock(Block &block) const +void TraceLogElement::appendToBlock(Block & block) const { MutableColumns columns = block.mutateColumns(); @@ -35,6 +36,7 @@ void TraceLogElement::appendToBlock(Block &block) const columns[i++]->insert(DateLUT::instance().toDayNum(event_time)); columns[i++]->insert(event_time); columns[i++]->insert(static_cast(timer_type)); + columns[i++]->insert(thread_number); columns[i++]->insertData(query_id.data(), query_id.size()); columns[i++]->insert(trace); diff --git a/dbms/src/Interpreters/TraceLog.h b/dbms/src/Interpreters/TraceLog.h index 7a28e30f50c..e86e789806f 100644 --- a/dbms/src/Interpreters/TraceLog.h +++ b/dbms/src/Interpreters/TraceLog.h @@ -16,6 +16,7 @@ struct TraceLogElement time_t event_time{}; TimerType timer_type{}; + UInt32 thread_number{}; String query_id{}; Array trace{}; From 4c574057709968b82eb954228608f852bd87117e Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 24 Jul 2019 23:12:32 +0300 Subject: [PATCH 0332/1165] Added information about revision to trace log --- dbms/src/Interpreters/TraceLog.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dbms/src/Interpreters/TraceLog.cpp b/dbms/src/Interpreters/TraceLog.cpp index 7340391c6d2..5cde9d30f0f 100644 --- a/dbms/src/Interpreters/TraceLog.cpp +++ b/dbms/src/Interpreters/TraceLog.cpp @@ -4,6 +4,8 @@ #include #include #include +#include + using namespace DB; @@ -20,6 +22,7 @@ Block TraceLogElement::createBlock() { {std::make_shared(), "event_date"}, {std::make_shared(), "event_time"}, + {std::make_shared(), "revision"}, {std::make_shared(timer_values), "timer_type"}, {std::make_shared(), "thread_number"}, {std::make_shared(), "query_id"}, @@ -35,6 +38,7 @@ void TraceLogElement::appendToBlock(Block & block) const columns[i++]->insert(DateLUT::instance().toDayNum(event_time)); columns[i++]->insert(event_time); + columns[i++]->insert(ClickHouseRevision::get()); columns[i++]->insert(static_cast(timer_type)); columns[i++]->insert(thread_number); columns[i++]->insertData(query_id.data(), query_id.size()); From 5755c93d5c2acae74a07efb230eda6c91e7e9b5e Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 25 Jul 2019 01:31:39 +0300 Subject: [PATCH 0333/1165] Fixed MSan report --- dbms/src/Common/memcmpSmall.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dbms/src/Common/memcmpSmall.h b/dbms/src/Common/memcmpSmall.h index 13269a13b29..8d69209b4ef 100644 --- a/dbms/src/Common/memcmpSmall.h +++ b/dbms/src/Common/memcmpSmall.h @@ -3,7 +3,13 @@ #include #include -#ifdef __SSE2__ +#include + +/// We can process uninitialized memory in the functions below. +/// Results don't depend on the values inside uninitialized memory but Memory Sanitizer cannot see it. +/// Disable optimized functions if compile with Memory Sanitizer. + +#if defined(__SSE2__) && !defined(MEMORY_SANITIZER) #include From d414e7366ca2da61efcd4e21178f33de5a7de12b Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 25 Jul 2019 02:11:00 +0300 Subject: [PATCH 0334/1165] Fixed MSan report --- libs/libcommon/include/common/StackTrace.h | 4 ++-- libs/libcommon/src/StackTrace.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/libcommon/include/common/StackTrace.h b/libs/libcommon/include/common/StackTrace.h index be3d6438386..fdb7e288c20 100644 --- a/libs/libcommon/include/common/StackTrace.h +++ b/libs/libcommon/include/common/StackTrace.h @@ -17,7 +17,7 @@ struct NoCapture }; /// Tries to capture current stack trace using libunwind or signal context -/// NOTE: All StackTrace constructors are signal safe +/// NOTE: StackTrace calculation is signal safe only if enablePHDRCache() was called beforehand. class StackTrace { public: @@ -53,7 +53,7 @@ protected: static std::string toStringImpl(const Frames & frames, size_t size); size_t size = 0; - Frames frames; + Frames frames{}; }; std::string signalToErrorMessage(int sig, const siginfo_t & info, const ucontext_t & context); diff --git a/libs/libcommon/src/StackTrace.cpp b/libs/libcommon/src/StackTrace.cpp index 8aea884d004..8323a737fdf 100644 --- a/libs/libcommon/src/StackTrace.cpp +++ b/libs/libcommon/src/StackTrace.cpp @@ -208,7 +208,7 @@ size_t StackTrace::getSize() const return size; } -const StackTrace::Frames& StackTrace::getFrames() const +const StackTrace::Frames & StackTrace::getFrames() const { return frames; } From 6b2810d346096f71352693b5a2b2a7326f215764 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 25 Jul 2019 03:28:27 +0300 Subject: [PATCH 0335/1165] Fixed error with non-SIMD implementation of memcmpSmall --- dbms/src/Common/memcmpSmall.h | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/dbms/src/Common/memcmpSmall.h b/dbms/src/Common/memcmpSmall.h index 8d69209b4ef..5dc5e04a707 100644 --- a/dbms/src/Common/memcmpSmall.h +++ b/dbms/src/Common/memcmpSmall.h @@ -5,13 +5,6 @@ #include -/// We can process uninitialized memory in the functions below. -/// Results don't depend on the values inside uninitialized memory but Memory Sanitizer cannot see it. -/// Disable optimized functions if compile with Memory Sanitizer. - -#if defined(__SSE2__) && !defined(MEMORY_SANITIZER) -#include - namespace detail { @@ -28,6 +21,15 @@ inline int cmp(T a, T b) } + +/// We can process uninitialized memory in the functions below. +/// Results don't depend on the values inside uninitialized memory but Memory Sanitizer cannot see it. +/// Disable optimized functions if compile with Memory Sanitizer. + +#if defined(__SSE2__) && !defined(MEMORY_SANITIZER) +#include + + /** All functions works under the following assumptions: * - it's possible to read up to 15 excessive bytes after end of 'a' and 'b' region; * - memory regions are relatively small and extra loop unrolling is not worth to do. @@ -198,7 +200,10 @@ inline bool memoryIsZeroSmallAllowOverflow15(const void * data, size_t size) template inline int memcmpSmallAllowOverflow15(const Char * a, size_t a_size, const Char * b, size_t b_size) { - return memcmp(a, b, std::min(a_size, b_size)); + if (auto res = memcmp(a, b, std::min(a_size, b_size))) + return res; + else + return detail::cmp(a_size, b_size); } template From 8f3c097c1b85169cc5d400d08359139ac9e2306a Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Thu, 25 Jul 2019 04:03:16 +0300 Subject: [PATCH 0336/1165] Update Settings.h --- dbms/src/Core/Settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Core/Settings.h b/dbms/src/Core/Settings.h index e55e58e9d28..56162f3b18f 100644 --- a/dbms/src/Core/Settings.h +++ b/dbms/src/Core/Settings.h @@ -305,6 +305,7 @@ struct Settings : public SettingsCollection M(SettingBool, log_query_threads, true, "Log query threads into system.query_thread_log table. This setting have effect only when 'log_queries' is true.") \ M(SettingLogsLevel, send_logs_level, LogsLevel::none, "Send server text logs with specified minimum level to client. Valid values: 'trace', 'debug', 'information', 'warning', 'error', 'none'") \ M(SettingBool, enable_optimize_predicate_expression, 1, "If it is set to true, optimize predicates to subqueries.") \ + M(SettingBool, enable_optimize_predicate_expression_to_final_subquery, 1, "Allow push predicate to final subquery.") \ M(SettingUInt64, low_cardinality_max_dictionary_size, 8192, "Maximum size (in rows) of shared global dictionary for LowCardinality type.") \ M(SettingBool, low_cardinality_use_single_dictionary_for_part, false, "LowCardinality type serialization setting. If is true, than will use additional keys when global dictionary overflows. Otherwise, will create several shared dictionaries.") \ @@ -337,7 +338,6 @@ struct Settings : public SettingsCollection /** Obsolete settings that do nothing but left for compatibility reasons. Remove each one after half a year of obsolescence. */ \ \ M(SettingBool, allow_experimental_low_cardinality_type, true, "Obsolete setting, does nothing. Will be removed after 2019-08-13") \ - M(SettingBool, allow_push_predicate_to_final_subquery, 1, "Allow push predicate to final subquery.") DECLARE_SETTINGS_COLLECTION(LIST_OF_SETTINGS) From 3022c4a759818bb1d498702706f455d4927d6a4b Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Thu, 25 Jul 2019 04:04:03 +0300 Subject: [PATCH 0337/1165] Update PredicateExpressionsOptimizer.cpp --- dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp b/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp index 5e0d11212dc..a97233d0798 100644 --- a/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp +++ b/dbms/src/Interpreters/PredicateExpressionsOptimizer.cpp @@ -138,10 +138,10 @@ bool PredicateExpressionsOptimizer::allowPushDown( const std::vector & dependencies, OptimizeKind & optimize_kind) { - if (!subquery || - (!settings.allow_push_predicate_to_final_subquery && subquery->final()) || - subquery->limitBy() || subquery->limitLength() || - subquery->with()) + if (!subquery + || (!settings.enable_optimize_predicate_expression_to_final_subquery && subquery->final()) + || subquery->limitBy() || subquery->limitLength() + || subquery->with()) return false; else { From a985897a0786287dbed385d13a5cc1124e5f18f8 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Thu, 25 Jul 2019 04:05:16 +0300 Subject: [PATCH 0338/1165] Update PredicateExpressionsOptimizer.h --- dbms/src/Interpreters/PredicateExpressionsOptimizer.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dbms/src/Interpreters/PredicateExpressionsOptimizer.h b/dbms/src/Interpreters/PredicateExpressionsOptimizer.h index 89d2bfcfbf0..f9df113abf2 100644 --- a/dbms/src/Interpreters/PredicateExpressionsOptimizer.h +++ b/dbms/src/Interpreters/PredicateExpressionsOptimizer.h @@ -37,11 +37,9 @@ class PredicateExpressionsOptimizer const UInt64 max_expanded_ast_elements; const String count_distinct_implementation; - /// for final PredicatePushOptimizer - const bool allow_push_predicate_to_final_subquery; - /// for PredicateExpressionsOptimizer const bool enable_optimize_predicate_expression; + const bool enable_optimize_predicate_expression_to_final_subquery; const bool join_use_nulls; template @@ -49,8 +47,8 @@ class PredicateExpressionsOptimizer : max_ast_depth(settings.max_ast_depth), max_expanded_ast_elements(settings.max_expanded_ast_elements), count_distinct_implementation(settings.count_distinct_implementation), - allow_push_predicate_to_final_subquery(settings.allow_push_predicate_to_final_subquery), enable_optimize_predicate_expression(settings.enable_optimize_predicate_expression), + enable_optimize_predicate_expression_to_final_subquery(settings.enable_optimize_predicate_expression_to_final_subquery), join_use_nulls(settings.join_use_nulls) {} }; From 26580844f51076dda148c2b37d097202d0a39674 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Thu, 25 Jul 2019 04:07:06 +0300 Subject: [PATCH 0339/1165] Update 00974_final_predicate_push_down.sql --- .../queries/0_stateless/00974_final_predicate_push_down.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.sql b/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.sql index 76b39b09acb..b9451e19661 100644 --- a/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.sql +++ b/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.sql @@ -6,12 +6,12 @@ CREATE TABLE test_00974 x Int32, ver UInt64 ) -ENGINE = ReplacingMergeTree(date, x, 4096); +ENGINE = ReplacingMergeTree(date, x, 1); INSERT INTO test_00974 VALUES ('2019-07-23', 1, 1), ('2019-07-23', 1, 2); INSERT INTO test_00974 VALUES ('2019-07-23', 2, 1), ('2019-07-23', 2, 2); -SELECT COUNT() FROM (SELECT * FROM test_00974 FINAL) where x = 1 SETTINGS allow_push_predicate_to_final_subquery = 0 FORMAT JSON ; -SELECT COUNT() FROM (SELECT * FROM test_00974 FINAL) where x = 1 SETTINGS allow_push_predicate_to_final_subquery = 1 FORMAT JSON ; +SELECT COUNT() FROM (SELECT * FROM test_00974 FINAL) where x = 1 SETTINGS allow_push_predicate_to_final_subquery = 0; +SELECT COUNT() FROM (SELECT * FROM test_00974 FINAL) where x = 1 SETTINGS allow_push_predicate_to_final_subquery = 1, max_rows_to_read = 2; DROP TABLE test_00974; From 290322b39deb1b6ccca989848cf4efa57b484003 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 25 Jul 2019 04:07:58 +0300 Subject: [PATCH 0340/1165] Updated instruction --- dbms/tests/instructions/sanitizers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/tests/instructions/sanitizers.md b/dbms/tests/instructions/sanitizers.md index c21ff9b0a9b..3ec8d30ae09 100644 --- a/dbms/tests/instructions/sanitizers.md +++ b/dbms/tests/instructions/sanitizers.md @@ -67,5 +67,5 @@ sudo -u clickhouse UBSAN_OPTIONS='print_stacktrace=1' ./clickhouse-ubsan server # How to use Memory Sanitizer ``` -CC=clang-8 CXX=clang++-8 cmake -D ENABLE_HDFS=0 -D ENABLE_CAPNP=0 -D ENABLE_RDKAFKA=0 -D ENABLE_ICU=0 -D ENABLE_POCO_MONGODB=0 -D ENABLE_POCO_NETSSL=0 -D ENABLE_POCO_ODBC=0 -D ENABLE_ODBC=0 -D ENABLE_MYSQL=0 -D ENABLE_EMBEDDED_COMPILER=0 -D USE_INTERNAL_CAPNP_LIBRARY=0 -D USE_INTERNAL_SSL_LIBRARY=0 -D USE_SIMDJSON=0 -DENABLE_READLINE=0 -D SANITIZE=memory .. +CC=clang-8 CXX=clang++-8 cmake -D ENABLE_HDFS=0 -D ENABLE_CAPNP=0 -D ENABLE_RDKAFKA=0 -D ENABLE_ICU=0 -D ENABLE_POCO_MONGODB=0 -D ENABLE_POCO_NETSSL=0 -D ENABLE_POCO_ODBC=0 -D ENABLE_ODBC=0 -D ENABLE_MYSQL=0 -D ENABLE_EMBEDDED_COMPILER=0 -D USE_INTERNAL_CAPNP_LIBRARY=0 -D USE_SIMDJSON=0 -DENABLE_READLINE=0 -D SANITIZE=memory .. ``` From e52653aa061ae224acc24a2e5717fe1850433d75 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 25 Jul 2019 04:08:33 +0300 Subject: [PATCH 0341/1165] Miscellaneous --- dbms/src/Storages/StorageMerge.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Storages/StorageMerge.cpp b/dbms/src/Storages/StorageMerge.cpp index 4c029fab677..3487a1becf5 100644 --- a/dbms/src/Storages/StorageMerge.cpp +++ b/dbms/src/Storages/StorageMerge.cpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #include #include @@ -23,8 +25,6 @@ #include #include #include -#include -#include #include #include #include From 65600efbfa19e98977b805439e953b92c39d2b9e Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Thu, 25 Jul 2019 04:09:26 +0300 Subject: [PATCH 0342/1165] Update 00974_final_predicate_push_down.reference --- .../00974_final_predicate_push_down.reference | 52 +------------------ 1 file changed, 2 insertions(+), 50 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.reference b/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.reference index 55b5763f76b..6ed281c757a 100644 --- a/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.reference +++ b/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.reference @@ -1,50 +1,2 @@ -{ - "meta": - [ - { - "name": "COUNT()", - "type": "UInt64" - } - ], - - "data": - [ - { - "COUNT()": "1" - } - ], - - "rows": 1, - - "statistics": - { - "elapsed": 0.000780393, - "rows_read": 4, - "bytes_read": 16 - } -} -{ - "meta": - [ - { - "name": "COUNT()", - "type": "UInt64" - } - ], - - "data": - [ - { - "COUNT()": "1" - } - ], - - "rows": 1, - - "statistics": - { - "elapsed": 0.000687364, - "rows_read": 2, - "bytes_read": 8 - } -} +1 +1 From 7f1fd1a918228376afa31874083a5de9067b58b0 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 25 Jul 2019 11:37:21 +0300 Subject: [PATCH 0343/1165] Use IInputFormat and IOutputFormat by default. --- dbms/src/Formats/FormatFactory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 5f1e2f25605..9e5645492a8 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -95,7 +95,7 @@ BlockOutputStreamPtr FormatFactory::getOutput(const String & name, WriteBuffer & /** Materialization is needed, because formats can use the functions `IDataType`, * which only work with full columns. */ - return std::make_shared(std::make_shared(format)); + return std::make_shared(std::make_shared(format), sample); } From f637e22eb6e3712729ddf40dc1af53befff5fb17 Mon Sep 17 00:00:00 2001 From: Nikita Mikhailov Date: Thu, 25 Jul 2019 11:50:16 +0300 Subject: [PATCH 0344/1165] tests... --- .../00974_text_log_table_not_empty.reference | 1 - .../0_stateless/00974_text_log_table_not_empty.sql | 10 ++++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference index 0c56a79a1c5..0cc5d717d83 100644 --- a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference +++ b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.reference @@ -1,3 +1,2 @@ 6103 -0 1 diff --git a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql index 8cf62c9cdbb..7f87ac29908 100644 --- a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql +++ b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql @@ -1,11 +1,9 @@ SELECT 6103; -SELECT sleep(1); - SYSTEM FLUSH LOGS; -SELECT count(query) > 0 -FROM system.text_log AS natural -INNER JOIN system.query_log USING (query_id) -WHERE query = 'SELECT 6103' +SELECT count() > 0 +FROM system.text_log +WHERE position(system.text_log.message, 'SELECT 6103') > 0 + From 4cc3bf77241320f5fca973fdbe7f3f7a0e0f9c44 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 25 Jul 2019 12:15:33 +0300 Subject: [PATCH 0345/1165] Use IInputFormat and IOutputFormat by default. --- dbms/src/Processors/Formats/InputStreamFromInputFormat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Processors/Formats/InputStreamFromInputFormat.h b/dbms/src/Processors/Formats/InputStreamFromInputFormat.h index 445f45068d4..4d690239adf 100644 --- a/dbms/src/Processors/Formats/InputStreamFromInputFormat.h +++ b/dbms/src/Processors/Formats/InputStreamFromInputFormat.h @@ -13,7 +13,7 @@ class InputStreamFromInputFormat : public IBlockInputStream public: explicit InputStreamFromInputFormat(InputFormatPtr input_format_) : input_format(std::move(input_format_)) - , port(input_format->getPort().getHeader()) + , port(input_format->getPort().getHeader(), input_format.get()) { connect(input_format->getPort(), port); } From a22540d010557479a13d106d403c31162e024112 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 25 Jul 2019 12:20:00 +0300 Subject: [PATCH 0346/1165] Use IInputFormat and IOutputFormat by default. --- dbms/src/Processors/Formats/InputStreamFromInputFormat.h | 1 + 1 file changed, 1 insertion(+) diff --git a/dbms/src/Processors/Formats/InputStreamFromInputFormat.h b/dbms/src/Processors/Formats/InputStreamFromInputFormat.h index 4d690239adf..266473f95de 100644 --- a/dbms/src/Processors/Formats/InputStreamFromInputFormat.h +++ b/dbms/src/Processors/Formats/InputStreamFromInputFormat.h @@ -16,6 +16,7 @@ public: , port(input_format->getPort().getHeader(), input_format.get()) { connect(input_format->getPort(), port); + port.setNeeded(); } String getName() const override { return input_format->getName(); } From 69f860a5efe93b190a5e7e2b142371df26ce3bfd Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 25 Jul 2019 12:28:33 +0300 Subject: [PATCH 0347/1165] Use IInputFormat and IOutputFormat by default. --- dbms/src/Processors/Formats/IOutputFormat.h | 4 ++-- dbms/src/Processors/Formats/OutputStreamToOutputFormat.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dbms/src/Processors/Formats/IOutputFormat.h b/dbms/src/Processors/Formats/IOutputFormat.h index 55555717070..63561749a7c 100644 --- a/dbms/src/Processors/Formats/IOutputFormat.h +++ b/dbms/src/Processors/Formats/IOutputFormat.h @@ -64,8 +64,8 @@ public: void write(const Block & block) { consume(Chunk(block.getColumns(), block.rows())); } - void writePrefix() {} - void writeSuffix() { finalize(); } + void doWritePrefix() {} + void doWriteSuffix() { finalize(); } void setTotals(const Block & totals) { consume(Chunk(totals.getColumns(), totals.rows())); } void setExtremes(const Block & extremes) { consume(Chunk(extremes.getColumns(), extremes.rows())); } diff --git a/dbms/src/Processors/Formats/OutputStreamToOutputFormat.cpp b/dbms/src/Processors/Formats/OutputStreamToOutputFormat.cpp index 153972fc65d..7acf41f6cf7 100644 --- a/dbms/src/Processors/Formats/OutputStreamToOutputFormat.cpp +++ b/dbms/src/Processors/Formats/OutputStreamToOutputFormat.cpp @@ -14,8 +14,8 @@ void OutputStreamToOutputFormat::write(const Block & block) output_format->write(block); } -void OutputStreamToOutputFormat::writePrefix() { output_format->writePrefix(); } -void OutputStreamToOutputFormat::writeSuffix() { output_format->writeSuffix(); } +void OutputStreamToOutputFormat::writePrefix() { output_format->doWritePrefix(); } +void OutputStreamToOutputFormat::writeSuffix() { output_format->doWriteSuffix(); } void OutputStreamToOutputFormat::flush() { output_format->flush(); } From 36a0275ff17a907bd2137d3474809c6fe579b72e Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 25 Jul 2019 12:31:38 +0300 Subject: [PATCH 0348/1165] Use IInputFormat and IOutputFormat by default. --- dbms/src/Processors/Formats/IOutputFormat.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Processors/Formats/IOutputFormat.h b/dbms/src/Processors/Formats/IOutputFormat.h index 63561749a7c..3242ab9da9a 100644 --- a/dbms/src/Processors/Formats/IOutputFormat.h +++ b/dbms/src/Processors/Formats/IOutputFormat.h @@ -67,8 +67,8 @@ public: void doWritePrefix() {} void doWriteSuffix() { finalize(); } - void setTotals(const Block & totals) { consume(Chunk(totals.getColumns(), totals.rows())); } - void setExtremes(const Block & extremes) { consume(Chunk(extremes.getColumns(), extremes.rows())); } + void setTotals(const Block & totals) { consumeTotals(Chunk(totals.getColumns(), totals.rows())); } + void setExtremes(const Block & extremes) { consumeExtremes(Chunk(extremes.getColumns(), extremes.rows())); } }; } From 78f056d83fba0693de4bbe319d6264967d0913d5 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 25 Jul 2019 12:35:16 +0300 Subject: [PATCH 0349/1165] Use IInputFormat and IOutputFormat by default. --- .../Formats/OutputStreamToOutputFormat.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/dbms/src/Processors/Formats/OutputStreamToOutputFormat.cpp b/dbms/src/Processors/Formats/OutputStreamToOutputFormat.cpp index 7acf41f6cf7..5d4e7832327 100644 --- a/dbms/src/Processors/Formats/OutputStreamToOutputFormat.cpp +++ b/dbms/src/Processors/Formats/OutputStreamToOutputFormat.cpp @@ -24,8 +24,17 @@ void OutputStreamToOutputFormat::setRowsBeforeLimit(size_t rows_before_limit) output_format->setRowsBeforeLimit(rows_before_limit); } -void OutputStreamToOutputFormat::setTotals(const Block & totals) { output_format->setTotals(totals); } -void OutputStreamToOutputFormat::setExtremes(const Block & extremes) { output_format->setExtremes(extremes); } +void OutputStreamToOutputFormat::setTotals(const Block & totals) +{ + if (totals) + output_format->setTotals(totals); +} + +void OutputStreamToOutputFormat::setExtremes(const Block & extremes) +{ + if (extremes) + output_format->setExtremes(extremes); +} void OutputStreamToOutputFormat::onProgress(const Progress & progress) { output_format->onProgress(progress); } From 795eebb5ad8d70e2077361582d7cc655e103807c Mon Sep 17 00:00:00 2001 From: Nikita Mikhailov Date: Thu, 25 Jul 2019 12:39:36 +0300 Subject: [PATCH 0350/1165] stable tests --- .../0_stateless/00974_text_log_table_not_empty.sh | 8 ++++++++ .../0_stateless/00974_text_log_table_not_empty.sql | 9 --------- 2 files changed, 8 insertions(+), 9 deletions(-) create mode 100755 dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sh delete mode 100644 dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql diff --git a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sh b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sh new file mode 100755 index 00000000000..7eaf2c35674 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +. $CURDIR/../shell_config.sh + +${CLICKHOUSE_CLIENT} --query="SELECT 6103" +${CLICKHOUSE_CLIENT} --query="SYSTEM FLUSH LOGS" +${CLICKHOUSE_CLIENT} --query="SELECT count() > 0 FROM system.text_log WHERE position(system.text_log.message, 'SELECT 6103') > 0" diff --git a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql deleted file mode 100644 index 7f87ac29908..00000000000 --- a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sql +++ /dev/null @@ -1,9 +0,0 @@ -SELECT 6103; - -SYSTEM FLUSH LOGS; - -SELECT count() > 0 -FROM system.text_log -WHERE position(system.text_log.message, 'SELECT 6103') > 0 - - From 6d9e6e0b9ddacc4b3a1199ca712d3ef19f92db24 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Thu, 25 Jul 2019 13:14:04 +0300 Subject: [PATCH 0351/1165] DOCAPI-3933: EN review and RU translation of hash functions doc (#5980) EN review for hash functions docs. RU translation of hash functions doc. --- .../functions/hash_functions.md | 51 +-- .../functions/hash_functions.md | 296 ++++++++++++++++-- .../functions/type_conversion_functions.md | 2 +- 3 files changed, 307 insertions(+), 42 deletions(-) diff --git a/docs/en/query_language/functions/hash_functions.md b/docs/en/query_language/functions/hash_functions.md index 368cfa1622b..296cca1e712 100644 --- a/docs/en/query_language/functions/hash_functions.md +++ b/docs/en/query_language/functions/hash_functions.md @@ -1,16 +1,16 @@ # Hash functions -Hash functions can be used for deterministic pseudo-random shuffling of elements. +Hash functions can be used for the deterministic pseudo-random shuffling of elements. ## halfMD5 {#hash_functions-halfmd5} -[Interprets](../../query_language/functions/type_conversion_functions.md#type_conversion_functions-reinterpretAsString) all the input parameters as strings and calculates the MD5 hash value for each of them. Then combines hashes. Then from the resulting string, takes the first 8 bytes of the hash and interprets them as `UInt64` in big-endian byte order. +[Interprets](../../query_language/functions/type_conversion_functions.md#type_conversion_functions-reinterpretAsString) all the input parameters as strings and calculates the [MD5](https://en.wikipedia.org/wiki/MD5) hash value for each of them. Then combines hashes, takes the first 8 bytes of the hash of the resulting string, and interprets them as `UInt64` in big-endian byte order. ``` halfMD5(par1, ...) ``` -The function works relatively slow (5 million short strings per second per processor core). +The function is relatively slow (5 million short strings per second per processor core). Consider using the [sipHash64](#hash_functions-siphash64) function instead. **Parameters** @@ -19,7 +19,7 @@ The function takes a variable number of input parameters. Parameters can be any **Returned Value** -Hash value having the [UInt64](../../data_types/int_uint.md) data type. +A [UInt64](../../data_types/int_uint.md) data type hash value. **Example** @@ -40,23 +40,28 @@ If you want to get the same result as output by the md5sum utility, use lower(he ## sipHash64 {#hash_functions-siphash64} -Produces 64-bit [SipHash](https://131002.net/siphash/) hash value. +Produces a 64-bit [SipHash](https://131002.net/siphash/) hash value. ``` sipHash64(par1,...) ``` -This function [interprets](../../query_language/functions/type_conversion_functions.md#type_conversion_functions-reinterpretAsString) all the input parameters as strings and calculates the hash value for each of them. Then combines hashes. - This is a cryptographic hash function. It works at least three times faster than the [MD5](#hash_functions-md5) function. +Function [interprets](../../query_language/functions/type_conversion_functions.md#type_conversion_functions-reinterpretAsString) all the input parameters as strings and calculates the hash value for each of them. Then combines hashes by the following algorithm: + +1. After hashing all the input parameters, the function gets the array of hashes. +2. Function takes the first and the second elements and calculates a hash for the array of them. +3. Then the function takes the hash value, calculated at the previous step, and the third element of the initial hash array, and calculates a hash for the array of them. +4. The previous step is repeated for all the remaining elements of the initial hash array. + **Parameters** The function takes a variable number of input parameters. Parameters can be any of the [supported data types](../../data_types/index.md). **Returned Value** -Hash value having the [UInt64](../../data_types/int_uint.md) data type. +A [UInt64](../../data_types/int_uint.md) data type hash value. **Example** @@ -77,13 +82,13 @@ Differs from sipHash64 in that the final xor-folding state is only done up to 12 ## cityHash64 -Produces 64-bit hash value. +Produces a 64-bit [CityHash](https://github.com/google/cityhash) hash value. ``` cityHash64(par1,...) ``` -This is the fast non-cryptographic hash function. It uses [CityHash](https://github.com/google/cityhash) algorithm for string parameters and implementation-specific fast non-cryptographic hash function for the parameters with other data types. To get the final result, the function uses the CityHash combinator. +This is a fast non-cryptographic hash function. It uses the CityHash algorithm for string parameters and implementation-specific fast non-cryptographic hash function for parameters with other data types. The function uses the CityHash combinator to get the final results. **Parameters** @@ -91,7 +96,7 @@ The function takes a variable number of input parameters. Parameters can be any **Returned Value** -Hash value having the [UInt64](../../data_types/int_uint.md) data type. +A [UInt64](../../data_types/int_uint.md) data type hash value. **Examples** @@ -100,7 +105,7 @@ Call example: ```sql SELECT cityHash64(array('e','x','a'), 'mple', 10, toDateTime('2019-06-15 23:00:00')) AS CityHash, toTypeName(CityHash) AS type ``` -``` +```text ┌─────────────CityHash─┬─type───┐ │ 12072650598913549138 │ UInt64 │ └──────────────────────┴────────┘ @@ -108,8 +113,8 @@ SELECT cityHash64(array('e','x','a'), 'mple', 10, toDateTime('2019-06-15 23:00:0 The following example shows how to compute the checksum of the entire table with accuracy up to the row order: -``` -SELECT sum(cityHash64(*)) FROM table +```sql +SELECT groupBitXor(cityHash64(*)) FROM table ``` @@ -157,7 +162,7 @@ The function takes a variable number of input parameters. Parameters can be any **Returned Value** -Hash value having the [UInt64](../../data_types/int_uint.md) data type. +A [UInt64](../../data_types/int_uint.md) data type hash value. **Example** @@ -172,15 +177,15 @@ SELECT farmHash64(array('e','x','a'), 'mple', 10, toDateTime('2019-06-15 23:00:0 ## javaHash {#hash_functions-javahash} -Calculates JavaHash from a string. +Calculates [JavaHash](http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/478a4add975b/src/share/classes/java/lang/String.java#l1452) + from a string. Accepts a String-type argument. Returns Int32. -For more information, see the link: [JavaHash](http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/478a4add975b/src/share/classes/java/lang/String.java#l1452) ## hiveHash Calculates HiveHash from a string. Accepts a String-type argument. Returns Int32. -Same as for [JavaHash](#hash_functions-javahash), except that the return value never has a negative number. +This is just [JavaHash](#hash_functions-javahash) with zeroed out sign bit. This function is used in [Apache Hive](https://en.wikipedia.org/wiki/Apache_Hive) for versions before 3.0. ## metroHash64 @@ -196,7 +201,7 @@ The function takes a variable number of input parameters. Parameters can be any **Returned Value** -Hash value having the [UInt64](../../data_types/int_uint.md) data type. +A [UInt64](../../data_types/int_uint.md) data type hash value. **Example** @@ -259,8 +264,8 @@ Both functions take a variable number of input parameters. Parameters can be any **Returned Value** -- The `murmurHash3_32` function returns hash value having the [UInt32](../../data_types/int_uint.md) data type. -- The `murmurHash3_64` function returns hash value having the [UInt64](../../data_types/int_uint.md) data type. +- The `murmurHash3_32` function returns a [UInt32](../../data_types/int_uint.md) data type hash value. +- The `murmurHash3_64` function returns a [UInt64](../../data_types/int_uint.md) data type hash value. **Example** @@ -283,11 +288,11 @@ murmurHash3_128( expr ) **Parameters** -- `expr` — [Expressions](../syntax.md#syntax-expressions) returning [String](../../data_types/string.md)-typed value. +- `expr` — [Expressions](../syntax.md#syntax-expressions) returning a [String](../../data_types/string.md)-type value. **Returned Value** -Hash value having [FixedString(16) data type](../../data_types/fixedstring.md). +A [FixedString(16)](../../data_types/fixedstring.md) data type hash value. **Example** diff --git a/docs/ru/query_language/functions/hash_functions.md b/docs/ru/query_language/functions/hash_functions.md index 62699d38d5b..e171b2bfa38 100644 --- a/docs/ru/query_language/functions/hash_functions.md +++ b/docs/ru/query_language/functions/hash_functions.md @@ -2,41 +2,130 @@ Функции хэширования могут использоваться для детерминированного псевдослучайного разбрасывания элементов. -## halfMD5 -Вычисляет MD5 от строки. Затем берёт первые 8 байт от хэша и интерпретирует их как UInt64 в big endian. -Принимает аргумент типа String. Возвращает UInt64. -Функция работает достаточно медленно (5 миллионов коротких строк в секунду на одном процессорном ядре). -Если вам не нужен конкретно MD5, то используйте вместо этого функцию sipHash64. +## halfMD5 {#hash_functions-halfmd5} -## MD5 +[Интерпретирует](../../query_language/functions/type_conversion_functions.md#type_conversion_functions-reinterpretAsString) все входные параметры как строки и вычисляет хэш [MD5](https://ru.wikipedia.org/wiki/MD5) для каждой из них. Затем объединяет хэши, берет первые 8 байт хэша результирующей строки и интерпретирует их как значение типа `UInt64` с big-endian порядком байтов. + +``` +halfMD5(par1, ...) +``` + +Функция относительно медленная (5 миллионов коротких строк в секунду на ядро процессора). +По возможности, используйте функцию [sipHash64](#hash_functions-siphash64) вместо неё. + +**Параметры** + +Функция принимает переменное число входных параметров. Параметры могут быть любого [поддерживаемого типа данных](../../data_types/index.md). + +**Возвращаемое значение** + +Значение хэша с типом данных [UInt64](../../data_types/int_uint.md). + +**Пример** + +```sql +SELECT halfMD5(array('e','x','a'), 'mple', 10, toDateTime('2019-06-15 23:00:00')) AS halfMD5hash, toTypeName(halfMD5hash) AS type +``` + +```text +┌────────halfMD5hash─┬─type───┐ +│ 186182704141653334 │ UInt64 │ +└────────────────────┴────────┘ +``` + +## MD5 {#hash_functions-md5} Вычисляет MD5 от строки и возвращает полученный набор байт в виде FixedString(16). Если вам не нужен конкретно MD5, а нужен неплохой криптографический 128-битный хэш, то используйте вместо этого функцию sipHash128. Если вы хотите получить такой же результат, как выдаёт утилита md5sum, напишите lower(hex(MD5(s))). -## sipHash64 -Вычисляет SipHash от строки. -Принимает аргумент типа String. Возвращает UInt64. -SipHash - криптографическая хэш-функция. Работает быстрее чем MD5 не менее чем в 3 раза. -Подробнее смотрите по ссылке: +## sipHash64 {#hash_functions-siphash64} + +Генерирует 64-х битное значение [SipHash](https://131002.net/siphash/). + +``` +sipHash64(par1,...) +``` + +Это криптографическая хэш-функция. Она работает по крайней мере в три раза быстрее, чем функция [MD5](#hash_functions-md5). + +Функция [интерпретирует](../../query_language/functions/type_conversion_functions.md#type_conversion_functions-reinterpretAsString) все входные параметры как строки и вычисляет хэш MD5 для каждой из них. Затем комбинирует хэши по следующему алгоритму. + +1. После хэширования всех входных параметров функция получает массив хэшей. +2. Функция принимает первый и второй элементы и вычисляет хэш для массива из них. +3. Затем функция принимает хэш-значение, вычисленное на предыдущем шаге, и третий элемент исходного хэш-массива, и вычисляет хэш для массива из них. +4. Предыдущий шаг повторяется для всех остальных элементов исходного хэш-массива. + +**Параметры** + +Функция принимает переменное число входных параметров. Параметры могут быть любого [поддерживаемого типа данных](../../data_types/index.md). + +**Возвращаемое значение** + +Значение хэша с типом данных [UInt64](../../data_types/int_uint.md). + +**Пример** + +```sql +SELECT sipHash64(array('e','x','a'), 'mple', 10, toDateTime('2019-06-15 23:00:00')) AS SipHash, toTypeName(SipHash) AS type +``` + +``` +┌──────────────SipHash─┬─type───┐ +│ 13726873534472839665 │ UInt64 │ +└──────────────────────┴────────┘ +``` ## sipHash128 + Вычисляет SipHash от строки. Принимает аргумент типа String. Возвращает FixedString(16). Отличается от sipHash64 тем, что финальный xor-folding состояния делается только до 128 бит. ## cityHash64 -Вычисляет CityHash64 от строки или похожую хэш-функцию для произвольного количества аргументов произвольного типа. -Если аргумент имеет тип String, то используется CityHash. Это быстрая некриптографическая хэш-функция неплохого качества для строк. -Если аргумент имеет другой тип, то используется implementation specific быстрая некриптографическая хэш-функция неплохого качества. -Если передано несколько аргументов, то функция вычисляется по тем же правилам, с помощью комбинации по цепочке с использованием комбинатора из CityHash. -Например, так вы можете вычислить чексумму всей таблицы с точностью до порядка строк: `SELECT sum(cityHash64(*)) FROM table`. + +Генерирует 64-х битное значение [CityHash](https://github.com/google/cityhash). + +``` +cityHash64(par1,...) +``` + +Это не криптографическая хэш-функция. Она использует CityHash алгоритм для строковых параметров и зависящую от реализации быструю некриптографическую хэш-функцию для параметров с другими типами данных. Функция использует комбинатор CityHash для получения конечных результатов. + +**Параметры** + +Функция принимает переменное число входных параметров. Параметры могут быть любого [поддерживаемого типа данных](../../data_types/index.md). + +**Возвращаемое значение** + +Значение хэша с типом данных [UInt64](../../data_types/int_uint.md). + +**Примеры** + +Пример вызова: + +```sql +SELECT cityHash64(array('e','x','a'), 'mple', 10, toDateTime('2019-06-15 23:00:00')) AS CityHash, toTypeName(CityHash) AS type +``` +```text +┌─────────────CityHash─┬─type───┐ +│ 12072650598913549138 │ UInt64 │ +└──────────────────────┴────────┘ +``` + +А вот так вы можете вычислить чексумму всей таблицы с точностью до порядка строк: + +```sql +SELECT groupBitXor(cityHash64(*)) FROM table +``` ## intHash32 + Вычисляет 32-битный хэш-код от целого числа любого типа. Это сравнительно быстрая некриптографическая хэш-функция среднего качества для чисел. ## intHash64 + Вычисляет 64-битный хэш-код от целого числа любого типа. Работает быстрее, чем intHash32. Качество среднее. @@ -45,15 +134,186 @@ SipHash - криптографическая хэш-функция. Работа ## SHA224 ## SHA256 + Вычисляет SHA-1, SHA-224, SHA-256 от строки и возвращает полученный набор байт в виде FixedString(20), FixedString(28), FixedString(32). Функция работает достаточно медленно (SHA-1 - примерно 5 миллионов коротких строк в секунду на одном процессорном ядре, SHA-224 и SHA-256 - примерно 2.2 миллионов). Рекомендуется использовать эти функции лишь в тех случаях, когда вам нужна конкретная хэш-функция и вы не можете её выбрать. Даже в этих случаях, рекомендуется применять функцию оффлайн - заранее вычисляя значения при вставке в таблицу, вместо того, чтобы применять её при SELECT-ах. ## URLHash(url\[, N\]) + Быстрая некриптографическая хэш-функция неплохого качества для строки, полученной из URL путём некоторой нормализации. -`URLHash(s)` - вычислить хэш от строки без одного завершающего символа `/`, `?` или `#` на конце, если такой там есть. -`URLHash(s, N)` - вычислить хэш от строки до N-го уровня в иерархии URL, без одного завершающего символа `/`, `?` или `#` на конце, если такой там есть. +`URLHash(s)` - вычислить хэш от строки без одного завершающего символа `/`, `?` или `#` на конце, если там такой есть. +`URLHash(s, N)` - вычислить хэш от строки до N-го уровня в иерархии URL, без одного завершающего символа `/`, `?` или `#` на конце, если там такой есть. Уровни аналогичные URLHierarchy. Функция специфична для Яндекс.Метрики. +## farmHash64 + +Генерирует 64-х битное значение [FarmHash](https://github.com/google/farmhash). + +``` +farmHash64(par1, ...) +``` + +Из всех [доступных методов](https://github.com/google/farmhash/blob/master/src/farmhash.h) функция использует `Hash64`. + +**Параметры** + +Функция принимает переменное число входных параметров. Параметры могут быть любого [поддерживаемого типа данных](../../data_types/index.md). + +**Возвращаемое значение** + +Значение хэша с типом данных [UInt64](../../data_types/int_uint.md). + +**Пример** + +```sql +SELECT farmHash64(array('e','x','a'), 'mple', 10, toDateTime('2019-06-15 23:00:00')) AS FarmHash, toTypeName(FarmHash) AS type +``` + +```text +┌─────────────FarmHash─┬─type───┐ +│ 17790458267262532859 │ UInt64 │ +└──────────────────────┴────────┘ +``` + +## javaHash {#hash_functions-javahash} + +Вычисляет [JavaHash](http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/478a4add975b/src/share/classes/java/lang/String.java#l1452) от строки. +Принимает аргумент типа String. Возвращает значение типа Int32. + +## hiveHash + +Вычисляет HiveHash от строки. +Принимает аргумент типа String. Возвращает значение типа Int32. +HiveHash — это результат [JavaHash](#hash_functions-javahash) с обнулённым битом знака числа. Функция используется в [Apache Hive](https://en.wikipedia.org/wiki/Apache_Hive) вплоть до версии 3.0. + +## metroHash64 + +Генерирует 64-х битное значение [MetroHash](http://www.jandrewrogers.com/2015/05/27/metrohash/). + +``` +metroHash64(par1, ...) +``` + +**Параметры** + +Функция принимает переменное число входных параметров. Параметры могут быть любого [поддерживаемого типа данных](../../data_types/index.md). + +**Возвращаемое значение** + +Значение хэша с типом данных [UInt64](../../data_types/int_uint.md). + +**Пример** + +```sql +SELECT metroHash64(array('e','x','a'), 'mple', 10, toDateTime('2019-06-15 23:00:00')) AS MetroHash, toTypeName(MetroHash) AS type +``` + +```text +┌────────────MetroHash─┬─type───┐ +│ 14235658766382344533 │ UInt64 │ +└──────────────────────┴────────┘ +``` + +## jumpConsistentHash + +Вычисляет JumpConsistentHash от значения типа UInt64. +Принимает аргумент типа UInt64. Возвращает значение типа Int32. +Дополнительные сведения смотрите по ссылке: [JumpConsistentHash](https://arxiv.org/pdf/1406.2294.pdf) + +## murmurHash2_32, murmurHash2_64 + +Генерирует значение [MurmurHash2](https://github.com/aappleby/smhasher). + +``` +murmurHash2_32(par1, ...) +murmurHash2_64(par1, ...) +``` + +**Параметры** + +Обе функции принимают переменное число входных параметров. Параметры могут быть любого [поддерживаемого типа данных](../../data_types/index.md). + +**Возвращаемое значение** + +- Функция `murmurHash2_32` возвращает значение типа [UInt32](../../data_types/int_uint.md). +- Функция `murmurHash2_64` возвращает значение типа [UInt64](../../data_types/int_uint.md). + +**Пример** + +```sql +SELECT murmurHash2_64(array('e','x','a'), 'mple', 10, toDateTime('2019-06-15 23:00:00')) AS MurmurHash2, toTypeName(MurmurHash2) AS type +``` + +```text +┌──────────MurmurHash2─┬─type───┐ +│ 11832096901709403633 │ UInt64 │ +└──────────────────────┴────────┘ +``` + +## murmurHash3_32, murmurHash3_64 + +Генерирует значение [MurmurHash3](https://github.com/aappleby/smhasher). + +``` +murmurHash3_32(par1, ...) +murmurHash3_64(par1, ...) +``` + +**Параметры** + +Обе функции принимают переменное число входных параметров. Параметры могут быть любого [поддерживаемого типа данных](../../data_types/index.md). + +**Возвращаемое значение** + +- Функция `murmurHash3_32` возвращает значение типа [UInt32](../../data_types/int_uint.md). +- Функция `murmurHash3_64` возвращает значение типа [UInt64](../../data_types/int_uint.md). + +**Пример** + +```sql +SELECT murmurHash3_32(array('e','x','a'), 'mple', 10, toDateTime('2019-06-15 23:00:00')) AS MurmurHash3, toTypeName(MurmurHash3) AS type +``` + +```text +┌─MurmurHash3─┬─type───┐ +│ 2152717 │ UInt32 │ +└─────────────┴────────┘ +``` + +## murmurHash3_128 + +Генерирует значение [MurmurHash3](https://github.com/aappleby/smhasher). + +``` +murmurHash3_128( expr ) +``` + +**Параметры** + +- `expr` — [выражение](../syntax.md#syntax-expressions) возвращающее значение типа[String](../../data_types/string.md). + +**Возвращаемое значение** + +Хэш-значение типа [FixedString(16)](../../data_types/fixedstring.md). + +**Пример** + +```sql +SELECT murmurHash3_128('example_string') AS MurmurHash3, toTypeName(MurmurHash3) AS type +``` + +```text +┌─MurmurHash3──────┬─type────────────┐ +│ 6�1�4"S5KT�~~q │ FixedString(16) │ +└──────────────────┴─────────────────┘ +``` + +## xxHash32, xxHash64 + +Вычисляет xxHash от строки. +Принимает аргумент типа String. Возвращает значение типа Uint64 или Uint32. +Дополнительные сведения см. по ссылке: [xxHash](http://cyan4973.github.io/xxHash/) + [Оригинальная статья](https://clickhouse.yandex/docs/ru/query_language/functions/hash_functions/) diff --git a/docs/ru/query_language/functions/type_conversion_functions.md b/docs/ru/query_language/functions/type_conversion_functions.md index 5e25d767e08..8635ea089e0 100644 --- a/docs/ru/query_language/functions/type_conversion_functions.md +++ b/docs/ru/query_language/functions/type_conversion_functions.md @@ -184,7 +184,7 @@ SELECT toFixedString('foo\0bar', 8) AS s, toStringCutToZero(s) AS s_cut Функции принимают строку и интерпретируют байты, расположенные в начале строки, как число в host order (little endian). Если строка имеет недостаточную длину, то функции работают так, как будто строка дополнена необходимым количеством нулевых байт. Если строка длиннее, чем нужно, то лишние байты игнорируются. Дата интерпретируется, как число дней с начала unix-эпохи, а дата-с-временем - как число секунд с начала unix-эпохи. -## reinterpretAsString +## reinterpretAsString {#type_conversion_functions-reinterpretAsString} Функция принимает число или дату или дату-с-временем и возвращает строку, содержащую байты, представляющие соответствующее значение в host order (little endian). При этом, отбрасываются нулевые байты с конца. Например, значение 255 типа UInt32 будет строкой длины 1 байт. ## CAST(x, t) {#type_conversion_function-cast} From 50e3839157faf643698beea7a9913799cfaaa695 Mon Sep 17 00:00:00 2001 From: chertus Date: Thu, 25 Jul 2019 13:35:57 +0300 Subject: [PATCH 0352/1165] NOT_UNBUNDLED -> UNBUNDLED --- dbms/src/Common/new_delete.cpp | 2 +- libs/libcommon/include/common/config_common.h.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Common/new_delete.cpp b/dbms/src/Common/new_delete.cpp index aff708135e1..9da6ccf492f 100644 --- a/dbms/src/Common/new_delete.cpp +++ b/dbms/src/Common/new_delete.cpp @@ -7,7 +7,7 @@ /// Replace default new/delete with memory tracking versions. /// @sa https://en.cppreference.com/w/cpp/memory/new/operator_new /// https://en.cppreference.com/w/cpp/memory/new/operator_delete -#if NOT_UNBUNDLED +#if !UNBUNDLED namespace Memory { diff --git a/libs/libcommon/include/common/config_common.h.in b/libs/libcommon/include/common/config_common.h.in index 247afd87aea..543e3cb60bd 100644 --- a/libs/libcommon/include/common/config_common.h.in +++ b/libs/libcommon/include/common/config_common.h.in @@ -7,4 +7,4 @@ #cmakedefine01 USE_READLINE #cmakedefine01 USE_LIBEDIT #cmakedefine01 HAVE_READLINE_HISTORY -#cmakedefine01 NOT_UNBUNDLED +#cmakedefine01 UNBUNDLED From f5b93eb9917e85711e7185d96a626b4d31254b6b Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Thu, 25 Jul 2019 13:45:01 +0300 Subject: [PATCH 0353/1165] fix order by optimization --- dbms/src/Interpreters/InterpreterSelectQuery.cpp | 16 +++++++--------- dbms/src/Storages/SelectQueryInfo.h | 8 +++----- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.cpp b/dbms/src/Interpreters/InterpreterSelectQuery.cpp index f33ac980fb3..f59e854a5b8 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSelectQuery.cpp @@ -655,7 +655,7 @@ static UInt64 getLimitForSorting(const ASTSelectQuery & query, const Context & c static SortingInfoPtr optimizeSortingWithPK(const MergeTreeData & merge_tree, const ASTSelectQuery & query, - const Context & context, const NamesAndTypesList & required_columns) + const Context & context, const ExpressionActionsPtr & expressions) { if (!merge_tree.hasSortingKey()) return {}; @@ -668,7 +668,8 @@ static SortingInfoPtr optimizeSortingWithPK(const MergeTreeData & merge_tree, co size_t prefix_size = std::min(order_descr.size(), sorting_key_columns.size()); auto order_by_expr = query.orderBy(); - auto syntax_result = SyntaxAnalyzer(context).analyze(order_by_expr, required_columns); + auto syntax_result = SyntaxAnalyzer(context).analyze(order_by_expr, + expressions->getRequiredColumnsWithTypes(), expressions->getSampleBlock().getNames()); for (size_t i = 0; i < prefix_size; ++i) { /// Read in pk order in case of exact match with order key element @@ -729,7 +730,7 @@ static SortingInfoPtr optimizeSortingWithPK(const MergeTreeData & merge_tree, co if (prefix_order_descr.empty()) return {}; - return std::make_shared(std::move(prefix_order_descr), read_direction); + return std::make_shared(std::move(prefix_order_descr), expressions, read_direction); } @@ -791,6 +792,7 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS } SortingInfoPtr sorting_info; + if (dry_run) { if constexpr (pipeline_with_processors) @@ -806,9 +808,7 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS if (settings.optimize_pk_order && storage && query.orderBy() && !query.groupBy() && !query.final()) { if (const MergeTreeData * merge_tree_data = dynamic_cast(storage.get())) - sorting_info = optimizeSortingWithPK(*merge_tree_data, query,context, expressions.before_order->getSampleBlock().getNamesAndTypesList()); - if (sorting_info) - sorting_info->setActions(expressions.before_order); + sorting_info = optimizeSortingWithPK(*merge_tree_data, query,context, expressions.before_order); } if (expressions.prewhere_info) @@ -850,9 +850,7 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS if (settings.optimize_pk_order && storage && query.orderBy() && !query.groupBy() && !query.final()) { if (const MergeTreeData * merge_tree_data = dynamic_cast(storage.get())) - sorting_info = optimizeSortingWithPK(*merge_tree_data, query, context, expressions.before_order->getSampleBlock().getNamesAndTypesList()); - if (sorting_info) - sorting_info->setActions(expressions.before_order); + sorting_info = optimizeSortingWithPK(*merge_tree_data, query,context, expressions.before_order); } /** Read the data from Storage. from_stage - to what stage the request was completed in Storage. */ diff --git a/dbms/src/Storages/SelectQueryInfo.h b/dbms/src/Storages/SelectQueryInfo.h index 56bbaff86a7..bf1eeb98833 100644 --- a/dbms/src/Storages/SelectQueryInfo.h +++ b/dbms/src/Storages/SelectQueryInfo.h @@ -37,13 +37,11 @@ struct FilterInfo struct SortingInfo { SortDescription prefix_order_descr; - int direction; ExpressionActionsPtr actions; + int direction; - SortingInfo(const SortDescription & prefix_order_descr_, int direction_) - : prefix_order_descr(prefix_order_descr_), direction(direction_) {} - - void setActions(const ExpressionActionsPtr & actions_) { actions = actions_; } + SortingInfo(const SortDescription & prefix_order_descr_, const ExpressionActionsPtr & actions_, int direction_) + : prefix_order_descr(prefix_order_descr_), actions(actions_), direction(direction_) {} }; using PrewhereInfoPtr = std::shared_ptr; From 079e41ac26d6f20f65f1352dec73ed8af35026aa Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 25 Jul 2019 13:51:32 +0300 Subject: [PATCH 0354/1165] Use IInputFormat and IOutputFormat by default. --- dbms/src/DataStreams/NullAndDoCopyBlockInputStream.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/DataStreams/NullAndDoCopyBlockInputStream.h b/dbms/src/DataStreams/NullAndDoCopyBlockInputStream.h index 296f198b01a..961f2b77bca 100644 --- a/dbms/src/DataStreams/NullAndDoCopyBlockInputStream.h +++ b/dbms/src/DataStreams/NullAndDoCopyBlockInputStream.h @@ -32,7 +32,7 @@ public: String getName() const override { return "NullAndDoCopy"; } - Block getHeader() const override { return {}; } + Block getHeader() const override { return input->getHeader(); } protected: Block readImpl() override From b1cc019bd4475efda53a95d77447e3eb537a1558 Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Thu, 25 Jul 2019 14:00:14 +0300 Subject: [PATCH 0355/1165] fix pipeline --- dbms/src/Interpreters/InterpreterSelectQuery.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.cpp b/dbms/src/Interpreters/InterpreterSelectQuery.cpp index f59e854a5b8..a9f98da9606 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSelectQuery.cpp @@ -1068,13 +1068,14 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS * - therefore, we merge the sorted streams from remote servers. */ - if (!query_info.sorting_info) // Otherwise we have executed them while reading - executeExpression(pipeline, expressions.before_order); - if (!expressions.first_stage && !expressions.need_aggregate && !(query.group_by_with_totals && !aggregate_final)) executeMergeSorted(pipeline); else /// Otherwise, just sort. + { + if (!query_info.sorting_info) // Otherwise we have executed them while reading + executeExpression(pipeline, expressions.before_order); executeOrder(pipeline, query_info.sorting_info); + } } /** Optimization - if there are several sources and there is LIMIT, then first apply the preliminary LIMIT, From 734da9c8391abaa63d2b0c1dde2b0eae1f26d0b1 Mon Sep 17 00:00:00 2001 From: avasiliev Date: Thu, 25 Jul 2019 15:10:29 +0300 Subject: [PATCH 0356/1165] Safer interface of mysqlxx::Pool --- libs/libmysqlxx/include/mysqlxx/Pool.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/libmysqlxx/include/mysqlxx/Pool.h b/libs/libmysqlxx/include/mysqlxx/Pool.h index 19b33a5c228..5261ffab017 100644 --- a/libs/libmysqlxx/include/mysqlxx/Pool.h +++ b/libs/libmysqlxx/include/mysqlxx/Pool.h @@ -72,25 +72,25 @@ public: return data == nullptr; } - operator mysqlxx::Connection & () + operator mysqlxx::Connection & () & { forceConnected(); return data->conn; } - operator const mysqlxx::Connection & () const + operator const mysqlxx::Connection & () const & { forceConnected(); return data->conn; } - const mysqlxx::Connection * operator->() const + const mysqlxx::Connection * operator->() const & { forceConnected(); return &data->conn; } - mysqlxx::Connection * operator->() + mysqlxx::Connection * operator->() & { forceConnected(); return &data->conn; From 95dd6222fe8f112561e56ed1408b9b7c6b4c134b Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 25 Jul 2019 15:17:57 +0300 Subject: [PATCH 0357/1165] Use IInputFormat and IOutputFormat by default. --- dbms/src/Processors/Formats/Impl/JSONCompactRowOutputFormat.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/dbms/src/Processors/Formats/Impl/JSONCompactRowOutputFormat.cpp b/dbms/src/Processors/Formats/Impl/JSONCompactRowOutputFormat.cpp index 0f63a4cf72d..72292cc0a26 100644 --- a/dbms/src/Processors/Formats/Impl/JSONCompactRowOutputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/JSONCompactRowOutputFormat.cpp @@ -34,8 +34,6 @@ void JSONCompactRowOutputFormat::writeTotalsFieldDelimiter() void JSONCompactRowOutputFormat::writeRowStartDelimiter() { - if (row_count > 0) - writeCString(",\n", *ostr); writeCString("\t\t[", *ostr); } From c3f82f0b8ce8ca04d9fa04259d310efc70cf29e9 Mon Sep 17 00:00:00 2001 From: alesapin Date: Thu, 25 Jul 2019 16:41:39 +0300 Subject: [PATCH 0358/1165] Fix indent and add init file --- .../integration/test_config_corresponding_root/__init__.py | 0 dbms/tests/integration/test_config_corresponding_root/test.py | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 dbms/tests/integration/test_config_corresponding_root/__init__.py diff --git a/dbms/tests/integration/test_config_corresponding_root/__init__.py b/dbms/tests/integration/test_config_corresponding_root/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dbms/tests/integration/test_config_corresponding_root/test.py b/dbms/tests/integration/test_config_corresponding_root/test.py index c29f0b53c3a..fd5d3eae3ff 100644 --- a/dbms/tests/integration/test_config_corresponding_root/test.py +++ b/dbms/tests/integration/test_config_corresponding_root/test.py @@ -16,7 +16,7 @@ def start_cluster(): try: cluster.start() except Exception as e: - caught_exception = str(e) + caught_exception = str(e) def test_work(start_cluster): - assert caught_exception.find("Root element doesn't have the corresponding root element as the config file.") != -1 + assert caught_exception.find("Root element doesn't have the corresponding root element as the config file.") != -1 From f53f22fd171deb4b04cce50775c50a4059213247 Mon Sep 17 00:00:00 2001 From: dimarub2000 Date: Thu, 25 Jul 2019 18:56:20 +0300 Subject: [PATCH 0359/1165] ISSUE-6136: Fix DB::Exception throwed by bitmapContains --- dbms/src/Storages/MergeTree/KeyCondition.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dbms/src/Storages/MergeTree/KeyCondition.cpp b/dbms/src/Storages/MergeTree/KeyCondition.cpp index f08a9c35c9e..790c72329a2 100644 --- a/dbms/src/Storages/MergeTree/KeyCondition.cpp +++ b/dbms/src/Storages/MergeTree/KeyCondition.cpp @@ -689,6 +689,9 @@ bool KeyCondition::atomFromAST(const ASTPtr & node, const Context & context, Blo MonotonicFunctionsChain chain; std::string func_name = func->name; + if (atom_map.find(func_name) == std::end(atom_map)) + return false; + if (args.size() == 1) { if (!(isKeyPossiblyWrappedByMonotonicFunctions(args[0], context, key_column_num, key_expr_type, chain))) @@ -775,8 +778,6 @@ bool KeyCondition::atomFromAST(const ASTPtr & node, const Context & context, Blo return false; const auto atom_it = atom_map.find(func_name); - if (atom_it == std::end(atom_map)) - return false; out.key_column = key_column_num; out.monotonic_functions_chain = std::move(chain); From f3580647a4977a060dd377d390925240aced48f0 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 25 Jul 2019 19:07:55 +0300 Subject: [PATCH 0360/1165] Trigger CI From 399799d83808b41f115ca0958dc1c930a09b2632 Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov Date: Thu, 25 Jul 2019 15:49:14 +0300 Subject: [PATCH 0361/1165] In debug version on Linux, increase OOM score. This way, clickhouse is killed first, and not some important service. --- libs/libdaemon/src/BaseDaemon.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/libs/libdaemon/src/BaseDaemon.cpp b/libs/libdaemon/src/BaseDaemon.cpp index 1ba03168496..7434e98b774 100644 --- a/libs/libdaemon/src/BaseDaemon.cpp +++ b/libs/libdaemon/src/BaseDaemon.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -501,6 +502,34 @@ void BaseDaemon::closeFDs() } } +namespace +{ +/// In debug version on Linux, increase oom score so that clickhouse is killed +/// first, instead of some service. Use a carefully chosen random score of 555: +/// the maximum is 1000, and chromium uses 300 for its tab processes. Ignore +/// whatever errors that occur, because it's just a debugging aid and we don't +/// care if it breaks. +#if defined(__linux__) and not defined(NDEBUG) +void debugIncreaseOOMScore() +{ + const std::string new_score = "555"; + try { + DB::WriteBufferFromFile buf("/proc/self/oom_score_adj"); + buf.write(new_score.c_str(), new_score.size()); + } + catch (Poco::Exception & e) + { + LOG_WARNING(&Logger::root(), "Failed to adjust OOM score: '" + + e.displayText() + "'."); + return; + } + LOG_INFO(&Logger::root(), "Set OOM score adjustment to " + new_score); +} +#else +void debugIncreaseOOMScore() {} +#endif +} + void BaseDaemon::initialize(Application & self) { closeFDs(); @@ -630,6 +659,7 @@ void BaseDaemon::initialize(Application & self) initializeTerminationAndSignalProcessing(); logRevision(); + debugIncreaseOOMScore(); for (const auto & key : DB::getMultipleKeysFromConfig(config(), "", "graphite")) { From 46e4b45f9654ba93b3c915f7cc903ba75c3d3ed3 Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Thu, 25 Jul 2019 19:26:48 +0300 Subject: [PATCH 0362/1165] test added` --- .../00974_bitmapContains_with_primary_key.reference | 1 + .../0_stateless/00974_bitmapContains_with_primary_key.sql | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00974_bitmapContains_with_primary_key.reference create mode 100644 dbms/tests/queries/0_stateless/00974_bitmapContains_with_primary_key.sql diff --git a/dbms/tests/queries/0_stateless/00974_bitmapContains_with_primary_key.reference b/dbms/tests/queries/0_stateless/00974_bitmapContains_with_primary_key.reference new file mode 100644 index 00000000000..d00491fd7e5 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_bitmapContains_with_primary_key.reference @@ -0,0 +1 @@ +1 diff --git a/dbms/tests/queries/0_stateless/00974_bitmapContains_with_primary_key.sql b/dbms/tests/queries/0_stateless/00974_bitmapContains_with_primary_key.sql new file mode 100644 index 00000000000..81dd7cab9f4 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_bitmapContains_with_primary_key.sql @@ -0,0 +1,5 @@ +DROP TABLE IF EXISTS test; +CREATE TABLE test (num UInt64, str String) ENGINE = MergeTree ORDER BY num; +INSERT INTO test (num) VALUES (1), (2), (10), (15), (23); +SELECT count(*) FROM test WHERE bitmapContains(bitmapBuild([1, 5, 7, 9]), toUInt32(num)); +DROP TABLE test; From 522aed71683e9d0e42db99298f942c099cfecdc7 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 25 Jul 2019 22:02:44 +0300 Subject: [PATCH 0363/1165] Fixed build --- dbms/src/Core/Settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Core/Settings.h b/dbms/src/Core/Settings.h index 6524f5c2bd4..a149ee15efa 100644 --- a/dbms/src/Core/Settings.h +++ b/dbms/src/Core/Settings.h @@ -307,7 +307,7 @@ struct Settings : public SettingsCollection M(SettingBool, log_query_threads, true, "Log query threads into system.query_thread_log table. This setting have effect only when 'log_queries' is true.") \ M(SettingLogsLevel, send_logs_level, LogsLevel::none, "Send server text logs with specified minimum level to client. Valid values: 'trace', 'debug', 'information', 'warning', 'error', 'none'") \ M(SettingBool, enable_optimize_predicate_expression, 1, "If it is set to true, optimize predicates to subqueries.") \ - M(SettingBool, enable_optimize_predicate_expression_to_final_subquery, 1, "Allow push predicate to final subquery.") + M(SettingBool, enable_optimize_predicate_expression_to_final_subquery, 1, "Allow push predicate to final subquery.") \ \ M(SettingUInt64, low_cardinality_max_dictionary_size, 8192, "Maximum size (in rows) of shared global dictionary for LowCardinality type.") \ M(SettingBool, low_cardinality_use_single_dictionary_for_part, false, "LowCardinality type serialization setting. If is true, than will use additional keys when global dictionary overflows. Otherwise, will create several shared dictionaries.") \ From d5b537224ec2434f8e0231e07d9d2d08b2cda799 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 25 Jul 2019 22:08:40 +0300 Subject: [PATCH 0364/1165] Fixed test --- .../queries/0_stateless/00974_final_predicate_push_down.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.sql b/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.sql index b9451e19661..96bcbf9aae6 100644 --- a/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.sql +++ b/dbms/tests/queries/0_stateless/00974_final_predicate_push_down.sql @@ -11,7 +11,7 @@ ENGINE = ReplacingMergeTree(date, x, 1); INSERT INTO test_00974 VALUES ('2019-07-23', 1, 1), ('2019-07-23', 1, 2); INSERT INTO test_00974 VALUES ('2019-07-23', 2, 1), ('2019-07-23', 2, 2); -SELECT COUNT() FROM (SELECT * FROM test_00974 FINAL) where x = 1 SETTINGS allow_push_predicate_to_final_subquery = 0; -SELECT COUNT() FROM (SELECT * FROM test_00974 FINAL) where x = 1 SETTINGS allow_push_predicate_to_final_subquery = 1, max_rows_to_read = 2; +SELECT COUNT() FROM (SELECT * FROM test_00974 FINAL) where x = 1 SETTINGS enable_optimize_predicate_expression_to_final_subquery = 0; +SELECT COUNT() FROM (SELECT * FROM test_00974 FINAL) where x = 1 SETTINGS enable_optimize_predicate_expression_to_final_subquery = 1, max_rows_to_read = 2; DROP TABLE test_00974; From 554e4ab5b8440ad44a8aaa9536c78f7cbb2f944f Mon Sep 17 00:00:00 2001 From: chertus Date: Thu, 25 Jul 2019 22:25:51 +0300 Subject: [PATCH 0365/1165] fix cross alliasing case with JOIN ON --- .../Interpreters/CollectJoinOnKeysVisitor.h | 3 +++ .../0_stateless/00974_fix_join_on.reference | 12 ++++++++++ .../queries/0_stateless/00974_fix_join_on.sql | 24 ++++++++++++------- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/dbms/src/Interpreters/CollectJoinOnKeysVisitor.h b/dbms/src/Interpreters/CollectJoinOnKeysVisitor.h index 1857bc88cf4..7dc3051167a 100644 --- a/dbms/src/Interpreters/CollectJoinOnKeysVisitor.h +++ b/dbms/src/Interpreters/CollectJoinOnKeysVisitor.h @@ -110,6 +110,9 @@ private: static const ASTIdentifier * unrollAliases(const ASTIdentifier * identifier, const Aliases & aliases) { + if (identifier->compound()) + return identifier; + UInt32 max_attempts = 100; for (auto it = aliases.find(identifier->name); it != aliases.end();) { diff --git a/dbms/tests/queries/0_stateless/00974_fix_join_on.reference b/dbms/tests/queries/0_stateless/00974_fix_join_on.reference index 1d0b18e4f96..90c76d8b931 100644 --- a/dbms/tests/queries/0_stateless/00974_fix_join_on.reference +++ b/dbms/tests/queries/0_stateless/00974_fix_join_on.reference @@ -12,6 +12,12 @@ y y y y y y y y +2 2 +2 2 +2 2 +2 2 +2 2 +2 2 2 y 2 w 2 y 2 w 2 2 @@ -26,3 +32,9 @@ y y y y y y y y +2 2 +2 2 +2 2 +2 2 +2 2 +2 2 diff --git a/dbms/tests/queries/0_stateless/00974_fix_join_on.sql b/dbms/tests/queries/0_stateless/00974_fix_join_on.sql index 1a3126f981d..feffe046d4f 100644 --- a/dbms/tests/queries/0_stateless/00974_fix_join_on.sql +++ b/dbms/tests/queries/0_stateless/00974_fix_join_on.sql @@ -10,6 +10,7 @@ insert into t1 values (1, 'x'), (2, 'y'), (3, 'z'); insert into t2 values (2, 'w'), (4, 'y'); set enable_optimize_predicate_expression = 0; + select * from t1 join t2 on a = c; select * from t1 join t2 on c = a; @@ -28,14 +29,13 @@ select b as a, d as c from t1 join t2 on c = a; select b as c, d as a from t1 join t2 on a = c; select b as c, d as a from t1 join t2 on c = a; --- TODO --- select t1.a as a, t2.c as c from t1 join t2 on a = c; --- select t1.a as a, t2.c as c from t1 join t2 on c = a; --- select t1.a as c, t2.c as a from t1 join t2 on a = c; --- select t1.a as c, t2.c as a from t1 join t2 on c = a; --- --- select t1.a as c, t2.c as a from t1 join t2 on t1.a = t2.c; --- select t1.a as c, t2.c as a from t1 join t2 on t2.c = t1.a; +select t1.a as a, t2.c as c from t1 join t2 on a = c; +select t1.a as a, t2.c as c from t1 join t2 on c = a; +select t1.a as c, t2.c as a from t1 join t2 on a = c; +select t1.a as c, t2.c as a from t1 join t2 on c = a; + +select t1.a as c, t2.c as a from t1 join t2 on t1.a = t2.c; +select t1.a as c, t2.c as a from t1 join t2 on t2.c = t1.a; set enable_optimize_predicate_expression = 1; @@ -57,5 +57,13 @@ select b as a, d as c from t1 join t2 on c = a; select b as c, d as a from t1 join t2 on a = c; select b as c, d as a from t1 join t2 on c = a; +select t1.a as a, t2.c as c from t1 join t2 on a = c; +select t1.a as a, t2.c as c from t1 join t2 on c = a; +select t1.a as c, t2.c as a from t1 join t2 on a = c; +select t1.a as c, t2.c as a from t1 join t2 on c = a; + +select t1.a as c, t2.c as a from t1 join t2 on t1.a = t2.c; +select t1.a as c, t2.c as a from t1 join t2 on t2.c = t1.a; + drop table t1; drop table t2; From 1d499bcdc00db36a7d5ff914696974cd7c906edc Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 25 Jul 2019 22:54:16 +0300 Subject: [PATCH 0366/1165] Allow to update PHDRCache --- dbms/programs/main.cpp | 2 +- libs/libcommon/include/common/phdr_cache.h | 15 ++++--- libs/libcommon/src/phdr_cache.cpp | 52 +++++++++++++++------- 3 files changed, 46 insertions(+), 23 deletions(-) diff --git a/dbms/programs/main.cpp b/dbms/programs/main.cpp index 27053147a65..ec33cdd2319 100644 --- a/dbms/programs/main.cpp +++ b/dbms/programs/main.cpp @@ -149,7 +149,7 @@ int main(int argc_, char ** argv_) /// PHDR cache is required for query profiler to work reliably /// It also speed up exception handling, but exceptions from dynamically loaded libraries (dlopen) won't work. - enablePHDRCache(); + updatePHDRCache(); #if USE_EMBEDDED_COMPILER if (argc_ >= 2 && 0 == strcmp(argv_[1], "-cc1")) diff --git a/libs/libcommon/include/common/phdr_cache.h b/libs/libcommon/include/common/phdr_cache.h index 76c28f7713a..9e3d38a1684 100644 --- a/libs/libcommon/include/common/phdr_cache.h +++ b/libs/libcommon/include/common/phdr_cache.h @@ -1,10 +1,11 @@ #pragma once -/// This code was developed by Fedor Korotkiy (prime@yandex-team.ru) for YT product in Yandex. +/// This code was based on code by Fedor Korotkiy (prime@yandex-team.ru) for YT product in Yandex. -//! Collects all dl_phdr_info items and caches them in a static array. -//! Also rewrites dl_iterate_phdr with a lockless version which consults the above cache -//! thus eliminating scalability bottleneck in C++ exception unwinding. -//! As a drawback, this only works if no dynamic object loading/unloading happens after this point. -//! This function is not thread-safe; the caller must guarantee that no concurrent unwinding takes place. -void enablePHDRCache(); +/// Collects all dl_phdr_info items and caches them in a static array. +/// Also rewrites dl_iterate_phdr with a lockless version which consults the above cache +/// thus eliminating scalability bottleneck in C++ exception unwinding. +/// As a drawback, this only works if no dynamic object unloading happens after this point. +/// This function is thread-safe. You should call it to update cache after loading new shared libraries. +/// Otherwise exception handling from dlopened libraries won't work (will call std::terminate immediately). +void updatePHDRCache(); diff --git a/libs/libcommon/src/phdr_cache.cpp b/libs/libcommon/src/phdr_cache.cpp index c27d42d40b5..3cc90f3521f 100644 --- a/libs/libcommon/src/phdr_cache.cpp +++ b/libs/libcommon/src/phdr_cache.cpp @@ -2,11 +2,30 @@ #include #include -#include +#include +#include #include #include +#if defined(__has_feature) + #if __has_feature(address_sanitizer) + #define ADDRESS_SANITIZER 1 + #endif +#elif defined(__SANITIZE_ADDRESS__) + #define ADDRESS_SANITIZER 1 +#endif + +extern "C" +{ +#ifdef ADDRESS_SANITIZER +void __lsan_ignore_object(const void *); +#else +void __lsan_ignore_object(const void *) {} +#endif +} + + namespace { @@ -25,10 +44,8 @@ DLIterateFunction getOriginalDLIteratePHDR() } -constexpr size_t phdr_cache_max_size = 128; -size_t phdr_cache_size = 0; -using PHDRCache = std::array; -PHDRCache phdr_cache; +using PHDRCache = std::vector; +std::atomic phdr_cache {}; } @@ -40,16 +57,17 @@ extern "C" #endif int dl_iterate_phdr(int (*callback) (dl_phdr_info * info, size_t size, void * data), void * data) { - if (0 == phdr_cache_size) + auto current_phdr_cache = phdr_cache.load(std::memory_order_relaxed); + if (!current_phdr_cache) { // Cache is not yet populated, pass through to the original function. return getOriginalDLIteratePHDR()(callback, data); } int result = 0; - for (size_t i = 0; i < phdr_cache_size; ++i) + for (auto & entry : *current_phdr_cache) { - result = callback(&phdr_cache[i], offsetof(dl_phdr_info, dlpi_adds), data); + result = callback(&entry, offsetof(dl_phdr_info, dlpi_adds), data); if (result != 0) break; } @@ -57,18 +75,22 @@ int dl_iterate_phdr(int (*callback) (dl_phdr_info * info, size_t size, void * da } -void enablePHDRCache() +void updatePHDRCache() { #if defined(__linux__) // Fill out ELF header cache for access without locking. // This assumes no dynamic object loading/unloading after this point - getOriginalDLIteratePHDR()([] (dl_phdr_info * info, size_t /*size*/, void * /*data*/) + + PHDRCache * new_phdr_cache = new PHDRCache; + getOriginalDLIteratePHDR()([] (dl_phdr_info * info, size_t /*size*/, void * data) { - if (phdr_cache_size >= phdr_cache_max_size) - throw std::runtime_error("phdr_cache_max_size is not enough to accomodate the result of dl_iterate_phdr. You must recompile the code."); - phdr_cache[phdr_cache_size] = *info; - ++phdr_cache_size; + reinterpret_cast(data)->push_back(*info); return 0; - }, nullptr); + }, new_phdr_cache); + phdr_cache.store(new_phdr_cache); + + /// Memory is intentionally leaked. + __lsan_ignore_object(new_phdr_cache); + #endif } From f5c1dfc5ac38d3b6125461d871b99cc8d18b1937 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 25 Jul 2019 22:54:43 +0300 Subject: [PATCH 0367/1165] Updated comment --- libs/libcommon/include/common/StackTrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/libcommon/include/common/StackTrace.h b/libs/libcommon/include/common/StackTrace.h index fdb7e288c20..997730eb440 100644 --- a/libs/libcommon/include/common/StackTrace.h +++ b/libs/libcommon/include/common/StackTrace.h @@ -17,7 +17,7 @@ struct NoCapture }; /// Tries to capture current stack trace using libunwind or signal context -/// NOTE: StackTrace calculation is signal safe only if enablePHDRCache() was called beforehand. +/// NOTE: StackTrace calculation is signal safe only if updatePHDRCache() was called beforehand. class StackTrace { public: From 472a61c1fa61dda2dad23873ccf1d3e602264834 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 25 Jul 2019 22:56:51 +0300 Subject: [PATCH 0368/1165] Updating PHDRCache after dlopen --- dbms/src/Common/SharedLibrary.cpp | 3 +++ libs/libcommon/include/common/phdr_cache.h | 2 +- libs/libcommon/src/phdr_cache.cpp | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dbms/src/Common/SharedLibrary.cpp b/dbms/src/Common/SharedLibrary.cpp index 30ed3bccaab..568bfaa4f3e 100644 --- a/dbms/src/Common/SharedLibrary.cpp +++ b/dbms/src/Common/SharedLibrary.cpp @@ -1,6 +1,7 @@ #include "SharedLibrary.h" #include #include +#include #include "Exception.h" @@ -17,6 +18,8 @@ SharedLibrary::SharedLibrary(const std::string & path, int flags) handle = dlopen(path.c_str(), flags); if (!handle) throw Exception(std::string("Cannot dlopen: ") + dlerror(), ErrorCodes::CANNOT_DLOPEN); + + updatePHDRCache(); } SharedLibrary::~SharedLibrary() diff --git a/libs/libcommon/include/common/phdr_cache.h b/libs/libcommon/include/common/phdr_cache.h index 9e3d38a1684..dff6782098b 100644 --- a/libs/libcommon/include/common/phdr_cache.h +++ b/libs/libcommon/include/common/phdr_cache.h @@ -1,6 +1,6 @@ #pragma once -/// This code was based on code by Fedor Korotkiy (prime@yandex-team.ru) for YT product in Yandex. +/// This code was based on the code by Fedor Korotkiy (prime@yandex-team.ru) for YT product in Yandex. /// Collects all dl_phdr_info items and caches them in a static array. /// Also rewrites dl_iterate_phdr with a lockless version which consults the above cache diff --git a/libs/libcommon/src/phdr_cache.cpp b/libs/libcommon/src/phdr_cache.cpp index 3cc90f3521f..4b324d4f181 100644 --- a/libs/libcommon/src/phdr_cache.cpp +++ b/libs/libcommon/src/phdr_cache.cpp @@ -1,4 +1,4 @@ -/// This code was developed by Fedor Korotkiy (prime@yandex-team.ru) for YT product in Yandex. +/// This code was based on the code by Fedor Korotkiy (prime@yandex-team.ru) for YT product in Yandex. #include #include From 9b8375a6ef312505931f40e571a718241019d25c Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 25 Jul 2019 22:57:49 +0300 Subject: [PATCH 0369/1165] More strict memory order just in case --- libs/libcommon/src/phdr_cache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/libcommon/src/phdr_cache.cpp b/libs/libcommon/src/phdr_cache.cpp index 4b324d4f181..f544d574129 100644 --- a/libs/libcommon/src/phdr_cache.cpp +++ b/libs/libcommon/src/phdr_cache.cpp @@ -57,7 +57,7 @@ extern "C" #endif int dl_iterate_phdr(int (*callback) (dl_phdr_info * info, size_t size, void * data), void * data) { - auto current_phdr_cache = phdr_cache.load(std::memory_order_relaxed); + auto current_phdr_cache = phdr_cache.load(); if (!current_phdr_cache) { // Cache is not yet populated, pass through to the original function. From bc74013f983084fc658b2783ee00a53ad94742cf Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 25 Jul 2019 23:10:33 +0300 Subject: [PATCH 0370/1165] Fixed UBSan report in ProtobufWriter --- dbms/src/Formats/ProtobufWriter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dbms/src/Formats/ProtobufWriter.cpp b/dbms/src/Formats/ProtobufWriter.cpp index bca3449cb59..fcaedcab2a0 100644 --- a/dbms/src/Formats/ProtobufWriter.cpp +++ b/dbms/src/Formats/ProtobufWriter.cpp @@ -141,7 +141,8 @@ void ProtobufWriter::SimpleWriter::endMessage() size_t size_of_message = buffer.size() - num_bytes_skipped; writeVarint(size_of_message, out); for (const auto & piece : pieces) - out.write(reinterpret_cast(&buffer[piece.start]), piece.end - piece.start); + if (piece.end > piece.start) + out.write(reinterpret_cast(&buffer[piece.start]), piece.end - piece.start); buffer.clear(); pieces.clear(); num_bytes_skipped = 0; From 21ef261702c0cf511a5b7d650f44bfb15d7a262f Mon Sep 17 00:00:00 2001 From: alesapin Date: Thu, 25 Jul 2019 23:11:26 +0300 Subject: [PATCH 0371/1165] Fix some integration tests and make kafka tests endless --- .../dictionaries/dictionary_preset_cmd.xml | 38 ++++--- .../dictionaries/dictionary_preset_dep_x.xml | 3 +- .../dictionaries/dictionary_preset_dep_y.xml | 3 +- .../dictionaries/dictionary_preset_dep_z.xml | 3 +- .../dictionaries/dictionary_preset_file.xml | 106 +++++++++--------- .../dictionary_preset_longload.xml | 38 ++++--- .../generate_dictionaries.py | 42 +++---- .../test_external_dictionaries/dictionary.py | 28 ++--- .../integration/test_storage_kafka/test.py | 33 +++--- 9 files changed, 156 insertions(+), 138 deletions(-) diff --git a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_cmd.xml b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_cmd.xml index a12428af5c7..a02ed5f8b2f 100644 --- a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_cmd.xml +++ b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_cmd.xml @@ -1,19 +1,21 @@ - - - cmd - - - echo '7\t8'; - TabSeparated - - - 0 - - key - aInt32 - 0 - - - - + + + + cmd + + + echo '7\t8'; + TabSeparated + + + 0 + + key + aInt32 + 0 + + + + + diff --git a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_x.xml b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_x.xml index 6eed3fbc891..f82bdb7c785 100644 --- a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_x.xml +++ b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_x.xml @@ -1,4 +1,4 @@ - + dep_x @@ -28,3 +28,4 @@ + diff --git a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_y.xml b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_y.xml index 7891e945566..5f140838139 100644 --- a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_y.xml +++ b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_y.xml @@ -1,4 +1,4 @@ - + dep_y @@ -38,3 +38,4 @@ + diff --git a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_z.xml b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_z.xml index e17107d2ac2..3fec7ac3cff 100644 --- a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_z.xml +++ b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_z.xml @@ -1,4 +1,4 @@ - + dep_z @@ -34,3 +34,4 @@ + diff --git a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_file.xml b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_file.xml index d04d0be3f90..3da0a55319c 100644 --- a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_file.xml +++ b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_file.xml @@ -1,53 +1,55 @@ - - - file - - - /etc/clickhouse-server/config.d/dictionary_preset_file.txt - TabSeparated - - - 1 - - key - aInt32 - 0 - - - - - - no_file - - - /etc/clickhouse-server/config.d/dictionary_preset_no_file.txt - TabSeparated - - - 1 - - key - aInt32 - 0 - - - - - - no_file_2 - - - /etc/clickhouse-server/config.d/dictionary_preset_no_file_2.txt - TabSeparated - - - 1 - - key - aInt32 - 0 - - - - + + + + file + + + /etc/clickhouse-server/config.d/dictionary_preset_file.txt + TabSeparated + + + 1 + + key + aInt32 + 0 + + + + + + no_file + + + /etc/clickhouse-server/config.d/dictionary_preset_no_file.txt + TabSeparated + + + 1 + + key + aInt32 + 0 + + + + + + no_file_2 + + + /etc/clickhouse-server/config.d/dictionary_preset_no_file_2.txt + TabSeparated + + + 1 + + key + aInt32 + 0 + + + + + diff --git a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_longload.xml b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_longload.xml index b96a6151eb9..b2e560b35e3 100644 --- a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_longload.xml +++ b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_longload.xml @@ -1,19 +1,21 @@ - - - longload - - - sleep 100 && echo '5\t6'; - TabSeparated - - - 0 - - key - aInt32 - 0 - - - - + + + + longload + + + sleep 100 && echo '5\t6'; + TabSeparated + + + 0 + + key + aInt32 + 0 + + + + + diff --git a/dbms/tests/integration/test_dictionaries/generate_dictionaries.py b/dbms/tests/integration/test_dictionaries/generate_dictionaries.py index d0b0dd67a3a..47f4ac12a80 100644 --- a/dbms/tests/integration/test_dictionaries/generate_dictionaries.py +++ b/dbms/tests/integration/test_dictionaries/generate_dictionaries.py @@ -52,32 +52,34 @@ def generate_structure(): def generate_dictionaries(path, structure): dictionary_skeleton = ''' - - - {name} + + + + {name} - - {source} - + + {source} + - - 0 - 0 - + + 0 + 0 + - - {layout} - + + {layout} + - - {key} + + {key} - %s + %s - {parent} - - - ''' + {parent} + + + + ''' attribute_skeleton = ''' %s_ diff --git a/dbms/tests/integration/test_external_dictionaries/dictionary.py b/dbms/tests/integration/test_external_dictionaries/dictionary.py index bdddc7a9604..44da511693a 100644 --- a/dbms/tests/integration/test_external_dictionaries/dictionary.py +++ b/dbms/tests/integration/test_external_dictionaries/dictionary.py @@ -290,19 +290,21 @@ class Dictionary(object): def generate_config(self): with open(self.config_path, 'w') as result: result.write(''' - - - - 3 - 5 - - {name} - {structure} - - {source} - - - + + + + + 3 + 5 + + {name} + {structure} + + {source} + + + + '''.format( name=self.name, structure=self.structure.get_structure_str(), diff --git a/dbms/tests/integration/test_storage_kafka/test.py b/dbms/tests/integration/test_storage_kafka/test.py index c2bdade170f..0324307a7a1 100644 --- a/dbms/tests/integration/test_storage_kafka/test.py +++ b/dbms/tests/integration/test_storage_kafka/test.py @@ -140,6 +140,7 @@ def test_kafka_settings_old_syntax(kafka_cluster): result += instance.query('SELECT * FROM test.kafka') if kafka_check_result(result): break + time.sleep(0.5) kafka_check_result(result, True) @@ -170,11 +171,11 @@ def test_kafka_settings_new_syntax(kafka_cluster): kafka_produce('new', messages) result = '' - while True: + for i in range(50): result += instance.query('SELECT * FROM test.kafka') if kafka_check_result(result): break - print result + time.sleep(0.5) kafka_check_result(result, True) @@ -195,10 +196,11 @@ def test_kafka_csv_with_delimiter(kafka_cluster): kafka_produce('csv', messages) result = '' - while True: + for i in range(50): result += instance.query('SELECT * FROM test.kafka') if kafka_check_result(result): break + time.sleep(0.5) kafka_check_result(result, True) @@ -219,10 +221,11 @@ def test_kafka_tsv_with_delimiter(kafka_cluster): kafka_produce('tsv', messages) result = '' - while True: + for i in range(50): result += instance.query('SELECT * FROM test.kafka') if kafka_check_result(result): break + time.sleep(0.5) kafka_check_result(result, True) @@ -247,10 +250,11 @@ def test_kafka_json_without_delimiter(kafka_cluster): kafka_produce('json', [messages]) result = '' - while True: + for i in range(50): result += instance.query('SELECT * FROM test.kafka') if kafka_check_result(result): break + time.sleep(0.5) kafka_check_result(result, True) @@ -270,10 +274,11 @@ def test_kafka_protobuf(kafka_cluster): kafka_produce_protobuf_messages('pb', 21, 29) result = '' - while True: + for i in range(50): result += instance.query('SELECT * FROM test.kafka') if kafka_check_result(result): break + time.sleep(0.5) kafka_check_result(result, True) @@ -300,11 +305,11 @@ def test_kafka_materialized_view(kafka_cluster): messages.append(json.dumps({'key': i, 'value': i})) kafka_produce('mv', messages) - while True: - time.sleep(1) + for i in range(50): result = instance.query('SELECT * FROM test.view') if kafka_check_result(result): break + time.sleep(0.5) kafka_check_result(result, True) instance.query(''' @@ -349,11 +354,11 @@ def test_kafka_flush_on_big_message(kafka_cluster): except kafka.errors.GroupCoordinatorNotAvailableError: continue - while True: - time.sleep(1) + for i in range(50): result = instance.query('SELECT count() FROM test.view') if int(result) == kafka_messages*batch_messages: break + time.sleep(0.5) assert int(result) == kafka_messages*batch_messages, 'ClickHouse lost some messages: {}'.format(result) @@ -379,11 +384,11 @@ def test_kafka_virtual_columns(kafka_cluster): kafka_produce('virt1', [messages]) result = '' - while True: - time.sleep(1) + for i in range(50): result += instance.query('SELECT _key, key, _topic, value, _offset FROM test.kafka') if kafka_check_result(result, False, 'test_kafka_virtual1.reference'): break + time.sleep(0.5) kafka_check_result(result, True, 'test_kafka_virtual1.reference') @@ -410,11 +415,11 @@ def test_kafka_virtual_columns_with_materialized_view(kafka_cluster): messages.append(json.dumps({'key': i, 'value': i})) kafka_produce('virt2', messages) - while True: - time.sleep(1) + for i in range(50): result = instance.query('SELECT kafka_key, key, topic, value, offset FROM test.view') if kafka_check_result(result, False, 'test_kafka_virtual2.reference'): break + time.sleep(0.5) kafka_check_result(result, True, 'test_kafka_virtual2.reference') instance.query(''' From a7cbbd4e4a15094bb8ed0607e7c7e8130a4c99f9 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Thu, 25 Jul 2019 23:17:17 +0300 Subject: [PATCH 0372/1165] Update BaseDaemon.cpp --- libs/libdaemon/src/BaseDaemon.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libs/libdaemon/src/BaseDaemon.cpp b/libs/libdaemon/src/BaseDaemon.cpp index 7434e98b774..aa4993acead 100644 --- a/libs/libdaemon/src/BaseDaemon.cpp +++ b/libs/libdaemon/src/BaseDaemon.cpp @@ -509,15 +509,16 @@ namespace /// the maximum is 1000, and chromium uses 300 for its tab processes. Ignore /// whatever errors that occur, because it's just a debugging aid and we don't /// care if it breaks. -#if defined(__linux__) and not defined(NDEBUG) +#if defined(__linux__) && !defined(NDEBUG) void debugIncreaseOOMScore() { const std::string new_score = "555"; - try { + try + { DB::WriteBufferFromFile buf("/proc/self/oom_score_adj"); buf.write(new_score.c_str(), new_score.size()); } - catch (Poco::Exception & e) + catch (const Poco::Exception & e) { LOG_WARNING(&Logger::root(), "Failed to adjust OOM score: '" + e.displayText() + "'."); From fdac4f29623a32c9fa0ba5ad27ea24a51fd91279 Mon Sep 17 00:00:00 2001 From: alesapin Date: Thu, 25 Jul 2019 23:24:58 +0300 Subject: [PATCH 0373/1165] More fixes in integration tests configs --- .../dictionaries/dictionary_preset_cmd.xml | 34 ++++---- .../dictionaries/dictionary_preset_dep_x.xml | 56 +++++++------ .../dictionaries/dictionary_preset_dep_y.xml | 74 +++++++++--------- .../dictionaries/dictionary_preset_file.xml | 2 - .../dictionary_preset_longload.xml | 34 ++++---- .../generate_dictionaries.py | 38 +++++---- .../test_external_dictionaries/dictionary.py | 24 +++--- .../postgres_odbc_hashed_dictionary.xml | 68 ++++++++-------- .../sqlite3_odbc_cached_dictionary.xml | 76 +++++++++--------- .../sqlite3_odbc_hashed_dictionary.xml | 78 +++++++++---------- 10 files changed, 235 insertions(+), 249 deletions(-) diff --git a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_cmd.xml b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_cmd.xml index a02ed5f8b2f..9f1e259e2d7 100644 --- a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_cmd.xml +++ b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_cmd.xml @@ -1,21 +1,19 @@ - - - cmd - - - echo '7\t8'; - TabSeparated - - - 0 - - key - aInt32 - 0 - - - - + + cmd + + + echo '7\t8'; + TabSeparated + + + 0 + + key + aInt32 + 0 + + + diff --git a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_x.xml b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_x.xml index f82bdb7c785..097fc7cf503 100644 --- a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_x.xml +++ b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_x.xml @@ -1,31 +1,29 @@ - - - dep_x - - - localhost - 9000 - default - - dict - dep_z
    -
    - - 5 - - - - - - id - - - a - String - XX - - -
    -
    + + dep_x + + + localhost + 9000 + default + + dict + dep_z
    +
    + + 5 + + + + + + id + + + a + String + XX + + +
    diff --git a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_y.xml b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_y.xml index 5f140838139..8806c724111 100644 --- a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_y.xml +++ b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_y.xml @@ -1,41 +1,39 @@ - - dep_y - - - localhost - 9000 - default - - test - small_dict_source
    -
    - - 5 - - - - - - id - - - b - Int32 - -1 - - - c - Float64 - -2 - - - a - String - YY - - -
    -
    + dep_y + + + localhost + 9000 + default + + test + small_dict_source
    +
    + + 5 + + + + + + id + + + b + Int32 + -1 + + + c + Float64 + -2 + + + a + String + YY + + +
    diff --git a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_file.xml b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_file.xml index 3da0a55319c..0e6db1f1637 100644 --- a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_file.xml +++ b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_file.xml @@ -1,6 +1,5 @@ - file @@ -51,5 +50,4 @@
    - diff --git a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_longload.xml b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_longload.xml index b2e560b35e3..f5d4cdec583 100644 --- a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_longload.xml +++ b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_longload.xml @@ -1,21 +1,19 @@ - - - longload - - - sleep 100 && echo '5\t6'; - TabSeparated - - - 0 - - key - aInt32 - 0 - - - - + + longload + + + sleep 100 && echo '5\t6'; + TabSeparated + + + 0 + + key + aInt32 + 0 + + + diff --git a/dbms/tests/integration/test_dictionaries/generate_dictionaries.py b/dbms/tests/integration/test_dictionaries/generate_dictionaries.py index 47f4ac12a80..c644bd8f644 100644 --- a/dbms/tests/integration/test_dictionaries/generate_dictionaries.py +++ b/dbms/tests/integration/test_dictionaries/generate_dictionaries.py @@ -53,32 +53,30 @@ def generate_structure(): def generate_dictionaries(path, structure): dictionary_skeleton = ''' - - - {name} + + {name} - - {source} - + + {source} + - - 0 - 0 - + + 0 + 0 + - - {layout} - + + {layout} + - - {key} + + {key} - %s + %s - {parent} - - - + {parent} + + ''' attribute_skeleton = ''' diff --git a/dbms/tests/integration/test_external_dictionaries/dictionary.py b/dbms/tests/integration/test_external_dictionaries/dictionary.py index 44da511693a..e84eda9bea7 100644 --- a/dbms/tests/integration/test_external_dictionaries/dictionary.py +++ b/dbms/tests/integration/test_external_dictionaries/dictionary.py @@ -291,19 +291,17 @@ class Dictionary(object): with open(self.config_path, 'w') as result: result.write(''' - - - - 3 - 5 - - {name} - {structure} - - {source} - - - + + + 3 + 5 + + {name} + {structure} + + {source} + + '''.format( name=self.name, diff --git a/dbms/tests/integration/test_odbc_interaction/configs/dictionaries/postgres_odbc_hashed_dictionary.xml b/dbms/tests/integration/test_odbc_interaction/configs/dictionaries/postgres_odbc_hashed_dictionary.xml index 1c293f66761..19eed6ebd6a 100644 --- a/dbms/tests/integration/test_odbc_interaction/configs/dictionaries/postgres_odbc_hashed_dictionary.xml +++ b/dbms/tests/integration/test_odbc_interaction/configs/dictionaries/postgres_odbc_hashed_dictionary.xml @@ -1,38 +1,38 @@ - - - postgres_odbc_hashed - - - clickhouse.test_table
    - DSN=postgresql_odbc; - postgres -
    - - - 5 - 5 - - - - + + + postgres_odbc_hashed + + + clickhouse.test_table
    + DSN=postgresql_odbc; + postgres +
    + + + 5 + 5 + + + + - - - column1 - + + + column1 + - - column1 - Int64 - 1 - + + column1 + Int64 + 1 + - - column2 - String - '' - + + column2 + String + '' + - -
    -
    + + + diff --git a/dbms/tests/integration/test_odbc_interaction/configs/dictionaries/sqlite3_odbc_cached_dictionary.xml b/dbms/tests/integration/test_odbc_interaction/configs/dictionaries/sqlite3_odbc_cached_dictionary.xml index f7eaea03a5e..45f3966ee8a 100644 --- a/dbms/tests/integration/test_odbc_interaction/configs/dictionaries/sqlite3_odbc_cached_dictionary.xml +++ b/dbms/tests/integration/test_odbc_interaction/configs/dictionaries/sqlite3_odbc_cached_dictionary.xml @@ -1,46 +1,46 @@ - - - sqlite3_odbc_cached - - - t3
    - DSN=sqlite3_odbc -
    - + + + sqlite3_odbc_cached + + + t3
    + DSN=sqlite3_odbc +
    + - - 128 - + + 128 + - - 1 - 1 - + + 1 + 1 + - - - X - + + + X + - - X - Int64 - 1 - + + X + Int64 + 1 + - - Y - Int64 - 1 - + + Y + Int64 + 1 + - - Z - UInt8 - 1 - + + Z + UInt8 + 1 + - -
    -
    + + + diff --git a/dbms/tests/integration/test_odbc_interaction/configs/dictionaries/sqlite3_odbc_hashed_dictionary.xml b/dbms/tests/integration/test_odbc_interaction/configs/dictionaries/sqlite3_odbc_hashed_dictionary.xml index 76ba4ad27f3..18a14b896bd 100644 --- a/dbms/tests/integration/test_odbc_interaction/configs/dictionaries/sqlite3_odbc_hashed_dictionary.xml +++ b/dbms/tests/integration/test_odbc_interaction/configs/dictionaries/sqlite3_odbc_hashed_dictionary.xml @@ -1,46 +1,46 @@ - - - sqlite3_odbc_hashed - - - t2
    - DSN=sqlite3_odbc - SELECT Z from t2 where X=1 -
    - + + + sqlite3_odbc_hashed + + + t2
    + DSN=sqlite3_odbc + SELECT Z from t2 where X=1 +
    + - - 1 - 1 - + + 1 + 1 + - - - + + + - - - X - + + + X + - - X - Int64 - 1 - + + X + Int64 + 1 + - - Y - Int64 - 1 - + + Y + Int64 + 1 + - - Z - UInt8 - 1 - + + Z + UInt8 + 1 + - -
    -
    + + + From 232d59bdcfa0a12fc6918d4d2580e60958237c3a Mon Sep 17 00:00:00 2001 From: alesapin Date: Thu, 25 Jul 2019 23:26:27 +0300 Subject: [PATCH 0374/1165] Update QueryProfiler.cpp --- dbms/src/Common/QueryProfiler.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index aedab2a9eff..5fd1c181994 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -84,7 +84,6 @@ QueryProfilerBase::QueryProfilerBase(const Int32 thread_id, const #else sev._sigev_un._tid = thread_id; #endif - if (timer_create(clock_type, &sev, &timer_id)) throwFromErrno("Failed to create thread timer", ErrorCodes::CANNOT_CREATE_TIMER); From fe3831b6ef1ce04ac1d16350c7fcb72f588dc52b Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Thu, 25 Jul 2019 23:32:13 +0300 Subject: [PATCH 0375/1165] Update build_macos.sh --- utils/build/build_macos.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/build/build_macos.sh b/utils/build/build_macos.sh index a9bf2481a0e..aa1b1a039b0 100755 --- a/utils/build/build_macos.sh +++ b/utils/build/build_macos.sh @@ -37,7 +37,7 @@ fi mkdir build cd build -cmake .. -DCMAKE_CXX_COMPILER=`which g++-8 g++-7` -DCMAKE_C_COMPILER=`which gcc-8 gcc-7` +cmake .. -DCMAKE_CXX_COMPILER=`which g++-9 g++-8 g++-7` -DCMAKE_C_COMPILER=`which gcc-9 gcc-8 gcc-7` cmake --build . cd .. From ae161d75142d2c4880526a1ebbeab5b42b240f8d Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 26 Jul 2019 00:33:30 +0300 Subject: [PATCH 0376/1165] Fixed test --- dbms/tests/queries/0_stateless/00808_not_optimize_predicate.sql | 1 - 1 file changed, 1 deletion(-) diff --git a/dbms/tests/queries/0_stateless/00808_not_optimize_predicate.sql b/dbms/tests/queries/0_stateless/00808_not_optimize_predicate.sql index 21424152da1..542bea690e8 100644 --- a/dbms/tests/queries/0_stateless/00808_not_optimize_predicate.sql +++ b/dbms/tests/queries/0_stateless/00808_not_optimize_predicate.sql @@ -16,7 +16,6 @@ SELECT * FROM (SELECT id FROM test_00808 GROUP BY id LIMIT 1 BY id) WHERE id = 1 SET force_primary_key = 1; SELECT '-------FORCE PRIMARY KEY-------'; -SELECT * FROM (SELECT * FROM test_00808 FINAL) WHERE id = 1; -- { serverError 277 } SELECT * FROM (SELECT * FROM test_00808 LIMIT 1) WHERE id = 1; -- { serverError 277 } SELECT * FROM (SELECT id FROM test_00808 GROUP BY id LIMIT 1 BY id) WHERE id = 1; -- { serverError 277 } From 673fb05a2a6aa284b7dffd602db5156accbe99ae Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 26 Jul 2019 01:18:27 +0300 Subject: [PATCH 0377/1165] Disable PHDR Cache with TSan --- libs/libcommon/src/phdr_cache.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/libs/libcommon/src/phdr_cache.cpp b/libs/libcommon/src/phdr_cache.cpp index f544d574129..1784c8c3139 100644 --- a/libs/libcommon/src/phdr_cache.cpp +++ b/libs/libcommon/src/phdr_cache.cpp @@ -12,8 +12,16 @@ #if __has_feature(address_sanitizer) #define ADDRESS_SANITIZER 1 #endif -#elif defined(__SANITIZE_ADDRESS__) - #define ADDRESS_SANITIZER 1 + #if __has_feature(thread_sanitizer) + #define THREAD_SANITIZER 1 + #endif +#else + #if defined(__SANITIZE_ADDRESS__) + #define ADDRESS_SANITIZER 1 + #endif + #if defined(__SANITIZE_THREAD__) + #define THREAD_SANITIZER 1 + #endif #endif extern "C" @@ -26,6 +34,9 @@ void __lsan_ignore_object(const void *) {} } +/// Thread Sanitizer uses dl_iterate_phdr function on initialization and fails if we provide our own. +#ifndef THREAD_SANITIZER + namespace { @@ -74,10 +85,12 @@ int dl_iterate_phdr(int (*callback) (dl_phdr_info * info, size_t size, void * da return result; } +#endif + void updatePHDRCache() { -#if defined(__linux__) +#if defined(__linux__) && !defined(THREAD_SANITIZER) // Fill out ELF header cache for access without locking. // This assumes no dynamic object loading/unloading after this point From 5a47b0b99069b01e463e010d0e366d32b8a4d412 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 26 Jul 2019 01:35:47 +0300 Subject: [PATCH 0378/1165] Sanity and configuration checks --- dbms/programs/server/Server.cpp | 4 +- dbms/src/Common/QueryProfiler.cpp | 10 ++++ dbms/src/Common/QueryProfiler.h | 1 + dbms/src/Common/ThreadStatus.cpp | 1 - .../include/common/config_common.h.in | 1 + libs/libcommon/include/common/phdr_cache.h | 20 +++++--- libs/libcommon/src/phdr_cache.cpp | 49 ++++++++++++------- 7 files changed, 60 insertions(+), 26 deletions(-) diff --git a/dbms/programs/server/Server.cpp b/dbms/programs/server/Server.cpp index 58f15f878b4..108b2aeee20 100644 --- a/dbms/programs/server/Server.cpp +++ b/dbms/programs/server/Server.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -509,7 +510,8 @@ int Server::main(const std::vector & /*args*/) LOG_DEBUG(log, "Loaded metadata."); /// Init trace collector only after trace_log system table was created - global_context->initializeTraceCollector(); + if (hasPHDRCache()) + global_context->initializeTraceCollector(); global_context->setCurrentDatabase(default_database); diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index d9ec571eaa2..d91bc75b609 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -1,6 +1,8 @@ #include "QueryProfiler.h" #include +#include +#include #include #include #include @@ -120,6 +122,11 @@ QueryProfilerBase::QueryProfilerBase(const Int32 thread_id, const : log(&Logger::get("QueryProfiler")) , pause_signal(pause_signal) { +#if USE_INTERNAL_UNWIND_LIBRARY + /// Sanity check. + if (!hasPHDRCache()) + throw Exception("QueryProfiler cannot be used without PHDR cache, that is not available for TSan build", ErrorCodes::NOT_IMPLEMENTED); + /// Too high frequency can introduce infinite busy loop of signal handlers. We will limit maximum frequency (with 1000 signals per second). if (period < 1000000) period = 1000000; @@ -156,6 +163,9 @@ QueryProfilerBase::QueryProfilerBase(const Int32 thread_id, const tryCleanup(); throw; } +#else + throw Exception("QueryProfiler cannot work with stock libunwind", ErrorCodes::NOT_IMPLEMENTED); +#endif } template diff --git a/dbms/src/Common/QueryProfiler.h b/dbms/src/Common/QueryProfiler.h index 80e38637053..c09fc2c05ad 100644 --- a/dbms/src/Common/QueryProfiler.h +++ b/dbms/src/Common/QueryProfiler.h @@ -5,6 +5,7 @@ #include #include + namespace Poco { class Logger; diff --git a/dbms/src/Common/ThreadStatus.cpp b/dbms/src/Common/ThreadStatus.cpp index ff6c23c1794..e5fe5d6f23b 100644 --- a/dbms/src/Common/ThreadStatus.cpp +++ b/dbms/src/Common/ThreadStatus.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include diff --git a/libs/libcommon/include/common/config_common.h.in b/libs/libcommon/include/common/config_common.h.in index 543e3cb60bd..c9a693a970a 100644 --- a/libs/libcommon/include/common/config_common.h.in +++ b/libs/libcommon/include/common/config_common.h.in @@ -8,3 +8,4 @@ #cmakedefine01 USE_LIBEDIT #cmakedefine01 HAVE_READLINE_HISTORY #cmakedefine01 UNBUNDLED +#cmakedefine01 USE_INTERNAL_UNWIND_LIBRARY diff --git a/libs/libcommon/include/common/phdr_cache.h b/libs/libcommon/include/common/phdr_cache.h index dff6782098b..d2854ece0bc 100644 --- a/libs/libcommon/include/common/phdr_cache.h +++ b/libs/libcommon/include/common/phdr_cache.h @@ -2,10 +2,18 @@ /// This code was based on the code by Fedor Korotkiy (prime@yandex-team.ru) for YT product in Yandex. -/// Collects all dl_phdr_info items and caches them in a static array. -/// Also rewrites dl_iterate_phdr with a lockless version which consults the above cache -/// thus eliminating scalability bottleneck in C++ exception unwinding. -/// As a drawback, this only works if no dynamic object unloading happens after this point. -/// This function is thread-safe. You should call it to update cache after loading new shared libraries. -/// Otherwise exception handling from dlopened libraries won't work (will call std::terminate immediately). +/** Collects all dl_phdr_info items and caches them in a static array. + * Also rewrites dl_iterate_phdr with a lock-free version which consults the above cache + * thus eliminating scalability bottleneck in C++ exception unwinding. + * As a drawback, this only works if no dynamic object unloading happens after this point. + * This function is thread-safe. You should call it to update cache after loading new shared libraries. + * Otherwise exception handling from dlopened libraries won't work (will call std::terminate immediately). + * + * NOTE: It is disabled with Thread Sanitizer because TSan can only use original "dl_iterate_phdr" function. + */ void updatePHDRCache(); + +/** Check if "dl_iterate_phdr" will be lock-free + * to determine if some features like Query Profiler can be used. + */ +bool hasPHDRCache(); diff --git a/libs/libcommon/src/phdr_cache.cpp b/libs/libcommon/src/phdr_cache.cpp index 1784c8c3139..a072bae3636 100644 --- a/libs/libcommon/src/phdr_cache.cpp +++ b/libs/libcommon/src/phdr_cache.cpp @@ -1,13 +1,5 @@ /// This code was based on the code by Fedor Korotkiy (prime@yandex-team.ru) for YT product in Yandex. -#include -#include -#include -#include -#include -#include - - #if defined(__has_feature) #if __has_feature(address_sanitizer) #define ADDRESS_SANITIZER 1 @@ -24,18 +16,21 @@ #endif #endif -extern "C" -{ -#ifdef ADDRESS_SANITIZER -void __lsan_ignore_object(const void *); -#else -void __lsan_ignore_object(const void *) {} +#if defined(__linux__) && !defined(THREAD_SANITIZER) + #define USE_PHDR_CACHE 1 #endif -} /// Thread Sanitizer uses dl_iterate_phdr function on initialization and fails if we provide our own. -#ifndef THREAD_SANITIZER +#ifdef USE_PHDR_CACHE + +#include +#include +#include +#include +#include +#include + namespace { @@ -85,12 +80,19 @@ int dl_iterate_phdr(int (*callback) (dl_phdr_info * info, size_t size, void * da return result; } + +extern "C" +{ +#ifdef ADDRESS_SANITIZER +void __lsan_ignore_object(const void *); +#else +void __lsan_ignore_object(const void *) {} #endif +} void updatePHDRCache() { -#if defined(__linux__) && !defined(THREAD_SANITIZER) // Fill out ELF header cache for access without locking. // This assumes no dynamic object loading/unloading after this point @@ -104,6 +106,17 @@ void updatePHDRCache() /// Memory is intentionally leaked. __lsan_ignore_object(new_phdr_cache); +} + + +bool hasPHDRCache() +{ + return phdr_cache.load() != nullptr; +} + +#else + +void updatePHDRCache() {} +bool hasPHDRCache() { return false; } #endif -} From cf67765fc8792309a6c7bc4552cda37b7064bb4d Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 26 Jul 2019 01:38:59 +0300 Subject: [PATCH 0379/1165] Reverted bad modification --- dbms/src/Common/ThreadStatus.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/dbms/src/Common/ThreadStatus.cpp b/dbms/src/Common/ThreadStatus.cpp index e5fe5d6f23b..ff6c23c1794 100644 --- a/dbms/src/Common/ThreadStatus.cpp +++ b/dbms/src/Common/ThreadStatus.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include From e5df077c21a339338cbf962b3d8e5eb1f67415d7 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 26 Jul 2019 02:00:18 +0300 Subject: [PATCH 0380/1165] Added example in config --- dbms/programs/server/config.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dbms/programs/server/config.xml b/dbms/programs/server/config.xml index a8f37a2cd78..c09913cbd87 100644 --- a/dbms/programs/server/config.xml +++ b/dbms/programs/server/config.xml @@ -322,6 +322,14 @@ --> + From 9734715b3f0fd895c2efdc824e177e5e573c7bc1 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Fri, 26 Jul 2019 08:49:26 +0300 Subject: [PATCH 0386/1165] DOCAPI-3911: EN review and RU translation for external dicts docs. (#6032) EN review RU translation --- .../dicts/external_dicts_dict_structure.md | 14 +++---- .../dicts/external_dicts_dict_structure.md | 39 +++++++++---------- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/docs/en/query_language/dicts/external_dicts_dict_structure.md b/docs/en/query_language/dicts/external_dicts_dict_structure.md index d8ecf4e2efa..d5377c39289 100644 --- a/docs/en/query_language/dicts/external_dicts_dict_structure.md +++ b/docs/en/query_language/dicts/external_dicts_dict_structure.md @@ -42,7 +42,7 @@ A structure can contain either `` or `` . ### Numeric Key -Format: `UInt64`. +Type: `UInt64`. Configuration example: @@ -54,7 +54,7 @@ Configuration example: Configuration fields: -- name – The name of the column with keys. +- `name` – The name of the column with keys. ### Composite Key @@ -93,7 +93,7 @@ Configuration example: ... Name - Type + ClickHouseDataType rand64() true @@ -108,11 +108,11 @@ Configuration fields: Tag | Description | Required ----|-------------|--------- `name`| Column name. | Yes -`type`| Column type.
    Sets the method for interpreting data in the source. For example, for MySQL, the field might be `TEXT`, `VARCHAR`, or `BLOB` in the source table, but it can be uploaded as `String`. | Yes -`null_value` | Default value for a non-existing element.
    In the example, it is an empty string. | Yes -`expression` | [Expression](../syntax.md#syntax-expressions) that ClickHouse executes on the value.
    The expression can be a column name in the remote SQL database. Thus, you can use it for creating an alias for the remote column.

    Default value: no expression. | No +`type`| ClickHouse data type.
    ClickHouse tries to cast value from dictionary to the specified data type. For example, for MySQL, the field might be `TEXT`, `VARCHAR`, or `BLOB` in the MySQL source table, but it can be uploaded as `String` in ClickHouse.
    [Nullable](../../data_types/nullable.md) is not supported. | Yes +`null_value` | Default value for a non-existing element.
    In the example, it is an empty string. You cannot use `NULL` in this field. | Yes +`expression` | [Expression](../syntax.md#syntax-expressions) that ClickHouse executes on the value.
    The expression can be a column name in the remote SQL database. Thus, you can use it to create an alias for the remote column.

    Default value: no expression. | No `hierarchical` | Hierarchical support. Mirrored to the parent identifier.

    Default value: `false`. | No -`injective` | Flag that shows whether the `id -> attribute` image is injective.
    If `true`, then you can optimize the `GROUP BY` clause.

    Default value: `false`. | No +`injective` | Flag that shows whether the `id -> attribute` image is [injective](https://en.wikipedia.org/wiki/Injective_function).
    If `true`, ClickHouse can automatically place after the `GROUP BY` clause the requests to dictionaries with injection. Usually it significantly reduces the amount of such requests.

    Default value: `false`. | No `is_object_id` | Flag that shows whether the query is executed for a MongoDB document by `ObjectID`.

    Default value: `false`. | No [Original article](https://clickhouse.yandex/docs/en/query_language/dicts/external_dicts_dict_structure/) diff --git a/docs/ru/query_language/dicts/external_dicts_dict_structure.md b/docs/ru/query_language/dicts/external_dicts_dict_structure.md index 482f47d4a8f..b553a6fdbea 100644 --- a/docs/ru/query_language/dicts/external_dicts_dict_structure.md +++ b/docs/ru/query_language/dicts/external_dicts_dict_structure.md @@ -1,4 +1,3 @@ - # Ключ и поля словаря Секция `` описывает ключ словаря и поля, доступные для запросов. @@ -24,25 +23,24 @@ В структуре описываются столбцы: -- `` - [ключевой столбец](external_dicts_dict_structure.md). -- `` - [столбец данных](external_dicts_dict_structure.md). Столбцов может быть много. +- `` — [ключевой столбец](external_dicts_dict_structure.md#ext_dict_structure-key). +- `` — [столбец данных](external_dicts_dict_structure.md#ext_dict_structure-attributes). Столбцов может быть много. - -## Ключ +## Ключ {#ext_dict_structure-key} ClickHouse поддерживает следующие виды ключей: -- Числовой ключ. Формат UInt64. Описывается в теге ``. -- Составной ключ. Набор значений разного типа. Описывается в теге ``. +- Числовой ключ. UInt64. Описывается в теге ``. +- Составной ключ. Набор значений разного типа. Описывается в теге ``. Структура может содержать либо `` либо ``. -!!! attention "Обратите внимание" +!!! warning "Обратите внимание" Ключ не надо дополнительно описывать в атрибутах. ### Числовой ключ -Формат: `UInt64`. +Тип: `UInt64`. Пример конфигурации: @@ -54,11 +52,11 @@ ClickHouse поддерживает следующие виды ключей: Поля конфигурации: -- name - имя столбца с ключами. +- `name` — имя столбца с ключами. ### Составной ключ -Ключом может быть кортеж (`tuple`) из полей произвольных типов. [layout](external_dicts_dict_layout.md) в этом случае должен быть `complex_key_hashed` или `complex_key_cache`. +Ключoм может быть кортеж (`tuple`) из полей произвольных типов. В этом случае [layout](external_dicts_dict_layout.md) должен быть `complex_key_hashed` или `complex_key_cache`. !!! tip "Совет" Cоставной ключ может состоять из одного элемента. Это даёт возможность использовать в качестве ключа, например, строку. @@ -93,7 +91,7 @@ ClickHouse поддерживает следующие виды ключей: ... Name - Type + ClickHouseDataType rand64() true @@ -105,13 +103,14 @@ ClickHouse поддерживает следующие виды ключей: Поля конфигурации: -- `name` - Имя столбца. -- `type` - Тип столбца. Задает способ интерпретации данных в источнике. Например, в случае MySQL, в таблице-источнике поле может быть `TEXT`, `VARCHAR`, `BLOB`, но загружено может быть как `String`. -- `null_value` - Значение по умолчанию для несуществующего элемента. В примере - пустая строка. -- `expression` - Атрибут может быть выражением. Тег не обязательный. -- `hierarchical` - Поддержка иерархии. Отображение в идентификатор родителя. По умолчанию, `false`. -- `injective` - Признак инъективности отображения `id -> attribute`. Если `true`, то можно оптимизировать `GROUP BY`. По умолчанию, `false`. -- `is_object_id` - Признак того, что запрос выполняется к документу MongoDB по `ObjectID`. - +| Тег | Описание | Обязательный | +| ---- | ------------- | --------- | +| `name` | Имя столбца. | Да | +| `type` | Тип данных ClickHouse.
    ClickHouse пытается привести значение из словаря к заданному типу данных. Например, в случае MySQL, в таблице-источнике поле может быть `TEXT`, `VARCHAR`, `BLOB`, но загружено может быть как `String`. [Nullable](../../data_types/nullable.md) не поддерживается. | Да | +| `null_value` | Значение по умолчанию для несуществующего элемента.
    В примере это пустая строка. Нельзя указать значение `NULL`. | Да | +| `expression` | [Выражение](../syntax.md#syntax-expressions), которое ClickHouse выполняет со значением.
    Выражением может быть имя столбца в удаленной SQL базе. Таким образом, вы можете использовать его для создания псевдонима удаленного столбца.

    Значение по умолчанию: нет выражения. | Нет | +| `hierarchical` | Поддержка иерархии. Отображение в идентификатор родителя.

    Значение по умолчанию: `false`. | Нет | +| `injective` | Признак [инъективности](https://ru.wikipedia.org/wiki/Инъекция_(математика)) отображения `id -> attribute`.
    Если `true`, то обращения к словарям с включенной инъективностью могут быть автоматически переставлены ClickHouse за стадию `GROUP BY`, что как правило существенно сокращает их количество.

    Значение по умолчанию: `false`. | Нет | +| `is_object_id` | Признак того, что запрос выполняется к документу MongoDB по `ObjectID`.

    Значение по умолчанию: `false`. | Нет | [Оригинальная статья](https://clickhouse.yandex/docs/ru/query_language/dicts/external_dicts_dict_structure/) From 2af3738aa49f3a7c1ba954c12bc3b4a00563f10b Mon Sep 17 00:00:00 2001 From: BayoNet Date: Fri, 26 Jul 2019 09:57:17 +0300 Subject: [PATCH 0387/1165] Clarification and fixes. --- docs/en/query_language/functions/ext_dict_functions.md | 4 ++-- docs/ru/query_language/functions/ext_dict_functions.md | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/en/query_language/functions/ext_dict_functions.md b/docs/en/query_language/functions/ext_dict_functions.md index cb033f14c24..a8ea76633e6 100644 --- a/docs/en/query_language/functions/ext_dict_functions.md +++ b/docs/en/query_language/functions/ext_dict_functions.md @@ -21,7 +21,7 @@ dictGetOrDefault('dict_name', 'attr_name', id_expr, default_value_expr) **Returned value** - If ClickHouse parses the attribute successfully in the [attribute's data type](../dicts/external_dicts_dict_structure.md#ext_dict_structure-attributes), functions return the value of the dictionary attribute that corresponds to `id_expr`. -- If there is no requested `id_expr` in the dictionary, then: +- If there is no the key, corresponding to `id_expr`, in the dictionary, then: - `dictGet` returns the content of the `` element specified for the attribute in the dictionary configuration. - `dictGetOrDefault` returns the value passed as the `default_value_expr` parameter. @@ -165,7 +165,7 @@ Functions: - `dictGetUUID` - `dictGetString` -All these functions take the `OrDefault` modifier. For example, `dictGetDateOrDefault`. +All these functions have the `OrDefault` modification. For example, `dictGetDateOrDefault`. Syntax: diff --git a/docs/ru/query_language/functions/ext_dict_functions.md b/docs/ru/query_language/functions/ext_dict_functions.md index 47e221d7e74..f3bc191ad4d 100644 --- a/docs/ru/query_language/functions/ext_dict_functions.md +++ b/docs/ru/query_language/functions/ext_dict_functions.md @@ -20,9 +20,9 @@ dictGetOrDefault('dict_name', 'attr_name', id_expr, default_value_expr) **Возвращаемое значение** -- Если ClickHouse успешно обработал атрибут в соответствии с [заданным типом данных](../dicts/external_dicts_dict_structure.md#ext_dict_structure-attributes), то функции возвращают значение атрибута, соответствующее ключу `id_expr`. +- Значение атрибута, соответствующее ключу `id_expr`, если ClickHouse смог привести это значение к [заданному типу данных](../dicts/external_dicts_dict_structure.md#ext_dict_structure-attributes). -- Если запрошенного `id_expr` в словаре нет, то: +- Если ключа, соответствущего `id_expr` в словаре нет, то: - `dictGet` возвращает содержимое элемента ``, указанного для атрибута в конфигурации словаря. - `dictGetOrDefault` возвращает атрибут `default_value_expr`. @@ -190,4 +190,3 @@ dictGet[Type]OrDefault('dict_name', 'attr_name', id_expr, default_value_expr) Если значение атрибута не удалось обработать или оно не соответствует типу данных атрибута, то ClickHouse генерирует исключение. [Оригинальная статья](https://clickhouse.yandex/docs/ru/query_language/functions/ext_dict_functions/) - From 567a08a88f9c0760e27d24eadb45ab87a9811004 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Fri, 26 Jul 2019 10:15:28 +0300 Subject: [PATCH 0388/1165] DOCAPI-7553: EN review. RU translation. Update of CHECK TABLE description (#6138) EN review. RU translation. --- docs/en/query_language/misc.md | 6 ++++-- docs/ru/query_language/misc.md | 13 ++++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/docs/en/query_language/misc.md b/docs/en/query_language/misc.md index c3e7e598547..31bfea5dc4d 100644 --- a/docs/en/query_language/misc.md +++ b/docs/en/query_language/misc.md @@ -39,9 +39,11 @@ The `CHECK TABLE` query supports the following table engines: - [StripeLog](../operations/table_engines/stripelog.md) - [MergeTree family](../operations/table_engines/mergetree.md) -The `*Log` engines do not provide automatic data recovery on failure. Use the `CHECK TABLE` query to track data loss in a timely manner. +Performed over the tables with another table engines causes an exception. -For the `MergeTree` family engines the `CHECK TABLE` query shows a check status for every individual table data part at the local server. +Engines from the `*Log` family don't provide automatic data recovery on failure. Use the `CHECK TABLE` query to track data loss in a timely manner. + +For `MergeTree` family engines, the `CHECK TABLE` query shows a check status for every individual data part of a table on the local server. **If the data is corrupted** diff --git a/docs/ru/query_language/misc.md b/docs/ru/query_language/misc.md index 942ce4a541d..93f548bf73c 100644 --- a/docs/ru/query_language/misc.md +++ b/docs/ru/query_language/misc.md @@ -30,15 +30,18 @@ CHECK TABLE [db.]name - 0 - данные в таблице повреждены; - 1 - данные не повреждены. -Запрос `CHECK TABLE` поддерживается только для следующих движков: +Запрос `CHECK TABLE` поддерживает следующие движки таблиц: - [Log](../operations/table_engines/log.md) - [TinyLog](../operations/table_engines/tinylog.md) -- StripeLog +- [StripeLog](../operations/table_engines/stripelog.md) +- [Семейство MergeTree](../operations/table_engines/mergetree.md) -В этих движках не предусмотрено автоматическое восстановление данных после сбоя. Поэтому используйте запрос `CHECK TABLE`, чтобы своевременно выявить повреждение данных. +При попытке выполнить запрос с таблицами с другими табличными движками, ClickHouse генерирует исключение. -Обратите внимание, высокая защита целостности данных обеспечивается в таблицах семейства [MergeTree](../operations/table_engines/mergetree.md). Для избежания потери данных рекомендуется использовать именно эти таблицы. +В движках `*Log` не предусмотрено автоматическое восстановление данных после сбоя. Используйте запрос `CHECK TABLE`, чтобы своевременно выявлять повреждение данных. + +Для движков из семейства `MergeTree` запрос `CHECK TABLE` показывает статус проверки для каждого отдельного куска данных таблицы на локальном сервере. **Что делать, если данные повреждены** @@ -56,7 +59,7 @@ DESC|DESCRIBE TABLE [db.]table [INTO OUTFILE filename] [FORMAT format] ``` Возвращает описание столбцов таблицы. -Результат запроса содержит столбцы (все столбцы имеют тип String): +Результат запроса содержит столбцы (все столбцы имеют тип String): - `name` — имя столбца таблицы; - `type`— тип столбца; From 74596ed8dcb5bc4422a1b88d6123a29ba0e9865a Mon Sep 17 00:00:00 2001 From: chertus Date: Fri, 26 Jul 2019 15:12:34 +0300 Subject: [PATCH 0389/1165] improve test --- .../0_stateless/00974_fix_join_on.reference | 6 ++++++ .../queries/0_stateless/00974_fix_join_on.sql | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00974_fix_join_on.reference b/dbms/tests/queries/0_stateless/00974_fix_join_on.reference index 90c76d8b931..d52dd8a375c 100644 --- a/dbms/tests/queries/0_stateless/00974_fix_join_on.reference +++ b/dbms/tests/queries/0_stateless/00974_fix_join_on.reference @@ -18,6 +18,9 @@ y y 2 2 2 2 2 2 +3 3 +3 3 +3 3 2 y 2 w 2 y 2 w 2 2 @@ -38,3 +41,6 @@ y y 2 2 2 2 2 2 +3 3 +3 3 +3 3 diff --git a/dbms/tests/queries/0_stateless/00974_fix_join_on.sql b/dbms/tests/queries/0_stateless/00974_fix_join_on.sql index feffe046d4f..1b3c7d8672b 100644 --- a/dbms/tests/queries/0_stateless/00974_fix_join_on.sql +++ b/dbms/tests/queries/0_stateless/00974_fix_join_on.sql @@ -1,13 +1,14 @@ -use test; - drop table if exists t1; drop table if exists t2; +drop table if exists t3; create table t1 (a UInt32, b String) engine = Memory; create table t2 (c UInt32, d String) engine = Memory; +create table t3 (a UInt32) engine = Memory; insert into t1 values (1, 'x'), (2, 'y'), (3, 'z'); insert into t2 values (2, 'w'), (4, 'y'); +insert into t3 values (3); set enable_optimize_predicate_expression = 0; @@ -37,6 +38,10 @@ select t1.a as c, t2.c as a from t1 join t2 on c = a; select t1.a as c, t2.c as a from t1 join t2 on t1.a = t2.c; select t1.a as c, t2.c as a from t1 join t2 on t2.c = t1.a; +select t1.a, t3.a from t1 join t3 on t1.a = t3.a; +select t1.a as t1_a, t3.a as t3_a from t1 join t3 on t1_a = t3_a; +select table1.a as t1_a, table3.a as t3_a from t1 as table1 join t3 as table3 on t1_a = t3_a; + set enable_optimize_predicate_expression = 1; select * from t1 join t2 on a = c; @@ -65,5 +70,10 @@ select t1.a as c, t2.c as a from t1 join t2 on c = a; select t1.a as c, t2.c as a from t1 join t2 on t1.a = t2.c; select t1.a as c, t2.c as a from t1 join t2 on t2.c = t1.a; +select t1.a, t3.a from t1 join t3 on t1.a = t3.a; +select t1.a as t1_a, t3.a as t3_a from t1 join t3 on t1_a = t3_a; +select table1.a as t1_a, table3.a as t3_a from t1 as table1 join t3 as table3 on t1_a = t3_a; + drop table t1; drop table t2; +drop table t3; From 363fca3895c30a195cb834533fa9c36493043302 Mon Sep 17 00:00:00 2001 From: alesapin Date: Fri, 26 Jul 2019 17:37:37 +0300 Subject: [PATCH 0390/1165] More integration fixes and disable kafka test test_kafka_settings_new_syntax --- .../dictionaries/dictionary_preset_dep_z.xml | 68 +++++++++---------- .../integration/test_storage_kafka/test.py | 2 +- 2 files changed, 34 insertions(+), 36 deletions(-) diff --git a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_z.xml b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_z.xml index 3fec7ac3cff..8eff3a6407b 100644 --- a/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_z.xml +++ b/dbms/tests/integration/test_dictionaries/configs/dictionaries/dictionary_preset_dep_z.xml @@ -1,37 +1,35 @@ - - - dep_z - - - localhost - 9000 - default - - dict - dep_y
    - SELECT intDiv(count(), 5) from dict.dep_y -
    - - 5 - - - - - - id - - - b - Int32 - -3 - - - a - String - ZZ - - -
    -
    + + dep_z + + + localhost + 9000 + default + + dict + dep_y
    + SELECT intDiv(count(), 5) from dict.dep_y +
    + + 5 + + + + + + id + + + b + Int32 + -3 + + + a + String + ZZ + + +
    diff --git a/dbms/tests/integration/test_storage_kafka/test.py b/dbms/tests/integration/test_storage_kafka/test.py index 0324307a7a1..9be725d33b7 100644 --- a/dbms/tests/integration/test_storage_kafka/test.py +++ b/dbms/tests/integration/test_storage_kafka/test.py @@ -143,7 +143,7 @@ def test_kafka_settings_old_syntax(kafka_cluster): time.sleep(0.5) kafka_check_result(result, True) - +@pytest.mark.skip(reason="fails for some reason") def test_kafka_settings_new_syntax(kafka_cluster): instance.query(''' CREATE TABLE test.kafka (key UInt64, value UInt64) From 2ced6a3adb0229d92d6186590adfe7927fefb523 Mon Sep 17 00:00:00 2001 From: Vasily Nemkov Date: Fri, 26 Jul 2019 19:17:07 +0300 Subject: [PATCH 0391/1165] Fixed Gorilla and DoubleDelta codec performance tests. * Converted to loop-tests * Set limits for both INSERT and SELECT to make those finite and more predictable --- dbms/tests/performance/codec_double_delta.xml | 29 +++++++++++-------- dbms/tests/performance/codec_gorilla.xml | 29 +++++++++++-------- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/dbms/tests/performance/codec_double_delta.xml b/dbms/tests/performance/codec_double_delta.xml index a713c606eb1..35bdbe4c3c4 100644 --- a/dbms/tests/performance/codec_double_delta.xml +++ b/dbms/tests/performance/codec_double_delta.xml @@ -1,11 +1,15 @@ - IPv4 Functions + Codec DoubleDelta - once + loop + + 10 + 10000 + - 1000 - 2000 + 50 + 60000 @@ -49,15 +53,16 @@ INSERT INTO mon_{table_suffix} (n) SELECT n FROM mon_{table_suffix} INSERT INTO rnd_{table_suffix} (n) SELECT n FROM rnd_{table_suffix} + + INSERT INTO seq_{table_suffix} (n) SELECT number FROM system.numbers LIMIT 100000 SETTINGS max_threads=1 + INSERT INTO mon_{table_suffix} (n) SELECT number*67+(rand()%67) FROM system.numbers LIMIT 100000 SETTINGS max_threads=1 + INSERT INTO rnd_{table_suffix} (n) SELECT rand() FROM system.numbers LIMIT 100000 SETTINGS max_threads=1 - INSERT INTO seq_{table_suffix} (n) SELECT number FROM system.numbers SETTINGS max_threads=1 - INSERT INTO mon_{table_suffix} (n) SELECT number*67+(rand()%67) FROM system.numbers SETTINGS max_threads=1 - INSERT INTO rnd_{table_suffix} (n) SELECT rand() FROM system.numbers SETTINGS max_threads=1 - - - SELECT count(n) FROM seq_{table_suffix} SETTINGS max_threads=1 - SELECT count(n) FROM mon_{table_suffix} SETTINGS max_threads=1 - SELECT count(n) FROM rnd_{table_suffix} SETTINGS max_threads=1 + + SELECT count(n) FROM seq_{table_suffix} LIMIT 1000000 SETTINGS max_threads=1 + SELECT count(n) FROM mon_{table_suffix} LIMIT 1000000 SETTINGS max_threads=1 + SELECT count(n) FROM rnd_{table_suffix} LIMIT 1000000 SETTINGS max_threads=1 DROP TABLE IF EXISTS seq_{table_suffix} diff --git a/dbms/tests/performance/codec_gorilla.xml b/dbms/tests/performance/codec_gorilla.xml index ba7d6297349..8935599dd16 100644 --- a/dbms/tests/performance/codec_gorilla.xml +++ b/dbms/tests/performance/codec_gorilla.xml @@ -1,11 +1,15 @@ - IPv4 Functions + Codec Gorilla - once + loop + + 10 + 10000 + - 1000 - 2000 + 50 + 60000 @@ -49,15 +53,16 @@ INSERT INTO mon_{table_suffix} (n) SELECT n FROM mon_{table_suffix} INSERT INTO rnd_{table_suffix} (n) SELECT n FROM rnd_{table_suffix} + + INSERT INTO seq_{table_suffix} (n) SELECT number/pi() FROM system.numbers LIMIT 100000 SETTINGS max_threads=1 + INSERT INTO mon_{table_suffix} (n) SELECT number+sin(number) FROM system.numbers LIMIT 100000 SETTINGS max_threads=1 + INSERT INTO rnd_{table_suffix} (n) SELECT (rand() - 4294967295)/pi() FROM system.numbers LIMIT 100000 SETTINGS max_threads=1 - INSERT INTO seq_{table_suffix} (n) SELECT number/pi() FROM system.numbers SETTINGS max_threads=1 - INSERT INTO mon_{table_suffix} (n) SELECT number+sin(number) FROM system.numbers SETTINGS max_threads=1 - INSERT INTO rnd_{table_suffix} (n) SELECT (rand() - 4294967295)/pi() FROM system.numbers SETTINGS max_threads=1 - - - SELECT count(n) FROM seq_{table_suffix} SETTINGS max_threads=1 - SELECT count(n) FROM mon_{table_suffix} SETTINGS max_threads=1 - SELECT count(n) FROM rnd_{table_suffix} SETTINGS max_threads=1 + + SELECT count(n) FROM seq_{table_suffix} LIMIT 100000 SETTINGS max_threads=1 + SELECT count(n) FROM mon_{table_suffix} LIMIT 100000 SETTINGS max_threads=1 + SELECT count(n) FROM rnd_{table_suffix} LIMIT 100000 SETTINGS max_threads=1 DROP TABLE IF EXISTS seq_{table_suffix} From 9f9ba3a06f0c245dd49029274999a82ea4e36df8 Mon Sep 17 00:00:00 2001 From: chertus Date: Fri, 26 Jul 2019 20:43:42 +0300 Subject: [PATCH 0392/1165] restore cropped names in JOIN ON section for distributed queries --- .../TranslateQualifiedNamesVisitor.cpp | 10 ++++++ .../TranslateQualifiedNamesVisitor.h | 11 ++++++ dbms/src/Parsers/ASTIdentifier.cpp | 9 +++++ dbms/src/Parsers/ASTIdentifier.h | 1 + dbms/src/Storages/StorageDistributed.cpp | 15 ++++++-- .../00974_distributed_join_on.reference | 8 +++++ .../0_stateless/00974_distributed_join_on.sql | 34 +++++++++++++++++++ 7 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00974_distributed_join_on.reference create mode 100644 dbms/tests/queries/0_stateless/00974_distributed_join_on.sql diff --git a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp index 1b063bc4625..34b59d4f993 100644 --- a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp +++ b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.cpp @@ -267,4 +267,14 @@ void TranslateQualifiedNamesMatcher::extractJoinUsingColumns(const ASTPtr ast, D } } +void RestoreQualifiedNamesData::visit(ASTIdentifier & identifier, ASTPtr & ast) +{ + if (IdentifierSemantic::getColumnName(identifier) && + IdentifierSemantic::getMembership(identifier)) + { + ast = identifier.clone(); + ast->as()->restoreCompoundName(); + } +} + } diff --git a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.h b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.h index 346c39b3344..413651ea843 100644 --- a/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.h +++ b/dbms/src/Interpreters/TranslateQualifiedNamesVisitor.h @@ -66,4 +66,15 @@ private: /// It finds columns and translate their names to the normal form. Expand asterisks and qualified asterisks with column names. using TranslateQualifiedNamesVisitor = TranslateQualifiedNamesMatcher::Visitor; +/// Restore ASTIdentifiers to long form +struct RestoreQualifiedNamesData +{ + using TypeToVisit = ASTIdentifier; + + void visit(ASTIdentifier & identifier, ASTPtr & ast); +}; + +using RestoreQualifiedNamesMatcher = OneTypeMatcher; +using RestoreQualifiedNamesVisitor = InDepthNodeVisitor; + } diff --git a/dbms/src/Parsers/ASTIdentifier.cpp b/dbms/src/Parsers/ASTIdentifier.cpp index 6b0329409a3..fe806ce795a 100644 --- a/dbms/src/Parsers/ASTIdentifier.cpp +++ b/dbms/src/Parsers/ASTIdentifier.cpp @@ -43,6 +43,15 @@ void ASTIdentifier::setShortName(const String & new_name) semantic->special = special; } +void ASTIdentifier::restoreCompoundName() +{ + if (name_parts.empty()) + return; + name = name_parts[0]; + for (size_t i = 1; i < name_parts.size(); ++i) + name += '.' + name_parts[i]; +} + void ASTIdentifier::formatImplWithoutAlias(const FormatSettings & settings, FormatState &, FormatStateStacked) const { auto format_element = [&](const String & elem_name) diff --git a/dbms/src/Parsers/ASTIdentifier.h b/dbms/src/Parsers/ASTIdentifier.h index 434f84eb77e..01f7766f1ef 100644 --- a/dbms/src/Parsers/ASTIdentifier.h +++ b/dbms/src/Parsers/ASTIdentifier.h @@ -38,6 +38,7 @@ public: bool isShort() const { return name_parts.empty() || name == name_parts.back(); } void setShortName(const String & new_name); + void restoreCompoundName(); const String & shortName() const { diff --git a/dbms/src/Storages/StorageDistributed.cpp b/dbms/src/Storages/StorageDistributed.cpp index 27ceb1f45db..7b810484d1c 100644 --- a/dbms/src/Storages/StorageDistributed.cpp +++ b/dbms/src/Storages/StorageDistributed.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -78,10 +79,20 @@ namespace ASTPtr rewriteSelectQuery(const ASTPtr & query, const std::string & database, const std::string & table, ASTPtr table_function_ptr = nullptr) { auto modified_query_ast = query->clone(); + + ASTSelectQuery & select_query = modified_query_ast->as(); + + /// restore long column names in JOIN ON expressions + if (auto tables = select_query.tables()) + { + RestoreQualifiedNamesVisitor::Data data; + RestoreQualifiedNamesVisitor(data).visit(tables); + } + if (table_function_ptr) - modified_query_ast->as().addTableFunction(table_function_ptr); + select_query.addTableFunction(table_function_ptr); else - modified_query_ast->as().replaceDatabaseAndTable(database, table); + select_query.replaceDatabaseAndTable(database, table); return modified_query_ast; } diff --git a/dbms/tests/queries/0_stateless/00974_distributed_join_on.reference b/dbms/tests/queries/0_stateless/00974_distributed_join_on.reference new file mode 100644 index 00000000000..b4628801267 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_distributed_join_on.reference @@ -0,0 +1,8 @@ +1 +1 +1 +1 +1 +1 +42 42 +42 42 diff --git a/dbms/tests/queries/0_stateless/00974_distributed_join_on.sql b/dbms/tests/queries/0_stateless/00974_distributed_join_on.sql new file mode 100644 index 00000000000..355d9f81e82 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_distributed_join_on.sql @@ -0,0 +1,34 @@ +DROP TABLE IF EXISTS source_table1; +DROP TABLE IF EXISTS source_table2; +DROP TABLE IF EXISTS distributed_table1; +DROP TABLE IF EXISTS distributed_table2; + +CREATE TABLE source_table1 (a Int64, b String) ENGINE = Memory; +CREATE TABLE source_table2 (c Int64, d String) ENGINE = Memory; + +INSERT INTO source_table1 VALUES (42, 'qwe'); +INSERT INTO source_table2 VALUES (42, 'qwe'); + +CREATE TABLE distributed_table1 AS source_table1 +ENGINE = Distributed('test_shard_localhost', currentDatabase(), source_table1); + +CREATE TABLE distributed_table2 AS source_table2 +ENGINE = Distributed('test_shard_localhost', currentDatabase(), source_table2); + +SET prefer_localhost_replica = 1; +SELECT 1 FROM distributed_table1 AS t1 GLOBAL JOIN distributed_table2 AS t2 ON t1.a = t2.c LIMIT 1; +SELECT 1 FROM distributed_table1 AS t1 GLOBAL JOIN distributed_table2 AS t2 ON t2.c = t1.a LIMIT 1; +SELECT 1 FROM distributed_table1 AS t1 GLOBAL JOIN distributed_table1 AS t2 ON t1.a = t2.a LIMIT 1; + +SET prefer_localhost_replica = 0; +SELECT 1 FROM distributed_table1 AS t1 GLOBAL JOIN distributed_table2 AS t2 ON t1.a = t2.c LIMIT 1; +SELECT 1 FROM distributed_table1 AS t1 GLOBAL JOIN distributed_table2 AS t2 ON t2.c = t1.a LIMIT 1; +SELECT 1 FROM distributed_table1 AS t1 GLOBAL JOIN distributed_table1 AS t2 ON t1.a = t2.a LIMIT 1; + +SELECT t1.a as t1_a, t2.a as t2_a FROM source_table1 AS t1 JOIN source_table1 AS t2 ON t1_a = t2_a LIMIT 1; +SELECT t1.a as t1_a, t2.a as t2_a FROM distributed_table1 AS t1 GLOBAL JOIN distributed_table1 AS t2 ON t1_a = t2_a LIMIT 1; + +DROP TABLE source_table1; +DROP TABLE source_table2; +DROP TABLE distributed_table1; +DROP TABLE distributed_table2; From b1d981ec3ae4fb30f8a6640163bf3024ee006cf7 Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Sat, 27 Jul 2019 01:18:27 +0300 Subject: [PATCH 0393/1165] better pipeline while reading in pk_order --- .../Interpreters/InterpreterSelectQuery.cpp | 58 +++++++------------ .../src/Interpreters/InterpreterSelectQuery.h | 3 +- .../MergeTree/MergeTreeDataSelectExecutor.cpp | 16 +++-- dbms/src/Storages/SelectQueryInfo.h | 5 +- .../00940_order_by_pk_order.reference | 35 +++++++++++ .../0_stateless/00940_order_by_pk_order.sql | 26 +++++++++ 6 files changed, 97 insertions(+), 46 deletions(-) diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.cpp b/dbms/src/Interpreters/InterpreterSelectQuery.cpp index a9f98da9606..6f444fa8aea 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSelectQuery.cpp @@ -535,19 +535,13 @@ InterpreterSelectQuery::analyzeExpressions(QueryProcessingStage::Enum from_stage } } + /// If there is aggregation, we execute expressions in SELECT and ORDER BY on the initiating server, otherwise on the source servers. query_analyzer->appendSelect(chain, dry_run || (res.need_aggregate ? !res.second_stage : !res.first_stage)); res.selected_columns = chain.getLastStep().required_output; - res.before_select = chain.getLastActions(); + res.has_order_by = query_analyzer->appendOrderBy(chain, dry_run || (res.need_aggregate ? !res.second_stage : !res.first_stage)); + res.before_order_and_select = chain.getLastActions(); chain.addStep(); - /// If there is aggregation, we execute expressions in SELECT and ORDER BY on the initiating server, otherwise on the source servers. - if (query_analyzer->appendOrderBy(chain, dry_run || (res.need_aggregate ? !res.second_stage : !res.first_stage))) - { - res.has_order_by = true; - res.before_order = chain.getLastActions(); - chain.addStep(); - } - if (query_analyzer->appendLimitBy(chain, dry_run || !res.second_stage)) { res.has_limit_by = true; @@ -654,8 +648,7 @@ static UInt64 getLimitForSorting(const ASTSelectQuery & query, const Context & c } -static SortingInfoPtr optimizeSortingWithPK(const MergeTreeData & merge_tree, const ASTSelectQuery & query, - const Context & context, const ExpressionActionsPtr & expressions) +static SortingInfoPtr optimizeSortingWithPK(const MergeTreeData & merge_tree, const ASTSelectQuery & query, const Context & context) { if (!merge_tree.hasSortingKey()) return {}; @@ -667,11 +660,19 @@ static SortingInfoPtr optimizeSortingWithPK(const MergeTreeData & merge_tree, co const auto & sorting_key_columns = merge_tree.getSortingKeyColumns(); size_t prefix_size = std::min(order_descr.size(), sorting_key_columns.size()); + auto is_virtual_column = [](const String & column_name) + { + return column_name == "_part" || column_name == "_part_index" + || column_name == "_partition_id" || column_name == "_sample_factor"; + }; + auto order_by_expr = query.orderBy(); - auto syntax_result = SyntaxAnalyzer(context).analyze(order_by_expr, - expressions->getRequiredColumnsWithTypes(), expressions->getSampleBlock().getNames()); + auto syntax_result = SyntaxAnalyzer(context).analyze(order_by_expr, merge_tree.getColumns().getAll()); for (size_t i = 0; i < prefix_size; ++i) { + if (is_virtual_column(order_descr[i].column_name)) + break; + /// Read in pk order in case of exact match with order key element /// or in some simple cases when order key element is wrapped into monotonic function. int current_direction = order_descr[i].direction; @@ -730,7 +731,7 @@ static SortingInfoPtr optimizeSortingWithPK(const MergeTreeData & merge_tree, co if (prefix_order_descr.empty()) return {}; - return std::make_shared(std::move(prefix_order_descr), expressions, read_direction); + return std::make_shared(std::move(prefix_order_descr), read_direction); } @@ -792,6 +793,11 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS } SortingInfoPtr sorting_info; + if (settings.optimize_pk_order && storage && query.orderBy() && !query.groupBy() && !query.final()) + { + if (const MergeTreeData * merge_tree_data = dynamic_cast(storage.get())) + sorting_info = optimizeSortingWithPK(*merge_tree_data, query, context); + } if (dry_run) { @@ -805,12 +811,6 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS if (storage && expressions.filter_info && expressions.prewhere_info) throw Exception("PREWHERE is not supported if the table is filtered by row-level security expression", ErrorCodes::ILLEGAL_PREWHERE); - if (settings.optimize_pk_order && storage && query.orderBy() && !query.groupBy() && !query.final()) - { - if (const MergeTreeData * merge_tree_data = dynamic_cast(storage.get())) - sorting_info = optimizeSortingWithPK(*merge_tree_data, query,context, expressions.before_order); - } - if (expressions.prewhere_info) { if constexpr (pipeline_with_processors) @@ -847,12 +847,6 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS if (storage && expressions.filter_info && expressions.prewhere_info) throw Exception("PREWHERE is not supported if the table is filtered by row-level security expression", ErrorCodes::ILLEGAL_PREWHERE); - if (settings.optimize_pk_order && storage && query.orderBy() && !query.groupBy() && !query.final()) - { - if (const MergeTreeData * merge_tree_data = dynamic_cast(storage.get())) - sorting_info = optimizeSortingWithPK(*merge_tree_data, query,context, expressions.before_order); - } - /** Read the data from Storage. from_stage - to what stage the request was completed in Storage. */ executeFetchColumns(from_stage, pipeline, sorting_info, expressions.prewhere_info, expressions.columns_to_remove_after_prewhere); @@ -960,7 +954,7 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS executeAggregation(pipeline, expressions.before_aggregation, aggregate_overflow_row, aggregate_final); else { - executeExpression(pipeline, expressions.before_select); + executeExpression(pipeline, expressions.before_order_and_select); executeDistinct(pipeline, true, expressions.selected_columns); } @@ -972,11 +966,7 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS if (!expressions.second_stage && !expressions.need_aggregate && !expressions.has_having) { if (expressions.has_order_by) - { - if (!query_info.sorting_info) // Otherwise we have executed expressions while reading - executeExpression(pipeline, expressions.before_order); executeOrder(pipeline, query_info.sorting_info); - } if (expressions.has_order_by && query.limitLength()) executeDistinct(pipeline, false, expressions.selected_columns); @@ -1030,7 +1020,7 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS else if (expressions.has_having) executeHaving(pipeline, expressions.before_having); - executeExpression(pipeline, expressions.before_select); + executeExpression(pipeline, expressions.before_order_and_select); executeDistinct(pipeline, true, expressions.selected_columns); need_second_distinct_pass = query.distinct && pipeline.hasMixedStreams(); @@ -1071,11 +1061,7 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS if (!expressions.first_stage && !expressions.need_aggregate && !(query.group_by_with_totals && !aggregate_final)) executeMergeSorted(pipeline); else /// Otherwise, just sort. - { - if (!query_info.sorting_info) // Otherwise we have executed them while reading - executeExpression(pipeline, expressions.before_order); executeOrder(pipeline, query_info.sorting_info); - } } /** Optimization - if there are several sources and there is LIMIT, then first apply the preliminary LIMIT, diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.h b/dbms/src/Interpreters/InterpreterSelectQuery.h index aaed7ce0a45..f6f3c0baf19 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.h +++ b/dbms/src/Interpreters/InterpreterSelectQuery.h @@ -152,8 +152,7 @@ private: ExpressionActionsPtr before_where; ExpressionActionsPtr before_aggregation; ExpressionActionsPtr before_having; - ExpressionActionsPtr before_order; - ExpressionActionsPtr before_select; + ExpressionActionsPtr before_order_and_select; ExpressionActionsPtr before_limit_by; ExpressionActionsPtr final_projection; diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index 22b97184d53..e85e017c47e 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -973,13 +973,19 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsPKOrd streams_per_thread.push_back(source_stream); } - if (sorting_info->actions && !sorting_info->actions->getActions().empty()) - for (auto & stream : streams_per_thread) - stream = std::make_shared(stream, sorting_info->actions); - if (streams_per_thread.size() > 1) + { + SortDescription sort_description; + for (size_t j = 0; j < query_info.sorting_info->prefix_order_descr.size(); ++j) + sort_description.emplace_back(data.sorting_key_columns[j], + sorting_info->direction, 1); + + for (auto & stream : streams_per_thread) + stream = std::make_shared(stream, data.sorting_key_expr); + streams.push_back(std::make_shared( - streams_per_thread, sorting_info->prefix_order_descr, max_block_size)); + streams_per_thread, sort_description, max_block_size)); + } else streams.push_back(streams_per_thread.at(0)); } diff --git a/dbms/src/Storages/SelectQueryInfo.h b/dbms/src/Storages/SelectQueryInfo.h index bf1eeb98833..74e28ede679 100644 --- a/dbms/src/Storages/SelectQueryInfo.h +++ b/dbms/src/Storages/SelectQueryInfo.h @@ -37,11 +37,10 @@ struct FilterInfo struct SortingInfo { SortDescription prefix_order_descr; - ExpressionActionsPtr actions; int direction; - SortingInfo(const SortDescription & prefix_order_descr_, const ExpressionActionsPtr & actions_, int direction_) - : prefix_order_descr(prefix_order_descr_), actions(actions_), direction(direction_) {} + SortingInfo(const SortDescription & prefix_order_descr_, int direction_) + : prefix_order_descr(prefix_order_descr_), direction(direction_) {} }; using PrewhereInfoPtr = std::shared_ptr; diff --git a/dbms/tests/queries/0_stateless/00940_order_by_pk_order.reference b/dbms/tests/queries/0_stateless/00940_order_by_pk_order.reference index fbd0257c0b1..8c594b6f683 100644 --- a/dbms/tests/queries/0_stateless/00940_order_by_pk_order.reference +++ b/dbms/tests/queries/0_stateless/00940_order_by_pk_order.reference @@ -163,3 +163,38 @@ 1 3 103 1 2 102 1 1 101 +2019-05-05 00:00:00 +2019-05-05 00:00:00 +2019-05-05 00:00:00 +2019-05-05 00:00:00 +2019-05-05 00:00:00 +2019-05-05 00:00:00 -1249512288 +2019-05-05 00:00:00 -916059969 +2019-05-05 00:00:00 -859523951 +2019-05-05 00:00:00 -45363190 +2019-05-05 00:00:00 345522721 +2019-05-14 00:00:00 99 +2019-05-14 00:00:00 89 +2019-05-14 00:00:00 79 +2019-05-14 00:00:00 69 +2019-05-14 00:00:00 59 +2019-05-14 00:00:00 99 +2019-05-14 00:00:00 89 +2019-05-14 00:00:00 79 +2019-05-14 00:00:00 69 +2019-05-14 00:00:00 59 +2019-05-14 00:00:00 99 +2019-05-14 00:00:00 89 +2019-05-14 00:00:00 79 +2019-05-14 00:00:00 69 +2019-05-14 00:00:00 59 +2019-05-05 00:00:00 +2019-05-05 00:00:00 +2019-05-05 00:00:00 +2019-05-05 00:00:00 +2019-05-05 00:00:00 +1 5 +1 5 +1 5 +1 3 +1 3 diff --git a/dbms/tests/queries/0_stateless/00940_order_by_pk_order.sql b/dbms/tests/queries/0_stateless/00940_order_by_pk_order.sql index 20af48de2f5..7c370563ed7 100644 --- a/dbms/tests/queries/0_stateless/00940_order_by_pk_order.sql +++ b/dbms/tests/queries/0_stateless/00940_order_by_pk_order.sql @@ -28,3 +28,29 @@ SELECT a, b, c FROM test.pk_order ORDER BY a, b DESC, c DESC; SELECT a, b, c FROM test.pk_order ORDER BY a DESC, b DESC, c DESC; DROP TABLE IF EXISTS test.pk_order; + +CREATE TABLE pk_order (d DateTime, a Int32, b Int32) ENGINE = MergeTree ORDER BY (d, a) + PARTITION BY toDate(d) SETTINGS index_granularity=1; + +INSERT INTO pk_order + SELECT toDateTime('2019-05-05 00:00:00') + INTERVAL number % 10 DAY, number, intHash32(number) from numbers(100); + +set max_block_size = 1; + +-- Currently checking number of read rows while reading in pk order not working precise. TODO: fix it. +-- SET max_rows_to_read = 10; + +SELECT d FROM pk_order ORDER BY d LIMIT 5; +SELECT d, b FROM pk_order ORDER BY d, b LIMIT 5; +SELECT d, a FROM pk_order ORDER BY d DESC, a DESC LIMIT 5; +SELECT d, a FROM pk_order ORDER BY d DESC, -a LIMIT 5; +SELECT d, a FROM pk_order ORDER BY d DESC, a DESC LIMIT 5; +SELECT toStartOfHour(d) as d1 FROM pk_order ORDER BY d1 LIMIT 5; + +DROP TABLE pk_order; + +CREATE TABLE pk_order (a Int, b Int) ENGINE = MergeTree ORDER BY (a / b); +INSERT INTO pk_order SELECT number % 10 + 1, number % 6 + 1 from numbers(100); +SELECT * FROM pk_order ORDER BY (a / b), a LIMIT 5; + + From cb85721cbaf5e0dda61bf4032d978612baeca7ba Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Sat, 27 Jul 2019 03:02:04 +0300 Subject: [PATCH 0394/1165] handle ExpressionAnalyzer exceptions, while trying to optimize order by, in case of complicated queries --- .../Interpreters/InterpreterSelectQuery.cpp | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.cpp b/dbms/src/Interpreters/InterpreterSelectQuery.cpp index 6f444fa8aea..3a5485e382b 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSelectQuery.cpp @@ -660,19 +660,10 @@ static SortingInfoPtr optimizeSortingWithPK(const MergeTreeData & merge_tree, co const auto & sorting_key_columns = merge_tree.getSortingKeyColumns(); size_t prefix_size = std::min(order_descr.size(), sorting_key_columns.size()); - auto is_virtual_column = [](const String & column_name) - { - return column_name == "_part" || column_name == "_part_index" - || column_name == "_partition_id" || column_name == "_sample_factor"; - }; - auto order_by_expr = query.orderBy(); - auto syntax_result = SyntaxAnalyzer(context).analyze(order_by_expr, merge_tree.getColumns().getAll()); + auto syntax_result = SyntaxAnalyzer(context).analyze(order_by_expr, merge_tree.getColumns().getAllPhysical()); for (size_t i = 0; i < prefix_size; ++i) { - if (is_virtual_column(order_descr[i].column_name)) - break; - /// Read in pk order in case of exact match with order key element /// or in some simple cases when order key element is wrapped into monotonic function. int current_direction = order_descr[i].direction; @@ -680,8 +671,18 @@ static SortingInfoPtr optimizeSortingWithPK(const MergeTreeData & merge_tree, co prefix_order_descr.push_back(order_descr[i]); else { - const auto & ast = query.orderBy()->children[0]; - auto actions = ExpressionAnalyzer(ast->children.at(0), syntax_result, context).getActions(false); + const auto & ast = query.orderBy()->children[i]; + ExpressionActionsPtr actions; + try + { + ExpressionAnalyzer(ast->children.at(0), syntax_result, context).getActions(false); + } + catch (const Exception &) + { + /// Can't analyze order expression at this stage. + /// May be some actions required for order will be executed later. + break; + } const auto & input_columns = actions->getRequiredColumnsWithTypes(); if (input_columns.size() != 1 || input_columns.front().name != sorting_key_columns[i]) From 60289cd7646abd68fd1e8c6ecf264e9ef4495541 Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Sat, 27 Jul 2019 03:15:22 +0300 Subject: [PATCH 0395/1165] fix optimizeSortingWithPK --- dbms/src/Interpreters/InterpreterSelectQuery.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.cpp b/dbms/src/Interpreters/InterpreterSelectQuery.cpp index 3a5485e382b..b6b371a9088 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSelectQuery.cpp @@ -675,7 +675,7 @@ static SortingInfoPtr optimizeSortingWithPK(const MergeTreeData & merge_tree, co ExpressionActionsPtr actions; try { - ExpressionAnalyzer(ast->children.at(0), syntax_result, context).getActions(false); + actions = ExpressionAnalyzer(ast->children.at(0), syntax_result, context).getActions(false); } catch (const Exception &) { From 12dcfe1f253b8fcf087c94adc9d13018107b32df Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Sat, 27 Jul 2019 03:33:47 +0300 Subject: [PATCH 0396/1165] reduce number of read rows while reading in reverse order --- dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index e85e017c47e..667178d940e 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -826,8 +826,8 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsPKOrd auto split_ranges = [max_block_size](const auto & ranges, size_t rows_granularity, size_t num_marks_in_part) { /// Constants is just a guess. - const size_t min_rows_in_range = max_block_size * 4; - const size_t max_num_ranges = 32; + const size_t min_rows_in_range = max_block_size; + const size_t max_num_ranges = 64; size_t min_marks_in_range = std::max( (min_rows_in_range + rows_granularity - 1) / rows_granularity, From 1118ce04b951271ddac4619a4d86476a9cfe7ffa Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Sat, 27 Jul 2019 18:36:40 +0300 Subject: [PATCH 0397/1165] fixed --- dbms/src/Storages/IStorage.cpp | 10 ++++++++++ dbms/src/Storages/IStorage.h | 2 ++ .../MergeTree/MergedColumnOnlyOutputStream.cpp | 17 ++++++++++------- .../MergeTree/MergedColumnOnlyOutputStream.h | 1 + .../MergeTree/StorageFromMergeTreeDataPart.h | 2 +- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/dbms/src/Storages/IStorage.cpp b/dbms/src/Storages/IStorage.cpp index b93c6ae478c..07b2b94c191 100644 --- a/dbms/src/Storages/IStorage.cpp +++ b/dbms/src/Storages/IStorage.cpp @@ -25,6 +25,11 @@ IStorage::IStorage(ColumnsDescription columns_) setColumns(std::move(columns_)); } +IStorage::IStorage(ColumnsDescription columns_, ColumnsDescription virtuals_) : virtuals(std::move(virtuals_)) +{ + setColumns(std::move(columns_)); +} + IStorage::IStorage(ColumnsDescription columns_, ColumnsDescription virtuals_, IndicesDescription indices_) : virtuals(std::move(virtuals_)) { setColumns(std::move(columns_)); @@ -36,6 +41,11 @@ const ColumnsDescription & IStorage::getColumns() const return columns; } +const ColumnsDescription & IStorage::getVirtuals() const +{ + return virtuals; +} + const IndicesDescription & IStorage::getIndices() const { return indices; diff --git a/dbms/src/Storages/IStorage.h b/dbms/src/Storages/IStorage.h index a2f5199486f..38441c10ee9 100644 --- a/dbms/src/Storages/IStorage.h +++ b/dbms/src/Storages/IStorage.h @@ -64,6 +64,7 @@ class IStorage : public std::enable_shared_from_this public: IStorage() = default; explicit IStorage(ColumnsDescription columns_); + IStorage(ColumnsDescription columns_, ColumnsDescription virtuals_); IStorage(ColumnsDescription columns_, ColumnsDescription virtuals_, IndicesDescription indices_); virtual ~IStorage() = default; @@ -102,6 +103,7 @@ public: public: /// thread-unsafe part. lockStructure must be acquired const ColumnsDescription & getColumns() const; /// returns combined set of columns + const ColumnsDescription & getVirtuals() const; const IndicesDescription & getIndices() const; /// NOTE: these methods should include virtual columns, diff --git a/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp b/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp index faf82321c83..d8eaef2a781 100644 --- a/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp @@ -85,14 +85,15 @@ void MergedColumnOnlyOutputStream::write(const Block & block) { /// Creating block for update Block indices_update_block(skip_indexes_columns); + size_t skip_index_current_mark = 0; + /// Filling and writing skip indices like in IMergedBlockOutputStream::writeColumn - for (size_t i = 0; i < skip_indices.size(); ++i) + for (size_t i = 0; i < storage.skip_indices.size(); ++i) { - const auto index = skip_indices[i]; + const auto index = storage.skip_indices[i]; auto & stream = *skip_indices_streams[i]; size_t prev_pos = 0; - - size_t current_mark = 0; + skip_index_current_mark = skip_index_mark; while (prev_pos < rows) { UInt64 limit = 0; @@ -102,7 +103,7 @@ void MergedColumnOnlyOutputStream::write(const Block & block) } else { - limit = index_granularity.getMarkRows(current_mark); + limit = index_granularity.getMarkRows(skip_index_current_mark); if (skip_indices_aggregators[i]->empty()) { skip_indices_aggregators[i] = index->createIndexAggregator(); @@ -115,8 +116,10 @@ void MergedColumnOnlyOutputStream::write(const Block & block) writeIntBinary(stream.compressed.offset(), stream.marks); /// Actually this numbers is redundant, but we have to store them /// to be compatible with normal .mrk2 file format - if (storage.index_granularity_info.is_adaptive) + if (storage.canUseAdaptiveGranularity()) writeIntBinary(1UL, stream.marks); + + ++skip_index_current_mark; } } @@ -135,9 +138,9 @@ void MergedColumnOnlyOutputStream::write(const Block & block) } } prev_pos = pos; - current_mark++; } } + skip_index_mark = skip_index_current_mark; } size_t new_index_offset = 0; diff --git a/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.h b/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.h index cdcbe837220..645e9f2ff36 100644 --- a/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.h +++ b/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.h @@ -32,6 +32,7 @@ private: bool initialized = false; bool sync; bool skip_offsets; + size_t skip_index_mark = 0; std::vector skip_indices; std::vector> skip_indices_streams; diff --git a/dbms/src/Storages/MergeTree/StorageFromMergeTreeDataPart.h b/dbms/src/Storages/MergeTree/StorageFromMergeTreeDataPart.h index c5d12b2fc98..83582c9779f 100644 --- a/dbms/src/Storages/MergeTree/StorageFromMergeTreeDataPart.h +++ b/dbms/src/Storages/MergeTree/StorageFromMergeTreeDataPart.h @@ -40,7 +40,7 @@ public: protected: StorageFromMergeTreeDataPart(const MergeTreeData::DataPartPtr & part_) - : IStorage(part_->storage.getColumns(), part_->storage.getIndices()), part(part_) + : IStorage(part_->storage.getColumns(), part_->storage.getVirtuals(), part_->storage.getIndices()), part(part_) {} private: From 98c3ff92ae293a5326f188e6f8bba741e7040cf9 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 27 Jul 2019 20:04:26 +0300 Subject: [PATCH 0398/1165] Fixed non-standard build --- dbms/src/Common/QueryProfiler.cpp | 1 + dbms/src/Core/Defines.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index a3d88af6007..5aafa35df94 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -176,6 +176,7 @@ QueryProfilerBase::QueryProfilerBase(const Int32 thread_id, const throw; } #else + UNUSED(thread_id, clock_type, period, pause_signal); throw Exception("QueryProfiler cannot work with stock libunwind", ErrorCodes::NOT_IMPLEMENTED); #endif } diff --git a/dbms/src/Core/Defines.h b/dbms/src/Core/Defines.h index 1214b742803..b9f3563a9db 100644 --- a/dbms/src/Core/Defines.h +++ b/dbms/src/Core/Defines.h @@ -142,4 +142,4 @@ /// A macro for suppressing warnings about unused variables or function results. /// Useful for structured bindings which have no standard way to declare this. -#define UNUSED(X) (void) (X) +#define UNUSED(...) (void)(__VA_ARGS__) From 3765ee39e0d404024b0f2553cf0d1316ed8108d4 Mon Sep 17 00:00:00 2001 From: Vasily Nemkov Date: Sat, 27 Jul 2019 20:54:04 +0300 Subject: [PATCH 0399/1165] Removed blank line --- dbms/tests/performance/codec_gorilla.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/dbms/tests/performance/codec_gorilla.xml b/dbms/tests/performance/codec_gorilla.xml index 8935599dd16..a807d5d9794 100644 --- a/dbms/tests/performance/codec_gorilla.xml +++ b/dbms/tests/performance/codec_gorilla.xml @@ -64,7 +64,6 @@ SELECT count(n) FROM mon_{table_suffix} LIMIT 100000 SETTINGS max_threads=1 SELECT count(n) FROM rnd_{table_suffix} LIMIT 100000 SETTINGS max_threads=1 - DROP TABLE IF EXISTS seq_{table_suffix} DROP TABLE IF EXISTS mon_{table_suffix} DROP TABLE IF EXISTS rnd_{table_suffix} From d61d489c2e14fc5fb16aee3be0254cf214a37818 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 28 Jul 2019 00:15:20 +0300 Subject: [PATCH 0400/1165] Removed from all performance tests #6179 --- dbms/tests/performance/base64.xml | 2 -- dbms/tests/performance/base64_hits.xml | 1 - dbms/tests/performance/codec_double_delta.xml | 2 -- dbms/tests/performance/codec_gorilla.xml | 2 -- dbms/tests/performance/consistent_hashes.xml | 2 -- dbms/tests/performance/count.xml | 1 - dbms/tests/performance/cryptographic_hashes.xml | 3 --- dbms/tests/performance/date_time.xml | 3 --- dbms/tests/performance/entropy.xml | 1 - dbms/tests/performance/float_parsing.xml | 1 - dbms/tests/performance/format_date_time.xml | 1 - dbms/tests/performance/general_purpose_hashes.xml | 3 --- dbms/tests/performance/group_array_moving_sum.xml | 1 - dbms/tests/performance/json_extract_rapidjson.xml | 2 -- dbms/tests/performance/json_extract_simdjson.xml | 2 -- dbms/tests/performance/merge_tree_many_partitions.xml | 1 - dbms/tests/performance/merge_tree_many_partitions_2.xml | 1 - dbms/tests/performance/merge_tree_simple_select.xml | 1 - dbms/tests/performance/number_formatting_formats.xml | 2 -- dbms/tests/performance/order_by_pk_order.xml | 1 - dbms/tests/performance/parse_engine_file.xml | 1 - dbms/tests/performance/right.xml | 1 - dbms/tests/performance/select_format.xml | 1 - dbms/tests/performance/set.xml | 2 -- dbms/tests/performance/string_sort.xml | 2 -- dbms/tests/performance/trim_numbers.xml | 1 - dbms/tests/performance/trim_urls.xml | 1 - dbms/tests/performance/trim_whitespace.xml | 1 - dbms/tests/performance/uniq.xml | 2 -- dbms/tests/performance/url_hits.xml | 1 - dbms/tests/performance/visit_param_extract_raw.xml | 1 - dbms/tests/performance/website.xml | 1 - 32 files changed, 48 deletions(-) diff --git a/dbms/tests/performance/base64.xml b/dbms/tests/performance/base64.xml index a479b10d48a..148015f9673 100644 --- a/dbms/tests/performance/base64.xml +++ b/dbms/tests/performance/base64.xml @@ -17,7 +17,6 @@ - string materialize('Hello, world!') materialize('This is a long string to test ClickHouse base64 functions impl..') @@ -25,7 +24,6 @@ - table numbers numbers_mt diff --git a/dbms/tests/performance/base64_hits.xml b/dbms/tests/performance/base64_hits.xml index be693a16bee..21b1b8185a0 100644 --- a/dbms/tests/performance/base64_hits.xml +++ b/dbms/tests/performance/base64_hits.xml @@ -21,7 +21,6 @@ - string SearchPhrase MobilePhoneModel diff --git a/dbms/tests/performance/codec_double_delta.xml b/dbms/tests/performance/codec_double_delta.xml index 35bdbe4c3c4..9224c4af3c8 100644 --- a/dbms/tests/performance/codec_double_delta.xml +++ b/dbms/tests/performance/codec_double_delta.xml @@ -1,5 +1,4 @@ - Codec DoubleDelta loop @@ -15,7 +14,6 @@ - table_suffix dd lz4 diff --git a/dbms/tests/performance/codec_gorilla.xml b/dbms/tests/performance/codec_gorilla.xml index a807d5d9794..3bb07862031 100644 --- a/dbms/tests/performance/codec_gorilla.xml +++ b/dbms/tests/performance/codec_gorilla.xml @@ -1,5 +1,4 @@ - Codec Gorilla loop @@ -15,7 +14,6 @@ - table_suffix g lz4 diff --git a/dbms/tests/performance/consistent_hashes.xml b/dbms/tests/performance/consistent_hashes.xml index b1c165428eb..93530850412 100644 --- a/dbms/tests/performance/consistent_hashes.xml +++ b/dbms/tests/performance/consistent_hashes.xml @@ -15,14 +15,12 @@ - hash_func yandexConsistentHash jumpConsistentHash - buckets 2 500 diff --git a/dbms/tests/performance/count.xml b/dbms/tests/performance/count.xml index 9ce3c0a98e4..da972c69059 100644 --- a/dbms/tests/performance/count.xml +++ b/dbms/tests/performance/count.xml @@ -1,5 +1,4 @@ - count loop diff --git a/dbms/tests/performance/cryptographic_hashes.xml b/dbms/tests/performance/cryptographic_hashes.xml index 2f5a0a1d779..a585dea3711 100644 --- a/dbms/tests/performance/cryptographic_hashes.xml +++ b/dbms/tests/performance/cryptographic_hashes.xml @@ -17,7 +17,6 @@ - crypto_hash_func MD5 SHA1 @@ -29,7 +28,6 @@ - string materialize('') toString(1000000000+number) @@ -37,7 +35,6 @@ - table numbers numbers_mt diff --git a/dbms/tests/performance/date_time.xml b/dbms/tests/performance/date_time.xml index b62cde40860..f7c36828fa2 100644 --- a/dbms/tests/performance/date_time.xml +++ b/dbms/tests/performance/date_time.xml @@ -15,7 +15,6 @@ - datetime_transform toSecond toMinute @@ -57,7 +56,6 @@ - date_transform toDayOfWeek toDayOfMonth @@ -86,7 +84,6 @@ - time_zone UTC Europe/Moscow diff --git a/dbms/tests/performance/entropy.xml b/dbms/tests/performance/entropy.xml index a7b8f76fcaf..ab302c00540 100644 --- a/dbms/tests/performance/entropy.xml +++ b/dbms/tests/performance/entropy.xml @@ -21,7 +21,6 @@ - args SearchEngineID SearchPhrase diff --git a/dbms/tests/performance/float_parsing.xml b/dbms/tests/performance/float_parsing.xml index 1cded361871..5cc7cafa6a1 100644 --- a/dbms/tests/performance/float_parsing.xml +++ b/dbms/tests/performance/float_parsing.xml @@ -20,7 +20,6 @@ - expr toString(1 / rand()) toString(rand() / 0xFFFFFFFF) diff --git a/dbms/tests/performance/format_date_time.xml b/dbms/tests/performance/format_date_time.xml index 0ecdb37734d..ed0dd056401 100644 --- a/dbms/tests/performance/format_date_time.xml +++ b/dbms/tests/performance/format_date_time.xml @@ -13,7 +13,6 @@ - format %F %T %H:%M:%S diff --git a/dbms/tests/performance/general_purpose_hashes.xml b/dbms/tests/performance/general_purpose_hashes.xml index c2462f8710b..bb75dfe950c 100644 --- a/dbms/tests/performance/general_purpose_hashes.xml +++ b/dbms/tests/performance/general_purpose_hashes.xml @@ -17,7 +17,6 @@ - gp_hash_func cityHash64 farmHash64 @@ -35,7 +34,6 @@ - string materialize('') toString(1000000000+number) @@ -43,7 +41,6 @@ - table numbers numbers_mt diff --git a/dbms/tests/performance/group_array_moving_sum.xml b/dbms/tests/performance/group_array_moving_sum.xml index d296da5dd11..ee2686c9af8 100644 --- a/dbms/tests/performance/group_array_moving_sum.xml +++ b/dbms/tests/performance/group_array_moving_sum.xml @@ -1,5 +1,4 @@ - Moving Sum loop diff --git a/dbms/tests/performance/json_extract_rapidjson.xml b/dbms/tests/performance/json_extract_rapidjson.xml index d9e152e7329..0979ed2ca32 100644 --- a/dbms/tests/performance/json_extract_rapidjson.xml +++ b/dbms/tests/performance/json_extract_rapidjson.xml @@ -17,13 +17,11 @@ - json '{"sparam":"test_string","nparam": 772}' - long_json '{"sparam":{"nested_1":"test_string","nested_2":"test_2"}, "nparam":8495, "fparam":{"nested_1":91.15,"nested_2":[334, 89.05, 1000.01]}, "bparam":false}' diff --git a/dbms/tests/performance/json_extract_simdjson.xml b/dbms/tests/performance/json_extract_simdjson.xml index 8b2128a686a..85d7e612e4c 100644 --- a/dbms/tests/performance/json_extract_simdjson.xml +++ b/dbms/tests/performance/json_extract_simdjson.xml @@ -21,13 +21,11 @@ - json '{"sparam":"test_string","nparam": 772}' - long_json '{"sparam":{"nested_1":"test_string","nested_2":"test_2"}, "nparam":8495, "fparam":{"nested_1":91.15,"nested_2":[334, 89.05, 1000.01]}, "bparam":false}' diff --git a/dbms/tests/performance/merge_tree_many_partitions.xml b/dbms/tests/performance/merge_tree_many_partitions.xml index 1b21bbcf780..8450a34dc59 100644 --- a/dbms/tests/performance/merge_tree_many_partitions.xml +++ b/dbms/tests/performance/merge_tree_many_partitions.xml @@ -1,5 +1,4 @@ - merge_tree_many_partitions loop CREATE TABLE bad_partitions (x UInt64) ENGINE = MergeTree PARTITION BY x ORDER BY x diff --git a/dbms/tests/performance/merge_tree_many_partitions_2.xml b/dbms/tests/performance/merge_tree_many_partitions_2.xml index a38a2cc0139..1ad06fcbf2f 100644 --- a/dbms/tests/performance/merge_tree_many_partitions_2.xml +++ b/dbms/tests/performance/merge_tree_many_partitions_2.xml @@ -1,5 +1,4 @@ - merge_tree_many_partitions_2 loop CREATE TABLE bad_partitions (a UInt64, b UInt64, c UInt64, d UInt64, e UInt64, f UInt64, g UInt64, h UInt64, i UInt64, j UInt64, k UInt64, l UInt64, m UInt64, n UInt64, o UInt64, p UInt64, q UInt64, r UInt64, s UInt64, t UInt64, u UInt64, v UInt64, w UInt64, x UInt64, y UInt64, z UInt64) ENGINE = MergeTree PARTITION BY x ORDER BY x diff --git a/dbms/tests/performance/merge_tree_simple_select.xml b/dbms/tests/performance/merge_tree_simple_select.xml index 3a303500f3a..5e482e0d44b 100644 --- a/dbms/tests/performance/merge_tree_simple_select.xml +++ b/dbms/tests/performance/merge_tree_simple_select.xml @@ -1,5 +1,4 @@ - merge_tree_simple_select loop diff --git a/dbms/tests/performance/number_formatting_formats.xml b/dbms/tests/performance/number_formatting_formats.xml index 7c9c4ea0fe9..7ad461d9026 100644 --- a/dbms/tests/performance/number_formatting_formats.xml +++ b/dbms/tests/performance/number_formatting_formats.xml @@ -1,5 +1,4 @@ - number_formatting_formats loop CREATE TABLE IF NOT EXISTS table_{format} (x UInt64) ENGINE = File(`{format}`) @@ -21,7 +20,6 @@ - format TabSeparated CSV diff --git a/dbms/tests/performance/order_by_pk_order.xml b/dbms/tests/performance/order_by_pk_order.xml index 7577d428160..f52c9a0ce55 100644 --- a/dbms/tests/performance/order_by_pk_order.xml +++ b/dbms/tests/performance/order_by_pk_order.xml @@ -1,5 +1,4 @@ - order_by_pk_order loop diff --git a/dbms/tests/performance/parse_engine_file.xml b/dbms/tests/performance/parse_engine_file.xml index 6bd4af0b45b..dbd0ae5dc4e 100644 --- a/dbms/tests/performance/parse_engine_file.xml +++ b/dbms/tests/performance/parse_engine_file.xml @@ -23,7 +23,6 @@ - format TabSeparated TabSeparatedWithNames diff --git a/dbms/tests/performance/right.xml b/dbms/tests/performance/right.xml index 8d1304a4604..41772553eeb 100644 --- a/dbms/tests/performance/right.xml +++ b/dbms/tests/performance/right.xml @@ -21,7 +21,6 @@ - func right(URL, 16) substring(URL, greatest(minus(plus(length(URL), 1), 16), 1)) diff --git a/dbms/tests/performance/select_format.xml b/dbms/tests/performance/select_format.xml index c5ad1acd396..9b315199ac2 100644 --- a/dbms/tests/performance/select_format.xml +++ b/dbms/tests/performance/select_format.xml @@ -24,7 +24,6 @@ - format TabSeparated TabSeparatedRaw diff --git a/dbms/tests/performance/set.xml b/dbms/tests/performance/set.xml index 1e62840d8d1..3953a504522 100644 --- a/dbms/tests/performance/set.xml +++ b/dbms/tests/performance/set.xml @@ -20,14 +20,12 @@ - table system.numbers system.numbers_mt - size 1 16 diff --git a/dbms/tests/performance/string_sort.xml b/dbms/tests/performance/string_sort.xml index 7b33bb20d52..6a99eddb66c 100644 --- a/dbms/tests/performance/string_sort.xml +++ b/dbms/tests/performance/string_sort.xml @@ -18,7 +18,6 @@ - str1 URL Referer @@ -29,7 +28,6 @@ - str2 URL Referer diff --git a/dbms/tests/performance/trim_numbers.xml b/dbms/tests/performance/trim_numbers.xml index 48fdb710cd9..9f45861b480 100644 --- a/dbms/tests/performance/trim_numbers.xml +++ b/dbms/tests/performance/trim_numbers.xml @@ -17,7 +17,6 @@ - func trim( ltrim( diff --git a/dbms/tests/performance/trim_urls.xml b/dbms/tests/performance/trim_urls.xml index 2b672d9d97d..3f1a5426b4c 100644 --- a/dbms/tests/performance/trim_urls.xml +++ b/dbms/tests/performance/trim_urls.xml @@ -21,7 +21,6 @@ - func trim( ltrim( diff --git a/dbms/tests/performance/trim_whitespace.xml b/dbms/tests/performance/trim_whitespace.xml index 26d89859432..98562e24510 100644 --- a/dbms/tests/performance/trim_whitespace.xml +++ b/dbms/tests/performance/trim_whitespace.xml @@ -16,7 +16,6 @@ - func value trimLeft(value) diff --git a/dbms/tests/performance/uniq.xml b/dbms/tests/performance/uniq.xml index c44a4e2ca58..c4a6407295b 100644 --- a/dbms/tests/performance/uniq.xml +++ b/dbms/tests/performance/uniq.xml @@ -23,7 +23,6 @@ - key 1 SearchEngineID @@ -33,7 +32,6 @@ - func sum uniq diff --git a/dbms/tests/performance/url_hits.xml b/dbms/tests/performance/url_hits.xml index a251a2706b8..475c3aaf4d5 100644 --- a/dbms/tests/performance/url_hits.xml +++ b/dbms/tests/performance/url_hits.xml @@ -21,7 +21,6 @@ - func protocol domain diff --git a/dbms/tests/performance/visit_param_extract_raw.xml b/dbms/tests/performance/visit_param_extract_raw.xml index 02b8224c361..4e9603a7774 100644 --- a/dbms/tests/performance/visit_param_extract_raw.xml +++ b/dbms/tests/performance/visit_param_extract_raw.xml @@ -17,7 +17,6 @@ - param '{"myparam":"test_string"}' '{"myparam":{"nested_1":"test_string","nested_2":"test_2"}}' diff --git a/dbms/tests/performance/website.xml b/dbms/tests/performance/website.xml index 4cb350a60a1..02b4213e970 100644 --- a/dbms/tests/performance/website.xml +++ b/dbms/tests/performance/website.xml @@ -26,7 +26,6 @@ - table hits_10m_single hits_100m_single From 97f11a6a3cdbda939ecbbd0a19e2fc44ba962499 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 28 Jul 2019 00:17:06 +0300 Subject: [PATCH 0401/1165] Fixed typo #6179 --- dbms/tests/performance/codec_double_delta.xml | 2 +- dbms/tests/performance/codec_gorilla.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/tests/performance/codec_double_delta.xml b/dbms/tests/performance/codec_double_delta.xml index 9224c4af3c8..5d25380c9c3 100644 --- a/dbms/tests/performance/codec_double_delta.xml +++ b/dbms/tests/performance/codec_double_delta.xml @@ -56,7 +56,7 @@ INSERT INTO mon_{table_suffix} (n) SELECT number*67+(rand()%67) FROM system.numbers LIMIT 100000 SETTINGS max_threads=1 INSERT INTO rnd_{table_suffix} (n) SELECT rand() FROM system.numbers LIMIT 100000 SETTINGS max_threads=1 - SELECT count(n) FROM seq_{table_suffix} LIMIT 1000000 SETTINGS max_threads=1 SELECT count(n) FROM mon_{table_suffix} LIMIT 1000000 SETTINGS max_threads=1 diff --git a/dbms/tests/performance/codec_gorilla.xml b/dbms/tests/performance/codec_gorilla.xml index 3bb07862031..ccc00d5df42 100644 --- a/dbms/tests/performance/codec_gorilla.xml +++ b/dbms/tests/performance/codec_gorilla.xml @@ -56,7 +56,7 @@ INSERT INTO mon_{table_suffix} (n) SELECT number+sin(number) FROM system.numbers LIMIT 100000 SETTINGS max_threads=1 INSERT INTO rnd_{table_suffix} (n) SELECT (rand() - 4294967295)/pi() FROM system.numbers LIMIT 100000 SETTINGS max_threads=1 - SELECT count(n) FROM seq_{table_suffix} LIMIT 100000 SETTINGS max_threads=1 SELECT count(n) FROM mon_{table_suffix} LIMIT 100000 SETTINGS max_threads=1 From febc935fa8cb0718e8ed0d046e59ef1e8659e15a Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 28 Jul 2019 00:17:44 +0300 Subject: [PATCH 0402/1165] Revert "Removed from all performance tests #6179" This reverts commit d61d489c2e14fc5fb16aee3be0254cf214a37818. --- dbms/tests/performance/base64.xml | 2 ++ dbms/tests/performance/base64_hits.xml | 1 + dbms/tests/performance/codec_double_delta.xml | 2 ++ dbms/tests/performance/codec_gorilla.xml | 2 ++ dbms/tests/performance/consistent_hashes.xml | 2 ++ dbms/tests/performance/count.xml | 1 + dbms/tests/performance/cryptographic_hashes.xml | 3 +++ dbms/tests/performance/date_time.xml | 3 +++ dbms/tests/performance/entropy.xml | 1 + dbms/tests/performance/float_parsing.xml | 1 + dbms/tests/performance/format_date_time.xml | 1 + dbms/tests/performance/general_purpose_hashes.xml | 3 +++ dbms/tests/performance/group_array_moving_sum.xml | 1 + dbms/tests/performance/json_extract_rapidjson.xml | 2 ++ dbms/tests/performance/json_extract_simdjson.xml | 2 ++ dbms/tests/performance/merge_tree_many_partitions.xml | 1 + dbms/tests/performance/merge_tree_many_partitions_2.xml | 1 + dbms/tests/performance/merge_tree_simple_select.xml | 1 + dbms/tests/performance/number_formatting_formats.xml | 2 ++ dbms/tests/performance/order_by_pk_order.xml | 1 + dbms/tests/performance/parse_engine_file.xml | 1 + dbms/tests/performance/right.xml | 1 + dbms/tests/performance/select_format.xml | 1 + dbms/tests/performance/set.xml | 2 ++ dbms/tests/performance/string_sort.xml | 2 ++ dbms/tests/performance/trim_numbers.xml | 1 + dbms/tests/performance/trim_urls.xml | 1 + dbms/tests/performance/trim_whitespace.xml | 1 + dbms/tests/performance/uniq.xml | 2 ++ dbms/tests/performance/url_hits.xml | 1 + dbms/tests/performance/visit_param_extract_raw.xml | 1 + dbms/tests/performance/website.xml | 1 + 32 files changed, 48 insertions(+) diff --git a/dbms/tests/performance/base64.xml b/dbms/tests/performance/base64.xml index 148015f9673..a479b10d48a 100644 --- a/dbms/tests/performance/base64.xml +++ b/dbms/tests/performance/base64.xml @@ -17,6 +17,7 @@ + string materialize('Hello, world!') materialize('This is a long string to test ClickHouse base64 functions impl..') @@ -24,6 +25,7 @@ + table numbers numbers_mt diff --git a/dbms/tests/performance/base64_hits.xml b/dbms/tests/performance/base64_hits.xml index 21b1b8185a0..be693a16bee 100644 --- a/dbms/tests/performance/base64_hits.xml +++ b/dbms/tests/performance/base64_hits.xml @@ -21,6 +21,7 @@ + string SearchPhrase MobilePhoneModel diff --git a/dbms/tests/performance/codec_double_delta.xml b/dbms/tests/performance/codec_double_delta.xml index 5d25380c9c3..97c31587548 100644 --- a/dbms/tests/performance/codec_double_delta.xml +++ b/dbms/tests/performance/codec_double_delta.xml @@ -1,4 +1,5 @@ + Codec DoubleDelta loop @@ -14,6 +15,7 @@ + table_suffix dd lz4 diff --git a/dbms/tests/performance/codec_gorilla.xml b/dbms/tests/performance/codec_gorilla.xml index ccc00d5df42..a066055cbcc 100644 --- a/dbms/tests/performance/codec_gorilla.xml +++ b/dbms/tests/performance/codec_gorilla.xml @@ -1,4 +1,5 @@ + Codec Gorilla loop @@ -14,6 +15,7 @@ + table_suffix g lz4 diff --git a/dbms/tests/performance/consistent_hashes.xml b/dbms/tests/performance/consistent_hashes.xml index 93530850412..b1c165428eb 100644 --- a/dbms/tests/performance/consistent_hashes.xml +++ b/dbms/tests/performance/consistent_hashes.xml @@ -15,12 +15,14 @@ + hash_func yandexConsistentHash jumpConsistentHash + buckets 2 500 diff --git a/dbms/tests/performance/count.xml b/dbms/tests/performance/count.xml index da972c69059..9ce3c0a98e4 100644 --- a/dbms/tests/performance/count.xml +++ b/dbms/tests/performance/count.xml @@ -1,4 +1,5 @@ + count loop diff --git a/dbms/tests/performance/cryptographic_hashes.xml b/dbms/tests/performance/cryptographic_hashes.xml index a585dea3711..2f5a0a1d779 100644 --- a/dbms/tests/performance/cryptographic_hashes.xml +++ b/dbms/tests/performance/cryptographic_hashes.xml @@ -17,6 +17,7 @@ + crypto_hash_func MD5 SHA1 @@ -28,6 +29,7 @@ + string materialize('') toString(1000000000+number) @@ -35,6 +37,7 @@ + table numbers numbers_mt diff --git a/dbms/tests/performance/date_time.xml b/dbms/tests/performance/date_time.xml index f7c36828fa2..b62cde40860 100644 --- a/dbms/tests/performance/date_time.xml +++ b/dbms/tests/performance/date_time.xml @@ -15,6 +15,7 @@ + datetime_transform toSecond toMinute @@ -56,6 +57,7 @@ + date_transform toDayOfWeek toDayOfMonth @@ -84,6 +86,7 @@ + time_zone UTC Europe/Moscow diff --git a/dbms/tests/performance/entropy.xml b/dbms/tests/performance/entropy.xml index ab302c00540..a7b8f76fcaf 100644 --- a/dbms/tests/performance/entropy.xml +++ b/dbms/tests/performance/entropy.xml @@ -21,6 +21,7 @@ + args SearchEngineID SearchPhrase diff --git a/dbms/tests/performance/float_parsing.xml b/dbms/tests/performance/float_parsing.xml index 5cc7cafa6a1..1cded361871 100644 --- a/dbms/tests/performance/float_parsing.xml +++ b/dbms/tests/performance/float_parsing.xml @@ -20,6 +20,7 @@ + expr toString(1 / rand()) toString(rand() / 0xFFFFFFFF) diff --git a/dbms/tests/performance/format_date_time.xml b/dbms/tests/performance/format_date_time.xml index ed0dd056401..0ecdb37734d 100644 --- a/dbms/tests/performance/format_date_time.xml +++ b/dbms/tests/performance/format_date_time.xml @@ -13,6 +13,7 @@ + format %F %T %H:%M:%S diff --git a/dbms/tests/performance/general_purpose_hashes.xml b/dbms/tests/performance/general_purpose_hashes.xml index bb75dfe950c..c2462f8710b 100644 --- a/dbms/tests/performance/general_purpose_hashes.xml +++ b/dbms/tests/performance/general_purpose_hashes.xml @@ -17,6 +17,7 @@ + gp_hash_func cityHash64 farmHash64 @@ -34,6 +35,7 @@ + string materialize('') toString(1000000000+number) @@ -41,6 +43,7 @@ + table numbers numbers_mt diff --git a/dbms/tests/performance/group_array_moving_sum.xml b/dbms/tests/performance/group_array_moving_sum.xml index ee2686c9af8..d296da5dd11 100644 --- a/dbms/tests/performance/group_array_moving_sum.xml +++ b/dbms/tests/performance/group_array_moving_sum.xml @@ -1,4 +1,5 @@ + Moving Sum loop diff --git a/dbms/tests/performance/json_extract_rapidjson.xml b/dbms/tests/performance/json_extract_rapidjson.xml index 0979ed2ca32..d9e152e7329 100644 --- a/dbms/tests/performance/json_extract_rapidjson.xml +++ b/dbms/tests/performance/json_extract_rapidjson.xml @@ -17,11 +17,13 @@ + json '{"sparam":"test_string","nparam": 772}' + long_json '{"sparam":{"nested_1":"test_string","nested_2":"test_2"}, "nparam":8495, "fparam":{"nested_1":91.15,"nested_2":[334, 89.05, 1000.01]}, "bparam":false}' diff --git a/dbms/tests/performance/json_extract_simdjson.xml b/dbms/tests/performance/json_extract_simdjson.xml index 85d7e612e4c..8b2128a686a 100644 --- a/dbms/tests/performance/json_extract_simdjson.xml +++ b/dbms/tests/performance/json_extract_simdjson.xml @@ -21,11 +21,13 @@ + json '{"sparam":"test_string","nparam": 772}' + long_json '{"sparam":{"nested_1":"test_string","nested_2":"test_2"}, "nparam":8495, "fparam":{"nested_1":91.15,"nested_2":[334, 89.05, 1000.01]}, "bparam":false}' diff --git a/dbms/tests/performance/merge_tree_many_partitions.xml b/dbms/tests/performance/merge_tree_many_partitions.xml index 8450a34dc59..1b21bbcf780 100644 --- a/dbms/tests/performance/merge_tree_many_partitions.xml +++ b/dbms/tests/performance/merge_tree_many_partitions.xml @@ -1,4 +1,5 @@ + merge_tree_many_partitions loop CREATE TABLE bad_partitions (x UInt64) ENGINE = MergeTree PARTITION BY x ORDER BY x diff --git a/dbms/tests/performance/merge_tree_many_partitions_2.xml b/dbms/tests/performance/merge_tree_many_partitions_2.xml index 1ad06fcbf2f..a38a2cc0139 100644 --- a/dbms/tests/performance/merge_tree_many_partitions_2.xml +++ b/dbms/tests/performance/merge_tree_many_partitions_2.xml @@ -1,4 +1,5 @@ + merge_tree_many_partitions_2 loop CREATE TABLE bad_partitions (a UInt64, b UInt64, c UInt64, d UInt64, e UInt64, f UInt64, g UInt64, h UInt64, i UInt64, j UInt64, k UInt64, l UInt64, m UInt64, n UInt64, o UInt64, p UInt64, q UInt64, r UInt64, s UInt64, t UInt64, u UInt64, v UInt64, w UInt64, x UInt64, y UInt64, z UInt64) ENGINE = MergeTree PARTITION BY x ORDER BY x diff --git a/dbms/tests/performance/merge_tree_simple_select.xml b/dbms/tests/performance/merge_tree_simple_select.xml index 5e482e0d44b..3a303500f3a 100644 --- a/dbms/tests/performance/merge_tree_simple_select.xml +++ b/dbms/tests/performance/merge_tree_simple_select.xml @@ -1,4 +1,5 @@ + merge_tree_simple_select loop diff --git a/dbms/tests/performance/number_formatting_formats.xml b/dbms/tests/performance/number_formatting_formats.xml index 7ad461d9026..7c9c4ea0fe9 100644 --- a/dbms/tests/performance/number_formatting_formats.xml +++ b/dbms/tests/performance/number_formatting_formats.xml @@ -1,4 +1,5 @@ + number_formatting_formats loop CREATE TABLE IF NOT EXISTS table_{format} (x UInt64) ENGINE = File(`{format}`) @@ -20,6 +21,7 @@ + format TabSeparated CSV diff --git a/dbms/tests/performance/order_by_pk_order.xml b/dbms/tests/performance/order_by_pk_order.xml index f52c9a0ce55..7577d428160 100644 --- a/dbms/tests/performance/order_by_pk_order.xml +++ b/dbms/tests/performance/order_by_pk_order.xml @@ -1,4 +1,5 @@ + order_by_pk_order loop diff --git a/dbms/tests/performance/parse_engine_file.xml b/dbms/tests/performance/parse_engine_file.xml index dbd0ae5dc4e..6bd4af0b45b 100644 --- a/dbms/tests/performance/parse_engine_file.xml +++ b/dbms/tests/performance/parse_engine_file.xml @@ -23,6 +23,7 @@ + format TabSeparated TabSeparatedWithNames diff --git a/dbms/tests/performance/right.xml b/dbms/tests/performance/right.xml index 41772553eeb..8d1304a4604 100644 --- a/dbms/tests/performance/right.xml +++ b/dbms/tests/performance/right.xml @@ -21,6 +21,7 @@ + func right(URL, 16) substring(URL, greatest(minus(plus(length(URL), 1), 16), 1)) diff --git a/dbms/tests/performance/select_format.xml b/dbms/tests/performance/select_format.xml index 9b315199ac2..c5ad1acd396 100644 --- a/dbms/tests/performance/select_format.xml +++ b/dbms/tests/performance/select_format.xml @@ -24,6 +24,7 @@ + format TabSeparated TabSeparatedRaw diff --git a/dbms/tests/performance/set.xml b/dbms/tests/performance/set.xml index 3953a504522..1e62840d8d1 100644 --- a/dbms/tests/performance/set.xml +++ b/dbms/tests/performance/set.xml @@ -20,12 +20,14 @@ + table system.numbers system.numbers_mt + size 1 16 diff --git a/dbms/tests/performance/string_sort.xml b/dbms/tests/performance/string_sort.xml index 6a99eddb66c..7b33bb20d52 100644 --- a/dbms/tests/performance/string_sort.xml +++ b/dbms/tests/performance/string_sort.xml @@ -18,6 +18,7 @@ + str1 URL Referer @@ -28,6 +29,7 @@ + str2 URL Referer diff --git a/dbms/tests/performance/trim_numbers.xml b/dbms/tests/performance/trim_numbers.xml index 9f45861b480..48fdb710cd9 100644 --- a/dbms/tests/performance/trim_numbers.xml +++ b/dbms/tests/performance/trim_numbers.xml @@ -17,6 +17,7 @@ + func trim( ltrim( diff --git a/dbms/tests/performance/trim_urls.xml b/dbms/tests/performance/trim_urls.xml index 3f1a5426b4c..2b672d9d97d 100644 --- a/dbms/tests/performance/trim_urls.xml +++ b/dbms/tests/performance/trim_urls.xml @@ -21,6 +21,7 @@ + func trim( ltrim( diff --git a/dbms/tests/performance/trim_whitespace.xml b/dbms/tests/performance/trim_whitespace.xml index 98562e24510..26d89859432 100644 --- a/dbms/tests/performance/trim_whitespace.xml +++ b/dbms/tests/performance/trim_whitespace.xml @@ -16,6 +16,7 @@ + func value trimLeft(value) diff --git a/dbms/tests/performance/uniq.xml b/dbms/tests/performance/uniq.xml index c4a6407295b..c44a4e2ca58 100644 --- a/dbms/tests/performance/uniq.xml +++ b/dbms/tests/performance/uniq.xml @@ -23,6 +23,7 @@ + key 1 SearchEngineID @@ -32,6 +33,7 @@ + func sum uniq diff --git a/dbms/tests/performance/url_hits.xml b/dbms/tests/performance/url_hits.xml index 475c3aaf4d5..a251a2706b8 100644 --- a/dbms/tests/performance/url_hits.xml +++ b/dbms/tests/performance/url_hits.xml @@ -21,6 +21,7 @@ + func protocol domain diff --git a/dbms/tests/performance/visit_param_extract_raw.xml b/dbms/tests/performance/visit_param_extract_raw.xml index 4e9603a7774..02b8224c361 100644 --- a/dbms/tests/performance/visit_param_extract_raw.xml +++ b/dbms/tests/performance/visit_param_extract_raw.xml @@ -17,6 +17,7 @@ + param '{"myparam":"test_string"}' '{"myparam":{"nested_1":"test_string","nested_2":"test_2"}}' diff --git a/dbms/tests/performance/website.xml b/dbms/tests/performance/website.xml index 02b4213e970..4cb350a60a1 100644 --- a/dbms/tests/performance/website.xml +++ b/dbms/tests/performance/website.xml @@ -26,6 +26,7 @@ + table hits_10m_single hits_100m_single From 3988fe7fe4bb75a8ca87ecd8ac6d6060e6a88933 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 28 Jul 2019 00:18:54 +0300 Subject: [PATCH 0403/1165] Removed from all performance tests #6179 --- dbms/tests/performance/codec_double_delta.xml | 1 - dbms/tests/performance/codec_gorilla.xml | 1 - dbms/tests/performance/count.xml | 1 - dbms/tests/performance/group_array_moving_sum.xml | 1 - dbms/tests/performance/merge_tree_many_partitions.xml | 1 - dbms/tests/performance/merge_tree_many_partitions_2.xml | 1 - dbms/tests/performance/merge_tree_simple_select.xml | 1 - dbms/tests/performance/number_formatting_formats.xml | 1 - dbms/tests/performance/order_by_pk_order.xml | 1 - 9 files changed, 9 deletions(-) diff --git a/dbms/tests/performance/codec_double_delta.xml b/dbms/tests/performance/codec_double_delta.xml index 97c31587548..8daf1e73442 100644 --- a/dbms/tests/performance/codec_double_delta.xml +++ b/dbms/tests/performance/codec_double_delta.xml @@ -1,5 +1,4 @@ - Codec DoubleDelta loop diff --git a/dbms/tests/performance/codec_gorilla.xml b/dbms/tests/performance/codec_gorilla.xml index a066055cbcc..cd6fa50e3e5 100644 --- a/dbms/tests/performance/codec_gorilla.xml +++ b/dbms/tests/performance/codec_gorilla.xml @@ -1,5 +1,4 @@ - Codec Gorilla loop diff --git a/dbms/tests/performance/count.xml b/dbms/tests/performance/count.xml index 9ce3c0a98e4..da972c69059 100644 --- a/dbms/tests/performance/count.xml +++ b/dbms/tests/performance/count.xml @@ -1,5 +1,4 @@ - count loop diff --git a/dbms/tests/performance/group_array_moving_sum.xml b/dbms/tests/performance/group_array_moving_sum.xml index d296da5dd11..ee2686c9af8 100644 --- a/dbms/tests/performance/group_array_moving_sum.xml +++ b/dbms/tests/performance/group_array_moving_sum.xml @@ -1,5 +1,4 @@ - Moving Sum loop diff --git a/dbms/tests/performance/merge_tree_many_partitions.xml b/dbms/tests/performance/merge_tree_many_partitions.xml index 1b21bbcf780..8450a34dc59 100644 --- a/dbms/tests/performance/merge_tree_many_partitions.xml +++ b/dbms/tests/performance/merge_tree_many_partitions.xml @@ -1,5 +1,4 @@ - merge_tree_many_partitions loop CREATE TABLE bad_partitions (x UInt64) ENGINE = MergeTree PARTITION BY x ORDER BY x diff --git a/dbms/tests/performance/merge_tree_many_partitions_2.xml b/dbms/tests/performance/merge_tree_many_partitions_2.xml index a38a2cc0139..1ad06fcbf2f 100644 --- a/dbms/tests/performance/merge_tree_many_partitions_2.xml +++ b/dbms/tests/performance/merge_tree_many_partitions_2.xml @@ -1,5 +1,4 @@ - merge_tree_many_partitions_2 loop CREATE TABLE bad_partitions (a UInt64, b UInt64, c UInt64, d UInt64, e UInt64, f UInt64, g UInt64, h UInt64, i UInt64, j UInt64, k UInt64, l UInt64, m UInt64, n UInt64, o UInt64, p UInt64, q UInt64, r UInt64, s UInt64, t UInt64, u UInt64, v UInt64, w UInt64, x UInt64, y UInt64, z UInt64) ENGINE = MergeTree PARTITION BY x ORDER BY x diff --git a/dbms/tests/performance/merge_tree_simple_select.xml b/dbms/tests/performance/merge_tree_simple_select.xml index 3a303500f3a..5e482e0d44b 100644 --- a/dbms/tests/performance/merge_tree_simple_select.xml +++ b/dbms/tests/performance/merge_tree_simple_select.xml @@ -1,5 +1,4 @@ - merge_tree_simple_select loop diff --git a/dbms/tests/performance/number_formatting_formats.xml b/dbms/tests/performance/number_formatting_formats.xml index 7c9c4ea0fe9..df83c5cbf11 100644 --- a/dbms/tests/performance/number_formatting_formats.xml +++ b/dbms/tests/performance/number_formatting_formats.xml @@ -1,5 +1,4 @@ - number_formatting_formats loop CREATE TABLE IF NOT EXISTS table_{format} (x UInt64) ENGINE = File(`{format}`) diff --git a/dbms/tests/performance/order_by_pk_order.xml b/dbms/tests/performance/order_by_pk_order.xml index 7577d428160..f52c9a0ce55 100644 --- a/dbms/tests/performance/order_by_pk_order.xml +++ b/dbms/tests/performance/order_by_pk_order.xml @@ -1,5 +1,4 @@ - order_by_pk_order loop From 95a6b852678c98ef5ebe7988d390d039f5e0bb8c Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Sun, 28 Jul 2019 03:41:26 +0300 Subject: [PATCH 0404/1165] fix reading in order of sorting_key --- .../MergeTree/MergeTreeDataSelectExecutor.cpp | 11 ++++++++++- .../Storages/MergeTree/MergeTreeDataSelectExecutor.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index 667178d940e..f7a7343e16b 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -591,6 +591,13 @@ BlockInputStreams MergeTreeDataSelectExecutor::readFromParts( } else if (settings.optimize_pk_order && query_info.sorting_info) { + size_t prefix_size = query_info.sorting_info->prefix_order_descr.size(); + auto order_key_prefix_ast = data.sorting_key_expr_ast->clone(); + order_key_prefix_ast->children.resize(prefix_size); + + auto syntax_result = SyntaxAnalyzer(context).analyze(order_key_prefix_ast, data.getColumns().getAllPhysical()); + auto sorting_key_prefix_expr = ExpressionAnalyzer(order_key_prefix_ast, syntax_result, context).getActions(false); + res = spreadMarkRangesAmongStreamsPKOrder( std::move(parts_with_ranges), num_streams, @@ -598,6 +605,7 @@ BlockInputStreams MergeTreeDataSelectExecutor::readFromParts( max_block_size, settings.use_uncompressed_cache, query_info, + sorting_key_prefix_expr, virt_column_names, settings); } @@ -814,6 +822,7 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsPKOrd UInt64 max_block_size, bool use_uncompressed_cache, const SelectQueryInfo & query_info, + const ExpressionActionsPtr & sorting_key_prefix_expr, const Names & virt_columns, const Settings & settings) const { @@ -981,7 +990,7 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsPKOrd sorting_info->direction, 1); for (auto & stream : streams_per_thread) - stream = std::make_shared(stream, data.sorting_key_expr); + stream = std::make_shared(stream, sorting_key_prefix_expr); streams.push_back(std::make_shared( streams_per_thread, sort_description, max_block_size)); diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h index 92ea39a80ec..ae4ed3bdcc0 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h +++ b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h @@ -63,6 +63,7 @@ private: UInt64 max_block_size, bool use_uncompressed_cache, const SelectQueryInfo & query_info, + const ExpressionActionsPtr & sorting_key_prefix_expr, const Names & virt_columns, const Settings & settings) const; From 96552a4d4ec3ad192b94621b978ebf7b50cc570e Mon Sep 17 00:00:00 2001 From: Yuriy Date: Sun, 28 Jul 2019 03:41:41 +0300 Subject: [PATCH 0405/1165] prevent rewriting packet in case of attempt to write more than initially calculated payload length --- dbms/programs/server/MySQLHandler.cpp | 10 +++++----- dbms/src/Core/MySQLProtocol.h | 13 ++++++++++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/dbms/programs/server/MySQLHandler.cpp b/dbms/programs/server/MySQLHandler.cpp index d236dc0710d..b75ac2ead5e 100644 --- a/dbms/programs/server/MySQLHandler.cpp +++ b/dbms/programs/server/MySQLHandler.cpp @@ -65,11 +65,7 @@ void MySQLHandler::run() { String scramble = generateScramble(); - /** Native authentication sent 20 bytes + '\0' character = 21 bytes. - * This plugin must do the same to stay consistent with historical behavior if it is set to operate as a default plugin. - * https://github.com/mysql/mysql-server/blob/8.0/sql/auth/sql_authentication.cc#L3994 - */ - Handshake handshake(server_capability_flags, connection_id, VERSION_STRING + String("-") + VERSION_NAME, scramble + '\0'); + Handshake handshake(server_capability_flags, connection_id, VERSION_STRING + String("-") + VERSION_NAME, Authentication::Native, scramble + '\0'); packet_sender->sendPacket(handshake, true); LOG_TRACE(log, "Sent handshake"); @@ -239,6 +235,10 @@ void MySQLHandler::authenticate(const HandshakeResponse & handshake_response, co AuthSwitchResponse response; if (handshake_response.auth_plugin_name != Authentication::SHA256) { + /** Native authentication sent 20 bytes + '\0' character = 21 bytes. + * This plugin must do the same to stay consistent with historical behavior if it is set to operate as a default plugin. + * https://github.com/mysql/mysql-server/blob/8.0/sql/auth/sql_authentication.cc#L3994 + */ packet_sender->sendPacket(AuthSwitchRequest(Authentication::SHA256, scramble + '\0'), true); if (in->eof()) throw Exception( diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index aaf6d70f256..6a0e7c49f4b 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -300,7 +300,12 @@ protected: } else if (total_left > 0 || payload_length == MAX_PACKET_LENGTH) { + // Starting new packet, since packets of size greater than MAX_PACKET_LENGTH should be split. startPacket(); + } else { + // Finished writing packet. Buffer is set to empty to prevent rewriting (pos will be set to the beginning of a working buffer in next()). + // Further attempts to write will stall in the infinite loop. + working_buffer = WriteBuffer::Buffer(out.position(), out.position()); } } }; @@ -408,15 +413,17 @@ class Handshake : public WritePacket uint32_t capability_flags; uint8_t character_set; uint32_t status_flags; + String auth_plugin_name; String auth_plugin_data; public: - explicit Handshake(uint32_t capability_flags, uint32_t connection_id, String server_version, String auth_plugin_data) + explicit Handshake(uint32_t capability_flags, uint32_t connection_id, String server_version, String auth_plugin_name, String auth_plugin_data) : protocol_version(0xa) , server_version(std::move(server_version)) , connection_id(connection_id) , capability_flags(capability_flags) , character_set(CharacterSet::utf8_general_ci) , status_flags(0) + , auth_plugin_name(std::move(auth_plugin_name)) , auth_plugin_data(std::move(auth_plugin_data)) { } @@ -424,7 +431,7 @@ public: protected: size_t getPayloadSize() const override { - return 26 + server_version.size() + auth_plugin_data.size() + Authentication::SHA256.size(); + return 26 + server_version.size() + auth_plugin_data.size() + auth_plugin_name.size(); } void writePayloadImpl(WriteBuffer & buffer) const override @@ -443,7 +450,7 @@ protected: // A workaround for PHP mysqlnd extension bug which occurs when sha256_password is used as a default authentication plugin. // Instead of using client response for mysql_native_password plugin, the server will always generate authentication method mismatch // and switch to sha256_password to simulate that mysql_native_password is used as a default plugin. - writeString(Authentication::Native, buffer); + writeString(auth_plugin_name, buffer); writeChar(0x0, 1, buffer); } }; From 997c94d0939c650a0c4ffc190d464e1cf5f48be6 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Sun, 28 Jul 2019 03:55:46 +0300 Subject: [PATCH 0406/1165] includes order --- dbms/programs/server/MySQLHandler.cpp | 29 +++++++++++++-------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/dbms/programs/server/MySQLHandler.cpp b/dbms/programs/server/MySQLHandler.cpp index b75ac2ead5e..c71e0554fb5 100644 --- a/dbms/programs/server/MySQLHandler.cpp +++ b/dbms/programs/server/MySQLHandler.cpp @@ -1,25 +1,24 @@ -#include -#include -#include -#include -#include -#include -#include -#include +#include "MySQLHandler.h" + +#include +#include +#include #include #include #include #include -#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include #include -#include "MySQLHandler.h" -#include -#include - -#include -#include +#include namespace DB From d69d68f06559f9d0c33df2886386bc93461acbf7 Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Sun, 28 Jul 2019 04:16:56 +0300 Subject: [PATCH 0407/1165] rename setting 'optimize_pk_order' and some functions --- dbms/src/Core/Settings.h | 2 +- .../Interpreters/InterpreterSelectQuery.cpp | 6 +- .../MergeTree/MergeTreeDataSelectExecutor.cpp | 6 +- .../MergeTree/MergeTreeDataSelectExecutor.h | 2 +- .../performance/order_by_read_in_order.xml | 33 + .../00940_order_by_read_in_order.reference | 200 ++++++ .../00940_order_by_read_in_order.sql | 56 ++ .../00151_order_by_read_in_order.reference | 600 ++++++++++++++++++ .../00151_order_by_read_in_order.sql | 14 + 9 files changed, 911 insertions(+), 8 deletions(-) create mode 100644 dbms/tests/performance/order_by_read_in_order.xml create mode 100644 dbms/tests/queries/0_stateless/00940_order_by_read_in_order.reference create mode 100644 dbms/tests/queries/0_stateless/00940_order_by_read_in_order.sql create mode 100644 dbms/tests/queries/1_stateful/00151_order_by_read_in_order.reference create mode 100644 dbms/tests/queries/1_stateful/00151_order_by_read_in_order.sql diff --git a/dbms/src/Core/Settings.h b/dbms/src/Core/Settings.h index 4f2ec113120..4dfe0257b1c 100644 --- a/dbms/src/Core/Settings.h +++ b/dbms/src/Core/Settings.h @@ -322,7 +322,7 @@ struct Settings : public SettingsCollection M(SettingBool, parallel_view_processing, false, "Enables pushing to attached views concurrently instead of sequentially.") \ M(SettingBool, enable_debug_queries, false, "Enables debug queries such as AST.") \ M(SettingBool, enable_unaligned_array_join, false, "Allow ARRAY JOIN with multiple arrays that have different sizes. When this settings is enabled, arrays will be resized to the longest one.") \ - M(SettingBool, optimize_pk_order, true, "Enable order by optimization in reading in primary key order.") \ + M(SettingBool, optimize_read_in_order, true, "Enable order by optimization in reading in primary key order.") \ M(SettingBool, low_cardinality_allow_in_native_format, true, "Use LowCardinality type in Native format. Otherwise, convert LowCardinality columns to ordinary for select query, and convert ordinary columns to required LowCardinality for insert query.") \ M(SettingBool, allow_experimental_multiple_joins_emulation, true, "Emulate multiple joins using subselects") \ M(SettingBool, allow_experimental_cross_to_join_conversion, true, "Convert CROSS JOIN to INNER JOIN if possible") \ diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.cpp b/dbms/src/Interpreters/InterpreterSelectQuery.cpp index b6b371a9088..11d90fd4f4a 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSelectQuery.cpp @@ -648,7 +648,7 @@ static UInt64 getLimitForSorting(const ASTSelectQuery & query, const Context & c } -static SortingInfoPtr optimizeSortingWithPK(const MergeTreeData & merge_tree, const ASTSelectQuery & query, const Context & context) +static SortingInfoPtr optimizeReadInOrder(const MergeTreeData & merge_tree, const ASTSelectQuery & query, const Context & context) { if (!merge_tree.hasSortingKey()) return {}; @@ -794,10 +794,10 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS } SortingInfoPtr sorting_info; - if (settings.optimize_pk_order && storage && query.orderBy() && !query.groupBy() && !query.final()) + if (settings.optimize_read_in_order && storage && query.orderBy() && !query.groupBy() && !query.final()) { if (const MergeTreeData * merge_tree_data = dynamic_cast(storage.get())) - sorting_info = optimizeSortingWithPK(*merge_tree_data, query, context); + sorting_info = optimizeReadInOrder(*merge_tree_data, query, context); } if (dry_run) diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index f7a7343e16b..ccbcd04857d 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -589,7 +589,7 @@ BlockInputStreams MergeTreeDataSelectExecutor::readFromParts( virt_column_names, settings); } - else if (settings.optimize_pk_order && query_info.sorting_info) + else if (settings.optimize_read_in_order && query_info.sorting_info) { size_t prefix_size = query_info.sorting_info->prefix_order_descr.size(); auto order_key_prefix_ast = data.sorting_key_expr_ast->clone(); @@ -598,7 +598,7 @@ BlockInputStreams MergeTreeDataSelectExecutor::readFromParts( auto syntax_result = SyntaxAnalyzer(context).analyze(order_key_prefix_ast, data.getColumns().getAllPhysical()); auto sorting_key_prefix_expr = ExpressionAnalyzer(order_key_prefix_ast, syntax_result, context).getActions(false); - res = spreadMarkRangesAmongStreamsPKOrder( + res = spreadMarkRangesAmongStreamsWithOrder( std::move(parts_with_ranges), num_streams, column_names_to_read, @@ -815,7 +815,7 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreams( return res; } -BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsPKOrder( +BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsWithOrder( RangesInDataParts && parts, size_t num_streams, const Names & column_names, diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h index ae4ed3bdcc0..44857799d01 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h +++ b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h @@ -56,7 +56,7 @@ private: const Names & virt_columns, const Settings & settings) const; - BlockInputStreams spreadMarkRangesAmongStreamsPKOrder( + BlockInputStreams spreadMarkRangesAmongStreamsWithOrder( RangesInDataParts && parts, size_t num_streams, const Names & column_names, diff --git a/dbms/tests/performance/order_by_read_in_order.xml b/dbms/tests/performance/order_by_read_in_order.xml new file mode 100644 index 00000000000..f52c9a0ce55 --- /dev/null +++ b/dbms/tests/performance/order_by_read_in_order.xml @@ -0,0 +1,33 @@ + + loop + + + + 5 + 10000 + + + 500 + 60000 + + + + + + + + + + + + + + + + + test.hits + + +SELECT CounterID FROM test.hits ORDER BY CounterID, EventDate DESC LIMIT 50 + + diff --git a/dbms/tests/queries/0_stateless/00940_order_by_read_in_order.reference b/dbms/tests/queries/0_stateless/00940_order_by_read_in_order.reference new file mode 100644 index 00000000000..8c594b6f683 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00940_order_by_read_in_order.reference @@ -0,0 +1,200 @@ +1 +2 +3 +4 +5 +6 +1 +1 +2 +3 +4 +1 +1 +1 +1 +1 +1 +2 +2 +2 +2 +2 +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +2 1 +2 1 +2 2 +2 3 +2 4 +2 1 +2 1 +2 2 +2 3 +2 4 +1 1 +1 2 +1 3 +1 4 +1 5 +1 6 +1 6 +1 5 +1 4 +1 3 +1 2 +1 1 +2 4 +2 3 +2 2 +2 1 +2 1 +2 4 +2 3 +2 2 +2 1 +2 1 +1 6 +1 5 +1 4 +1 3 +1 2 +1 1 +2 +2 +2 +2 +2 +1 +1 +1 +1 +1 +1 +1 1 101 +1 2 102 +1 3 103 +1 4 104 +1 5 104 +1 6 105 +2 1 106 +2 1 107 +2 2 107 +2 3 108 +2 4 109 +2 1 106 +2 1 107 +2 2 107 +2 3 108 +2 4 109 +1 1 101 +1 2 102 +1 3 103 +1 4 104 +1 5 104 +1 6 105 +1 6 105 +1 5 104 +1 4 104 +1 3 103 +1 2 102 +1 1 101 +2 4 109 +2 3 108 +2 2 107 +2 1 106 +2 1 107 +1 1 101 +1 2 102 +1 3 103 +1 4 104 +1 5 104 +1 6 105 +2 1 107 +2 1 106 +2 2 107 +2 3 108 +2 4 109 +2 4 109 +2 3 108 +2 2 107 +2 1 106 +2 1 107 +1 6 105 +1 5 104 +1 4 104 +1 3 103 +1 2 102 +1 1 101 +2 1 107 +2 1 106 +2 2 107 +2 3 108 +2 4 109 +1 1 101 +1 2 102 +1 3 103 +1 4 104 +1 5 104 +1 6 105 +1 6 105 +1 5 104 +1 4 104 +1 3 103 +1 2 102 +1 1 101 +2 4 109 +2 3 108 +2 2 107 +2 1 107 +2 1 106 +2 4 109 +2 3 108 +2 2 107 +2 1 107 +2 1 106 +1 6 105 +1 5 104 +1 4 104 +1 3 103 +1 2 102 +1 1 101 +2019-05-05 00:00:00 +2019-05-05 00:00:00 +2019-05-05 00:00:00 +2019-05-05 00:00:00 +2019-05-05 00:00:00 +2019-05-05 00:00:00 -1249512288 +2019-05-05 00:00:00 -916059969 +2019-05-05 00:00:00 -859523951 +2019-05-05 00:00:00 -45363190 +2019-05-05 00:00:00 345522721 +2019-05-14 00:00:00 99 +2019-05-14 00:00:00 89 +2019-05-14 00:00:00 79 +2019-05-14 00:00:00 69 +2019-05-14 00:00:00 59 +2019-05-14 00:00:00 99 +2019-05-14 00:00:00 89 +2019-05-14 00:00:00 79 +2019-05-14 00:00:00 69 +2019-05-14 00:00:00 59 +2019-05-14 00:00:00 99 +2019-05-14 00:00:00 89 +2019-05-14 00:00:00 79 +2019-05-14 00:00:00 69 +2019-05-14 00:00:00 59 +2019-05-05 00:00:00 +2019-05-05 00:00:00 +2019-05-05 00:00:00 +2019-05-05 00:00:00 +2019-05-05 00:00:00 +1 5 +1 5 +1 5 +1 3 +1 3 diff --git a/dbms/tests/queries/0_stateless/00940_order_by_read_in_order.sql b/dbms/tests/queries/0_stateless/00940_order_by_read_in_order.sql new file mode 100644 index 00000000000..55fca9700dd --- /dev/null +++ b/dbms/tests/queries/0_stateless/00940_order_by_read_in_order.sql @@ -0,0 +1,56 @@ +CREATE DATABASE IF NOT EXISTS test; +DROP TABLE IF EXISTS test.pk_order; + +SET optimize_read_in_order = 1; + +CREATE TABLE test.pk_order(a UInt64, b UInt64, c UInt64, d UInt64) ENGINE=MergeTree() ORDER BY (a, b); +INSERT INTO test.pk_order(a, b, c, d) VALUES (1, 1, 101, 1), (1, 2, 102, 1), (1, 3, 103, 1), (1, 4, 104, 1); +INSERT INTO test.pk_order(a, b, c, d) VALUES (1, 5, 104, 1), (1, 6, 105, 1), (2, 1, 106, 2), (2, 1, 107, 2); + +INSERT INTO test.pk_order(a, b, c, d) VALUES (2, 2, 107, 2), (2, 3, 108, 2), (2, 4, 109, 2); + +SELECT b FROM test.pk_order ORDER BY a, b; +SELECT a FROM test.pk_order ORDER BY a, b; + +SELECT a, b FROM test.pk_order ORDER BY a, b; +SELECT a, b FROM test.pk_order ORDER BY a DESC, b; +SELECT a, b FROM test.pk_order ORDER BY a, b DESC; +SELECT a, b FROM test.pk_order ORDER BY a DESC, b DESC; +SELECT a FROM test.pk_order ORDER BY a DESC; + +SELECT a, b, c FROM test.pk_order ORDER BY a, b, c; +SELECT a, b, c FROM test.pk_order ORDER BY a DESC, b, c; +SELECT a, b, c FROM test.pk_order ORDER BY a, b DESC, c; +SELECT a, b, c FROM test.pk_order ORDER BY a, b, c DESC; +SELECT a, b, c FROM test.pk_order ORDER BY a DESC, b DESC, c; +SELECT a, b, c FROM test.pk_order ORDER BY a DESC, b, c DESC; +SELECT a, b, c FROM test.pk_order ORDER BY a, b DESC, c DESC; +SELECT a, b, c FROM test.pk_order ORDER BY a DESC, b DESC, c DESC; + +DROP TABLE IF EXISTS test.pk_order; + +CREATE TABLE pk_order (d DateTime, a Int32, b Int32) ENGINE = MergeTree ORDER BY (d, a) + PARTITION BY toDate(d) SETTINGS index_granularity=1; + +INSERT INTO pk_order + SELECT toDateTime('2019-05-05 00:00:00') + INTERVAL number % 10 DAY, number, intHash32(number) from numbers(100); + +set max_block_size = 1; + +-- Currently checking number of read rows while reading in pk order not working precise. TODO: fix it. +-- SET max_rows_to_read = 10; + +SELECT d FROM pk_order ORDER BY d LIMIT 5; +SELECT d, b FROM pk_order ORDER BY d, b LIMIT 5; +SELECT d, a FROM pk_order ORDER BY d DESC, a DESC LIMIT 5; +SELECT d, a FROM pk_order ORDER BY d DESC, -a LIMIT 5; +SELECT d, a FROM pk_order ORDER BY d DESC, a DESC LIMIT 5; +SELECT toStartOfHour(d) as d1 FROM pk_order ORDER BY d1 LIMIT 5; + +DROP TABLE pk_order; + +CREATE TABLE pk_order (a Int, b Int) ENGINE = MergeTree ORDER BY (a / b); +INSERT INTO pk_order SELECT number % 10 + 1, number % 6 + 1 from numbers(100); +SELECT * FROM pk_order ORDER BY (a / b), a LIMIT 5; + + diff --git a/dbms/tests/queries/1_stateful/00151_order_by_read_in_order.reference b/dbms/tests/queries/1_stateful/00151_order_by_read_in_order.reference new file mode 100644 index 00000000000..551357900df --- /dev/null +++ b/dbms/tests/queries/1_stateful/00151_order_by_read_in_order.reference @@ -0,0 +1,600 @@ +33554106 +33554106 +33553911 +33553911 +33553911 +33553911 +33553911 +33553828 +33553772 +33553718 +33553718 +33553673 +33553673 +33553673 +33553673 +33553362 +33553353 +33553353 +33553353 +33553353 +33553353 +33553353 +33553004 +33553004 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +2014-03-17 +2014-03-17 +2014-03-17 +2014-03-17 +2014-03-17 +2014-03-17 +2014-03-17 +2014-03-17 +2014-03-17 +2014-03-17 +2014-03-17 +2014-03-17 +2014-03-17 +2014-03-17 +2014-03-17 +2014-03-17 +2014-03-17 +2014-03-17 +2014-03-17 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-18 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +57 +33554106 +33554106 +33553911 +33553911 +33553911 +33553911 +33553911 +33553828 +33553772 +33553718 +33553718 +33553673 +33553673 +33553673 +33553673 +33553362 +33553353 +33553353 +33553353 +33553353 +33553353 +33553353 +33553004 +33553004 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +33552322 +2014-03-21 +2014-03-21 +2014-03-23 +2014-03-23 +2014-03-20 +2014-03-20 +2014-03-20 +2014-03-17 +2014-03-19 +2014-03-23 +2014-03-23 +2014-03-20 +2014-03-20 +2014-03-18 +2014-03-18 +2014-03-17 +2014-03-21 +2014-03-21 +2014-03-21 +2014-03-21 +2014-03-21 +2014-03-21 +2014-03-17 +2014-03-17 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-23 +2014-03-22 +57 2014-03-17 +57 2014-03-17 +57 2014-03-17 +57 2014-03-17 +57 2014-03-17 +57 2014-03-17 +57 2014-03-17 +57 2014-03-17 +57 2014-03-17 +57 2014-03-17 +57 2014-03-17 +57 2014-03-17 +57 2014-03-17 +57 2014-03-17 +57 2014-03-17 +57 2014-03-17 +57 2014-03-17 +57 2014-03-17 +57 2014-03-17 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-18 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +57 2014-03-23 +33554106 2014-03-21 +33554106 2014-03-21 +33553911 2014-03-20 +33553911 2014-03-20 +33553911 2014-03-20 +33553911 2014-03-23 +33553911 2014-03-23 +33553828 2014-03-17 +33553772 2014-03-19 +33553718 2014-03-23 +33553718 2014-03-23 +33553673 2014-03-18 +33553673 2014-03-18 +33553673 2014-03-20 +33553673 2014-03-20 +33553362 2014-03-17 +33553353 2014-03-21 +33553353 2014-03-21 +33553353 2014-03-21 +33553353 2014-03-21 +33553353 2014-03-21 +33553353 2014-03-21 +33553004 2014-03-17 +33553004 2014-03-17 +33552322 2014-03-17 +33552322 2014-03-17 +33552322 2014-03-17 +33552322 2014-03-17 +33552322 2014-03-17 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33552322 2014-03-18 +33554106 2014-03-21 +33554106 2014-03-21 +33553911 2014-03-23 +33553911 2014-03-23 +33553911 2014-03-20 +33553911 2014-03-20 +33553911 2014-03-20 +33553828 2014-03-17 +33553772 2014-03-19 +33553718 2014-03-23 +33553718 2014-03-23 +33553673 2014-03-20 +33553673 2014-03-20 +33553673 2014-03-18 +33553673 2014-03-18 +33553362 2014-03-17 +33553353 2014-03-21 +33553353 2014-03-21 +33553353 2014-03-21 +33553353 2014-03-21 +33553353 2014-03-21 +33553353 2014-03-21 +33553004 2014-03-17 +33553004 2014-03-17 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-23 +33552322 2014-03-22 diff --git a/dbms/tests/queries/1_stateful/00151_order_by_read_in_order.sql b/dbms/tests/queries/1_stateful/00151_order_by_read_in_order.sql new file mode 100644 index 00000000000..59cffec71e9 --- /dev/null +++ b/dbms/tests/queries/1_stateful/00151_order_by_read_in_order.sql @@ -0,0 +1,14 @@ +SET optimize_read_in_order = 1; +SELECT CounterID FROM test.hits ORDER BY CounterID DESC LIMIT 50; +SELECT CounterID FROM test.hits ORDER BY CounterID LIMIT 50; +SELECT CounterID FROM test.hits ORDER BY CounterID, EventDate LIMIT 50; +SELECT EventDate FROM test.hits ORDER BY CounterID, EventDate LIMIT 50; +SELECT EventDate FROM test.hits ORDER BY CounterID, EventDate DESC LIMIT 50; +SELECT CounterID FROM test.hits ORDER BY CounterID, EventDate DESC LIMIT 50; +SELECT CounterID FROM test.hits ORDER BY CounterID DESC, EventDate DESC LIMIT 50; +SELECT EventDate FROM test.hits ORDER BY CounterID DESC, EventDate DESC LIMIT 50; + +SELECT CounterID, EventDate FROM test.hits ORDER BY CounterID, EventDate LIMIT 50; +SELECT CounterID, EventDate FROM test.hits ORDER BY CounterID, EventDate DESC LIMIT 50; +SELECT CounterID, EventDate FROM test.hits ORDER BY CounterID DESC, EventDate LIMIT 50; +SELECT CounterID, EventDate FROM test.hits ORDER BY CounterID DESC, EventDate DESC LIMIT 50; From 2dc2eb56d80510a8f1d73747521a6b0db319ab18 Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Sun, 28 Jul 2019 04:21:25 +0300 Subject: [PATCH 0408/1165] remove renamed tests --- dbms/tests/performance/order_by_pk_order.xml | 34 - .../00940_order_by_pk_order.reference | 200 ------ .../0_stateless/00940_order_by_pk_order.sql | 56 -- .../00151_order_by_pk_order.reference | 600 ------------------ .../1_stateful/00151_order_by_pk_order.sql | 14 - 5 files changed, 904 deletions(-) delete mode 100644 dbms/tests/performance/order_by_pk_order.xml delete mode 100644 dbms/tests/queries/0_stateless/00940_order_by_pk_order.reference delete mode 100644 dbms/tests/queries/0_stateless/00940_order_by_pk_order.sql delete mode 100644 dbms/tests/queries/1_stateful/00151_order_by_pk_order.reference delete mode 100644 dbms/tests/queries/1_stateful/00151_order_by_pk_order.sql diff --git a/dbms/tests/performance/order_by_pk_order.xml b/dbms/tests/performance/order_by_pk_order.xml deleted file mode 100644 index 7577d428160..00000000000 --- a/dbms/tests/performance/order_by_pk_order.xml +++ /dev/null @@ -1,34 +0,0 @@ - - order_by_pk_order - loop - - - - 5 - 10000 - - - 500 - 60000 - - - - - - - - - - - - - - - - - test.hits - - -SELECT CounterID FROM test.hits ORDER BY CounterID, EventDate DESC LIMIT 50 - - diff --git a/dbms/tests/queries/0_stateless/00940_order_by_pk_order.reference b/dbms/tests/queries/0_stateless/00940_order_by_pk_order.reference deleted file mode 100644 index 8c594b6f683..00000000000 --- a/dbms/tests/queries/0_stateless/00940_order_by_pk_order.reference +++ /dev/null @@ -1,200 +0,0 @@ -1 -2 -3 -4 -5 -6 -1 -1 -2 -3 -4 -1 -1 -1 -1 -1 -1 -2 -2 -2 -2 -2 -1 1 -1 2 -1 3 -1 4 -1 5 -1 6 -2 1 -2 1 -2 2 -2 3 -2 4 -2 1 -2 1 -2 2 -2 3 -2 4 -1 1 -1 2 -1 3 -1 4 -1 5 -1 6 -1 6 -1 5 -1 4 -1 3 -1 2 -1 1 -2 4 -2 3 -2 2 -2 1 -2 1 -2 4 -2 3 -2 2 -2 1 -2 1 -1 6 -1 5 -1 4 -1 3 -1 2 -1 1 -2 -2 -2 -2 -2 -1 -1 -1 -1 -1 -1 -1 1 101 -1 2 102 -1 3 103 -1 4 104 -1 5 104 -1 6 105 -2 1 106 -2 1 107 -2 2 107 -2 3 108 -2 4 109 -2 1 106 -2 1 107 -2 2 107 -2 3 108 -2 4 109 -1 1 101 -1 2 102 -1 3 103 -1 4 104 -1 5 104 -1 6 105 -1 6 105 -1 5 104 -1 4 104 -1 3 103 -1 2 102 -1 1 101 -2 4 109 -2 3 108 -2 2 107 -2 1 106 -2 1 107 -1 1 101 -1 2 102 -1 3 103 -1 4 104 -1 5 104 -1 6 105 -2 1 107 -2 1 106 -2 2 107 -2 3 108 -2 4 109 -2 4 109 -2 3 108 -2 2 107 -2 1 106 -2 1 107 -1 6 105 -1 5 104 -1 4 104 -1 3 103 -1 2 102 -1 1 101 -2 1 107 -2 1 106 -2 2 107 -2 3 108 -2 4 109 -1 1 101 -1 2 102 -1 3 103 -1 4 104 -1 5 104 -1 6 105 -1 6 105 -1 5 104 -1 4 104 -1 3 103 -1 2 102 -1 1 101 -2 4 109 -2 3 108 -2 2 107 -2 1 107 -2 1 106 -2 4 109 -2 3 108 -2 2 107 -2 1 107 -2 1 106 -1 6 105 -1 5 104 -1 4 104 -1 3 103 -1 2 102 -1 1 101 -2019-05-05 00:00:00 -2019-05-05 00:00:00 -2019-05-05 00:00:00 -2019-05-05 00:00:00 -2019-05-05 00:00:00 -2019-05-05 00:00:00 -1249512288 -2019-05-05 00:00:00 -916059969 -2019-05-05 00:00:00 -859523951 -2019-05-05 00:00:00 -45363190 -2019-05-05 00:00:00 345522721 -2019-05-14 00:00:00 99 -2019-05-14 00:00:00 89 -2019-05-14 00:00:00 79 -2019-05-14 00:00:00 69 -2019-05-14 00:00:00 59 -2019-05-14 00:00:00 99 -2019-05-14 00:00:00 89 -2019-05-14 00:00:00 79 -2019-05-14 00:00:00 69 -2019-05-14 00:00:00 59 -2019-05-14 00:00:00 99 -2019-05-14 00:00:00 89 -2019-05-14 00:00:00 79 -2019-05-14 00:00:00 69 -2019-05-14 00:00:00 59 -2019-05-05 00:00:00 -2019-05-05 00:00:00 -2019-05-05 00:00:00 -2019-05-05 00:00:00 -2019-05-05 00:00:00 -1 5 -1 5 -1 5 -1 3 -1 3 diff --git a/dbms/tests/queries/0_stateless/00940_order_by_pk_order.sql b/dbms/tests/queries/0_stateless/00940_order_by_pk_order.sql deleted file mode 100644 index 7c370563ed7..00000000000 --- a/dbms/tests/queries/0_stateless/00940_order_by_pk_order.sql +++ /dev/null @@ -1,56 +0,0 @@ -CREATE DATABASE IF NOT EXISTS test; -DROP TABLE IF EXISTS test.pk_order; - -SET optimize_pk_order = 1; - -CREATE TABLE test.pk_order(a UInt64, b UInt64, c UInt64, d UInt64) ENGINE=MergeTree() ORDER BY (a, b); -INSERT INTO test.pk_order(a, b, c, d) VALUES (1, 1, 101, 1), (1, 2, 102, 1), (1, 3, 103, 1), (1, 4, 104, 1); -INSERT INTO test.pk_order(a, b, c, d) VALUES (1, 5, 104, 1), (1, 6, 105, 1), (2, 1, 106, 2), (2, 1, 107, 2); - -INSERT INTO test.pk_order(a, b, c, d) VALUES (2, 2, 107, 2), (2, 3, 108, 2), (2, 4, 109, 2); - -SELECT b FROM test.pk_order ORDER BY a, b; -SELECT a FROM test.pk_order ORDER BY a, b; - -SELECT a, b FROM test.pk_order ORDER BY a, b; -SELECT a, b FROM test.pk_order ORDER BY a DESC, b; -SELECT a, b FROM test.pk_order ORDER BY a, b DESC; -SELECT a, b FROM test.pk_order ORDER BY a DESC, b DESC; -SELECT a FROM test.pk_order ORDER BY a DESC; - -SELECT a, b, c FROM test.pk_order ORDER BY a, b, c; -SELECT a, b, c FROM test.pk_order ORDER BY a DESC, b, c; -SELECT a, b, c FROM test.pk_order ORDER BY a, b DESC, c; -SELECT a, b, c FROM test.pk_order ORDER BY a, b, c DESC; -SELECT a, b, c FROM test.pk_order ORDER BY a DESC, b DESC, c; -SELECT a, b, c FROM test.pk_order ORDER BY a DESC, b, c DESC; -SELECT a, b, c FROM test.pk_order ORDER BY a, b DESC, c DESC; -SELECT a, b, c FROM test.pk_order ORDER BY a DESC, b DESC, c DESC; - -DROP TABLE IF EXISTS test.pk_order; - -CREATE TABLE pk_order (d DateTime, a Int32, b Int32) ENGINE = MergeTree ORDER BY (d, a) - PARTITION BY toDate(d) SETTINGS index_granularity=1; - -INSERT INTO pk_order - SELECT toDateTime('2019-05-05 00:00:00') + INTERVAL number % 10 DAY, number, intHash32(number) from numbers(100); - -set max_block_size = 1; - --- Currently checking number of read rows while reading in pk order not working precise. TODO: fix it. --- SET max_rows_to_read = 10; - -SELECT d FROM pk_order ORDER BY d LIMIT 5; -SELECT d, b FROM pk_order ORDER BY d, b LIMIT 5; -SELECT d, a FROM pk_order ORDER BY d DESC, a DESC LIMIT 5; -SELECT d, a FROM pk_order ORDER BY d DESC, -a LIMIT 5; -SELECT d, a FROM pk_order ORDER BY d DESC, a DESC LIMIT 5; -SELECT toStartOfHour(d) as d1 FROM pk_order ORDER BY d1 LIMIT 5; - -DROP TABLE pk_order; - -CREATE TABLE pk_order (a Int, b Int) ENGINE = MergeTree ORDER BY (a / b); -INSERT INTO pk_order SELECT number % 10 + 1, number % 6 + 1 from numbers(100); -SELECT * FROM pk_order ORDER BY (a / b), a LIMIT 5; - - diff --git a/dbms/tests/queries/1_stateful/00151_order_by_pk_order.reference b/dbms/tests/queries/1_stateful/00151_order_by_pk_order.reference deleted file mode 100644 index 551357900df..00000000000 --- a/dbms/tests/queries/1_stateful/00151_order_by_pk_order.reference +++ /dev/null @@ -1,600 +0,0 @@ -33554106 -33554106 -33553911 -33553911 -33553911 -33553911 -33553911 -33553828 -33553772 -33553718 -33553718 -33553673 -33553673 -33553673 -33553673 -33553362 -33553353 -33553353 -33553353 -33553353 -33553353 -33553353 -33553004 -33553004 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -2014-03-17 -2014-03-17 -2014-03-17 -2014-03-17 -2014-03-17 -2014-03-17 -2014-03-17 -2014-03-17 -2014-03-17 -2014-03-17 -2014-03-17 -2014-03-17 -2014-03-17 -2014-03-17 -2014-03-17 -2014-03-17 -2014-03-17 -2014-03-17 -2014-03-17 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-18 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -57 -33554106 -33554106 -33553911 -33553911 -33553911 -33553911 -33553911 -33553828 -33553772 -33553718 -33553718 -33553673 -33553673 -33553673 -33553673 -33553362 -33553353 -33553353 -33553353 -33553353 -33553353 -33553353 -33553004 -33553004 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -33552322 -2014-03-21 -2014-03-21 -2014-03-23 -2014-03-23 -2014-03-20 -2014-03-20 -2014-03-20 -2014-03-17 -2014-03-19 -2014-03-23 -2014-03-23 -2014-03-20 -2014-03-20 -2014-03-18 -2014-03-18 -2014-03-17 -2014-03-21 -2014-03-21 -2014-03-21 -2014-03-21 -2014-03-21 -2014-03-21 -2014-03-17 -2014-03-17 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-23 -2014-03-22 -57 2014-03-17 -57 2014-03-17 -57 2014-03-17 -57 2014-03-17 -57 2014-03-17 -57 2014-03-17 -57 2014-03-17 -57 2014-03-17 -57 2014-03-17 -57 2014-03-17 -57 2014-03-17 -57 2014-03-17 -57 2014-03-17 -57 2014-03-17 -57 2014-03-17 -57 2014-03-17 -57 2014-03-17 -57 2014-03-17 -57 2014-03-17 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-18 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -57 2014-03-23 -33554106 2014-03-21 -33554106 2014-03-21 -33553911 2014-03-20 -33553911 2014-03-20 -33553911 2014-03-20 -33553911 2014-03-23 -33553911 2014-03-23 -33553828 2014-03-17 -33553772 2014-03-19 -33553718 2014-03-23 -33553718 2014-03-23 -33553673 2014-03-18 -33553673 2014-03-18 -33553673 2014-03-20 -33553673 2014-03-20 -33553362 2014-03-17 -33553353 2014-03-21 -33553353 2014-03-21 -33553353 2014-03-21 -33553353 2014-03-21 -33553353 2014-03-21 -33553353 2014-03-21 -33553004 2014-03-17 -33553004 2014-03-17 -33552322 2014-03-17 -33552322 2014-03-17 -33552322 2014-03-17 -33552322 2014-03-17 -33552322 2014-03-17 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33552322 2014-03-18 -33554106 2014-03-21 -33554106 2014-03-21 -33553911 2014-03-23 -33553911 2014-03-23 -33553911 2014-03-20 -33553911 2014-03-20 -33553911 2014-03-20 -33553828 2014-03-17 -33553772 2014-03-19 -33553718 2014-03-23 -33553718 2014-03-23 -33553673 2014-03-20 -33553673 2014-03-20 -33553673 2014-03-18 -33553673 2014-03-18 -33553362 2014-03-17 -33553353 2014-03-21 -33553353 2014-03-21 -33553353 2014-03-21 -33553353 2014-03-21 -33553353 2014-03-21 -33553353 2014-03-21 -33553004 2014-03-17 -33553004 2014-03-17 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-23 -33552322 2014-03-22 diff --git a/dbms/tests/queries/1_stateful/00151_order_by_pk_order.sql b/dbms/tests/queries/1_stateful/00151_order_by_pk_order.sql deleted file mode 100644 index 141640029bf..00000000000 --- a/dbms/tests/queries/1_stateful/00151_order_by_pk_order.sql +++ /dev/null @@ -1,14 +0,0 @@ -SET optimize_pk_order = 1; -SELECT CounterID FROM test.hits ORDER BY CounterID DESC LIMIT 50; -SELECT CounterID FROM test.hits ORDER BY CounterID LIMIT 50; -SELECT CounterID FROM test.hits ORDER BY CounterID, EventDate LIMIT 50; -SELECT EventDate FROM test.hits ORDER BY CounterID, EventDate LIMIT 50; -SELECT EventDate FROM test.hits ORDER BY CounterID, EventDate DESC LIMIT 50; -SELECT CounterID FROM test.hits ORDER BY CounterID, EventDate DESC LIMIT 50; -SELECT CounterID FROM test.hits ORDER BY CounterID DESC, EventDate DESC LIMIT 50; -SELECT EventDate FROM test.hits ORDER BY CounterID DESC, EventDate DESC LIMIT 50; - -SELECT CounterID, EventDate FROM test.hits ORDER BY CounterID, EventDate LIMIT 50; -SELECT CounterID, EventDate FROM test.hits ORDER BY CounterID, EventDate DESC LIMIT 50; -SELECT CounterID, EventDate FROM test.hits ORDER BY CounterID DESC, EventDate LIMIT 50; -SELECT CounterID, EventDate FROM test.hits ORDER BY CounterID DESC, EventDate DESC LIMIT 50; From ec33f4bd2aecb540efc5321bc16a2a1456fdae8d Mon Sep 17 00:00:00 2001 From: Yuriy Date: Sun, 28 Jul 2019 04:34:48 +0300 Subject: [PATCH 0409/1165] fixed style --- dbms/src/Core/MySQLProtocol.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index 6a0e7c49f4b..cb0e6ab001c 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -302,7 +302,9 @@ protected: { // Starting new packet, since packets of size greater than MAX_PACKET_LENGTH should be split. startPacket(); - } else { + } + else + { // Finished writing packet. Buffer is set to empty to prevent rewriting (pos will be set to the beginning of a working buffer in next()). // Further attempts to write will stall in the infinite loop. working_buffer = WriteBuffer::Buffer(out.position(), out.position()); From 9819ca8119e8a92d2eeee894d7ed7c291feac863 Mon Sep 17 00:00:00 2001 From: Doge Date: Sun, 28 Jul 2019 14:22:07 +0800 Subject: [PATCH 0410/1165] fix some spelling mistakes in chinese doc Change-Id: I8174ce04ac92a3cf5cec41ccba8351e99d1a6d1b --- docs/zh/development/architecture.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/zh/development/architecture.md b/docs/zh/development/architecture.md index ad00ce932d1..dd6c96bf113 100644 --- a/docs/zh/development/architecture.md +++ b/docs/zh/development/architecture.md @@ -1,8 +1,8 @@ # ClickHouse 架构概述 -ClickHouse 是一个真正的列式数据库管理系统(DBMS)。在 ClickHouse 中,数据始终是按列存储的,包括失量(向量或列块)执行的过程。只要有可能,操作都是基于失量进行分派的,而不是单个的值,这被称为“矢量化查询执行”,它有利于降低实际的数据处理开销。 +ClickHouse 是一个真正的列式数据库管理系统(DBMS)。在 ClickHouse 中,数据始终是按列存储的,包括矢量(向量或列块)执行的过程。只要有可能,操作都是基于矢量进行分派的,而不是单个的值,这被称为“矢量化查询执行”,它有利于降低实际的数据处理开销。 -> 这个想法并不新鲜,其可以追溯到 `APL` 编程语言及其后代:`A +`、`J`、`K` 和 `Q`。失量编程被大量用于科学数据处理中。即使在关系型数据库中,这个想法也不是什么新的东西:比如,失量编程也被大量用于 `Vectorwise` 系统中。 +> 这个想法并不新鲜,其可以追溯到 `APL` 编程语言及其后代:`A +`、`J`、`K` 和 `Q`。矢量编程被大量用于科学数据处理中。即使在关系型数据库中,这个想法也不是什么新的东西:比如,矢量编程也被大量用于 `Vectorwise` 系统中。 通常有两种不同的加速查询处理的方法:矢量化查询执行和运行时代码生成。在后者中,动态地为每一类查询生成代码,消除了间接分派和动态分派。这两种方法中,并没有哪一种严格地比另一种好。运行时代码生成可以更好地将多个操作融合在一起,从而充分利用 CPU 执行单元和流水线。矢量化查询执行不是特别实用,因为它涉及必须写到缓存并读回的临时向量。如果 L2 缓存容纳不下临时数据,那么这将成为一个问题。但矢量化查询执行更容易利用 CPU 的 SIMD 功能。朋友写的一篇[研究论文](http://15721.courses.cs.cmu.edu/spring2016/papers/p5-sompolski.pdf)表明,将两种方法结合起来是更好的选择。ClickHouse 使用了矢量化查询执行,同时初步提供了有限的运行时动态代码生成。 From b91c0c8c9b784b38c5dca5e8003125b15fa8bea9 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Sun, 28 Jul 2019 11:50:01 +0300 Subject: [PATCH 0411/1165] Update Settings.h --- dbms/src/Core/Settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Core/Settings.h b/dbms/src/Core/Settings.h index 4dfe0257b1c..60f2599c73f 100644 --- a/dbms/src/Core/Settings.h +++ b/dbms/src/Core/Settings.h @@ -322,7 +322,7 @@ struct Settings : public SettingsCollection M(SettingBool, parallel_view_processing, false, "Enables pushing to attached views concurrently instead of sequentially.") \ M(SettingBool, enable_debug_queries, false, "Enables debug queries such as AST.") \ M(SettingBool, enable_unaligned_array_join, false, "Allow ARRAY JOIN with multiple arrays that have different sizes. When this settings is enabled, arrays will be resized to the longest one.") \ - M(SettingBool, optimize_read_in_order, true, "Enable order by optimization in reading in primary key order.") \ + M(SettingBool, optimize_read_in_order, true, "Enable ORDER BY optimization for reading data in corresponding order in MergeTree tables.") \ M(SettingBool, low_cardinality_allow_in_native_format, true, "Use LowCardinality type in Native format. Otherwise, convert LowCardinality columns to ordinary for select query, and convert ordinary columns to required LowCardinality for insert query.") \ M(SettingBool, allow_experimental_multiple_joins_emulation, true, "Emulate multiple joins using subselects") \ M(SettingBool, allow_experimental_cross_to_join_conversion, true, "Convert CROSS JOIN to INNER JOIN if possible") \ From 63fe71442003a17c708247731484365a183faba8 Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Sun, 28 Jul 2019 14:10:35 +0300 Subject: [PATCH 0412/1165] fix --- .../MergeTree/IMergedBlockOutputStream.cpp | 105 ++++++++++++++++ .../MergeTree/IMergedBlockOutputStream.h | 15 ++- .../MergeTree/MergeTreeDataMergerMutator.cpp | 1 - .../MergeTree/MergedBlockOutputStream.cpp | 114 ++---------------- .../MergeTree/MergedBlockOutputStream.h | 7 -- .../MergedColumnOnlyOutputStream.cpp | 108 ++--------------- .../MergeTree/MergedColumnOnlyOutputStream.h | 8 -- 7 files changed, 140 insertions(+), 218 deletions(-) diff --git a/dbms/src/Storages/MergeTree/IMergedBlockOutputStream.cpp b/dbms/src/Storages/MergeTree/IMergedBlockOutputStream.cpp index fc19fbd6792..a7475ae7c18 100644 --- a/dbms/src/Storages/MergeTree/IMergedBlockOutputStream.cpp +++ b/dbms/src/Storages/MergeTree/IMergedBlockOutputStream.cpp @@ -12,18 +12,22 @@ namespace ErrorCodes namespace { constexpr auto DATA_FILE_EXTENSION = ".bin"; + constexpr auto INDEX_FILE_EXTENSION = ".idx"; } IMergedBlockOutputStream::IMergedBlockOutputStream( MergeTreeData & storage_, + String part_path_, size_t min_compress_block_size_, size_t max_compress_block_size_, CompressionCodecPtr codec_, size_t aio_threshold_, bool blocks_are_granules_size_, + const std::vector & indices_to_recalc, const MergeTreeIndexGranularity & index_granularity_) : storage(storage_) + , part_path(part_path_) , min_compress_block_size(min_compress_block_size_) , max_compress_block_size(max_compress_block_size_) , aio_threshold(aio_threshold_) @@ -32,6 +36,7 @@ IMergedBlockOutputStream::IMergedBlockOutputStream( , index_granularity(index_granularity_) , compute_granularity(index_granularity.empty()) , codec(std::move(codec_)) + , skip_indices(indices_to_recalc) , with_final_mark(storage.settings.write_final_mark && storage.canUseAdaptiveGranularity()) { if (blocks_are_granules_size && !index_granularity.empty()) @@ -304,6 +309,106 @@ void IMergedBlockOutputStream::writeFinalMark( }, path); } +void IMergedBlockOutputStream::initSkipIndices() +{ + for (const auto & index : skip_indices) + { + String stream_name = index->getFileName(); + skip_indices_streams.emplace_back( + std::make_unique( + stream_name, + part_path + stream_name, INDEX_FILE_EXTENSION, + part_path + stream_name, marks_file_extension, + codec, max_compress_block_size, + 0, aio_threshold)); + skip_indices_aggregators.push_back(index->createIndexAggregator()); + skip_index_filling.push_back(0); + } +} + +void IMergedBlockOutputStream::calculateAndSerializeSkipIndices( + const ColumnsWithTypeAndName & skip_indexes_columns, size_t rows) +{ + /// Creating block for update + Block indices_update_block(skip_indexes_columns); + size_t skip_index_current_mark = 0; + + /// Filling and writing skip indices like in IMergedBlockOutputStream::writeColumn + for (size_t i = 0; i < storage.skip_indices.size(); ++i) + { + const auto index = storage.skip_indices[i]; + auto & stream = *skip_indices_streams[i]; + size_t prev_pos = 0; + skip_index_current_mark = skip_index_mark; + while (prev_pos < rows) + { + UInt64 limit = 0; + if (prev_pos == 0 && index_offset != 0) + { + limit = index_offset; + } + else + { + limit = index_granularity.getMarkRows(skip_index_current_mark); + if (skip_indices_aggregators[i]->empty()) + { + skip_indices_aggregators[i] = index->createIndexAggregator(); + skip_index_filling[i] = 0; + + if (stream.compressed.offset() >= min_compress_block_size) + stream.compressed.next(); + + writeIntBinary(stream.plain_hashing.count(), stream.marks); + writeIntBinary(stream.compressed.offset(), stream.marks); + /// Actually this numbers is redundant, but we have to store them + /// to be compatible with normal .mrk2 file format + if (storage.canUseAdaptiveGranularity()) + writeIntBinary(1UL, stream.marks); + + ++skip_index_current_mark; + } + } + + size_t pos = prev_pos; + skip_indices_aggregators[i]->update(indices_update_block, &pos, limit); + + if (pos == prev_pos + limit) + { + ++skip_index_filling[i]; + + /// write index if it is filled + if (skip_index_filling[i] == index->granularity) + { + skip_indices_aggregators[i]->getGranuleAndReset()->serializeBinary(stream.compressed); + skip_index_filling[i] = 0; + } + } + prev_pos = pos; + } + } + skip_index_mark = skip_index_current_mark; +} + +void IMergedBlockOutputStream::finishSkipIndicesSerialization( + MergeTreeData::DataPart::Checksums & checksums) +{ + for (size_t i = 0; i < skip_indices.size(); ++i) + { + auto & stream = *skip_indices_streams[i]; + if (!skip_indices_aggregators[i]->empty()) + skip_indices_aggregators[i]->getGranuleAndReset()->serializeBinary(stream.compressed); + } + + for (auto & stream : skip_indices_streams) + { + stream->finalize(); + stream->addToChecksums(checksums); + } + + skip_indices_streams.clear(); + skip_indices_aggregators.clear(); + skip_index_filling.clear(); +} /// Implementation of IMergedBlockOutputStream::ColumnStream. diff --git a/dbms/src/Storages/MergeTree/IMergedBlockOutputStream.h b/dbms/src/Storages/MergeTree/IMergedBlockOutputStream.h index b9d083f3a19..276a5c37d17 100644 --- a/dbms/src/Storages/MergeTree/IMergedBlockOutputStream.h +++ b/dbms/src/Storages/MergeTree/IMergedBlockOutputStream.h @@ -16,11 +16,13 @@ class IMergedBlockOutputStream : public IBlockOutputStream public: IMergedBlockOutputStream( MergeTreeData & storage_, + String part_path_, size_t min_compress_block_size_, size_t max_compress_block_size_, CompressionCodecPtr default_codec_, size_t aio_threshold_, bool blocks_are_granules_size_, + const std::vector & indices_to_recalc, const MergeTreeIndexGranularity & index_granularity_); using WrittenOffsetColumns = std::set; @@ -117,10 +119,15 @@ protected: bool skip_offsets, DB::IDataType::SubstreamPath & path); + void initSkipIndices(); + void calculateAndSerializeSkipIndices(const ColumnsWithTypeAndName & skip_indexes_columns, size_t rows); + void finishSkipIndicesSerialization(MergeTreeData::DataPart::Checksums & checksums); protected: - MergeTreeData & storage; + SerializationStates serialization_states; + String part_path; + ColumnStreams column_streams; /// The offset to the first row of the block for which you want to write the index. @@ -132,6 +139,7 @@ protected: size_t aio_threshold; size_t current_mark = 0; + size_t skip_index_mark = 0; const std::string marks_file_extension; const bool blocks_are_granules_size; @@ -141,6 +149,11 @@ protected: const bool compute_granularity; CompressionCodecPtr codec; + std::vector skip_indices; + std::vector> skip_indices_streams; + MergeTreeIndexAggregators skip_indices_aggregators; + std::vector skip_index_filling; + const bool with_final_mark; }; diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp index c7e853aa647..27d013da32b 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp @@ -1000,7 +1000,6 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mutatePartToTempor } } } - /// TODO: add indices from materialize if (!indices_to_recalc.empty()) { diff --git a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp index b3a481b48c5..703cf0dd01b 100644 --- a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp @@ -18,11 +18,6 @@ namespace ErrorCodes extern const int BAD_ARGUMENTS; } -namespace -{ - constexpr auto INDEX_FILE_EXTENSION = ".idx"; -} - MergedBlockOutputStream::MergedBlockOutputStream( MergeTreeData & storage_, @@ -31,12 +26,13 @@ MergedBlockOutputStream::MergedBlockOutputStream( CompressionCodecPtr default_codec_, bool blocks_are_granules_size_) : IMergedBlockOutputStream( - storage_, storage_.global_context.getSettings().min_compress_block_size, + storage_, part_path_, storage_.global_context.getSettings().min_compress_block_size, storage_.global_context.getSettings().max_compress_block_size, default_codec_, storage_.global_context.getSettings().min_bytes_to_use_direct_io, blocks_are_granules_size_, - {}), - columns_list(columns_list_), part_path(part_path_) + std::vector(std::begin(storage_.skip_indices), std::end(storage_.skip_indices)), + {}) + , columns_list(columns_list_) { init(); for (const auto & it : columns_list) @@ -55,10 +51,11 @@ MergedBlockOutputStream::MergedBlockOutputStream( size_t aio_threshold_, bool blocks_are_granules_size_) : IMergedBlockOutputStream( - storage_, storage_.global_context.getSettings().min_compress_block_size, + storage_, part_path_, storage_.global_context.getSettings().min_compress_block_size, storage_.global_context.getSettings().max_compress_block_size, default_codec_, - aio_threshold_, blocks_are_granules_size_, {}), - columns_list(columns_list_), part_path(part_path_) + aio_threshold_, blocks_are_granules_size_, + std::vector(std::begin(storage_.skip_indices), std::end(storage_.skip_indices)), {}) + , columns_list(columns_list_) { init(); @@ -134,15 +131,6 @@ void MergedBlockOutputStream::writeSuffixAndFinalizePart( if (with_final_mark && rows_count != 0) index_granularity.appendMark(0); /// last mark - /// Finish skip index serialization - for (size_t i = 0; i < storage.skip_indices.size(); ++i) - { - auto & stream = *skip_indices_streams[i]; - if (!skip_indices_aggregators[i]->empty()) - skip_indices_aggregators[i]->getGranuleAndReset()->serializeBinary(stream.compressed); - } - - if (!total_column_list) total_column_list = &columns_list; @@ -171,22 +159,14 @@ void MergedBlockOutputStream::writeSuffixAndFinalizePart( index_stream = nullptr; } - for (auto & stream : skip_indices_streams) - { - stream->finalize(); - stream->addToChecksums(checksums); - } - - skip_indices_streams.clear(); - skip_indices_aggregators.clear(); - skip_index_filling.clear(); - for (ColumnStreams::iterator it = column_streams.begin(); it != column_streams.end(); ++it) { it->second->finalize(); it->second->addToChecksums(checksums); } + finishSkipIndicesSerialization(checksums); + column_streams.clear(); if (storage.format_version >= MERGE_TREE_DATA_MIN_FORMAT_VERSION_WITH_CUSTOM_PARTITIONING) @@ -248,19 +228,7 @@ void MergedBlockOutputStream::init() index_stream = std::make_unique(*index_file_stream); } - for (const auto & index : storage.skip_indices) - { - String stream_name = index->getFileName(); - skip_indices_streams.emplace_back( - std::make_unique( - stream_name, - part_path + stream_name, INDEX_FILE_EXTENSION, - part_path + stream_name, marks_file_extension, - codec, max_compress_block_size, - 0, aio_threshold)); - skip_indices_aggregators.push_back(index->createIndexAggregator()); - skip_index_filling.push_back(0); - } + initSkipIndices(); } @@ -380,66 +348,8 @@ void MergedBlockOutputStream::writeImpl(const Block & block, const IColumn::Perm } rows_count += rows; - { - /// Creating block for update - Block indices_update_block(skip_indexes_columns); - size_t skip_index_current_mark = 0; - /// Filling and writing skip indices like in IMergedBlockOutputStream::writeColumn - for (size_t i = 0; i < storage.skip_indices.size(); ++i) - { - const auto index = storage.skip_indices[i]; - auto & stream = *skip_indices_streams[i]; - size_t prev_pos = 0; - skip_index_current_mark = skip_index_mark; - while (prev_pos < rows) - { - UInt64 limit = 0; - if (prev_pos == 0 && index_offset != 0) - { - limit = index_offset; - } - else - { - limit = index_granularity.getMarkRows(skip_index_current_mark); - if (skip_indices_aggregators[i]->empty()) - { - skip_indices_aggregators[i] = index->createIndexAggregator(); - skip_index_filling[i] = 0; - - if (stream.compressed.offset() >= min_compress_block_size) - stream.compressed.next(); - - writeIntBinary(stream.plain_hashing.count(), stream.marks); - writeIntBinary(stream.compressed.offset(), stream.marks); - /// Actually this numbers is redundant, but we have to store them - /// to be compatible with normal .mrk2 file format - if (storage.canUseAdaptiveGranularity()) - writeIntBinary(1UL, stream.marks); - - ++skip_index_current_mark; - } - } - - size_t pos = prev_pos; - skip_indices_aggregators[i]->update(indices_update_block, &pos, limit); - - if (pos == prev_pos + limit) - { - ++skip_index_filling[i]; - - /// write index if it is filled - if (skip_index_filling[i] == index->granularity) - { - skip_indices_aggregators[i]->getGranuleAndReset()->serializeBinary(stream.compressed); - skip_index_filling[i] = 0; - } - } - prev_pos = pos; - } - } - skip_index_mark = skip_index_current_mark; - } + calculateAndSerializeSkipIndices(skip_indexes_columns, rows); { /** While filling index (index_columns), disable memory tracker. diff --git a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.h b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.h index 3acb01c3c0a..4efb5b528a0 100644 --- a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.h +++ b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.h @@ -64,11 +64,8 @@ private: private: NamesAndTypesList columns_list; - SerializationStates serialization_states; - String part_path; size_t rows_count = 0; - size_t skip_index_mark = 0; std::unique_ptr index_file_stream; std::unique_ptr index_stream; @@ -76,10 +73,6 @@ private: /// Index columns values from the last row from the last block /// It's written to index file in the `writeSuffixAndFinalizePart` method ColumnsWithTypeAndName last_index_row; - - std::vector> skip_indices_streams; - MergeTreeIndexAggregators skip_indices_aggregators; - std::vector skip_index_filling; }; } diff --git a/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp b/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp index d8eaef2a781..68f033cf401 100644 --- a/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp @@ -3,10 +3,6 @@ namespace DB { -namespace -{ - constexpr auto INDEX_FILE_EXTENSION = ".idx"; -} MergedColumnOnlyOutputStream::MergedColumnOnlyOutputStream( MergeTreeData & storage_, const Block & header_, String part_path_, bool sync_, @@ -15,13 +11,14 @@ MergedColumnOnlyOutputStream::MergedColumnOnlyOutputStream( WrittenOffsetColumns & already_written_offset_columns, const MergeTreeIndexGranularity & index_granularity_) : IMergedBlockOutputStream( - storage_, storage_.global_context.getSettings().min_compress_block_size, + storage_, part_path_, storage_.global_context.getSettings().min_compress_block_size, storage_.global_context.getSettings().max_compress_block_size, default_codec_, storage_.global_context.getSettings().min_bytes_to_use_direct_io, - false, - index_granularity_), - header(header_), part_path(part_path_), sync(sync_), skip_offsets(skip_offsets_), - skip_indices(indices_to_recalc), already_written_offset_columns(already_written_offset_columns) + false, indices_to_recalc, index_granularity_) + , header(header_) + , sync(sync_) + , skip_offsets(skip_offsets_) + , already_written_offset_columns(already_written_offset_columns) { } @@ -46,19 +43,7 @@ void MergedColumnOnlyOutputStream::write(const Block & block) col.type->serializeBinaryBulkStatePrefix(settings, serialization_states.back()); } - for (const auto & index : skip_indices) - { - String stream_name = index->getFileName(); - skip_indices_streams.emplace_back( - std::make_unique( - stream_name, - part_path + stream_name, INDEX_FILE_EXTENSION, - part_path + stream_name, marks_file_extension, - codec, max_compress_block_size, - 0, aio_threshold)); - skip_indices_aggregators.push_back(index->createIndexAggregator()); - skip_index_filling.push_back(0); - } + initSkipIndices(); initialized = true; } @@ -82,66 +67,7 @@ void MergedColumnOnlyOutputStream::write(const Block & block) if (!rows) return; - { - /// Creating block for update - Block indices_update_block(skip_indexes_columns); - size_t skip_index_current_mark = 0; - - /// Filling and writing skip indices like in IMergedBlockOutputStream::writeColumn - for (size_t i = 0; i < storage.skip_indices.size(); ++i) - { - const auto index = storage.skip_indices[i]; - auto & stream = *skip_indices_streams[i]; - size_t prev_pos = 0; - skip_index_current_mark = skip_index_mark; - while (prev_pos < rows) - { - UInt64 limit = 0; - if (prev_pos == 0 && index_offset != 0) - { - limit = index_offset; - } - else - { - limit = index_granularity.getMarkRows(skip_index_current_mark); - if (skip_indices_aggregators[i]->empty()) - { - skip_indices_aggregators[i] = index->createIndexAggregator(); - skip_index_filling[i] = 0; - - if (stream.compressed.offset() >= min_compress_block_size) - stream.compressed.next(); - - writeIntBinary(stream.plain_hashing.count(), stream.marks); - writeIntBinary(stream.compressed.offset(), stream.marks); - /// Actually this numbers is redundant, but we have to store them - /// to be compatible with normal .mrk2 file format - if (storage.canUseAdaptiveGranularity()) - writeIntBinary(1UL, stream.marks); - - ++skip_index_current_mark; - } - } - - size_t pos = prev_pos; - skip_indices_aggregators[i]->update(indices_update_block, &pos, limit); - - if (pos == prev_pos + limit) - { - ++skip_index_filling[i]; - - /// write index if it is filled - if (skip_index_filling[i] == index->granularity) - { - skip_indices_aggregators[i]->getGranuleAndReset()->serializeBinary(stream.compressed); - skip_index_filling[i] = 0; - } - } - prev_pos = pos; - } - } - skip_index_mark = skip_index_current_mark; - } + calculateAndSerializeSkipIndices(skip_indexes_columns, rows); size_t new_index_offset = 0; size_t new_current_mark = 0; @@ -181,14 +107,6 @@ MergeTreeData::DataPart::Checksums MergedColumnOnlyOutputStream::writeSuffixAndG writeFinalMark(column.name, column.type, offset_columns, skip_offsets, serialize_settings.path); } - /// Finish skip index serialization - for (size_t i = 0; i < skip_indices.size(); ++i) - { - auto & stream = *skip_indices_streams[i]; - if (!skip_indices_aggregators[i]->empty()) - skip_indices_aggregators[i]->getGranuleAndReset()->serializeBinary(stream.compressed); - } - MergeTreeData::DataPart::Checksums checksums; for (auto & column_stream : column_streams) @@ -200,20 +118,12 @@ MergeTreeData::DataPart::Checksums MergedColumnOnlyOutputStream::writeSuffixAndG column_stream.second->addToChecksums(checksums); } - for (auto & stream : skip_indices_streams) - { - stream->finalize(); - stream->addToChecksums(checksums); - } + finishSkipIndicesSerialization(checksums); column_streams.clear(); serialization_states.clear(); initialized = false; - skip_indices_streams.clear(); - skip_indices_aggregators.clear(); - skip_index_filling.clear(); - return checksums; } diff --git a/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.h b/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.h index 645e9f2ff36..7daaf03fd66 100644 --- a/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.h +++ b/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.h @@ -26,18 +26,10 @@ public: private: Block header; - SerializationStates serialization_states; - String part_path; bool initialized = false; bool sync; bool skip_offsets; - size_t skip_index_mark = 0; - - std::vector skip_indices; - std::vector> skip_indices_streams; - MergeTreeIndexAggregators skip_indices_aggregators; - std::vector skip_index_filling; /// To correctly write Nested elements column-by-column. WrittenOffsetColumns & already_written_offset_columns; From 908623c029a0a2ed6ee0c19b7f94efb39049842e Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Sun, 28 Jul 2019 14:32:03 +0300 Subject: [PATCH 0413/1165] style --- dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp b/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp index 68f033cf401..129a84d1e76 100644 --- a/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp @@ -3,7 +3,6 @@ namespace DB { - MergedColumnOnlyOutputStream::MergedColumnOnlyOutputStream( MergeTreeData & storage_, const Block & header_, String part_path_, bool sync_, CompressionCodecPtr default_codec_, bool skip_offsets_, From 4c5003b3b9fc593ccbb031ec4e4e30cec081b13d Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Sun, 28 Jul 2019 14:45:50 +0300 Subject: [PATCH 0414/1165] const & --- dbms/src/Storages/MergeTree/IMergedBlockOutputStream.cpp | 2 +- dbms/src/Storages/MergeTree/IMergedBlockOutputStream.h | 2 +- dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp | 4 ++-- dbms/src/Storages/MergeTree/MergedBlockOutputStream.h | 4 ++-- dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp | 2 +- dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.h | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dbms/src/Storages/MergeTree/IMergedBlockOutputStream.cpp b/dbms/src/Storages/MergeTree/IMergedBlockOutputStream.cpp index a7475ae7c18..8321d7dc8b2 100644 --- a/dbms/src/Storages/MergeTree/IMergedBlockOutputStream.cpp +++ b/dbms/src/Storages/MergeTree/IMergedBlockOutputStream.cpp @@ -18,7 +18,7 @@ namespace IMergedBlockOutputStream::IMergedBlockOutputStream( MergeTreeData & storage_, - String part_path_, + const String & part_path_, size_t min_compress_block_size_, size_t max_compress_block_size_, CompressionCodecPtr codec_, diff --git a/dbms/src/Storages/MergeTree/IMergedBlockOutputStream.h b/dbms/src/Storages/MergeTree/IMergedBlockOutputStream.h index 276a5c37d17..f1fbb058436 100644 --- a/dbms/src/Storages/MergeTree/IMergedBlockOutputStream.h +++ b/dbms/src/Storages/MergeTree/IMergedBlockOutputStream.h @@ -16,7 +16,7 @@ class IMergedBlockOutputStream : public IBlockOutputStream public: IMergedBlockOutputStream( MergeTreeData & storage_, - String part_path_, + const String & part_path_, size_t min_compress_block_size_, size_t max_compress_block_size_, CompressionCodecPtr default_codec_, diff --git a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp index 703cf0dd01b..b923337d71a 100644 --- a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.cpp @@ -21,7 +21,7 @@ namespace ErrorCodes MergedBlockOutputStream::MergedBlockOutputStream( MergeTreeData & storage_, - String part_path_, + const String & part_path_, const NamesAndTypesList & columns_list_, CompressionCodecPtr default_codec_, bool blocks_are_granules_size_) @@ -44,7 +44,7 @@ MergedBlockOutputStream::MergedBlockOutputStream( MergedBlockOutputStream::MergedBlockOutputStream( MergeTreeData & storage_, - String part_path_, + const String & part_path_, const NamesAndTypesList & columns_list_, CompressionCodecPtr default_codec_, const MergeTreeData::DataPart::ColumnToSize & merged_column_to_size_, diff --git a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.h b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.h index 4efb5b528a0..ff45934f106 100644 --- a/dbms/src/Storages/MergeTree/MergedBlockOutputStream.h +++ b/dbms/src/Storages/MergeTree/MergedBlockOutputStream.h @@ -15,14 +15,14 @@ class MergedBlockOutputStream final : public IMergedBlockOutputStream public: MergedBlockOutputStream( MergeTreeData & storage_, - String part_path_, + const String & part_path_, const NamesAndTypesList & columns_list_, CompressionCodecPtr default_codec_, bool blocks_are_granules_size_ = false); MergedBlockOutputStream( MergeTreeData & storage_, - String part_path_, + const String & part_path_, const NamesAndTypesList & columns_list_, CompressionCodecPtr default_codec_, const MergeTreeData::DataPart::ColumnToSize & merged_column_to_size_, diff --git a/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp b/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp index 129a84d1e76..a694d509b68 100644 --- a/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.cpp @@ -4,7 +4,7 @@ namespace DB { MergedColumnOnlyOutputStream::MergedColumnOnlyOutputStream( - MergeTreeData & storage_, const Block & header_, String part_path_, bool sync_, + MergeTreeData & storage_, const Block & header_, const String & part_path_, bool sync_, CompressionCodecPtr default_codec_, bool skip_offsets_, const std::vector & indices_to_recalc, WrittenOffsetColumns & already_written_offset_columns, diff --git a/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.h b/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.h index 7daaf03fd66..adf5d7f7bfd 100644 --- a/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.h +++ b/dbms/src/Storages/MergeTree/MergedColumnOnlyOutputStream.h @@ -13,7 +13,7 @@ public: /// Pass empty 'already_written_offset_columns' first time then and pass the same object to subsequent instances of MergedColumnOnlyOutputStream /// if you want to serialize elements of Nested data structure in different instances of MergedColumnOnlyOutputStream. MergedColumnOnlyOutputStream( - MergeTreeData & storage_, const Block & header_, String part_path_, bool sync_, + MergeTreeData & storage_, const Block & header_, const String & part_path_, bool sync_, CompressionCodecPtr default_codec_, bool skip_offsets_, const std::vector & indices_to_recalc, WrittenOffsetColumns & already_written_offset_columns, From 538c17be3f6c719b377d350e81462be775b7891c Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Sun, 28 Jul 2019 14:56:16 +0300 Subject: [PATCH 0415/1165] replicated test --- ...es_mutation_replicated_zookeeper.reference | 6 ++ ...5_indices_mutation_replicated_zookeeper.sh | 61 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00975_indices_mutation_replicated_zookeeper.reference create mode 100644 dbms/tests/queries/0_stateless/00975_indices_mutation_replicated_zookeeper.sh diff --git a/dbms/tests/queries/0_stateless/00975_indices_mutation_replicated_zookeeper.reference b/dbms/tests/queries/0_stateless/00975_indices_mutation_replicated_zookeeper.reference new file mode 100644 index 00000000000..9c5382e5cbe --- /dev/null +++ b/dbms/tests/queries/0_stateless/00975_indices_mutation_replicated_zookeeper.reference @@ -0,0 +1,6 @@ +2 + "rows_read": 4, +2 + "rows_read": 6, +2 + "rows_read": 4, diff --git a/dbms/tests/queries/0_stateless/00975_indices_mutation_replicated_zookeeper.sh b/dbms/tests/queries/0_stateless/00975_indices_mutation_replicated_zookeeper.sh new file mode 100644 index 00000000000..4490487663f --- /dev/null +++ b/dbms/tests/queries/0_stateless/00975_indices_mutation_replicated_zookeeper.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +. $CURDIR/../shell_config.sh + +$CLICKHOUSE_CLIENT --query="DROP TABLE IF EXISTS test.minmax_idx;" + + +$CLICKHOUSE_CLIENT -n --query=" +SET allow_experimental_data_skipping_indices=1; +CREATE TABLE test.indices_mutaions1 +( + u64 UInt64, + i64 Int64, + i32 Int32, + INDEX idx (i64, u64 * i64) TYPE minmax GRANULARITY 1 +) ENGINE = ReplicatedMergeTree('/clickhouse/tables/test/indices_mutaions', 'r1') +PARTITION BY i32 +ORDER BY u64 +SETTINGS index_granularity = 2; +CREATE TABLE test.indices_mutaions2 +( + u64 UInt64, + i64 Int64, + i32 Int32, + INDEX idx (i64, u64 * i64) TYPE minmax GRANULARITY 1 +) ENGINE = ReplicatedMergeTree('/clickhouse/tables/test/indices_mutaions', 'r2') +PARTITION BY i32 +ORDER BY u64 +SETTINGS index_granularity = 2;" + + +$CLICKHOUSE_CLIENT --query="INSERT INTO test.indices_mutaions1 VALUES +(0, 2, 1), +(1, 1, 1), +(2, 1, 1), +(3, 1, 1), +(4, 1, 1), +(5, 2, 1), +(6, 1, 2), +(7, 1, 2), +(8, 1, 2), +(9, 1, 2)" + +$CLICKHOUSE_CLIENT --query="SELECT count() FROM test.indices_mutaions2 WHERE i64 = 2;" +$CLICKHOUSE_CLIENT --query="SELECT count() FROM test.indices_mutaions2 WHERE i64 = 2 FORMAT JSON" | grep "rows_read" + +$CLICKHOUSE_CLIENT --query="ALTER TABLE test.indices_mutaions1 CLEAR INDEX idx IN PARTITION 1;" +sleep 1 + +$CLICKHOUSE_CLIENT --query="SELECT count() FROM test.indices_mutaions2 WHERE i64 = 2;" +$CLICKHOUSE_CLIENT --query="SELECT count() FROM test.indices_mutaions2 WHERE i64 = 2 FORMAT JSON" | grep "rows_read" + +$CLICKHOUSE_CLIENT --query="ALTER TABLE test.indices_mutaions1 MATERIALIZE INDEX idx IN PARTITION 1;" +sleep 1 + +$CLICKHOUSE_CLIENT --query="SELECT count() FROM test.indices_mutaions2 WHERE i64 = 2;" +$CLICKHOUSE_CLIENT --query="SELECT count() FROM test.indices_mutaions2 WHERE i64 = 2 FORMAT JSON" | grep "rows_read" + +$CLICKHOUSE_CLIENT --query="DROP TABLE test.indices_mutaions1" +$CLICKHOUSE_CLIENT --query="DROP TABLE test.indices_mutaions2" From 21ce5331d19d2fd09c6029606cb440fd6ecfe071 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Sun, 28 Jul 2019 16:12:26 +0300 Subject: [PATCH 0416/1165] implemented mysql_native_password auth plugin for compatibility with mysqljs --- dbms/programs/server/MySQLHandler.cpp | 140 ++------ dbms/programs/server/MySQLHandler.h | 6 +- dbms/programs/server/users.xml | 8 + dbms/src/Core/MySQLProtocol.h | 330 +++++++++++++++--- dbms/src/Interpreters/Context.cpp | 4 + dbms/src/Interpreters/Context.h | 5 + dbms/src/Interpreters/Users.cpp | 18 +- dbms/src/Interpreters/Users.h | 1 + dbms/src/Interpreters/UsersManager.cpp | 62 ++-- .../clients/mysqljs/Dockerfile | 5 + .../clients/mysqljs/docker_compose.yml | 8 + .../clients/mysqljs/test.js | 21 ++ .../test_mysql_protocol/configs/users.xml | 21 ++ .../integration/test_mysql_protocol/test.py | 32 +- 14 files changed, 459 insertions(+), 202 deletions(-) create mode 100644 dbms/tests/integration/test_mysql_protocol/clients/mysqljs/Dockerfile create mode 100644 dbms/tests/integration/test_mysql_protocol/clients/mysqljs/docker_compose.yml create mode 100644 dbms/tests/integration/test_mysql_protocol/clients/mysqljs/test.js diff --git a/dbms/programs/server/MySQLHandler.cpp b/dbms/programs/server/MySQLHandler.cpp index c71e0554fb5..52dbc0a135a 100644 --- a/dbms/programs/server/MySQLHandler.cpp +++ b/dbms/programs/server/MySQLHandler.cpp @@ -2,7 +2,6 @@ #include #include -#include #include #include #include @@ -45,6 +44,7 @@ MySQLHandler::MySQLHandler(IServer & server_, const Poco::Net::StreamSocket & so , connection_id(connection_id) , public_key(public_key) , private_key(private_key) + , auth_plugin(new Authentication::Native41()) { server_capability_flags = CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION | CLIENT_PLUGIN_AUTH | CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA | CLIENT_CONNECT_WITH_DB | CLIENT_DEPRECATE_EOF; if (ssl_enabled) @@ -62,9 +62,7 @@ void MySQLHandler::run() try { - String scramble = generateScramble(); - - Handshake handshake(server_capability_flags, connection_id, VERSION_STRING + String("-") + VERSION_NAME, Authentication::Native, scramble + '\0'); + Handshake handshake(server_capability_flags, connection_id, VERSION_STRING + String("-") + VERSION_NAME, auth_plugin->getName(), auth_plugin->getAuthPluginData()); packet_sender->sendPacket(handshake, true); LOG_TRACE(log, "Sent handshake"); @@ -96,10 +94,21 @@ void MySQLHandler::run() client_capability_flags = handshake_response.capability_flags; if (!(client_capability_flags & CLIENT_PROTOCOL_41)) throw Exception("Required capability: CLIENT_PROTOCOL_41.", ErrorCodes::MYSQL_CLIENT_INSUFFICIENT_CAPABILITIES); - if (!(client_capability_flags & CLIENT_PLUGIN_AUTH)) - throw Exception("Required capability: CLIENT_PLUGIN_AUTH.", ErrorCodes::MYSQL_CLIENT_INSUFFICIENT_CAPABILITIES); - authenticate(handshake_response, scramble); + authenticate(handshake_response.username, handshake_response.auth_plugin_name, handshake_response.auth_response); + + try + { + if (!handshake_response.database.empty()) + connection_context.setCurrentDatabase(handshake_response.database); + connection_context.setCurrentQueryId(""); + } + catch (const Exception & exc) + { + log->log(exc); + packet_sender->sendPacket(ERR_Packet(exc.code(), "00000", exc.message()), true); + } + OK_Packet ok_packet(0, handshake_response.capability_flags, 0, 0, 0); packet_sender->sendPacket(ok_packet, true); @@ -216,121 +225,24 @@ void MySQLHandler::finishHandshake(MySQLProtocol::HandshakeResponse & packet) } } -String MySQLHandler::generateScramble() +void MySQLHandler::authenticate(const String & user_name, const String & auth_plugin_name, const String & initial_auth_response) { - String scramble(MySQLProtocol::SCRAMBLE_LENGTH, 0); - Poco::RandomInputStream generator; - for (size_t i = 0; i < scramble.size(); i++) - { - generator >> scramble[i]; - } - return scramble; -} + // For compatibility with JavaScript MySQL client, Native41 authentication plugin is used when it is possible. If password is specified using SHA-2, then SHA256 plugin is used. + auto user = connection_context.getUser(user_name); + if (!user->password_sha256_hex.empty()) + auth_plugin = std::make_unique(public_key, private_key, log); -void MySQLHandler::authenticate(const HandshakeResponse & handshake_response, const String & scramble) -{ - - String auth_response; - AuthSwitchResponse response; - if (handshake_response.auth_plugin_name != Authentication::SHA256) - { - /** Native authentication sent 20 bytes + '\0' character = 21 bytes. - * This plugin must do the same to stay consistent with historical behavior if it is set to operate as a default plugin. - * https://github.com/mysql/mysql-server/blob/8.0/sql/auth/sql_authentication.cc#L3994 - */ - packet_sender->sendPacket(AuthSwitchRequest(Authentication::SHA256, scramble + '\0'), true); - if (in->eof()) - throw Exception( - "Client doesn't support authentication method " + String(Authentication::SHA256) + " used by ClickHouse", - ErrorCodes::MYSQL_CLIENT_INSUFFICIENT_CAPABILITIES); - packet_sender->receivePacket(response); - auth_response = response.value; - LOG_TRACE(log, "Authentication method mismatch."); - } - else - { - auth_response = handshake_response.auth_response; - LOG_TRACE(log, "Authentication method match."); - } - - if (auth_response == "\1") - { - LOG_TRACE(log, "Client requests public key."); - - BIO * mem = BIO_new(BIO_s_mem()); - SCOPE_EXIT(BIO_free(mem)); - if (PEM_write_bio_RSA_PUBKEY(mem, &public_key) != 1) - { - throw Exception("Failed to write public key to memory. Error: " + getOpenSSLErrors(), ErrorCodes::OPENSSL_ERROR); - } - char * pem_buf = nullptr; - long pem_size = BIO_get_mem_data(mem, &pem_buf); - String pem(pem_buf, pem_size); - - LOG_TRACE(log, "Key: " << pem); - - AuthMoreData data(pem); - packet_sender->sendPacket(data, true); - packet_sender->receivePacket(response); - auth_response = response.value; - } - else - { - LOG_TRACE(log, "Client didn't request public key."); - } - - String password; - - /** Decrypt password, if it's not empty. - * The original intention was that the password is a string[NUL] but this never got enforced properly so now we have to accept that - * an empty packet is a blank password, thus the check for auth_response.empty() has to be made too. - * https://github.com/mysql/mysql-server/blob/8.0/sql/auth/sql_authentication.cc#L4017 - */ - if (!secure_connection && !auth_response.empty() && auth_response != String("\0", 1)) - { - LOG_TRACE(log, "Received nonempty password"); - auto ciphertext = reinterpret_cast(auth_response.data()); - - unsigned char plaintext[RSA_size(&private_key)]; - int plaintext_size = RSA_private_decrypt(auth_response.size(), ciphertext, plaintext, &private_key, RSA_PKCS1_OAEP_PADDING); - if (plaintext_size == -1) - { - throw Exception("Failed to decrypt auth data. Error: " + getOpenSSLErrors(), ErrorCodes::OPENSSL_ERROR); - } - - password.resize(plaintext_size); - for (int i = 0; i < plaintext_size; i++) - { - password[i] = plaintext[i] ^ static_cast(scramble[i % scramble.size()]); - } - } - else if (secure_connection) - { - password = auth_response; - } - else - { - LOG_TRACE(log, "Received empty password"); - } - - if (!password.empty() && password.back() == 0) - { - password.pop_back(); - } - - try - { - connection_context.setUser(handshake_response.username, password, socket().address(), ""); - if (!handshake_response.database.empty()) connection_context.setCurrentDatabase(handshake_response.database); - connection_context.setCurrentQueryId(""); - LOG_INFO(log, "Authentication for user " << handshake_response.username << " succeeded."); + try { + std::optional auth_response = auth_plugin_name == auth_plugin->getName() ? std::make_optional(initial_auth_response) : std::nullopt; + auth_plugin->authenticate(user_name, auth_response, connection_context, packet_sender, secure_connection, socket().address()); } catch (const Exception & exc) { - LOG_ERROR(log, "Authentication for user " << handshake_response.username << " failed."); + LOG_ERROR(log, "Authentication for user " << user_name << " failed."); packet_sender->sendPacket(ERR_Packet(exc.code(), "00000", exc.message()), true); throw; } + LOG_INFO(log, "Authentication for user " << user_name << " succeeded."); } void MySQLHandler::comInitDB(ReadBuffer & payload) diff --git a/dbms/programs/server/MySQLHandler.h b/dbms/programs/server/MySQLHandler.h index e899d8ef501..3e521004aca 100644 --- a/dbms/programs/server/MySQLHandler.h +++ b/dbms/programs/server/MySQLHandler.h @@ -30,9 +30,7 @@ private: void comInitDB(ReadBuffer & payload); - static String generateScramble(); - - void authenticate(const MySQLProtocol::HandshakeResponse &, const String & scramble); + void authenticate(const String & user_name, const String & auth_plugin_name, const String & auth_response); IServer & server; Poco::Logger * log; @@ -48,6 +46,8 @@ private: RSA & public_key; RSA & private_key; + std::unique_ptr auth_plugin; + std::shared_ptr ss; std::shared_ptr in; std::shared_ptr out; diff --git a/dbms/programs/server/users.xml b/dbms/programs/server/users.xml index 24b8f628c3a..9755c29d480 100644 --- a/dbms/programs/server/users.xml +++ b/dbms/programs/server/users.xml @@ -39,10 +39,18 @@ If you want to specify SHA256, place it in 'password_sha256_hex' element. Example: 65e84be33532fb784c48129675f9eff3a682b27168c0ea744b2cf58ee02337c5 + Restrictions of SHA256: impossibility to connect to ClickHouse using MySQL JS client (as of July 2019). + + If you want to specify double SHA1, place it in 'password_double_sha1_hex' element. + Example: e395796d6546b1b65db9d665cd43f0e858dd4303 How to generate decent password: Execute: PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha256sum | tr -d '-' In first line will be password and in second - corresponding SHA256. + + How to generate double SHA1: + Execute: PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | openssl dgst -sha1 -binary | openssl dgst -sha1 + In first line will be password and in second - corresponding double SHA1. --> diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index cb0e6ab001c..0704cec0edb 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -1,9 +1,17 @@ #pragma once +#include +#include +#include +#include +#include #include +#include #include #include +#include #include +#include #include #include #include @@ -12,11 +20,12 @@ #include #include #include +#include +#include #include #include -#include -#include -#include +#include +#include /// Implementation of MySQL wire protocol. /// Works only on little-endian architecture. @@ -27,6 +36,9 @@ namespace DB namespace ErrorCodes { extern const int UNKNOWN_PACKET_FROM_CLIENT; + extern const int MYSQL_CLIENT_INSUFFICIENT_CAPABILITIES; + extern const int OPENSSL_ERROR; + extern const int UNKNOWN_EXCEPTION; } namespace MySQLProtocol @@ -39,11 +51,6 @@ const size_t MYSQL_ERRMSG_SIZE = 512; const size_t PACKET_HEADER_SIZE = 4; const size_t SSL_REQUEST_PAYLOAD_SIZE = 32; -namespace Authentication -{ - const String Native = "mysql_native_password"; - const String SHA256 = "sha256_password"; /// Caching SHA2 plugin is not used because it would be possible to authenticate knowing hash from users.xml. -} enum CharacterSet { @@ -139,8 +146,7 @@ class PacketPayloadReadBuffer : public ReadBuffer public: PacketPayloadReadBuffer(ReadBuffer & in, uint8_t & sequence_id) : ReadBuffer(in.position(), 0) // not in.buffer().begin(), because working buffer may include previous packet - , in(in) - , sequence_id(sequence_id) + , in(in), sequence_id(sequence_id) { } @@ -149,6 +155,8 @@ private: uint8_t & sequence_id; const size_t max_packet_size = MAX_PACKET_LENGTH; + bool has_read_header = false; + // Size of packet which is being read now. size_t payload_length = 0; @@ -158,8 +166,9 @@ private: protected: bool nextImpl() override { - if (payload_length == 0 || (payload_length == max_packet_size && offset == payload_length)) + if (!has_read_header || (payload_length == max_packet_size && offset == payload_length)) { + has_read_header = true; working_buffer.resize(0); offset = 0; payload_length = 0; @@ -171,10 +180,6 @@ protected: tmp << "Received packet with payload larger than max_packet_size: " << payload_length; throw ProtocolError(tmp.str(), ErrorCodes::UNKNOWN_PACKET_FROM_CLIENT); } - else if (payload_length == 0) - { - return false; - } size_t packet_sequence_id = 0; in.read(reinterpret_cast(packet_sequence_id)); @@ -185,6 +190,9 @@ protected: throw ProtocolError(tmp.str(), ErrorCodes::UNKNOWN_PACKET_FROM_CLIENT); } sequence_id++; + + if (payload_length == 0) + return false; } else if (offset == payload_length) { @@ -208,6 +216,7 @@ class ClientPacket { public: ClientPacket() = default; + ClientPacket(ClientPacket &&) = default; virtual void read(ReadBuffer & in, uint8_t & sequence_id) @@ -246,10 +255,7 @@ class PacketPayloadWriteBuffer : public WriteBuffer { public: PacketPayloadWriteBuffer(WriteBuffer & out, size_t payload_length, uint8_t & sequence_id) - : WriteBuffer(out.position(), 0) - , out(out) - , sequence_id(sequence_id) - , total_left(payload_length) + : WriteBuffer(out.position(), 0), out(out), sequence_id(sequence_id), total_left(payload_length) { startPacket(); } @@ -265,7 +271,9 @@ public: } } - ~PacketPayloadWriteBuffer() override { next(); } + ~PacketPayloadWriteBuffer() override + { next(); } + private: WriteBuffer & out; uint8_t & sequence_id; @@ -286,6 +294,7 @@ private: working_buffer = WriteBuffer::Buffer(out.position(), out.position() + std::min(payload_length - bytes_written, out.available())); pos = working_buffer.begin(); } + protected: void nextImpl() override { @@ -345,17 +354,13 @@ public: /// For reading and writing. PacketSender(ReadBuffer & in, WriteBuffer & out, uint8_t & sequence_id) - : sequence_id(sequence_id) - , in(&in) - , out(&out) + : sequence_id(sequence_id), in(&in), out(&out) { } /// For writing. PacketSender(WriteBuffer & out, uint8_t & sequence_id) - : sequence_id(sequence_id) - , in(nullptr) - , out(&out) + : sequence_id(sequence_id), in(nullptr), out(&out) { } @@ -419,14 +424,8 @@ class Handshake : public WritePacket String auth_plugin_data; public: explicit Handshake(uint32_t capability_flags, uint32_t connection_id, String server_version, String auth_plugin_name, String auth_plugin_data) - : protocol_version(0xa) - , server_version(std::move(server_version)) - , connection_id(connection_id) - , capability_flags(capability_flags) - , character_set(CharacterSet::utf8_general_ci) - , status_flags(0) - , auth_plugin_name(std::move(auth_plugin_name)) - , auth_plugin_data(std::move(auth_plugin_data)) + : protocol_version(0xa), server_version(std::move(server_version)), connection_id(connection_id), capability_flags(capability_flags), character_set(CharacterSet::utf8_general_ci), + status_flags(0), auth_plugin_name(std::move(auth_plugin_name)), auth_plugin_data(std::move(auth_plugin_data)) { } @@ -449,9 +448,6 @@ protected: buffer.write(static_cast(auth_plugin_data.size())); writeChar(0x0, 10, buffer); writeString(auth_plugin_data.substr(AUTH_PLUGIN_DATA_PART_1_LENGTH, auth_plugin_data.size() - AUTH_PLUGIN_DATA_PART_1_LENGTH), buffer); - // A workaround for PHP mysqlnd extension bug which occurs when sha256_password is used as a default authentication plugin. - // Instead of using client response for mysql_native_password plugin, the server will always generate authentication method mismatch - // and switch to sha256_password to simulate that mysql_native_password is used as a default plugin. writeString(auth_plugin_name, buffer); writeChar(0x0, 1, buffer); } @@ -563,7 +559,8 @@ class AuthMoreData : public WritePacket { String data; public: - explicit AuthMoreData(String data): data(std::move(data)) {} + explicit AuthMoreData(String data) : data(std::move(data)) + {} protected: size_t getPayloadSize() const override @@ -590,19 +587,14 @@ class OK_Packet : public WritePacket String info; public: OK_Packet(uint8_t header, - uint32_t capabilities, - uint64_t affected_rows, - uint32_t status_flags, - int16_t warnings, - String session_state_changes = "", - String info = "") - : header(header) - , capabilities(capabilities) - , affected_rows(affected_rows) - , warnings(warnings) - , status_flags(status_flags) - , session_state_changes(std::move(session_state_changes)) - , info(std::move(info)) + uint32_t capabilities, + uint64_t affected_rows, + uint32_t status_flags, + int16_t warnings, + String session_state_changes = "", + String info = "") + : header(header), capabilities(capabilities), affected_rows(affected_rows), warnings(warnings), status_flags(status_flags), session_state_changes(std::move(session_state_changes)), + info(std::move(info)) { } @@ -798,7 +790,7 @@ class LengthEncodedNumber : public WritePacket { uint64_t value; public: - explicit LengthEncodedNumber(uint64_t value): value(value) + explicit LengthEncodedNumber(uint64_t value) : value(value) { } @@ -840,5 +832,239 @@ protected: } }; +namespace Authentication +{ + +class IPlugin +{ +public: + virtual String getName() = 0; + + virtual String getAuthPluginData() = 0; + + virtual void authenticate(const String & user_name, std::optional auth_response, Context & context, std::shared_ptr packet_sender, bool is_secure_connection, + const Poco::Net::SocketAddress & address) = 0; + + virtual ~IPlugin() = default; +}; + +/// https://dev.mysql.com/doc/internals/en/secure-password-authentication.html +class Native41 : public IPlugin +{ +public: + Native41() + { + scramble.resize(SCRAMBLE_LENGTH + 1, 0); + Poco::RandomInputStream generator; + + for (size_t i = 0; i < SCRAMBLE_LENGTH; i++) + generator >> scramble[i]; + } + + String getName() override + { + return "mysql_native_password"; + } + + String getAuthPluginData() override + { + return scramble; + } + + void authenticate( + const String & user_name, + std::optional auth_response, + Context & context, + std::shared_ptr packet_sender, + bool /* is_secure_connection */, + const Poco::Net::SocketAddress & address) override + { + if (!auth_response) + { + packet_sender->sendPacket(AuthSwitchRequest(getName(), scramble), true); + AuthSwitchResponse response; + packet_sender->receivePacket(response); + auth_response = response.value; + } + + if (auth_response->empty()) + { + context.setUser(user_name, "", address, ""); + return; + } + + if (auth_response->size() != Poco::SHA1Engine::DIGEST_SIZE) + throw Exception("Wrong size of auth response. Expected: " + std::to_string(Poco::SHA1Engine::DIGEST_SIZE) + " bytes, received: " + std::to_string(auth_response->size()) + " bytes.", + ErrorCodes::UNKNOWN_EXCEPTION); + + auto user = context.getUser(user_name); + + if (!user->password_sha256_hex.empty()) + throw Exception("Cannot use " + getName() + " auth plugin for user " + user_name + " since its password is specified using SHA256.", ErrorCodes::UNKNOWN_EXCEPTION); + + Poco::SHA1Engine::Digest double_sha1_value; + Poco::SHA1Engine engine; + + /// If password is specified using double SHA1, than it is non-empty (unlike plaintext password, which can be empty). + if (!user->password_double_sha1_hex.empty()) + { + double_sha1_value = Poco::DigestEngine::digestFromHex(user->password_double_sha1_hex); + assert(double_sha1_value.size() == Poco::SHA1Engine::DIGEST_SIZE); + } + else + { + engine.update(user->password); + const Poco::SHA1Engine::Digest & first_sha1 = engine.digest(); + engine.update(first_sha1.data(), first_sha1.size()); + double_sha1_value = engine.digest(); + } + + engine.update(scramble.data(), SCRAMBLE_LENGTH); + engine.update(double_sha1_value.data(), double_sha1_value.size()); + + String password_sha1(Poco::SHA1Engine::DIGEST_SIZE, 0x0); + const Poco::SHA1Engine::Digest & digest = engine.digest(); + for (size_t i = 0; i < password_sha1.size(); i++) + { + password_sha1[i] = digest[i] ^ static_cast((*auth_response)[i]); + } + context.setUser(user_name, password_sha1, address, ""); + } +private: + String scramble; +}; + +/// Caching SHA2 plugin is not used because it would be possible to authenticate knowing hash from users.xml. +/// https://dev.mysql.com/doc/internals/en/sha256.html +class Sha256Password : public IPlugin +{ +public: + Sha256Password(RSA & public_key, RSA & private_key, Logger * log) : public_key(public_key), private_key(private_key), log(log) + { + /** Native authentication sent 20 bytes + '\0' character = 21 bytes. + * This plugin must do the same to stay consistent with historical behavior if it is set to operate as a default plugin. [1] + * https://github.com/mysql/mysql-server/blob/8.0/sql/auth/sql_authentication.cc#L3994 + */ + scramble.resize(SCRAMBLE_LENGTH + 1, 0); + Poco::RandomInputStream generator; + + for (char & c : scramble) + generator >> c; + } + + String getName() override + { + return "sha256_password"; + } + + String getAuthPluginData() override + { + return scramble; + } + + void authenticate( + const String & user_name, + std::optional auth_response, + Context & context, + std::shared_ptr packet_sender, + bool is_secure_connection, + const Poco::Net::SocketAddress & address) override + { + if (!auth_response) + { + packet_sender->sendPacket(AuthSwitchRequest(getName(), scramble), true); + + if (packet_sender->in->eof()) + throw Exception("Client doesn't support authentication method " + getName() + " used by ClickHouse", ErrorCodes::MYSQL_CLIENT_INSUFFICIENT_CAPABILITIES); + + AuthSwitchResponse response; + packet_sender->receivePacket(response); + auth_response = response.value; + LOG_TRACE(log, "Authentication method mismatch."); + } + else + { + LOG_TRACE(log, "Authentication method match."); + } + + if (auth_response == "\1") + { + LOG_TRACE(log, "Client requests public key."); + + BIO * mem = BIO_new(BIO_s_mem()); + SCOPE_EXIT(BIO_free(mem)); + if (PEM_write_bio_RSA_PUBKEY(mem, &public_key) != 1) + { + throw Exception("Failed to write public key to memory. Error: " + getOpenSSLErrors(), ErrorCodes::OPENSSL_ERROR); + } + char * pem_buf = nullptr; + long pem_size = BIO_get_mem_data(mem, &pem_buf); + String pem(pem_buf, pem_size); + + LOG_TRACE(log, "Key: " << pem); + + AuthMoreData data(pem); + packet_sender->sendPacket(data, true); + + AuthSwitchResponse response; + packet_sender->receivePacket(response); + auth_response = response.value; + } + else + { + LOG_TRACE(log, "Client didn't request public key."); + } + + String password; + + /** Decrypt password, if it's not empty. + * The original intention was that the password is a string[NUL] but this never got enforced properly so now we have to accept that + * an empty packet is a blank password, thus the check for auth_response.empty() has to be made too. + * https://github.com/mysql/mysql-server/blob/8.0/sql/auth/sql_authentication.cc#L4017 + */ + if (!is_secure_connection && !auth_response->empty() && auth_response != String("\0", 1)) + { + LOG_TRACE(log, "Received nonempty password"); + auto ciphertext = reinterpret_cast(auth_response->data()); + + unsigned char plaintext[RSA_size(&private_key)]; + int plaintext_size = RSA_private_decrypt(auth_response->size(), ciphertext, plaintext, &private_key, RSA_PKCS1_OAEP_PADDING); + if (plaintext_size == -1) + { + throw Exception("Failed to decrypt auth data. Error: " + getOpenSSLErrors(), ErrorCodes::OPENSSL_ERROR); + } + + password.resize(plaintext_size); + for (int i = 0; i < plaintext_size; i++) + { + password[i] = plaintext[i] ^ static_cast(scramble[i % scramble.size()]); + } + } + else if (is_secure_connection) + { + password = *auth_response; + } + else + { + LOG_TRACE(log, "Received empty password"); + } + + if (!password.empty() && password.back() == 0) + { + password.pop_back(); + } + + context.setUser(user_name, password, address, ""); + } + +private: + RSA & public_key; + RSA & private_key; + Logger * log; + String scramble; +}; + +} + } } diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index cec36f42469..4b9599942db 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -661,6 +661,10 @@ void Context::setProfile(const String & profile) settings_constraints = std::move(new_constraints); } +std::shared_ptr Context::getUser(const String & user_name) +{ + return shared->users_manager->getUser(user_name); +} void Context::setUser(const String & name, const String & password, const Poco::Net::SocketAddress & address, const String & quota_key) { diff --git a/dbms/src/Interpreters/Context.h b/dbms/src/Interpreters/Context.h index d2e08a45026..a168e2af5f1 100644 --- a/dbms/src/Interpreters/Context.h +++ b/dbms/src/Interpreters/Context.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -197,6 +198,10 @@ public: /// Must be called before getClientInfo. void setUser(const String & name, const String & password, const Poco::Net::SocketAddress & address, const String & quota_key); + + /// Used by MySQL Secure Password Authentication plugin. + std::shared_ptr getUser(const String & user_name); + /// Compute and set actual user settings, client_info.current_user should be set void calculateUserSettings(); diff --git a/dbms/src/Interpreters/Users.cpp b/dbms/src/Interpreters/Users.cpp index 1f5a474d6f1..2dff8c32a69 100644 --- a/dbms/src/Interpreters/Users.cpp +++ b/dbms/src/Interpreters/Users.cpp @@ -278,12 +278,14 @@ User::User(const String & name_, const String & config_elem, const Poco::Util::A { bool has_password = config.has(config_elem + ".password"); bool has_password_sha256_hex = config.has(config_elem + ".password_sha256_hex"); + bool has_password_double_sha1_hex = config.has(config_elem + ".password_double_sha1_hex"); - if (has_password && has_password_sha256_hex) - throw Exception("Both fields 'password' and 'password_sha256_hex' are specified for user " + name + ". Must be only one of them.", ErrorCodes::BAD_ARGUMENTS); + if (has_password + has_password_sha256_hex + has_password_double_sha1_hex > 1) + throw Exception("More than one field of 'password', 'password_sha256_hex', 'password_double_sha1_hex' is used to specify password for user " + name + ". Must be only one of them.", + ErrorCodes::BAD_ARGUMENTS); - if (!has_password && !has_password_sha256_hex) - throw Exception("Either 'password' or 'password_sha256_hex' must be specified for user " + name + ".", ErrorCodes::BAD_ARGUMENTS); + if (!has_password && !has_password_sha256_hex && !has_password_double_sha1_hex) + throw Exception("Either 'password' or 'password_sha256_hex' or 'password_double_sha1_hex' must be specified for user " + name + ".", ErrorCodes::BAD_ARGUMENTS); if (has_password) password = config.getString(config_elem + ".password"); @@ -296,6 +298,14 @@ User::User(const String & name_, const String & config_elem, const Poco::Util::A throw Exception("password_sha256_hex for user " + name + " has length " + toString(password_sha256_hex.size()) + " but must be exactly 64 symbols.", ErrorCodes::BAD_ARGUMENTS); } + if (has_password_double_sha1_hex) + { + password_double_sha1_hex = Poco::toLower(config.getString(config_elem + ".password_double_sha1_hex")); + + if (password_double_sha1_hex.size() != 40) + throw Exception("password_double_sha1_hex for user " + name + " has length " + toString(password_double_sha1_hex.size()) + " but must be exactly 40 symbols.", ErrorCodes::BAD_ARGUMENTS); + } + profile = config.getString(config_elem + ".profile"); quota = config.getString(config_elem + ".quota"); diff --git a/dbms/src/Interpreters/Users.h b/dbms/src/Interpreters/Users.h index 95dde778b62..8baeec57e50 100644 --- a/dbms/src/Interpreters/Users.h +++ b/dbms/src/Interpreters/Users.h @@ -56,6 +56,7 @@ struct User /// Required password. Could be stored in plaintext or in SHA256. String password; String password_sha256_hex; + String password_double_sha1_hex; String profile; String quota; diff --git a/dbms/src/Interpreters/UsersManager.cpp b/dbms/src/Interpreters/UsersManager.cpp index 9c8434cdbe9..d5b454f2acc 100644 --- a/dbms/src/Interpreters/UsersManager.cpp +++ b/dbms/src/Interpreters/UsersManager.cpp @@ -1,17 +1,17 @@ #include -#include -#include -#include +#include "config_core.h" #include +#include #include #include #include -#include -#include "config_core.h" -#if USE_SSL -# include -#endif +#include +#include +#include +#include +#include +#include namespace DB @@ -70,32 +70,40 @@ UserPtr UsersManager::authorizeAndGetUser( if (!it->second->password_sha256_hex.empty()) { -#if USE_SSL - unsigned char hash[32]; - - SHA256_CTX ctx; - SHA256_Init(&ctx); - SHA256_Update(&ctx, reinterpret_cast(password.data()), password.size()); - SHA256_Final(hash, &ctx); - - String hash_hex; + Poco::SHA2Engine engine; + engine.update(password); + if (Poco::SHA2Engine::digestToHex(engine.digest()) != it->second->password_sha256_hex) + on_wrong_password(); + } + else if (!it->second->password_double_sha1_hex.empty()) + { + /// MySQL compatibility server passes SHA1 instead of a password. If password length equals to 20, it is treated as a SHA1. Server stores double SHA1. + Poco::SHA1Engine engine; + if (password.size() == Poco::SHA1Engine::DIGEST_SIZE) { - WriteBufferFromString buf(hash_hex); - HexWriteBuffer hex_buf(buf); - hex_buf.write(reinterpret_cast(hash), sizeof(hash)); + engine.update(password); + } + else + { + engine.update(password); + const auto & first_sha1 = engine.digest(); + engine.update(first_sha1.data(), first_sha1.size()); } - Poco::toLowerInPlace(hash_hex); - - if (hash_hex != it->second->password_sha256_hex) + if (Poco::SHA1Engine::digestToHex(engine.digest()) != it->second->password_double_sha1_hex) on_wrong_password(); -#else - throw DB::Exception("SHA256 passwords support is disabled, because ClickHouse was built without SSL library", DB::ErrorCodes::SUPPORT_IS_DISABLED); -#endif } else if (password != it->second->password) { - on_wrong_password(); + /// MySQL compatibility server passes SHA1 instead of a password. + if (password.size() != Poco::SHA1Engine::DIGEST_SIZE) + on_wrong_password(); + + Poco::SHA1Engine engine; + engine.update(it->second->password); + + if (engine.digest() != Poco::SHA1Engine::Digest(password.begin(), password.end())) + on_wrong_password(); } return it->second; diff --git a/dbms/tests/integration/test_mysql_protocol/clients/mysqljs/Dockerfile b/dbms/tests/integration/test_mysql_protocol/clients/mysqljs/Dockerfile new file mode 100644 index 00000000000..5381915efba --- /dev/null +++ b/dbms/tests/integration/test_mysql_protocol/clients/mysqljs/Dockerfile @@ -0,0 +1,5 @@ +FROM node:8 + +RUN npm install mysql + +COPY ./test.js test.js diff --git a/dbms/tests/integration/test_mysql_protocol/clients/mysqljs/docker_compose.yml b/dbms/tests/integration/test_mysql_protocol/clients/mysqljs/docker_compose.yml new file mode 100644 index 00000000000..9485662dd6c --- /dev/null +++ b/dbms/tests/integration/test_mysql_protocol/clients/mysqljs/docker_compose.yml @@ -0,0 +1,8 @@ +version: '2.2' +services: + mysqljs1: + build: + context: ./ + network: host + # to keep container running + command: sleep infinity diff --git a/dbms/tests/integration/test_mysql_protocol/clients/mysqljs/test.js b/dbms/tests/integration/test_mysql_protocol/clients/mysqljs/test.js new file mode 100644 index 00000000000..0cbe38acb07 --- /dev/null +++ b/dbms/tests/integration/test_mysql_protocol/clients/mysqljs/test.js @@ -0,0 +1,21 @@ +var mysql = require('mysql'); + +var connection = mysql.createConnection({ + host : process.argv[2], + port : process.argv[3], + user : process.argv[4], + password : process.argv[5], + database : 'system', +}); + +connection.connect(); + +connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) { + if (error) throw error; + + if (results[0].solution.toString() !== '2') { + throw Error('Wrong result of a query. Expected: "2", received: ' + results[0].solution + '.') + } +}); + +connection.end(); diff --git a/dbms/tests/integration/test_mysql_protocol/configs/users.xml b/dbms/tests/integration/test_mysql_protocol/configs/users.xml index 2be13dca499..fb4b948d896 100644 --- a/dbms/tests/integration/test_mysql_protocol/configs/users.xml +++ b/dbms/tests/integration/test_mysql_protocol/configs/users.xml @@ -14,6 +14,27 @@ default default + + + + e395796d6546b1b65db9d665cd43f0e858dd4303 + + ::/0 + + default + default + + + + + + + + ::/0 + + default + default + diff --git a/dbms/tests/integration/test_mysql_protocol/test.py b/dbms/tests/integration/test_mysql_protocol/test.py index edacfb751c9..39f3793cc5c 100644 --- a/dbms/tests/integration/test_mysql_protocol/test.py +++ b/dbms/tests/integration/test_mysql_protocol/test.py @@ -50,8 +50,22 @@ def php_container(): yield docker.from_env().containers.get(cluster.project_name + '_php1_1') +@pytest.fixture(scope='module') +def nodejs_container(): + docker_compose = os.path.join(SCRIPT_DIR, 'clients', 'mysqljs', 'docker_compose.yml') + subprocess.check_call(['docker-compose', '-p', cluster.project_name, '-f', docker_compose, 'up', '--no-recreate', '-d', '--build']) + yield docker.from_env().containers.get(cluster.project_name + '_mysqljs1_1') + + def test_mysql_client(mysql_client, server_address): # type: (Container, str) -> None + code, (stdout, stderr) = mysql_client.exec_run(''' + mysql --protocol tcp -h {host} -P {port} default -u user_with_double_sha1 --password=abacaba + -e "SELECT 1;" + '''.format(host=server_address, port=server_port), demux=True) + + assert stdout == '\n'.join(['1', '1', '']) + code, (stdout, stderr) = mysql_client.exec_run(''' mysql --protocol tcp -h {host} -P {port} default -u default --password=123 -e "SELECT 1 as a;" @@ -149,10 +163,24 @@ def test_golang_client(server_address, golang_container): def test_php_client(server_address, php_container): # type: (str, Container) -> None - code, (stdout, stderr) = php_container.exec_run('php -f test.php {host} {port} default 123 '.format(host=server_address, port=server_port), demux=True) + code, (stdout, stderr) = php_container.exec_run('php -f test.php {host} {port} default 123'.format(host=server_address, port=server_port), demux=True) assert code == 0 assert stdout == 'tables\n' - code, (stdout, stderr) = php_container.exec_run('php -f test_ssl.php {host} {port} default 123 '.format(host=server_address, port=server_port), demux=True) + code, (stdout, stderr) = php_container.exec_run('php -f test_ssl.php {host} {port} default 123'.format(host=server_address, port=server_port), demux=True) assert code == 0 assert stdout == 'tables\n' + + +def test_mysqljs_client(server_address, nodejs_container): + code, (_, _) = nodejs_container.exec_run('node test.js {host} {port} default 123'.format(host=server_address, port=server_port), demux=True) + assert code == 0 + + code, (_, _) = nodejs_container.exec_run('node test.js {host} {port} user_with_double_sha1 abacaba'.format(host=server_address, port=server_port), demux=True) + assert code == 0 + + code, (_, _) = nodejs_container.exec_run('node test.js {host} {port} user_with_empty_password ""'.format(host=server_address, port=server_port), demux=True) + assert code == 0 + + code, (_, _) = nodejs_container.exec_run('node test.js {host} {port} user_with_empty_password 123'.format(host=server_address, port=server_port), demux=True) + assert code == 1 From 760afb007c402b518cfa02bb07ad46f3554d951b Mon Sep 17 00:00:00 2001 From: Yuriy Date: Sun, 28 Jul 2019 16:36:27 +0300 Subject: [PATCH 0417/1165] arbitrary passwords --- dbms/src/Interpreters/UsersManager.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/dbms/src/Interpreters/UsersManager.cpp b/dbms/src/Interpreters/UsersManager.cpp index d5b454f2acc..057257f1754 100644 --- a/dbms/src/Interpreters/UsersManager.cpp +++ b/dbms/src/Interpreters/UsersManager.cpp @@ -77,18 +77,15 @@ UserPtr UsersManager::authorizeAndGetUser( } else if (!it->second->password_double_sha1_hex.empty()) { - /// MySQL compatibility server passes SHA1 instead of a password. If password length equals to 20, it is treated as a SHA1. Server stores double SHA1. Poco::SHA1Engine engine; - if (password.size() == Poco::SHA1Engine::DIGEST_SIZE) - { - engine.update(password); - } - else - { - engine.update(password); - const auto & first_sha1 = engine.digest(); - engine.update(first_sha1.data(), first_sha1.size()); - } + engine.update(password); + const auto & first_sha1 = engine.digest(); + + /// If it was MySQL compatibility server, then first_sha1 already contains double SHA1. + if (Poco::SHA1Engine::digestToHex(first_sha1) != it->second->password_double_sha1_hex) + return it->second; + + engine.update(first_sha1.data(), first_sha1.size()); if (Poco::SHA1Engine::digestToHex(engine.digest()) != it->second->password_double_sha1_hex) on_wrong_password(); From b1d5f4ca20a5275499dd6940bee60c4840459494 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Sun, 28 Jul 2019 17:17:33 +0300 Subject: [PATCH 0418/1165] disabled mysql_native_password when password is specified as a plain text as it allows to connect to ClickHouse knowing only SHA1 instead of a password --- dbms/programs/server/MySQLHandler.cpp | 4 +-- dbms/src/Core/MySQLProtocol.h | 30 ++++++------------- dbms/src/Interpreters/UsersManager.cpp | 12 ++------ .../integration/test_mysql_protocol/test.py | 12 ++++---- 4 files changed, 20 insertions(+), 38 deletions(-) diff --git a/dbms/programs/server/MySQLHandler.cpp b/dbms/programs/server/MySQLHandler.cpp index 52dbc0a135a..d225b7a58e8 100644 --- a/dbms/programs/server/MySQLHandler.cpp +++ b/dbms/programs/server/MySQLHandler.cpp @@ -227,9 +227,9 @@ void MySQLHandler::finishHandshake(MySQLProtocol::HandshakeResponse & packet) void MySQLHandler::authenticate(const String & user_name, const String & auth_plugin_name, const String & initial_auth_response) { - // For compatibility with JavaScript MySQL client, Native41 authentication plugin is used when it is possible. If password is specified using SHA-2, then SHA256 plugin is used. + // For compatibility with JavaScript MySQL client, Native41 authentication plugin is used when possible (if password is specified using double SHA1). Otherwise SHA256 plugin is used. auto user = connection_context.getUser(user_name); - if (!user->password_sha256_hex.empty()) + if (user->password_double_sha1_hex.empty()) auth_plugin = std::make_unique(public_key, private_key, log); try { diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index 0704cec0edb..625f689d02f 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -899,26 +899,13 @@ public: auto user = context.getUser(user_name); - if (!user->password_sha256_hex.empty()) - throw Exception("Cannot use " + getName() + " auth plugin for user " + user_name + " since its password is specified using SHA256.", ErrorCodes::UNKNOWN_EXCEPTION); + if (user->password_double_sha1_hex.empty()) + throw Exception("Cannot use " + getName() + " auth plugin for user " + user_name + " since its password isn't specified using double SHA1.", ErrorCodes::UNKNOWN_EXCEPTION); + + Poco::SHA1Engine::Digest double_sha1_value = Poco::DigestEngine::digestFromHex(user->password_double_sha1_hex); + assert(double_sha1_value.size() == Poco::SHA1Engine::DIGEST_SIZE); - Poco::SHA1Engine::Digest double_sha1_value; Poco::SHA1Engine engine; - - /// If password is specified using double SHA1, than it is non-empty (unlike plaintext password, which can be empty). - if (!user->password_double_sha1_hex.empty()) - { - double_sha1_value = Poco::DigestEngine::digestFromHex(user->password_double_sha1_hex); - assert(double_sha1_value.size() == Poco::SHA1Engine::DIGEST_SIZE); - } - else - { - engine.update(user->password); - const Poco::SHA1Engine::Digest & first_sha1 = engine.digest(); - engine.update(first_sha1.data(), first_sha1.size()); - double_sha1_value = engine.digest(); - } - engine.update(scramble.data(), SCRAMBLE_LENGTH); engine.update(double_sha1_value.data(), double_sha1_value.size()); @@ -948,8 +935,8 @@ public: scramble.resize(SCRAMBLE_LENGTH + 1, 0); Poco::RandomInputStream generator; - for (char & c : scramble) - generator >> c; + for (size_t i = 0; i < SCRAMBLE_LENGTH; i++) + generator >> scramble[i]; } String getName() override @@ -975,7 +962,8 @@ public: packet_sender->sendPacket(AuthSwitchRequest(getName(), scramble), true); if (packet_sender->in->eof()) - throw Exception("Client doesn't support authentication method " + getName() + " used by ClickHouse", ErrorCodes::MYSQL_CLIENT_INSUFFICIENT_CAPABILITIES); + throw Exception("Client doesn't support authentication method " + getName() + " used by ClickHouse. Specifying user password using 'password_double_sha1_hex' may fix the problem.", + ErrorCodes::MYSQL_CLIENT_INSUFFICIENT_CAPABILITIES); AuthSwitchResponse response; packet_sender->receivePacket(response); diff --git a/dbms/src/Interpreters/UsersManager.cpp b/dbms/src/Interpreters/UsersManager.cpp index 057257f1754..6c33187f526 100644 --- a/dbms/src/Interpreters/UsersManager.cpp +++ b/dbms/src/Interpreters/UsersManager.cpp @@ -82,7 +82,7 @@ UserPtr UsersManager::authorizeAndGetUser( const auto & first_sha1 = engine.digest(); /// If it was MySQL compatibility server, then first_sha1 already contains double SHA1. - if (Poco::SHA1Engine::digestToHex(first_sha1) != it->second->password_double_sha1_hex) + if (Poco::SHA1Engine::digestToHex(first_sha1) == it->second->password_double_sha1_hex) return it->second; engine.update(first_sha1.data(), first_sha1.size()); @@ -92,15 +92,7 @@ UserPtr UsersManager::authorizeAndGetUser( } else if (password != it->second->password) { - /// MySQL compatibility server passes SHA1 instead of a password. - if (password.size() != Poco::SHA1Engine::DIGEST_SIZE) - on_wrong_password(); - - Poco::SHA1Engine engine; - engine.update(it->second->password); - - if (engine.digest() != Poco::SHA1Engine::Digest(password.begin(), password.end())) - on_wrong_password(); + on_wrong_password(); } return it->second; diff --git a/dbms/tests/integration/test_mysql_protocol/test.py b/dbms/tests/integration/test_mysql_protocol/test.py index 39f3793cc5c..f8d79cb2e32 100644 --- a/dbms/tests/integration/test_mysql_protocol/test.py +++ b/dbms/tests/integration/test_mysql_protocol/test.py @@ -173,14 +173,16 @@ def test_php_client(server_address, php_container): def test_mysqljs_client(server_address, nodejs_container): - code, (_, _) = nodejs_container.exec_run('node test.js {host} {port} default 123'.format(host=server_address, port=server_port), demux=True) - assert code == 0 + code, (_, stderr) = nodejs_container.exec_run('node test.js {host} {port} default 123'.format(host=server_address, port=server_port), demux=True) + assert code == 1 + assert 'MySQL is requesting the sha256_password authentication method, which is not supported.' in stderr + + code, (_, stderr) = nodejs_container.exec_run('node test.js {host} {port} user_with_empty_password ""'.format(host=server_address, port=server_port), demux=True) + assert code == 1 + assert 'MySQL is requesting the sha256_password authentication method, which is not supported.' in stderr code, (_, _) = nodejs_container.exec_run('node test.js {host} {port} user_with_double_sha1 abacaba'.format(host=server_address, port=server_port), demux=True) assert code == 0 - code, (_, _) = nodejs_container.exec_run('node test.js {host} {port} user_with_empty_password ""'.format(host=server_address, port=server_port), demux=True) - assert code == 0 - code, (_, _) = nodejs_container.exec_run('node test.js {host} {port} user_with_empty_password 123'.format(host=server_address, port=server_port), demux=True) assert code == 1 From dd2e3ab7f78b87d045664b0d15038f904d6a0825 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Sun, 28 Jul 2019 17:24:52 +0300 Subject: [PATCH 0419/1165] removed wrong comment --- dbms/tests/integration/test_mysql_protocol/configs/users.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/dbms/tests/integration/test_mysql_protocol/configs/users.xml b/dbms/tests/integration/test_mysql_protocol/configs/users.xml index fb4b948d896..ebcd1a297e1 100644 --- a/dbms/tests/integration/test_mysql_protocol/configs/users.xml +++ b/dbms/tests/integration/test_mysql_protocol/configs/users.xml @@ -27,7 +27,6 @@ - ::/0 From f63f763c3ea7cd853fdebe8f89d5f5bff9cc757e Mon Sep 17 00:00:00 2001 From: Amos Bird Date: Sun, 28 Jul 2019 22:43:38 +0800 Subject: [PATCH 0420/1165] build fix --- libs/libcommon/include/common/memory.h | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/libs/libcommon/include/common/memory.h b/libs/libcommon/include/common/memory.h index d8dced79cfb..58070334ac1 100644 --- a/libs/libcommon/include/common/memory.h +++ b/libs/libcommon/include/common/memory.h @@ -15,10 +15,26 @@ #define USE_JEMALLOC 0 #include #endif +#else +#include #endif -#define ALWAYS_INLINE inline __attribute__((__always_inline__)) -#define NO_INLINE __attribute__((__noinline__)) +// Also defined in Core/Defines.h +#if !defined(ALWAYS_INLINE) +#if defined(_MSC_VER) + #define ALWAYS_INLINE inline __forceinline +#else + #define ALWAYS_INLINE inline __attribute__((__always_inline__)) +#endif +#endif + +#if !defined(NO_INLINE) +#if defined(_MSC_VER) + #define NO_INLINE static __declspec(noinline) +#else + #define NO_INLINE __attribute__((__noinline__)) +#endif +#endif namespace Memory { From 32a9b27876d2c1c409cac8026afe3c801d4207ec Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 28 Jul 2019 17:55:02 +0300 Subject: [PATCH 0421/1165] Added a comment --- dbms/src/Common/SharedLibrary.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dbms/src/Common/SharedLibrary.cpp b/dbms/src/Common/SharedLibrary.cpp index 568bfaa4f3e..1cc512f925d 100644 --- a/dbms/src/Common/SharedLibrary.cpp +++ b/dbms/src/Common/SharedLibrary.cpp @@ -20,6 +20,9 @@ SharedLibrary::SharedLibrary(const std::string & path, int flags) throw Exception(std::string("Cannot dlopen: ") + dlerror(), ErrorCodes::CANNOT_DLOPEN); updatePHDRCache(); + + /// NOTE: race condition exists when loading multiple shared libraries concurrently. + /// We don't care (or add global mutex for this method). } SharedLibrary::~SharedLibrary() From 39b40f8e429ace52f19d206eec89bb897f2af079 Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Sun, 28 Jul 2019 17:55:51 +0300 Subject: [PATCH 0422/1165] fix replicated indices mutations --- dbms/src/Storages/StorageReplicatedMergeTree.cpp | 2 +- .../0_stateless/00975_indices_mutation_replicated_zookeeper.sh | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) mode change 100644 => 100755 dbms/tests/queries/0_stateless/00975_indices_mutation_replicated_zookeeper.sh diff --git a/dbms/src/Storages/StorageReplicatedMergeTree.cpp b/dbms/src/Storages/StorageReplicatedMergeTree.cpp index 0134c425a94..ef474e612cf 100644 --- a/dbms/src/Storages/StorageReplicatedMergeTree.cpp +++ b/dbms/src/Storages/StorageReplicatedMergeTree.cpp @@ -865,7 +865,7 @@ bool StorageReplicatedMergeTree::executeLogEntry(LogEntry & entry) return true; } - if (entry.type == LogEntry::CLEAR_COLUMN) + if (entry.type == LogEntry::CLEAR_COLUMN || entry.type == LogEntry::CLEAR_INDEX) { executeClearColumnOrIndexInPartition(entry); return true; diff --git a/dbms/tests/queries/0_stateless/00975_indices_mutation_replicated_zookeeper.sh b/dbms/tests/queries/0_stateless/00975_indices_mutation_replicated_zookeeper.sh old mode 100644 new mode 100755 index 4490487663f..613226a3fb7 --- a/dbms/tests/queries/0_stateless/00975_indices_mutation_replicated_zookeeper.sh +++ b/dbms/tests/queries/0_stateless/00975_indices_mutation_replicated_zookeeper.sh @@ -3,7 +3,8 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) . $CURDIR/../shell_config.sh -$CLICKHOUSE_CLIENT --query="DROP TABLE IF EXISTS test.minmax_idx;" +$CLICKHOUSE_CLIENT --query="DROP TABLE IF EXISTS test.indices_mutaions1;" +$CLICKHOUSE_CLIENT --query="DROP TABLE IF EXISTS test.indices_mutaions2;" $CLICKHOUSE_CLIENT -n --query=" From c0e0166991489dea6eb1c678bc0eb2adb24848e4 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 28 Jul 2019 18:11:47 +0300 Subject: [PATCH 0423/1165] Updated contributors --- .../StorageSystemContributors.generated.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/dbms/src/Storages/System/StorageSystemContributors.generated.cpp b/dbms/src/Storages/System/StorageSystemContributors.generated.cpp index d05314c680d..debd1fe2dc6 100644 --- a/dbms/src/Storages/System/StorageSystemContributors.generated.cpp +++ b/dbms/src/Storages/System/StorageSystemContributors.generated.cpp @@ -38,6 +38,7 @@ const char * auto_contributors[] { "Aliaksandr Pliutau", "Amos Bird", "Amy Krishnevsky", + "Anastasiya Rodigina", "Anastasiya Tsarkova", "AndreevDm", "Andrew Grigorev", @@ -65,6 +66,7 @@ const char * auto_contributors[] { "Azat Khuzhin", "BSD_Conqueror", "Babacar Diassé", + "Bakhtiyor Ruziev", "BanyRule", "BayoNet", "BlahGeek", @@ -92,6 +94,7 @@ const char * auto_contributors[] { "Dmitry Luhtionov", "Dmitry Moskowski", "Dmitry Petukhov", + "Dmitry Rubashkin", "Dmitry S..ky / skype: dvska-at-skype", "Elghazal Ahmed", "Emmanuel Donin de Rosière", @@ -103,6 +106,7 @@ const char * auto_contributors[] { "Evgeniy Udodov", "Evgeny Konkov", "Fadi Hadzh", + "FeehanG", "Flowyi", "Fruit of Eden", "Gary Dotzler", @@ -119,6 +123,7 @@ const char * auto_contributors[] { "Igor Hatarist", "Igor Strykhar", "Ildar Musin", + "Ildus Kurbangaliev", "Ilya", "Ilya Breev", "Ilya Khomutov", @@ -158,6 +163,7 @@ const char * auto_contributors[] { "Lopatin Konstantin", "Loud_Scream", "Luis Bosque", + "Lv Feng", "Léo Ercolanelli", "Maks Skorokhod", "Maksim", @@ -196,12 +202,16 @@ const char * auto_contributors[] { "Milad Arabi", "Mohammad Hossein Sekhavat", "Murat Kabilov", + "NIKITA MIKHAILOV", "Narek Galstyan", "NeZeD [Mac Pro]", "Neeke Gao", "Nicolae Vartolomei", + "Nik", "Nikhil Raman", "Nikita Lapkov", + "Nikita Mikhailov", + "Nikita Mikhaylov", "Nikita Vasilev", "Nikolai Kochetov", "Nikolay Kirsh", @@ -287,6 +297,7 @@ const char * auto_contributors[] { "Vojtech Splichal", "Vsevolod Orlov", "Vyacheslav Alipov", + "Weiqing Xu", "William Shallum", "Winter Zhang", "Yangkuan Liu", @@ -301,15 +312,18 @@ const char * auto_contributors[] { "abdrakhmanov", "abyss7", "achulkov2", + "akonyaev", "akuzm", "alesapin", "alexander kozhikhov", "alexey-milovidov", "andrewsg", + "anrodigina", "anton", "ap11", "aprudaev", "artpaul", + "avasiliev", "avsharapov", "benamazing", "bgranvea", @@ -324,6 +338,7 @@ const char * auto_contributors[] { "daoready", "davydovska", "decaseal", + "dimarub2000", "dmitry kuzmin", "eejoin", "egatov", From f632a0b24180f9252ecf3a294c97730fd57e0768 Mon Sep 17 00:00:00 2001 From: Max Akhmedov Date: Sun, 28 Jul 2019 18:12:07 +0300 Subject: [PATCH 0424/1165] Fix build under gcc-8.2 --- dbms/src/Interpreters/Aggregator.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dbms/src/Interpreters/Aggregator.h b/dbms/src/Interpreters/Aggregator.h index 983f34c1933..5f552223a24 100644 --- a/dbms/src/Interpreters/Aggregator.h +++ b/dbms/src/Interpreters/Aggregator.h @@ -120,8 +120,9 @@ private: template struct AggregationDataWithNullKeyTwoLevel : public Base { - using Base::Base; using Base::impls; + + AggregationDataWithNullKeyTwoLevel() {} template explicit AggregationDataWithNullKeyTwoLevel(const Other & other) : Base(other) From 856cc1b9c540a5397275ef3db934bb89718a54ea Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 28 Jul 2019 18:30:38 +0300 Subject: [PATCH 0425/1165] Added thread_local_rng --- dbms/src/Common/Allocator.h | 6 ++---- dbms/src/Common/QueryProfiler.cpp | 6 ++---- dbms/src/Common/ZooKeeper/ZooKeeper.cpp | 6 ++---- dbms/src/Common/thread_local_rng.cpp | 4 ++++ dbms/src/Common/thread_local_rng.h | 5 +++++ dbms/src/Compression/LZ4_decompress_faster.h | 1 + .../src/DataStreams/narrowBlockInputStreams.cpp | 6 ++---- dbms/src/Interpreters/Context.cpp | 12 +++--------- .../src/Storages/StorageReplicatedMergeTree.cpp | 17 +++++------------ .../System/StorageSystemContributors.cpp | 6 ++---- 10 files changed, 28 insertions(+), 41 deletions(-) create mode 100644 dbms/src/Common/thread_local_rng.cpp create mode 100644 dbms/src/Common/thread_local_rng.h diff --git a/dbms/src/Common/Allocator.h b/dbms/src/Common/Allocator.h index e9569673678..8d2ab415aaf 100644 --- a/dbms/src/Common/Allocator.h +++ b/dbms/src/Common/Allocator.h @@ -11,7 +11,7 @@ #endif #include -#include +#include #if !defined(__APPLE__) && !defined(__FreeBSD__) #include @@ -86,10 +86,8 @@ struct RandomHint { void * mmap_hint() { - return reinterpret_cast(std::uniform_int_distribution(0x100000000000UL, 0x700000000000UL)(rng)); + return reinterpret_cast(std::uniform_int_distribution(0x100000000000UL, 0x700000000000UL)(thread_local_rng)); } -private: - pcg64 rng{randomSeed()}; }; } diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index 5aafa35df94..8e8110e8f9f 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -1,7 +1,6 @@ #include "QueryProfiler.h" #include -#include #include #include #include @@ -10,7 +9,7 @@ #include #include #include -#include +#include #include #include @@ -63,7 +62,6 @@ namespace constexpr size_t QUERY_ID_MAX_LEN = 1024; thread_local size_t write_trace_iteration = 0; - thread_local pcg64 rng{randomSeed()}; void writeTraceInfo(TimerType timer_type, int /* sig */, siginfo_t * info, void * context) { @@ -161,7 +159,7 @@ QueryProfilerBase::QueryProfilerBase(const Int32 thread_id, const /// It will allow to sample short queries even if timer period is large. /// (For example, with period of 1 second, query with 50 ms duration will be sampled with 1 / 20 probability). /// It also helps to avoid interference (moire). - UInt32 period_rand = std::uniform_int_distribution(0, period)(rng); + UInt32 period_rand = std::uniform_int_distribution(0, period)(thread_local_rng); struct timespec interval{.tv_sec = period / TIMER_PRECISION, .tv_nsec = period % TIMER_PRECISION}; struct timespec offset{.tv_sec = period_rand / TIMER_PRECISION, .tv_nsec = period_rand % TIMER_PRECISION}; diff --git a/dbms/src/Common/ZooKeeper/ZooKeeper.cpp b/dbms/src/Common/ZooKeeper/ZooKeeper.cpp index 7a7ec42f6ff..caebc59ce7f 100644 --- a/dbms/src/Common/ZooKeeper/ZooKeeper.cpp +++ b/dbms/src/Common/ZooKeeper/ZooKeeper.cpp @@ -4,14 +4,13 @@ #include "TestKeeper.h" #include -#include #include #include #include #include #include -#include +#include #include #include @@ -159,8 +158,7 @@ struct ZooKeeperArgs } /// Shuffle the hosts to distribute the load among ZooKeeper nodes. - pcg64 rng(randomSeed()); - std::shuffle(hosts_strings.begin(), hosts_strings.end(), rng); + std::shuffle(hosts_strings.begin(), hosts_strings.end(), thread_local_rng); for (auto & host : hosts_strings) { diff --git a/dbms/src/Common/thread_local_rng.cpp b/dbms/src/Common/thread_local_rng.cpp new file mode 100644 index 00000000000..031b2123481 --- /dev/null +++ b/dbms/src/Common/thread_local_rng.cpp @@ -0,0 +1,4 @@ +#include +#include + +thread_local pcg64 thread_local_rng{randomSeed()}; diff --git a/dbms/src/Common/thread_local_rng.h b/dbms/src/Common/thread_local_rng.h new file mode 100644 index 00000000000..990f6f64948 --- /dev/null +++ b/dbms/src/Common/thread_local_rng.h @@ -0,0 +1,5 @@ +#pragma once +#include + +/// Fairly good thread-safe random number generator, but probably slow-down thread creation a little. +extern thread_local pcg64 thread_local_rng; diff --git a/dbms/src/Compression/LZ4_decompress_faster.h b/dbms/src/Compression/LZ4_decompress_faster.h index 68a55c04581..ff29c205276 100644 --- a/dbms/src/Compression/LZ4_decompress_faster.h +++ b/dbms/src/Compression/LZ4_decompress_faster.h @@ -101,6 +101,7 @@ struct PerformanceStatistics Element data[NUM_ELEMENTS]; + /// It's Ok that generator is not seeded. pcg64 rng; /// To select from different algorithms we use a kind of "bandits" algorithm. diff --git a/dbms/src/DataStreams/narrowBlockInputStreams.cpp b/dbms/src/DataStreams/narrowBlockInputStreams.cpp index 07c26bc9b67..ede12019d25 100644 --- a/dbms/src/DataStreams/narrowBlockInputStreams.cpp +++ b/dbms/src/DataStreams/narrowBlockInputStreams.cpp @@ -1,6 +1,5 @@ #include -#include -#include +#include #include @@ -21,8 +20,7 @@ BlockInputStreams narrowBlockInputStreams(BlockInputStreams & inputs, size_t wid for (size_t i = 0; i < size; ++i) distribution[i] = i % width; - pcg64 generator(randomSeed()); - std::shuffle(distribution.begin(), distribution.end(), generator); + std::shuffle(distribution.begin(), distribution.end(), thread_local_rng); for (size_t i = 0; i < size; ++i) partitions[distribution[i]].push_back(inputs[i]); diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index cec36f42469..ed8d5a33046 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -5,12 +5,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include #include @@ -205,8 +205,6 @@ struct ContextShared Context::ApplicationType application_type = Context::ApplicationType::SERVER; - pcg64 rng{randomSeed()}; - /// vector of xdbc-bridge commands, they will be killed when Context will be destroyed std::vector> bridge_commands; @@ -1172,12 +1170,8 @@ void Context::setCurrentQueryId(const String & query_id) } words; } random; - { - auto lock = getLock(); - - random.words.a = shared->rng(); - random.words.b = shared->rng(); - } + random.words.a = thread_local_rng(); + random.words.b = thread_local_rng(); /// Use protected constructor. struct UUID : Poco::UUID diff --git a/dbms/src/Storages/StorageReplicatedMergeTree.cpp b/dbms/src/Storages/StorageReplicatedMergeTree.cpp index 934d651fead..64141a509b5 100644 --- a/dbms/src/Storages/StorageReplicatedMergeTree.cpp +++ b/dbms/src/Storages/StorageReplicatedMergeTree.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -162,14 +163,6 @@ static const auto MUTATIONS_FINALIZING_SLEEP_MS = 1 * 1000; extern const int MAX_AGE_OF_LOCAL_PART_THAT_WASNT_ADDED_TO_ZOOKEEPER = 5 * 60; -/** For randomized selection of replicas. */ -/// avoid error: non-local variable 'DB::rng' declared '__thread' needs dynamic initialization -#ifndef __APPLE__ -thread_local -#endif - pcg64 rng{randomSeed()}; - - void StorageReplicatedMergeTree::setZooKeeper(zkutil::ZooKeeperPtr zookeeper) { std::lock_guard lock(current_zookeeper_mutex); @@ -708,7 +701,7 @@ void StorageReplicatedMergeTree::checkPartChecksumsAndAddCommitOps(const zkutil: part->columns, part->checksums); Strings replicas = zookeeper->getChildren(zookeeper_path + "/replicas"); - std::shuffle(replicas.begin(), replicas.end(), rng); + std::shuffle(replicas.begin(), replicas.end(), thread_local_rng); bool has_been_already_added = false; for (const String & replica : replicas) @@ -2445,7 +2438,7 @@ String StorageReplicatedMergeTree::findReplicaHavingPart(const String & part_nam Strings replicas = zookeeper->getChildren(zookeeper_path + "/replicas"); /// Select replicas in uniformly random order. - std::shuffle(replicas.begin(), replicas.end(), rng); + std::shuffle(replicas.begin(), replicas.end(), thread_local_rng); for (const String & replica : replicas) { @@ -2470,7 +2463,7 @@ String StorageReplicatedMergeTree::findReplicaHavingCoveringPart(LogEntry & entr Strings replicas = zookeeper->getChildren(zookeeper_path + "/replicas"); /// Select replicas in uniformly random order. - std::shuffle(replicas.begin(), replicas.end(), rng); + std::shuffle(replicas.begin(), replicas.end(), thread_local_rng); for (const String & replica : replicas) { @@ -2529,7 +2522,7 @@ String StorageReplicatedMergeTree::findReplicaHavingCoveringPart( Strings replicas = zookeeper->getChildren(zookeeper_path + "/replicas"); /// Select replicas in uniformly random order. - std::shuffle(replicas.begin(), replicas.end(), rng); + std::shuffle(replicas.begin(), replicas.end(), thread_local_rng); String largest_part_found; String largest_replica_found; diff --git a/dbms/src/Storages/System/StorageSystemContributors.cpp b/dbms/src/Storages/System/StorageSystemContributors.cpp index 6e165a4ee40..f1a3c68efc5 100644 --- a/dbms/src/Storages/System/StorageSystemContributors.cpp +++ b/dbms/src/Storages/System/StorageSystemContributors.cpp @@ -2,8 +2,7 @@ #include #include -#include -#include +#include extern const char * auto_contributors[]; @@ -23,8 +22,7 @@ void StorageSystemContributors::fillData(MutableColumns & res_columns, const Con for (auto it = auto_contributors; *it; ++it) contributors.emplace_back(*it); - pcg64 rng(randomSeed()); - std::shuffle(contributors.begin(), contributors.end(), rng); + std::shuffle(contributors.begin(), contributors.end(), thread_local_rng); for (auto & it : contributors) res_columns[0]->insert(String(it)); From ea6515dac681cd975bd85d9ee8381e04f34ff6e7 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 28 Jul 2019 20:15:25 +0300 Subject: [PATCH 0426/1165] Added failing test --- dbms/tests/queries/0_stateless/00975_json_hang.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 dbms/tests/queries/0_stateless/00975_json_hang.sql diff --git a/dbms/tests/queries/0_stateless/00975_json_hang.sql b/dbms/tests/queries/0_stateless/00975_json_hang.sql new file mode 100644 index 00000000000..d60411cb796 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00975_json_hang.sql @@ -0,0 +1 @@ +SELECT DISTINCT JSONExtractRaw(concat('{"x":', rand() % 2 ? 'true' : 'false', '}'), 'x') AS res FROM numbers(1000000) ORDER BY res; From f03df37b57e720d38efa61e9bc5f5510fb4a6a52 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 28 Jul 2019 20:16:48 +0300 Subject: [PATCH 0427/1165] Fixed error #6195 --- dbms/src/IO/WriteBufferFromVector.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/IO/WriteBufferFromVector.h b/dbms/src/IO/WriteBufferFromVector.h index 6e7b764f2e3..46080e227f5 100644 --- a/dbms/src/IO/WriteBufferFromVector.h +++ b/dbms/src/IO/WriteBufferFromVector.h @@ -57,7 +57,7 @@ public: : WriteBuffer(nullptr, 0), vector(vector_) { size_t old_size = vector.size(); - vector.resize(vector.capacity() < initial_size ? initial_size : vector.capacity()); + vector.resize(std::max(vector.size() + initial_size, vector.capacity())); set(reinterpret_cast(vector.data() + old_size), (vector.size() - old_size) * sizeof(typename VectorType::value_type)); } From 41d2ed0ee52486810c95c23415a3c1845972926d Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 28 Jul 2019 20:19:15 +0300 Subject: [PATCH 0428/1165] Added test result --- dbms/tests/queries/0_stateless/00975_json_hang.reference | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00975_json_hang.reference diff --git a/dbms/tests/queries/0_stateless/00975_json_hang.reference b/dbms/tests/queries/0_stateless/00975_json_hang.reference new file mode 100644 index 00000000000..1d474d52557 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00975_json_hang.reference @@ -0,0 +1,2 @@ +false +true From 5e9ea2a905cfeca33487e3ee8d9798309db417db Mon Sep 17 00:00:00 2001 From: Max Akhmedov Date: Sun, 28 Jul 2019 20:46:48 +0300 Subject: [PATCH 0429/1165] Remove spaces from empty line --- dbms/src/Interpreters/Aggregator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Interpreters/Aggregator.h b/dbms/src/Interpreters/Aggregator.h index 5f552223a24..8c67271b1d5 100644 --- a/dbms/src/Interpreters/Aggregator.h +++ b/dbms/src/Interpreters/Aggregator.h @@ -121,7 +121,7 @@ template struct AggregationDataWithNullKeyTwoLevel : public Base { using Base::impls; - + AggregationDataWithNullKeyTwoLevel() {} template From a1dacdd25f5db7cc28969b6123aad1020b8890a3 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 29 Jul 2019 02:03:55 +0300 Subject: [PATCH 0430/1165] Fixed bad test --- ...411_long_accurate_number_comparison.python | 23 ++++++++----------- ..._accurate_number_comparison_int3.reference | 1 + ...11_long_accurate_number_comparison_int3.sh | 8 +++++++ ..._accurate_number_comparison_int4.reference | 1 + ...11_long_accurate_number_comparison_int4.sh | 8 +++++++ 5 files changed, 27 insertions(+), 14 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison_int3.reference create mode 100755 dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison_int3.sh create mode 100644 dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison_int4.reference create mode 100755 dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison_int4.sh diff --git a/dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison.python b/dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison.python index aefcdec3610..47c5d7f3d5b 100644 --- a/dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison.python +++ b/dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison.python @@ -124,21 +124,16 @@ def main(): sql_file = open(base_name + '.sql', 'wt') ref_file = open(base_name + '.reference', 'wt') - num_int_tests = len(VALUES) ** 2 + num_int_tests = len(list(itertools.combinations(VALUES, 2))) - if 'int1' in sys.argv[1:]: - for (v1, v2) in itertools.islice(itertools.combinations(VALUES, 2), None, num_int_tests / 2): - q, a = test_pair(v1, v2) - if GENERATE_TEST_FILES: - sql_file.write(q + ";\n") - ref_file.write(a + "\n") - - if 'int2' in sys.argv[1:]: - for (v1, v2) in itertools.islice(itertools.combinations(VALUES, 2), num_int_tests / 2, None): - q, a = test_pair(v1, v2) - if GENERATE_TEST_FILES: - sql_file.write(q + ";\n") - ref_file.write(a + "\n") + num_parts = 4 + for part in xrange(0, num_parts): + if 'int' + str(part + 1) in sys.argv[1:]: + for (v1, v2) in itertools.islice(itertools.combinations(VALUES, 2), part * num_int_tests / num_parts, (part + 1) * num_int_tests / num_parts): + q, a = test_pair(v1, v2) + if GENERATE_TEST_FILES: + sql_file.write(q + ";\n") + ref_file.write(a + "\n") if 'float' in sys.argv[1:]: for (i, f) in itertools.product(VALUES_INT, VALUES_FLOAT): diff --git a/dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison_int3.reference b/dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison_int3.reference new file mode 100644 index 00000000000..53cdf1e9393 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison_int3.reference @@ -0,0 +1 @@ +PASSED diff --git a/dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison_int3.sh b/dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison_int3.sh new file mode 100755 index 00000000000..ec1fb335bf4 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison_int3.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +. $CURDIR/../shell_config.sh + +# We should have correct env vars from shell_config.sh to run this test + +python $CURDIR/00411_long_accurate_number_comparison.python int3 diff --git a/dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison_int4.reference b/dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison_int4.reference new file mode 100644 index 00000000000..53cdf1e9393 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison_int4.reference @@ -0,0 +1 @@ +PASSED diff --git a/dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison_int4.sh b/dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison_int4.sh new file mode 100755 index 00000000000..c353e599bb1 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00411_long_accurate_number_comparison_int4.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +. $CURDIR/../shell_config.sh + +# We should have correct env vars from shell_config.sh to run this test + +python $CURDIR/00411_long_accurate_number_comparison.python int4 From 48a3c82f6f5c2f2df1b6eb0b970027c2deca0c0e Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 29 Jul 2019 02:57:49 +0300 Subject: [PATCH 0431/1165] Removed useless code from MySQLWireBlockOutputStream --- .../Formats/MySQLWireBlockOutputStream.cpp | 20 +++++++++---------- dbms/src/Formats/MySQLWireBlockOutputStream.h | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/dbms/src/Formats/MySQLWireBlockOutputStream.cpp b/dbms/src/Formats/MySQLWireBlockOutputStream.cpp index 621a624fb0e..d7766ffe61a 100644 --- a/dbms/src/Formats/MySQLWireBlockOutputStream.cpp +++ b/dbms/src/Formats/MySQLWireBlockOutputStream.cpp @@ -12,9 +12,9 @@ using namespace MySQLProtocol; MySQLWireBlockOutputStream::MySQLWireBlockOutputStream(WriteBuffer & buf, const Block & header, Context & context) : header(header) , context(context) - , packet_sender(std::make_shared(buf, context.mysql.sequence_id)) + , packet_sender(buf, context.mysql.sequence_id) { - packet_sender->max_packet_size = context.mysql.max_packet_size; + packet_sender.max_packet_size = context.mysql.max_packet_size; } void MySQLWireBlockOutputStream::writePrefix() @@ -22,17 +22,17 @@ void MySQLWireBlockOutputStream::writePrefix() if (header.columns() == 0) return; - packet_sender->sendPacket(LengthEncodedNumber(header.columns())); + packet_sender.sendPacket(LengthEncodedNumber(header.columns())); for (const ColumnWithTypeAndName & column : header.getColumnsWithTypeAndName()) { ColumnDefinition column_definition(column.name, CharacterSet::binary, 0, ColumnType::MYSQL_TYPE_STRING, 0, 0); - packet_sender->sendPacket(column_definition); + packet_sender.sendPacket(column_definition); } if (!(context.mysql.client_capabilities & Capability::CLIENT_DEPRECATE_EOF)) { - packet_sender->sendPacket(EOF_Packet(0, 0)); + packet_sender.sendPacket(EOF_Packet(0, 0)); } } @@ -49,7 +49,7 @@ void MySQLWireBlockOutputStream::write(const Block & block) column.type->serializeAsText(*column.column.get(), i, ostr, format_settings); row_packet.appendColumn(std::move(ostr.str())); } - packet_sender->sendPacket(row_packet); + packet_sender.sendPacket(row_packet); } } @@ -67,17 +67,17 @@ void MySQLWireBlockOutputStream::writeSuffix() << formatReadableSizeWithBinarySuffix(info.read_bytes / info.elapsed_seconds) << "/sec."; if (header.columns() == 0) - packet_sender->sendPacket(OK_Packet(0x0, context.mysql.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); + packet_sender.sendPacket(OK_Packet(0x0, context.mysql.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); else if (context.mysql.client_capabilities & CLIENT_DEPRECATE_EOF) - packet_sender->sendPacket(OK_Packet(0xfe, context.mysql.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); + packet_sender.sendPacket(OK_Packet(0xfe, context.mysql.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); else - packet_sender->sendPacket(EOF_Packet(0, 0), true); + packet_sender.sendPacket(EOF_Packet(0, 0), true); } void MySQLWireBlockOutputStream::flush() { - packet_sender->out->next(); + packet_sender.out->next(); } } diff --git a/dbms/src/Formats/MySQLWireBlockOutputStream.h b/dbms/src/Formats/MySQLWireBlockOutputStream.h index d6419e00714..f54bc83eabc 100644 --- a/dbms/src/Formats/MySQLWireBlockOutputStream.h +++ b/dbms/src/Formats/MySQLWireBlockOutputStream.h @@ -27,7 +27,7 @@ public: private: Block header; Context & context; - std::shared_ptr packet_sender; + MySQLProtocol::PacketSender packet_sender; FormatSettings format_settings; }; From f1694a17467bcae6f42398c2870837ccea200568 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Mon, 29 Jul 2019 03:09:17 +0300 Subject: [PATCH 0432/1165] build fix --- dbms/src/Core/MySQLProtocol.h | 2 -- dbms/src/Interpreters/UsersManager.cpp | 1 - 2 files changed, 3 deletions(-) diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index 625f689d02f..046fb297fb1 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -20,8 +20,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/dbms/src/Interpreters/UsersManager.cpp b/dbms/src/Interpreters/UsersManager.cpp index 6c33187f526..6d1f7152b9e 100644 --- a/dbms/src/Interpreters/UsersManager.cpp +++ b/dbms/src/Interpreters/UsersManager.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include From 5fbe53b562d9af092e4b35b2b692d3fc0882d845 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 29 Jul 2019 04:08:52 +0300 Subject: [PATCH 0433/1165] Speedup "symbolizeAddress" function --- dbms/src/Common/SymbolIndex.cpp | 196 ++++++++++++++++++++++++ dbms/src/Common/SymbolIndex.h | 39 +++++ dbms/src/Common/tests/CMakeLists.txt | 3 + dbms/src/Common/tests/symbol_index.cpp | 39 +++++ dbms/src/Functions/symbolizeAddress.cpp | 38 +---- 5 files changed, 284 insertions(+), 31 deletions(-) create mode 100644 dbms/src/Common/SymbolIndex.cpp create mode 100644 dbms/src/Common/SymbolIndex.h create mode 100644 dbms/src/Common/tests/symbol_index.cpp diff --git a/dbms/src/Common/SymbolIndex.cpp b/dbms/src/Common/SymbolIndex.cpp new file mode 100644 index 00000000000..ea199a29ace --- /dev/null +++ b/dbms/src/Common/SymbolIndex.cpp @@ -0,0 +1,196 @@ +#include +#include + +#include +#include + +#include + +#include + + +namespace +{ + +/// Based on the code of musl-libc and the answer of Kanalpiroge on +/// https://stackoverflow.com/questions/15779185/list-all-the-functions-symbols-on-the-fly-in-c-code-on-a-linux-architecture + +/* Callback for dl_iterate_phdr. + * Is called by dl_iterate_phdr for every loaded shared lib until something + * else than 0 is returned by one call of this function. + */ +int collectSymbols(dl_phdr_info * info, size_t, void * out_symbols) +{ + /* ElfW is a macro that creates proper typenames for the used system architecture + * (e.g. on a 32 bit system, ElfW(Dyn*) becomes "Elf32_Dyn*") + */ + + std::vector & symbols = *reinterpret_cast *>(out_symbols); + + /* Iterate over all headers of the current shared lib + * (first call is for the executable itself) */ + for (size_t header_index = 0; header_index < info->dlpi_phnum; ++header_index) + { + /* Further processing is only needed if the dynamic section is reached + */ + if (info->dlpi_phdr[header_index].p_type != PT_DYNAMIC) + continue; + +// std::cerr << info->dlpi_name << "\n"; + + /* Get a pointer to the first entry of the dynamic section. + * It's address is the shared lib's address + the virtual address + */ + const ElfW(Dyn *) dyn_begin = reinterpret_cast(info->dlpi_addr + info->dlpi_phdr[header_index].p_vaddr); + +// std::cerr << "dlpi_addr: " << info->dlpi_addr << "\n"; + + /// For unknown reason, addresses are sometimes relative sometimes absolute. + auto correct_address = [](ElfW(Addr) base, ElfW(Addr) ptr) + { + return ptr > base ? ptr : base + ptr; + }; + + /* Iterate over all entries of the dynamic section until the + * end of the symbol table is reached. This is indicated by + * an entry with d_tag == DT_NULL. + */ + +/* for (auto it = dyn_begin; it->d_tag != DT_NULL; ++it) + std::cerr << it->d_tag << "\n";*/ + + size_t sym_cnt = 0; + for (auto it = dyn_begin; it->d_tag != DT_NULL; ++it) + { + if (it->d_tag == DT_HASH) + { + const ElfW(Word *) hash = reinterpret_cast(correct_address(info->dlpi_addr, it->d_un.d_ptr)); + +// std::cerr << it->d_un.d_ptr << ", " << it->d_un.d_val << "\n"; + + sym_cnt = hash[1]; + break; + } + else if (it->d_tag == DT_GNU_HASH) + { +// std::cerr << it->d_un.d_ptr << ", " << it->d_un.d_val << "\n"; + + /// This code based on Musl-libc. + + const uint32_t * buckets = nullptr; + const uint32_t * hashval = nullptr; + + const ElfW(Word *) hash = reinterpret_cast(correct_address(info->dlpi_addr, it->d_un.d_ptr)); + + buckets = hash + 4 + (hash[2] * sizeof(size_t) / 4); + + for (ElfW(Word) i = 0; i < hash[0]; ++i) + if (buckets[i] > sym_cnt) + sym_cnt = buckets[i]; + + if (sym_cnt) + { + sym_cnt -= hash[1]; + hashval = buckets + hash[0] + sym_cnt; + do + { + ++sym_cnt; + } + while (!(*hashval++ & 1)); + } + + break; + } + } + +// std::cerr << "sym_cnt: " << sym_cnt << "\n"; + if (!sym_cnt) + continue; + + const char * strtab = nullptr; + for (auto it = dyn_begin; it->d_tag != DT_NULL; ++it) + { + if (it->d_tag == DT_STRTAB) + { + strtab = reinterpret_cast(correct_address(info->dlpi_addr, it->d_un.d_ptr)); + break; + } + } + + if (!strtab) + continue; + +// std::cerr << "Having strtab" << "\n"; + + for (auto it = dyn_begin; it->d_tag != DT_NULL; ++it) + { + if (it->d_tag == DT_SYMTAB) + { + /* Get the pointer to the first entry of the symbol table */ + const ElfW(Sym *) elf_sym = reinterpret_cast(correct_address(info->dlpi_addr, it->d_un.d_ptr)); + + /* Iterate over the symbol table */ + for (ElfW(Word) sym_index = 0; sym_index < sym_cnt; ++sym_index) + { + /* Get the name of the sym_index-th symbol. + * This is located at the address of st_name relative to the beginning of the string table. + */ + const char * sym_name = &strtab[elf_sym[sym_index].st_name]; + + if (!sym_name) + continue; + +// std::cerr << sym_name << "\n"; + + DB::SymbolIndex::Symbol symbol; + symbol.address_begin = reinterpret_cast(info->dlpi_addr + elf_sym[sym_index].st_value); + symbol.address_end = reinterpret_cast(info->dlpi_addr + elf_sym[sym_index].st_value + elf_sym[sym_index].st_size); + int unused = 0; + symbol.name = demangle(sym_name, unused); + symbol.object = info->dlpi_name; + + symbols.push_back(std::move(symbol)); + } + + break; + } + } + } + + /* Continue iterations */ + return 0; +} + +} + + +namespace DB +{ + +void SymbolIndex::update() +{ + dl_iterate_phdr(collectSymbols, &symbols); + std::sort(symbols.begin(), symbols.end()); +} + +const SymbolIndex::Symbol * SymbolIndex::find(const void * address) const +{ + /// First range that has left boundary greater than address. + +// std::cerr << "Searching " << address << "\n"; + + auto it = std::lower_bound(symbols.begin(), symbols.end(), address); + if (it == symbols.begin()) + return nullptr; + else + --it; /// Last range that has left boundary less or equals than address. + +// std::cerr << "Range: " << it->address_begin << " ... " << it->address_end << "\n"; + + if (address >= it->address_begin && address < it->address_end) + return &*it; + else + return nullptr; +} + +} diff --git a/dbms/src/Common/SymbolIndex.h b/dbms/src/Common/SymbolIndex.h new file mode 100644 index 00000000000..b6b8284d2a9 --- /dev/null +++ b/dbms/src/Common/SymbolIndex.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include + + +namespace DB +{ + +/** Allow to quickly find symbol name from address. + * Used as a replacement for "dladdr" function which is extremely slow. + */ +class SymbolIndex +{ +public: + struct Symbol + { + const void * address_begin; + const void * address_end; + const char * object; + std::string name; /// demangled + + bool operator< (const Symbol & rhs) const { return address_begin < rhs.address_begin; } + bool operator< (const void * addr) const { return address_begin <= addr; } + }; + + SymbolIndex() { update(); } + void update(); + + const Symbol * find(const void * address) const; + + auto begin() const { return symbols.cbegin(); } + auto end() const { return symbols.cend(); } + +private: + std::vector symbols; +}; + +} diff --git a/dbms/src/Common/tests/CMakeLists.txt b/dbms/src/Common/tests/CMakeLists.txt index 83d69b2c8f2..d11a46a38d9 100644 --- a/dbms/src/Common/tests/CMakeLists.txt +++ b/dbms/src/Common/tests/CMakeLists.txt @@ -78,3 +78,6 @@ target_link_libraries (stopwatch PRIVATE clickhouse_common_io) add_executable (mi_malloc_test mi_malloc_test.cpp) target_link_libraries (mi_malloc_test PRIVATE clickhouse_common_io) + +add_executable (symbol_index symbol_index.cpp) +target_link_libraries (symbol_index PRIVATE clickhouse_common_io) diff --git a/dbms/src/Common/tests/symbol_index.cpp b/dbms/src/Common/tests/symbol_index.cpp new file mode 100644 index 00000000000..a9fec7069e9 --- /dev/null +++ b/dbms/src/Common/tests/symbol_index.cpp @@ -0,0 +1,39 @@ +#include +#include +#include +#include + + +void f() {} + +using namespace DB; + +int main(int argc, char ** argv) +{ + if (argc < 2) + { + std::cerr << "Usage: ./symbol_index address\n"; + return 1; + } + + SymbolIndex symbol_index; + + for (const auto & symbol : symbol_index) + std::cout << symbol.name << ": " << symbol.address_begin << " ... " << symbol.address_end << "\n"; + + const void * address = reinterpret_cast(std::stoull(argv[1], nullptr, 16)); + + auto symbol = symbol_index.find(address); + if (symbol) + std::cerr << symbol->name << ": " << symbol->address_begin << " ... " << symbol->address_end << "\n"; + else + std::cerr << "Not found\n"; + + Dl_info info; + if (dladdr(address, &info) && info.dli_sname) + std::cerr << demangle(info.dli_sname) << ": " << info.dli_saddr << "\n"; + else + std::cerr << "Not found\n"; + + return 0; +} diff --git a/dbms/src/Functions/symbolizeAddress.cpp b/dbms/src/Functions/symbolizeAddress.cpp index 1096a8924b3..65c1aa84d37 100644 --- a/dbms/src/Functions/symbolizeAddress.cpp +++ b/dbms/src/Functions/symbolizeAddress.cpp @@ -1,9 +1,4 @@ -#include -#include -#include -#include -#include -#include +#include #include #include #include @@ -63,25 +58,10 @@ public: return true; } - static std::string addressToSymbol(UInt64 uint_address) - { - void * addr = unalignedLoad(&uint_address); - - /// This is extremely slow. - Dl_info info; - if (dladdr(addr, &info) && info.dli_sname) - { - int demangling_status = 0; - return demangle(info.dli_sname, demangling_status); - } - else - { - return {}; - } - } - void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override { + static SymbolIndex symbol_index; + const ColumnPtr & column = block.getByPosition(arguments[0]).column; const ColumnUInt64 * column_concrete = checkAndGetColumn(column.get()); @@ -91,19 +71,15 @@ public: const typename ColumnVector::Container & data = column_concrete->getData(); auto result_column = ColumnString::create(); - static SimpleCache func_cached; - for (size_t i = 0; i < input_rows_count; ++i) { - std::string symbol = func_cached(data[i]); - result_column->insertDataWithTerminatingZero(symbol.data(), symbol.size() + 1); + if (const auto * symbol = symbol_index.find(reinterpret_cast(data[i]))) + result_column->insertDataWithTerminatingZero(symbol->name.data(), symbol->name.size() + 1); + else + result_column->insertDefault(); } block.getByPosition(result).column = std::move(result_column); - - /// Do not let our cache to grow indefinitely (simply drop it) - if (func_cached.size() > 1000000) - func_cached.drop(); } }; From 24498668a05c421ea563101608834692c23509b6 Mon Sep 17 00:00:00 2001 From: Big Elephant Date: Mon, 29 Jul 2019 14:24:11 +0800 Subject: [PATCH 0434/1165] Update overview.md --- docs/zh/data_types/domains/overview.md | 27 +++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/docs/zh/data_types/domains/overview.md b/docs/zh/data_types/domains/overview.md index 13465d655ee..25fc5d3850a 120000 --- a/docs/zh/data_types/domains/overview.md +++ b/docs/zh/data_types/domains/overview.md @@ -1 +1,26 @@ -../../../en/data_types/domains/overview.md \ No newline at end of file +# Domains + +Domains是特殊用途的类型,它在现有的基础类型之上添加了一些额外的特性,能够让线上和磁盘上的表格式保持不变。目前,ClickHouse暂不支持自定义的domains. + +您可以在任何地方使用domains,相应的基础类型的使用方式如下: + +* 构建一列domain类型的数据 +* 从/向domain列读/写数据 +* 作为索引,如果基础类型能够被作为索引的话 +* 以domain列的值作为参数调用函数 +* 等等. + +### Domains的额外特性 + +* 在使用`SHOW CREATE TABLE` 或 `DESCRIBE TABLE`时,明确地显示列类型名称 +* 使用 `INSERT INTO domain_table(domain_column) VALUES(...)`实现人性化格式输入 +* 使用`SELECT domain_column FROM domain_table`实现人性化格式输出 +* 使用 `INSERT INTO domain_table FORMAT CSV ...`实现外部源数据的人性化格式载入 + +### 缺陷 + +* 无法通过 `ALTER TABLE`将基础类型的索引转换为domain类型的索引. +* 当从其他列或表插入数据时,无法将string类型的值隐式地转换为domain类型的值. +* 无法对存储为domain类型的值添加约束. + +[Original article](https://clickhouse.yandex/docs/en/data_types/domains/overview) From 98b5c741315c96f9dee2f5b63d8473c7b0a959f3 Mon Sep 17 00:00:00 2001 From: Big Elephant Date: Mon, 29 Jul 2019 14:33:46 +0800 Subject: [PATCH 0435/1165] Update ipv6.md --- docs/zh/data_types/domains/ipv6.md | 78 +++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/docs/zh/data_types/domains/ipv6.md b/docs/zh/data_types/domains/ipv6.md index cca37a22458..13c6809e4a9 120000 --- a/docs/zh/data_types/domains/ipv6.md +++ b/docs/zh/data_types/domains/ipv6.md @@ -1 +1,77 @@ -../../../en/data_types/domains/ipv6.md \ No newline at end of file +## IPv6 + +`IPv6` 是基于`FixedString(16)` 类型的domain类型,用来存储IPv6地址值。它使用紧凑的存储方式,提供用户友好的输入输出格式, 自动检查列类型。 + +### 基本用法 + +``` sql +CREATE TABLE hits (url String, from IPv6) ENGINE = MergeTree() ORDER BY url; + +DESCRIBE TABLE hits; +``` + +``` +┌─name─┬─type───┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┐ +│ url │ String │ │ │ │ │ +│ from │ IPv6 │ │ │ │ │ +└──────┴────────┴──────────────┴────────────────────┴─────────┴──────────────────┘ +``` + +您也可以使用 `IPv6`domain做主键: + +``` sql +CREATE TABLE hits (url String, from IPv6) ENGINE = MergeTree() ORDER BY from; +``` + +`IPv6` domain支持定制化的IPv6地址字符串格式: + +``` sql +INSERT INTO hits (url, from) VALUES ('https://wikipedia.org', '2a02:aa08:e000:3100::2')('https://clickhouse.yandex', '2001:44c8:129:2632:33:0:252:2')('https://clickhouse.yandex/docs/en/', '2a02:e980:1e::1'); + +SELECT * FROM hits; +``` + +``` +┌─url────────────────────────────────┬─from──────────────────────────┐ +│ https://clickhouse.yandex │ 2001:44c8:129:2632:33:0:252:2 │ +│ https://clickhouse.yandex/docs/en/ │ 2a02:e980:1e::1 │ +│ https://wikipedia.org │ 2a02:aa08:e000:3100::2 │ +└────────────────────────────────────┴───────────────────────────────┘ +``` + +它以紧凑的二进制格式存储数值: + +``` sql +SELECT toTypeName(from), hex(from) FROM hits LIMIT 1; +``` + +``` +┌─toTypeName(from)─┬─hex(from)────────────────────────┐ +│ IPv6 │ 200144C8012926320033000002520002 │ +└──────────────────┴──────────────────────────────────┘ +``` +Domain不可隐式转换为除`FixedString(16)`以外的类型。如果要将`IPv6`值转换为字符串,则必须使用`IPv6NumToString()`函数显示地进行此操作: + +``` sql +SELECT toTypeName(s), IPv6NumToString(from) as s FROM hits LIMIT 1; +``` + +``` +┌─toTypeName(IPv6NumToString(from))─┬─s─────────────────────────────┐ +│ String │ 2001:44c8:129:2632:33:0:252:2 │ +└───────────────────────────────────┴───────────────────────────────┘ +``` + +或转换为 `FixedString(16)`类型: + +``` sql +SELECT toTypeName(i), CAST(from as FixedString(16)) as i FROM hits LIMIT 1; +``` + +``` +┌─toTypeName(CAST(from, 'FixedString(16)'))─┬─i───────┐ +│ FixedString(16) │ ��� │ +└───────────────────────────────────────────┴─────────┘ +``` + +[Original article](https://clickhouse.yandex/docs/en/data_types/domains/ipv6) From bb16ffaadc6e4ed7778c2cef3272370d5a1e0d73 Mon Sep 17 00:00:00 2001 From: Big Elephant Date: Mon, 29 Jul 2019 14:35:08 +0800 Subject: [PATCH 0436/1165] Update ipv4.md --- docs/zh/data_types/domains/ipv4.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/zh/data_types/domains/ipv4.md b/docs/zh/data_types/domains/ipv4.md index baecb7d86b1..1dd2cb03794 120000 --- a/docs/zh/data_types/domains/ipv4.md +++ b/docs/zh/data_types/domains/ipv4.md @@ -3,7 +3,7 @@ `IPv4` 是基于 `UInt32` 的domain类型,用来存储IPv4地址。它使用紧凑的存储方式,提供用户友好的输入输出格式, 自动检查列类型。 -### Basic Usage +### 基本使用 ``` sql CREATE TABLE hits (url String, from IPv4) ENGINE = MergeTree() ORDER BY url; @@ -18,7 +18,7 @@ DESCRIBE TABLE hits; └──────┴────────┴──────────────┴────────────────────┴─────────┴──────────────────┘ ``` -或者你可以使用IPv4 domain作主键: +您也可以使用IPv4 domain作主键: ``` sql CREATE TABLE hits (url String, from IPv4) ENGINE = MergeTree() ORDER BY from; From e12ab0cccc95ac41e6964ce0684fa13568b3f3db Mon Sep 17 00:00:00 2001 From: Yuriy Date: Mon, 29 Jul 2019 11:45:43 +0300 Subject: [PATCH 0437/1165] disabled tests of MySQLWire format until it is fixed --- dbms/tests/performance/number_formatting_formats.xml | 1 - dbms/tests/performance/select_format.xml | 1 - 2 files changed, 2 deletions(-) diff --git a/dbms/tests/performance/number_formatting_formats.xml b/dbms/tests/performance/number_formatting_formats.xml index df83c5cbf11..144c8aaba00 100644 --- a/dbms/tests/performance/number_formatting_formats.xml +++ b/dbms/tests/performance/number_formatting_formats.xml @@ -35,7 +35,6 @@ Parquet ODBCDriver2 Null - MySQLWire diff --git a/dbms/tests/performance/select_format.xml b/dbms/tests/performance/select_format.xml index c5ad1acd396..0182401c640 100644 --- a/dbms/tests/performance/select_format.xml +++ b/dbms/tests/performance/select_format.xml @@ -44,7 +44,6 @@ Native XML ODBCDriver2 - MySQLWire From ea6053eadc40b71408cc58f033c233c9a01df552 Mon Sep 17 00:00:00 2001 From: alesapin Date: Mon, 29 Jul 2019 12:05:37 +0300 Subject: [PATCH 0438/1165] Do not report strange exception messages into JSON report from performance-test --- dbms/programs/performance-test/ReportBuilder.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/dbms/programs/performance-test/ReportBuilder.cpp b/dbms/programs/performance-test/ReportBuilder.cpp index 4aa1933a209..cfefc37c470 100644 --- a/dbms/programs/performance-test/ReportBuilder.cpp +++ b/dbms/programs/performance-test/ReportBuilder.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "JSONString.h" @@ -29,6 +30,10 @@ std::string getMainMetric(const PerformanceTestInfo & test_info) main_metric = test_info.main_metric; return main_metric; } +bool isASCIIString(const std::string & str) +{ + return std::all_of(str.begin(), str.end(), isASCII); +} } ReportBuilder::ReportBuilder(const std::string & server_version_) @@ -109,7 +114,12 @@ std::string ReportBuilder::buildFullReport( runJSON.set("query", query); runJSON.set("query_index", query_index); if (!statistics.exception.empty()) - runJSON.set("exception", statistics.exception); + { + if (isASCIIString(statistics.exception)) + runJSON.set("exception", std::regex_replace(statistics.exception, QUOTE_REGEX, "\\\"")); + else + runJSON.set("exception", "Some exception occured with non ASCII message. This may produce invalid JSON. Try reproduce locally."); + } if (test_info.exec_type == ExecutionType::Loop) { From ad6159f62cd12b173e78eb05a6c0aa42d3078025 Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Mon, 29 Jul 2019 12:13:24 +0300 Subject: [PATCH 0439/1165] Remove past meetup --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 25dccdf16e4..9a240170627 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,5 @@ ClickHouse is an open-source column-oriented database management system that all * You can also [fill this form](https://forms.yandex.com/surveys/meet-yandex-clickhouse-team/) to meet Yandex ClickHouse team in person. ## Upcoming Events -* [ClickHouse Meetup in Saint Petersburg](https://yandex.ru/promo/clickhouse/saint-petersburg-2019) on July 27. * [ClickHouse Meetup in Shenzhen](https://www.huodongxing.com/event/3483759917300) on October 20. * [ClickHouse Meetup in Shanghai](https://www.huodongxing.com/event/4483760336000) on October 27. From acb2a54c96e68a445b3632f1660280f46fdb074b Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Mon, 29 Jul 2019 12:15:31 +0300 Subject: [PATCH 0440/1165] Update upcoming meetups (#6206) --- website/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/index.html b/website/index.html index 57d67fc0f3b..3b25c65fcdf 100644 --- a/website/index.html +++ b/website/index.html @@ -94,7 +94,7 @@
    - Upcoming Meetups: Saint Petersburg on July 27 and Shenzhen on October 20 + Upcoming Meetups: Shenzhen on October 20 and Shanghai on October 27
    From 40ae9aa60bda349ccc698d783ed5a7764f959e6b Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Mon, 29 Jul 2019 13:15:03 +0300 Subject: [PATCH 0441/1165] Update send logs tests. --- .../00965_logs_level_bugfix.reference | 11 +++++++++ .../0_stateless/00965_logs_level_bugfix.sh | 20 ++++++++++++++++ ...0965_pocopatch_logs_level_bugfix.reference | 24 ------------------- .../00965_pocopatch_logs_level_bugfix.sh | 17 ------------- ...nd_logs_level_concurrent_queries.reference | 12 ---------- ...atch_send_logs_level_concurrent_queries.sh | 17 ------------- ...nd_logs_level_concurrent_queries.reference | 0 ...0965_send_logs_level_concurrent_queries.sh | 14 +++++++++++ 8 files changed, 45 insertions(+), 70 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00965_logs_level_bugfix.reference create mode 100755 dbms/tests/queries/0_stateless/00965_logs_level_bugfix.sh delete mode 100644 dbms/tests/queries/0_stateless/00965_pocopatch_logs_level_bugfix.reference delete mode 100755 dbms/tests/queries/0_stateless/00965_pocopatch_logs_level_bugfix.sh delete mode 100644 dbms/tests/queries/0_stateless/00965_pocopatch_send_logs_level_concurrent_queries.reference delete mode 100755 dbms/tests/queries/0_stateless/00965_pocopatch_send_logs_level_concurrent_queries.sh create mode 100644 dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.reference create mode 100755 dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.sh diff --git a/dbms/tests/queries/0_stateless/00965_logs_level_bugfix.reference b/dbms/tests/queries/0_stateless/00965_logs_level_bugfix.reference new file mode 100644 index 00000000000..52396b3fe79 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00965_logs_level_bugfix.reference @@ -0,0 +1,11 @@ + +. + +. + +. + +- +. +. +. diff --git a/dbms/tests/queries/0_stateless/00965_logs_level_bugfix.sh b/dbms/tests/queries/0_stateless/00965_logs_level_bugfix.sh new file mode 100755 index 00000000000..4999ca4d1ee --- /dev/null +++ b/dbms/tests/queries/0_stateless/00965_logs_level_bugfix.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +. $CURDIR/../shell_config.sh + +clickhouse-client --send_logs_level="trace" --query="SELECT 1" 2>&1 | awk '{ print $8 }' | grep "Trace" | head -n 1 +echo "." +clickhouse-client --send_logs_level="debug" --query="SELECT 1" 2>&1 | awk '{ print $8 }' | grep "Debug" | head -n 1 +echo "." +clickhouse-client --send_logs_level="information" --query="SELECT 1" 2>&1 | awk '{ print $8 }' | grep "Information" | head -n 1 +echo "." +clickhouse-client --send_logs_level="error" --query="SELECT throwIf(1)" 2>&1 | awk '{ print $8 }' | grep "Error" | head -n 1 +echo "-" +clickhouse-client --send_logs_level="debug" --query="SELECT 1" 2>&1 | awk '{ print $8 }' | grep "Trace" | head -n 1 +echo "." +clickhouse-client --send_logs_level="information" --query="SELECT 1" 2>&1 | awk '{ print $8 }' | grep "Debug\|Trace" | head -n 1 +echo "." +clickhouse-client --send_logs_level="error" --query="SELECT throwIf(1)" 2>&1 | awk '{ print $8 }' | grep "Debug\|Trace\|Information" | head -n 1 +echo "." +clickhouse-client --send_logs_level="None" --query="SELECT throwIf(1)" 2>&1 | awk '{ print $8 }' | grep "Debug\|Trace\|Information\|Error" | head -n 1 diff --git a/dbms/tests/queries/0_stateless/00965_pocopatch_logs_level_bugfix.reference b/dbms/tests/queries/0_stateless/00965_pocopatch_logs_level_bugfix.reference deleted file mode 100644 index 233d012cabe..00000000000 --- a/dbms/tests/queries/0_stateless/00965_pocopatch_logs_level_bugfix.reference +++ /dev/null @@ -1,24 +0,0 @@ -1 -1 -1 -1 -1 -1 - - - - - - - - - - - - - - - - - - diff --git a/dbms/tests/queries/0_stateless/00965_pocopatch_logs_level_bugfix.sh b/dbms/tests/queries/0_stateless/00965_pocopatch_logs_level_bugfix.sh deleted file mode 100755 index 99de8cfb2d5..00000000000 --- a/dbms/tests/queries/0_stateless/00965_pocopatch_logs_level_bugfix.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -. $CURDIR/../shell_config.sh - -> 00965_logs_level_bugfix.tmp - -clickhouse-client --send_logs_level="trace" --query="SELECT 1;" 2>> 00965_logs_level_bugfix.tmp -clickhouse-client --send_logs_level="debug" --query="SELECT 1;" 2>> 00965_logs_level_bugfix.tmp -clickhouse-client --send_logs_level="information" --query="SELECT 1;" 2>> 00965_logs_level_bugfix.tmp -clickhouse-client --send_logs_level="warning" --query="SELECT 1;" 2>> 00965_logs_level_bugfix.tmp -clickhouse-client --send_logs_level="error" --query="SELECT 1;" 2>> 00965_logs_level_bugfix.tmp -clickhouse-client --send_logs_level="none" --query="SELECT 1;" 2>> 00965_logs_level_bugfix.tmp - -awk '{ print $8 }' 00965_logs_level_bugfix.tmp - - diff --git a/dbms/tests/queries/0_stateless/00965_pocopatch_send_logs_level_concurrent_queries.reference b/dbms/tests/queries/0_stateless/00965_pocopatch_send_logs_level_concurrent_queries.reference deleted file mode 100644 index 45c133ba43b..00000000000 --- a/dbms/tests/queries/0_stateless/00965_pocopatch_send_logs_level_concurrent_queries.reference +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - -***** - diff --git a/dbms/tests/queries/0_stateless/00965_pocopatch_send_logs_level_concurrent_queries.sh b/dbms/tests/queries/0_stateless/00965_pocopatch_send_logs_level_concurrent_queries.sh deleted file mode 100755 index 48b6b41282c..00000000000 --- a/dbms/tests/queries/0_stateless/00965_pocopatch_send_logs_level_concurrent_queries.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -. $CURDIR/../shell_config.sh - -> 00965_send_logs_level_concurrent_queries_first.tmp -> 00965_send_logs_level_concurrent_queries_second.tmp - -clickhouse-client --send_logs_level="trace" --query="SELECT * from numbers(100000);" >> /dev/null 2>> 00965_send_logs_level_concurrent_queries_first.tmp & -clickhouse-client --send_logs_level="information" --query="SELECT * from numbers(100000);" >> /dev/null 2>> 00965_send_logs_level_concurrent_queries_second.tmp - -sleep 2 - -awk '{ print $8 }' 00965_send_logs_level_concurrent_queries_first.tmp -echo "*****" -awk '{ print $8 }' 00965_send_logs_level_concurrent_queries_second.tmp - diff --git a/dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.reference b/dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.sh b/dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.sh new file mode 100755 index 00000000000..c99118f88e6 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +. $CURDIR/../shell_config.sh + +> 00965_send_logs_level_concurrent_queries_first.tmp +> 00965_send_logs_level_concurrent_queries_second.tmp + +clickhouse-client --send_logs_level="trace" --query="SELECT * from numbers(100000);" 2>&1 | awk '{ print $8 }' > 00965_send_logs_level_concurrent_queries_first.tmp & +clickhouse-client --send_logs_level="trace" --query="SELECT * from numbers(100000);" 2>&1 | awk '{ print $8 }' > 00965_send_logs_level_concurrent_queries_second.tmp & + +wait + +diff 00965_send_logs_level_concurrent_queries_first.tmp 00965_send_logs_level_concurrent_queries_second.tmp From c4f1038efca30d3f0d6f8cb14cdda9006caf9055 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Mon, 29 Jul 2019 13:19:30 +0300 Subject: [PATCH 0442/1165] DOCAPI-4148: EN review, RU translation. MergeTree partially monotonic keys (#6085) * Update http.md * Update settings.md * Update mergetree.md * DOCAPI-6213: RU translastion. * DOCAPI-4148: 4148 --- docs/en/operations/table_engines/mergetree.md | 6 +++--- docs/ru/operations/table_engines/mergetree.md | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/en/operations/table_engines/mergetree.md b/docs/en/operations/table_engines/mergetree.md index f6ee0a7313d..6cd3082498a 100644 --- a/docs/en/operations/table_engines/mergetree.md +++ b/docs/en/operations/table_engines/mergetree.md @@ -238,11 +238,11 @@ The key for partitioning by month allows reading only those data blocks which co ### Use of Index for Partially-Monotonic Primary Keys -Consider, for example, the days of the month. They are the [monotonic sequence](https://en.wikipedia.org/wiki/Monotonic_function) inside one month, but they are not monotonic for a more extended period. This is the partially-monotonic sequence. If a user creates the table with such partially-monotonic primary key, ClickHouse creates a sparse index as usual. When a user selects data from such a table, ClickHouse analyzes query conditions. If the user wants to get data between two marks of the index and both this marks are within one month, ClickHouse can use the index in this particular case because it can calculate the distance between parameters of query and index marks. +Consider, for example, the days of the month. They form a [monotonic sequence](https://en.wikipedia.org/wiki/Monotonic_function) for one month, but not monotonic for more extended periods. This is a partially-monotonic sequence. If a user creates the table with partially-monotonic primary key, ClickHouse creates a sparse index as usual. When a user selects data from this kind of table, ClickHouse analyzes the query conditions. If the user wants to get data between two marks of the index and both these marks fall within one month, ClickHouse can use the index in this particular case because it can calculate the distance between the parameters of a query and index marks. -ClickHouse cannot use an index if the values of the primary key on the query parameters range don't represent the monotonic sequence. In this case, ClickHouse uses full scan method. +ClickHouse cannot use an index if the values of the primary key in the query parameter range don't represent a monotonic sequence. In this case, ClickHouse uses the full scan method. -ClickHouse uses this logic not only for days of month sequences but for any primary key which represents a partially-monotonic sequence. +ClickHouse uses this logic not only for days of the month sequences, but for any primary key that represents a partially-monotonic sequence. ### Data Skipping Indices (Experimental) diff --git a/docs/ru/operations/table_engines/mergetree.md b/docs/ru/operations/table_engines/mergetree.md index 0ce16a5c310..84ca187fd6a 100644 --- a/docs/ru/operations/table_engines/mergetree.md +++ b/docs/ru/operations/table_engines/mergetree.md @@ -233,6 +233,14 @@ SELECT count() FROM table WHERE CounterID = 34 OR URL LIKE '%upyachka%' Ключ партиционирования по месяцам обеспечивает чтение только тех блоков данных, которые содержат даты из нужного диапазона. При этом блок данных может содержать данные за многие даты (до целого месяца). В пределах одного блока данные упорядочены по первичному ключу, который может не содержать дату в качестве первого столбца. В связи с этим, при использовании запроса с указанием условия только на дату, но не на префикс первичного ключа, будет читаться данных больше, чем за одну дату. +### Использование индекса для частично-монотонных первичных ключей + +Рассмотрим, например, дни месяца. Они образуют последовательность [монотонную](https://ru.wikipedia.org/wiki/Монотонная_последовательность) в течение одного месяца, но не монотонную на более длительных периодах. Это частично-монотонная последовательность. Если пользователь создаёт таблицу с частично-монотонным первичным ключом, ClickHouse как обычно создаёт разреженный индекс. Когда пользователь выбирает данные из такого рода таблиц, ClickHouse анализирует условия запроса. Если пользователь хочет получить данные между двумя метками индекса, и обе эти метки находятся внутри одного месяца, ClickHouse может использовать индекс в данном конкретном случае, поскольку он может рассчитать расстояние между параметрами запроса и индексными метками. + +ClickHouse не может использовать индекс, если значения первичного ключа в диапазоне параметров запроса не представляют собой монотонную последовательность. В этом случае ClickHouse использует метод полного сканирования. + +ClickHouse использует эту логику не только для последовательностей дней месяца, но и для любого частично-монотонного первичного ключа. + ### Дополнительные индексы (Экспериментальная функциональность) Для использования требуется установить настройку `allow_experimental_data_skipping_indices` в 1. (запустить `SET allow_experimental_data_skipping_indices = 1`). From 52a9341082e6c2c318aa95a8eb48583f06c7944d Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Mon, 29 Jul 2019 13:51:56 +0300 Subject: [PATCH 0443/1165] Update send logs tests. --- .../0_stateless/00965_logs_level_bugfix.sh | 16 ++++++++-------- .../00965_send_logs_level_concurrent_queries.sh | 11 ++++------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00965_logs_level_bugfix.sh b/dbms/tests/queries/0_stateless/00965_logs_level_bugfix.sh index 4999ca4d1ee..e39b8c2d2b1 100755 --- a/dbms/tests/queries/0_stateless/00965_logs_level_bugfix.sh +++ b/dbms/tests/queries/0_stateless/00965_logs_level_bugfix.sh @@ -3,18 +3,18 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) . $CURDIR/../shell_config.sh -clickhouse-client --send_logs_level="trace" --query="SELECT 1" 2>&1 | awk '{ print $8 }' | grep "Trace" | head -n 1 +$CLICKHOUSE_BINARY client --send_logs_level="trace" --query="SELECT 1" 2>&1 | awk '{ print $8 }' | grep "Trace" | head -n 1 echo "." -clickhouse-client --send_logs_level="debug" --query="SELECT 1" 2>&1 | awk '{ print $8 }' | grep "Debug" | head -n 1 +$CLICKHOUSE_BINARY client --send_logs_level="debug" --query="SELECT 1" 2>&1 | awk '{ print $8 }' | grep "Debug" | head -n 1 echo "." -clickhouse-client --send_logs_level="information" --query="SELECT 1" 2>&1 | awk '{ print $8 }' | grep "Information" | head -n 1 +$CLICKHOUSE_BINARY client --send_logs_level="information" --query="SELECT 1" 2>&1 | awk '{ print $8 }' | grep "Information" | head -n 1 echo "." -clickhouse-client --send_logs_level="error" --query="SELECT throwIf(1)" 2>&1 | awk '{ print $8 }' | grep "Error" | head -n 1 +$CLICKHOUSE_BINARY client --send_logs_level="error" --query="SELECT throwIf(1)" 2>&1 | awk '{ print $8 }' | grep "Error" | head -n 1 echo "-" -clickhouse-client --send_logs_level="debug" --query="SELECT 1" 2>&1 | awk '{ print $8 }' | grep "Trace" | head -n 1 +$CLICKHOUSE_BINARY client --send_logs_level="debug" --query="SELECT 1" 2>&1 | awk '{ print $8 }' | grep "Trace" | head -n 1 echo "." -clickhouse-client --send_logs_level="information" --query="SELECT 1" 2>&1 | awk '{ print $8 }' | grep "Debug\|Trace" | head -n 1 +$CLICKHOUSE_BINARY client --send_logs_level="information" --query="SELECT 1" 2>&1 | awk '{ print $8 }' | grep "Debug\|Trace" | head -n 1 echo "." -clickhouse-client --send_logs_level="error" --query="SELECT throwIf(1)" 2>&1 | awk '{ print $8 }' | grep "Debug\|Trace\|Information" | head -n 1 +$CLICKHOUSE_BINARY client --send_logs_level="error" --query="SELECT throwIf(1)" 2>&1 | awk '{ print $8 }' | grep "Debug\|Trace\|Information" | head -n 1 echo "." -clickhouse-client --send_logs_level="None" --query="SELECT throwIf(1)" 2>&1 | awk '{ print $8 }' | grep "Debug\|Trace\|Information\|Error" | head -n 1 +$CLICKHOUSE_BINARY client --send_logs_level="None" --query="SELECT throwIf(1)" 2>&1 | awk '{ print $8 }' | grep "Debug\|Trace\|Information\|Error" | head -n 1 diff --git a/dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.sh b/dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.sh index c99118f88e6..d2726bb11f2 100755 --- a/dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.sh +++ b/dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.sh @@ -3,12 +3,9 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) . $CURDIR/../shell_config.sh -> 00965_send_logs_level_concurrent_queries_first.tmp -> 00965_send_logs_level_concurrent_queries_second.tmp - -clickhouse-client --send_logs_level="trace" --query="SELECT * from numbers(100000);" 2>&1 | awk '{ print $8 }' > 00965_send_logs_level_concurrent_queries_first.tmp & -clickhouse-client --send_logs_level="trace" --query="SELECT * from numbers(100000);" 2>&1 | awk '{ print $8 }' > 00965_send_logs_level_concurrent_queries_second.tmp & +for i in {1..100}; do + $CLICKHOUSE_BINARY client --send_logs_level="trace" --query="SELECT * from numbers(100000);" > /dev/null 2> /dev/null & + $CLICKHOUSE_BINARY client --send_logs_level="information" --query="SELECT * from numbers(100000);" 2>&1 | awk '{ print $8 }' | grep "Debug\|Trace" & +done wait - -diff 00965_send_logs_level_concurrent_queries_first.tmp 00965_send_logs_level_concurrent_queries_second.tmp From fc0532a4517c0d8574c20b3b782f244077acf7c3 Mon Sep 17 00:00:00 2001 From: alesapin Date: Mon, 29 Jul 2019 14:04:25 +0300 Subject: [PATCH 0444/1165] Add gcc-9 to build images --- docker/packager/binary/Dockerfile | 3 +++ docker/packager/deb/Dockerfile | 3 +++ 2 files changed, 6 insertions(+) diff --git a/docker/packager/binary/Dockerfile b/docker/packager/binary/Dockerfile index 7f45a687767..20cab726056 100644 --- a/docker/packager/binary/Dockerfile +++ b/docker/packager/binary/Dockerfile @@ -13,6 +13,7 @@ RUN apt-get --allow-unauthenticated update -y \ RUN echo "deb [trusted=yes] http://apt.llvm.org/bionic/ llvm-toolchain-bionic-7 main" >> /etc/apt/sources.list RUN echo "deb [trusted=yes] http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main" >> /etc/apt/sources.list +RUN add-apt-repository ppa:ubuntu-toolchain-r/test RUN apt-get update -y \ && env DEBIAN_FRONTEND=noninteractive \ @@ -25,6 +26,8 @@ RUN apt-get update -y \ g++-7 \ gcc-8 \ g++-8 \ + gcc-9 \ + g++-9 \ clang-6.0 \ lld-6.0 \ libclang-6.0-dev \ diff --git a/docker/packager/deb/Dockerfile b/docker/packager/deb/Dockerfile index 0c9c82a5e1f..f08c2dc3eab 100644 --- a/docker/packager/deb/Dockerfile +++ b/docker/packager/deb/Dockerfile @@ -13,6 +13,7 @@ RUN apt-get --allow-unauthenticated update -y \ RUN echo "deb [trusted=yes] http://apt.llvm.org/bionic/ llvm-toolchain-bionic-7 main" >> /etc/apt/sources.list RUN echo "deb [trusted=yes] http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main" >> /etc/apt/sources.list +RUN add-apt-repository ppa:ubuntu-toolchain-r/test RUN apt-get --allow-unauthenticated update -y \ && env DEBIAN_FRONTEND=noninteractive \ @@ -21,6 +22,8 @@ RUN apt-get --allow-unauthenticated update -y \ g++-7 \ gcc-8 \ g++-8 \ + gcc-9 \ + g++-9 \ clang-6.0 \ lld-6.0 \ libclang-6.0-dev \ From 300d25256e9bfd8b9958bc3bf95205897187ac30 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 29 Jul 2019 15:48:19 +0300 Subject: [PATCH 0445/1165] Include private symbols in stack traces of QueryProfiler --- dbms/src/Common/SymbolIndex.cpp | 228 +++++++++++++++++++++++++++++--- 1 file changed, 209 insertions(+), 19 deletions(-) diff --git a/dbms/src/Common/SymbolIndex.cpp b/dbms/src/Common/SymbolIndex.cpp index ea199a29ace..f8893bd4ac6 100644 --- a/dbms/src/Common/SymbolIndex.cpp +++ b/dbms/src/Common/SymbolIndex.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -6,27 +7,25 @@ #include -#include +//#include +#include namespace { +/// Notes: "PHDR" is "Program Headers". +/// To look at program headers, you can run: objdump -p ./clickhouse-server +/// Also look at: https://wiki.osdev.org/ELF +/// Also look at: man elf +/// http://www.linker-aliens.org/blogs/ali/entry/inside_elf_symbol_tables/ +/// https://stackoverflow.com/questions/32088140/multiple-string-tables-in-elf-object + + /// Based on the code of musl-libc and the answer of Kanalpiroge on /// https://stackoverflow.com/questions/15779185/list-all-the-functions-symbols-on-the-fly-in-c-code-on-a-linux-architecture - -/* Callback for dl_iterate_phdr. - * Is called by dl_iterate_phdr for every loaded shared lib until something - * else than 0 is returned by one call of this function. - */ -int collectSymbols(dl_phdr_info * info, size_t, void * out_symbols) +void collectSymbolsFromProgramHeaders(dl_phdr_info * info, std::vector & symbols) { - /* ElfW is a macro that creates proper typenames for the used system architecture - * (e.g. on a 32 bit system, ElfW(Dyn*) becomes "Elf32_Dyn*") - */ - - std::vector & symbols = *reinterpret_cast *>(out_symbols); - /* Iterate over all headers of the current shared lib * (first call is for the executable itself) */ for (size_t header_index = 0; header_index < info->dlpi_phnum; ++header_index) @@ -36,12 +35,10 @@ int collectSymbols(dl_phdr_info * info, size_t, void * out_symbols) if (info->dlpi_phdr[header_index].p_type != PT_DYNAMIC) continue; -// std::cerr << info->dlpi_name << "\n"; - /* Get a pointer to the first entry of the dynamic section. * It's address is the shared lib's address + the virtual address */ - const ElfW(Dyn *) dyn_begin = reinterpret_cast(info->dlpi_addr + info->dlpi_phdr[header_index].p_vaddr); + const ElfW(Dyn) * dyn_begin = reinterpret_cast(info->dlpi_addr + info->dlpi_phdr[header_index].p_vaddr); // std::cerr << "dlpi_addr: " << info->dlpi_addr << "\n"; @@ -64,7 +61,7 @@ int collectSymbols(dl_phdr_info * info, size_t, void * out_symbols) { if (it->d_tag == DT_HASH) { - const ElfW(Word *) hash = reinterpret_cast(correct_address(info->dlpi_addr, it->d_un.d_ptr)); + const ElfW(Word) * hash = reinterpret_cast(correct_address(info->dlpi_addr, it->d_un.d_ptr)); // std::cerr << it->d_un.d_ptr << ", " << it->d_un.d_val << "\n"; @@ -80,7 +77,7 @@ int collectSymbols(dl_phdr_info * info, size_t, void * out_symbols) const uint32_t * buckets = nullptr; const uint32_t * hashval = nullptr; - const ElfW(Word *) hash = reinterpret_cast(correct_address(info->dlpi_addr, it->d_un.d_ptr)); + const ElfW(Word) * hash = reinterpret_cast(correct_address(info->dlpi_addr, it->d_un.d_ptr)); buckets = hash + 4 + (hash[2] * sizeof(size_t) / 4); @@ -127,11 +124,15 @@ int collectSymbols(dl_phdr_info * info, size_t, void * out_symbols) if (it->d_tag == DT_SYMTAB) { /* Get the pointer to the first entry of the symbol table */ - const ElfW(Sym *) elf_sym = reinterpret_cast(correct_address(info->dlpi_addr, it->d_un.d_ptr)); + const ElfW(Sym) * elf_sym = reinterpret_cast(correct_address(info->dlpi_addr, it->d_un.d_ptr)); /* Iterate over the symbol table */ for (ElfW(Word) sym_index = 0; sym_index < sym_cnt; ++sym_index) { + /// We are not interested in empty symbols. + if (!elf_sym[sym_index].st_size) + continue; + /* Get the name of the sym_index-th symbol. * This is located at the address of st_name relative to the beginning of the string table. */ @@ -156,6 +157,195 @@ int collectSymbols(dl_phdr_info * info, size_t, void * out_symbols) } } } +} + + +void collectSymbolsFromELFSymbolTable( + dl_phdr_info * info, + const char * mapped_elf, + size_t elf_size, + const ElfW(Shdr) * symbol_table, + const ElfW(Shdr) * string_table, + std::vector & symbols) +{ + if (symbol_table->sh_offset + symbol_table->sh_size > elf_size + || string_table->sh_offset + string_table->sh_size > elf_size) + return; + + /// Iterate symbol table. + const ElfW(Sym) * symbol_table_entry = reinterpret_cast(mapped_elf + symbol_table->sh_offset); + const ElfW(Sym) * symbol_table_end = reinterpret_cast(mapped_elf + symbol_table->sh_offset + symbol_table->sh_size); + +// std::cerr << "Symbol table has: " << (symbol_table_end - symbol_table_entry) << "\n"; + + const char * strings = reinterpret_cast(mapped_elf + string_table->sh_offset); + + for (; symbol_table_entry < symbol_table_end; ++symbol_table_entry) + { + if (!symbol_table_entry->st_name + || !symbol_table_entry->st_value + || !symbol_table_entry->st_size + || string_table->sh_offset + symbol_table_entry->st_name >= elf_size) + continue; + +// std::cerr << "Symbol Ok" << "\n"; + + /// Find the name in strings table. + const char * symbol_name = strings + symbol_table_entry->st_name; + +// std::cerr << "Symbol name: " << symbol_name << "\n"; + + DB::SymbolIndex::Symbol symbol; + symbol.address_begin = reinterpret_cast(info->dlpi_addr + symbol_table_entry->st_value); + symbol.address_end = reinterpret_cast(info->dlpi_addr + symbol_table_entry->st_value + symbol_table_entry->st_size); + int unused = 0; + symbol.name = demangle(symbol_name, unused); + symbol.object = info->dlpi_name; + + symbols.push_back(std::move(symbol)); + } +} + + +bool collectSymbolsFromELFSymbolTable( + dl_phdr_info * info, + const char * mapped_elf, + size_t elf_size, + const ElfW(Shdr) * section_headers, + size_t section_header_num_entries, + ElfW(Off) section_names_offset, + const char * section_names, + ElfW(Word) section_header_type, + const char * string_table_name, + std::vector & symbols) +{ + const ElfW(Shdr) * symbol_table = nullptr; + const ElfW(Shdr) * string_table = nullptr; + + for (size_t section_header_idx = 0; section_header_idx < section_header_num_entries; ++section_header_idx) + { + auto & entry = section_headers[section_header_idx]; + +// std::cerr << entry.sh_type << ", " << (section_names + entry.sh_name) << "\n"; + + if (section_names_offset + entry.sh_name >= elf_size) + return false; + + if (entry.sh_type == section_header_type) + symbol_table = &entry; + else if (entry.sh_type == SHT_STRTAB && 0 == strcmp(section_names + entry.sh_name, string_table_name)) + string_table = &entry; + + if (symbol_table && string_table) + break; + } + + if (!symbol_table || !string_table) + return false; + +// std::cerr << "Found tables for " << string_table_name << "\n"; + + collectSymbolsFromELFSymbolTable(info, mapped_elf, elf_size, symbol_table, string_table, symbols); + return true; +} + + +void collectSymbolsFromELF(dl_phdr_info * info, std::vector & symbols) +{ + std::string object_name = info->dlpi_name; + + /// If the name is empty - it's main executable. + /// Find a elf file for the main executable. + + if (object_name.empty()) + object_name = "/proc/self/exe"; + + std::error_code ec; + object_name = std::filesystem::canonical(object_name, ec); + + if (ec) + return; + +// std::cerr << object_name << "\n"; + + /// Read elf file. + DB::MMapReadBufferFromFile in(object_name, 0); + + /// Check if it's an elf. + size_t elf_size = in.buffer().size(); + if (elf_size < sizeof(ElfW(Ehdr))) + return; + +// std::cerr << "Size Ok" << "\n"; + + const char * mapped_elf = in.buffer().begin(); + const ElfW(Ehdr) * elf_header = reinterpret_cast(mapped_elf); + + if (memcmp(elf_header->e_ident, "\x7F""ELF", 4) != 0) + return; + +// std::cerr << "Header Ok" << "\n"; + + /// Get section header. + ElfW(Off) section_header_offset = elf_header->e_shoff; + uint16_t section_header_num_entries = elf_header->e_shnum; + +// std::cerr << section_header_offset << ", " << section_header_num_entries << ", " << (section_header_num_entries * sizeof(ElfW(Shdr))) << ", " << elf_size << "\n"; + + if (!section_header_offset + || !section_header_num_entries + || section_header_offset + section_header_num_entries * sizeof(ElfW(Shdr)) > elf_size) + return; + +// std::cerr << "Section header Ok" << "\n"; + + /// Find symtab, strtab or dyndym, dynstr. + const ElfW(Shdr) * section_headers = reinterpret_cast(mapped_elf + section_header_offset); + + /// The string table with section names. + ElfW(Off) section_names_offset = 0; + const char * section_names = nullptr; + for (size_t section_header_idx = 0; section_header_idx < section_header_num_entries; ++section_header_idx) + { + auto & entry = section_headers[section_header_idx]; + if (entry.sh_type == SHT_STRTAB && elf_header->e_shstrndx == section_header_idx) + { +// std::cerr << "Found section names\n"; + section_names_offset = entry.sh_offset; + if (section_names_offset >= elf_size) + return; + section_names = reinterpret_cast(mapped_elf + section_names_offset); + break; + } + } + + if (!section_names) + return; + + collectSymbolsFromELFSymbolTable( + info, mapped_elf, elf_size, section_headers, section_header_num_entries, + section_names_offset, section_names, SHT_SYMTAB, ".strtab", symbols); + + collectSymbolsFromELFSymbolTable( + info, mapped_elf, elf_size, section_headers, section_header_num_entries, + section_names_offset, section_names, SHT_DYNSYM, ".dynstr", symbols); +} + + +/* Callback for dl_iterate_phdr. + * Is called by dl_iterate_phdr for every loaded shared lib until something + * else than 0 is returned by one call of this function. + */ +int collectSymbols(dl_phdr_info * info, size_t, void * out_symbols) +{ + /* ElfW is a macro that creates proper typenames for the used system architecture + * (e.g. on a 32 bit system, ElfW(Dyn*) becomes "Elf32_Dyn*") + */ + + std::vector & symbols = *reinterpret_cast *>(out_symbols); + + collectSymbolsFromProgramHeaders(info, symbols); + collectSymbolsFromELF(info, symbols); /* Continue iterations */ return 0; From 1bbd192543361b78df22180e0aeaa443fc64508b Mon Sep 17 00:00:00 2001 From: proller Date: Mon, 29 Jul 2019 16:45:04 +0300 Subject: [PATCH 0446/1165] Freebsd fix --- dbms/src/Common/TraceCollector.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dbms/src/Common/TraceCollector.cpp b/dbms/src/Common/TraceCollector.cpp index e66a580289d..bfb49c4ef75 100644 --- a/dbms/src/Common/TraceCollector.cpp +++ b/dbms/src/Common/TraceCollector.cpp @@ -46,6 +46,7 @@ TraceCollector::TraceCollector(std::shared_ptr & trace_log) if (-1 == fcntl(trace_pipe.fds_rw[1], F_SETFL, flags | O_NONBLOCK)) throwFromErrno("Cannot set non-blocking mode of pipe", ErrorCodes::CANNOT_FCNTL); +#if !defined(__FreeBSD__) /** Increase pipe size to avoid slowdown during fine-grained trace collection. */ constexpr int max_pipe_capacity_to_set = 1048576; @@ -57,6 +58,7 @@ TraceCollector::TraceCollector(std::shared_ptr & trace_log) throwFromErrno("Cannot increase pipe capacity to " + toString(pipe_size * 2), ErrorCodes::CANNOT_FCNTL); LOG_TRACE(log, "Pipe capacity is " << formatReadableSizeWithBinarySuffix(std::min(pipe_size, max_pipe_capacity_to_set))); +#endif thread = ThreadFromGlobalPool(&TraceCollector::run, this); } From e9784573ea72bab97fdf9faf6560b24a68c08d06 Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Mon, 29 Jul 2019 16:50:13 +0300 Subject: [PATCH 0447/1165] Values list implementation --- dbms/src/Storages/StorageValues.cpp | 25 +++++ dbms/src/Storages/StorageValues.h | 31 +++++++ .../System/StorageSystemTableFunctions.cpp | 6 +- .../TableFunctions/TableFunctionFactory.cpp | 34 +++++-- .../src/TableFunctions/TableFunctionFactory.h | 43 ++++----- .../TableFunctions/TableFunctionValues.cpp | 92 +++++++++++++++++++ dbms/src/TableFunctions/TableFunctionValues.h | 18 ++++ .../TableFunctions/registerTableFunctions.cpp | 2 + 8 files changed, 219 insertions(+), 32 deletions(-) create mode 100644 dbms/src/Storages/StorageValues.cpp create mode 100644 dbms/src/Storages/StorageValues.h create mode 100644 dbms/src/TableFunctions/TableFunctionValues.cpp create mode 100644 dbms/src/TableFunctions/TableFunctionValues.h diff --git a/dbms/src/Storages/StorageValues.cpp b/dbms/src/Storages/StorageValues.cpp new file mode 100644 index 00000000000..52166c5aa4f --- /dev/null +++ b/dbms/src/Storages/StorageValues.cpp @@ -0,0 +1,25 @@ +#include +#include +#include + +namespace DB +{ + +StorageValues::StorageValues(const std::string & database_name_, const std::string & table_name_, const Block & res_block_) + : database_name(database_name_), table_name(table_name_), res_block(res_block_) + { + setColumns(ColumnsDescription(res_block.getNamesAndTypesList())); + } + +BlockInputStreams StorageValues::read(const Names & column_names, + const SelectQueryInfo &, + const Context & /*context*/, + QueryProcessingStage::Enum /*processed_stage*/, + size_t /*max_block_size*/, + unsigned /*num_streams*/) +{ + check(column_names); + + return BlockInputStreams(1, std::make_shared(res_block)); +} +} \ No newline at end of file diff --git a/dbms/src/Storages/StorageValues.h b/dbms/src/Storages/StorageValues.h new file mode 100644 index 00000000000..5b78dd91bf7 --- /dev/null +++ b/dbms/src/Storages/StorageValues.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +namespace DB +{ + +class StorageValues : public ext::shared_ptr_helper, public IStorage +{ +public: + std::string getName() const override { return "Values"; } + std::string getTableName() const override { return table_name; } + std::string getDatabaseName() const override { return database_name; } + + BlockInputStreams read(const Names & column_names, + const SelectQueryInfo & query_info, + const Context & context, + QueryProcessingStage::Enum processed_stage, + size_t max_block_size, + unsigned num_streams) override; + +private: + std::string database_name; + std::string table_name; + Block res_block; + +protected: + StorageValues(const std::string & database_name_, const std::string & table_name_, const Block & res_block_); +}; +} diff --git a/dbms/src/Storages/System/StorageSystemTableFunctions.cpp b/dbms/src/Storages/System/StorageSystemTableFunctions.cpp index 15067bbc41f..367595e9742 100644 --- a/dbms/src/Storages/System/StorageSystemTableFunctions.cpp +++ b/dbms/src/Storages/System/StorageSystemTableFunctions.cpp @@ -11,10 +11,10 @@ NamesAndTypesList StorageSystemTableFunctions::getNamesAndTypes() void StorageSystemTableFunctions::fillData(MutableColumns & res_columns, const Context &, const SelectQueryInfo &) const { - const auto & functions = TableFunctionFactory::instance().getAllTableFunctions(); - for (const auto & pair : functions) + const auto & functions_names = TableFunctionFactory::instance().getAllRegisteredNames(); + for (const auto & name : functions_names) { - res_columns[0]->insert(pair.first); + res_columns[0]->insert(name); } } diff --git a/dbms/src/TableFunctions/TableFunctionFactory.cpp b/dbms/src/TableFunctions/TableFunctionFactory.cpp index 7edd445379a..883ecf4abf8 100644 --- a/dbms/src/TableFunctions/TableFunctionFactory.cpp +++ b/dbms/src/TableFunctions/TableFunctionFactory.cpp @@ -17,11 +17,16 @@ namespace ErrorCodes } -void TableFunctionFactory::registerFunction(const std::string & name, Creator creator) +void TableFunctionFactory::registerFunction(const std::string & name, Creator creator, CaseSensitiveness case_sensitiveness) { - if (!functions.emplace(name, std::move(creator)).second) + if (!table_functions.emplace(name, creator).second) throw Exception("TableFunctionFactory: the table function name '" + name + "' is not unique", ErrorCodes::LOGICAL_ERROR); + + if (case_sensitiveness == CaseInsensitive + && !case_insensitive_table_functions.emplace(Poco::toLower(name), creator).second) + throw Exception("TableFunctionFactory: the case insensitive aggregate function name '" + name + "' is not unique", + ErrorCodes::LOGICAL_ERROR); } TableFunctionPtr TableFunctionFactory::get( @@ -31,8 +36,8 @@ TableFunctionPtr TableFunctionFactory::get( if (context.getSettings().readonly == 1) /** For example, for readonly = 2 - allowed. */ throw Exception("Table functions are forbidden in readonly mode", ErrorCodes::READONLY); - auto it = functions.find(name); - if (it == functions.end()) + auto res = tryGet(name, context); + if (!res) { auto hints = getHints(name); if (!hints.empty()) @@ -41,12 +46,29 @@ TableFunctionPtr TableFunctionFactory::get( throw Exception("Unknown table function " + name, ErrorCodes::UNKNOWN_FUNCTION); } - return it->second(); + return res; +} + +TableFunctionPtr TableFunctionFactory::tryGet( + const std::string & name_param, + const Context &) const +{ + String name = getAliasToOrName(name_param); + + auto it = table_functions.find(name); + if (table_functions.end() != it) + return it->second(); + + it = case_insensitive_table_functions.find(Poco::toLower(name)); + if (case_insensitive_table_functions.end() != it) + return it->second(); + + return {}; } bool TableFunctionFactory::isTableFunctionName(const std::string & name) const { - return functions.count(name); + return table_functions.count(name); } } diff --git a/dbms/src/TableFunctions/TableFunctionFactory.h b/dbms/src/TableFunctions/TableFunctionFactory.h index acbb6244c4e..ae1c3e997e7 100644 --- a/dbms/src/TableFunctions/TableFunctionFactory.h +++ b/dbms/src/TableFunctions/TableFunctionFactory.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -16,51 +17,47 @@ namespace DB class Context; +using TableFunctionCreator = std::function; /** Lets you get a table function by its name. */ -class TableFunctionFactory final: public ext::singleton, public IHints<1, TableFunctionFactory> +class TableFunctionFactory final: public ext::singleton, public IFactoryWithAliases { public: - using Creator = std::function; - using TableFunctions = std::unordered_map; /// Register a function by its name. /// No locking, you must register all functions before usage of get. - void registerFunction(const std::string & name, Creator creator); + void registerFunction(const std::string & name, Creator creator, CaseSensitiveness case_sensitiveness = CaseSensitive); template - void registerFunction() + void registerFunction(CaseSensitiveness case_sensitiveness = CaseSensitive) { auto creator = [] () -> TableFunctionPtr { return std::make_shared(); }; - registerFunction(Function::name, std::move(creator)); + registerFunction(Function::name, std::move(creator), case_sensitiveness); } /// Throws an exception if not found. - TableFunctionPtr get( - const std::string & name, - const Context & context) const; + TableFunctionPtr get(const std::string & name, const Context & context) const; + + /// Returns nullptr if not found. + TableFunctionPtr tryGet(const std::string & name, const Context & context) const; bool isTableFunctionName(const std::string & name) const; - const TableFunctions & getAllTableFunctions() const - { - return functions; - } - - std::vector getAllRegisteredNames() const override - { - std::vector result; - auto getter = [](const auto & pair) { return pair.first; }; - std::transform(functions.begin(), functions.end(), std::back_inserter(result), getter); - return result; - } - private: - TableFunctions functions; + using TableFunctions = std::unordered_map; + + const TableFunctions & getCreatorMap() const override { return table_functions; } + + const TableFunctions & getCaseInsensitiveCreatorMap() const override { return case_insensitive_table_functions; } + + String getFactoryName() const override { return "TableFunctionFactory"; } + + TableFunctions table_functions; + TableFunctions case_insensitive_table_functions; }; } diff --git a/dbms/src/TableFunctions/TableFunctionValues.cpp b/dbms/src/TableFunctions/TableFunctionValues.cpp new file mode 100644 index 00000000000..0588f657b18 --- /dev/null +++ b/dbms/src/TableFunctions/TableFunctionValues.cpp @@ -0,0 +1,92 @@ +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace DB +{ + +namespace ErrorCodes +{ + extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; +} + +StoragePtr TableFunctionValues::executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const +{ + ASTs & args_func = ast_function->children; + + if (args_func.size() != 1) + throw Exception("Table function '" + getName() + "' must have arguments.", ErrorCodes::LOGICAL_ERROR); + + ASTs & args = args_func.at(0)->children; + + if (args.size() < 2) + throw Exception("Table function '" + getName() + "' requires 2 or more arguments: structure and values.", + ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); + + ///Parsing first argument as table structure + std::string structure = args[0]->as().value.safeGet(); + + std::vector structure_values; + boost::split(structure_values, structure, boost::algorithm::is_any_of(" ,"), boost::algorithm::token_compress_on); + + if (structure_values.size() % 2 != 0) + throw Exception("Odd number of elements in section structure: must be a list of name type pairs", ErrorCodes::LOGICAL_ERROR); + + Block sample_block; + const DataTypeFactory & data_type_factory = DataTypeFactory::instance(); + + for (size_t i = 0, size = structure_values.size(); i < size; i += 2) + { + ColumnWithTypeAndName column; + column.name = structure_values[i]; + column.type = data_type_factory.get(structure_values[i + 1]); + column.column = column.type->createColumn(); + sample_block.insert(std::move(column)); + } + + MutableColumns res_columns = sample_block.cloneEmptyColumns(); + + ///Parsing other arguments as Fields + for (size_t i = 1; i < args.size(); ++i) + { + const auto & [value_field, value_type_ptr] = evaluateConstantExpression(args[i], context); + const TupleBackend & value_tuple = value_field.safeGet().toUnderType(); + + if (value_tuple.size() != sample_block.columns()) + throw Exception("Values size should match with number of columns", ErrorCodes::LOGICAL_ERROR); + + for (size_t j = 0; j < value_tuple.size(); ++j) + { + Field value = convertFieldToType(value_tuple[j], *sample_block.getByPosition(j).type, value_type_ptr.get()); + res_columns[j]->insert(value); + } + } + + Block res_block = sample_block.cloneWithColumns(std::move(res_columns)); + + auto res = StorageValues::create(getDatabaseName(), table_name, res_block); + res->startup(); + return res; + +} + +void registerTableFunctionValues(TableFunctionFactory & factory) +{ + factory.registerFunction(TableFunctionFactory::CaseInsensitive); +} + +} diff --git a/dbms/src/TableFunctions/TableFunctionValues.h b/dbms/src/TableFunctions/TableFunctionValues.h new file mode 100644 index 00000000000..b6a4eb98b6b --- /dev/null +++ b/dbms/src/TableFunctions/TableFunctionValues.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +namespace DB +{ + +class TableFunctionValues : public ITableFunction +{ +public: + static constexpr auto name = "values"; + std::string getName() const override { return name; } +private: + StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const override; +}; + + +} diff --git a/dbms/src/TableFunctions/registerTableFunctions.cpp b/dbms/src/TableFunctions/registerTableFunctions.cpp index 43583c8e1bb..76eeb23f6cc 100644 --- a/dbms/src/TableFunctions/registerTableFunctions.cpp +++ b/dbms/src/TableFunctions/registerTableFunctions.cpp @@ -13,6 +13,7 @@ void registerTableFunctionNumbers(TableFunctionFactory & factory); void registerTableFunctionCatBoostPool(TableFunctionFactory & factory); void registerTableFunctionFile(TableFunctionFactory & factory); void registerTableFunctionURL(TableFunctionFactory & factory); +void registerTableFunctionValues(TableFunctionFactory & factory); #if USE_HDFS void registerTableFunctionHDFS(TableFunctionFactory & factory); @@ -39,6 +40,7 @@ void registerTableFunctions() registerTableFunctionCatBoostPool(factory); registerTableFunctionFile(factory); registerTableFunctionURL(factory); + registerTableFunctionValues(factory); #if USE_HDFS registerTableFunctionHDFS(factory); From a270717919eb67c6d6b7a31f9aff1302eaad55c3 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Mon, 29 Jul 2019 17:38:32 +0300 Subject: [PATCH 0448/1165] TRANSLATE-2372: EN review --- docs/en/operations/table_engines/mergetree.md | 88 +++++++++---------- 1 file changed, 40 insertions(+), 48 deletions(-) diff --git a/docs/en/operations/table_engines/mergetree.md b/docs/en/operations/table_engines/mergetree.md index f6ee0a7313d..317145a886b 100644 --- a/docs/en/operations/table_engines/mergetree.md +++ b/docs/en/operations/table_engines/mergetree.md @@ -1,8 +1,8 @@ # MergeTree {#table_engines-mergetree} -The `MergeTree` engine and other engines of this family (`*MergeTree`) are the most robust ClickHouse table engines. +The `MergeTree` engine and other engines of this family (`*MergeTree`) are the most robust ClickHousе table engines. -The basic idea for `MergeTree` engines family is the following. When you have tremendous amount of a data that should be inserted into the table, you should write them quickly part by part and then merge parts by some rules in background. This method is much more efficient than constantly rewriting data in the storage at the insert. +Engines in the `MergeTree` family are designed for inserting a very large amount of data into a table. The data is quickly written to the table part by part, then rules are applied for merging the parts in the background. This method is much more efficient than continually rewriting the data in storage during insert. Main features: @@ -10,13 +10,13 @@ Main features: This allows you to create a small sparse index that helps find data faster. -- This allows you to use partitions if the [partitioning key](custom_partitioning_key.md) is specified. +- Partitions can be used if the [partitioning key](custom_partitioning_key.md) is specified. - ClickHouse supports certain operations with partitions that are more effective than general operations on the same data with the same result. ClickHouse also automatically cuts off the partition data where the partitioning key is specified in the query. This also increases the query performance. + ClickHouse supports certain operations with partitions that are more effective than general operations on the same data with the same result. ClickHouse also automatically cuts off the partition data where the partitioning key is specified in the query. This also improves query performance. - Data replication support. - The family of `ReplicatedMergeTree` tables is used for this. For more information, see the [Data replication](replication.md) section. + The family of `ReplicatedMergeTree` tables provides data replication. For more information, see [Data replication](replication.md). - Data sampling support. @@ -45,11 +45,11 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] [SETTINGS name=value, ...] ``` -For a description of request parameters, see [request description](../../query_language/create.md). +For descriptions of request parameters, see the [request description](../../query_language/create.md). **Query clauses** -- `ENGINE` — Name and parameters of the engine. `ENGINE = MergeTree()`. `MergeTree` engine does not have parameters. +- `ENGINE` — Name and parameters of the engine. `ENGINE = MergeTree()`. The `MergeTree` engine does not have parameters. - `PARTITION BY` — The [partitioning key](custom_partitioning_key.md). @@ -69,19 +69,19 @@ For a description of request parameters, see [request description](../../query_l - `TTL` — An expression for setting storage time for rows. - It must depends on `Date` or `DateTime` column and has one `Date` or `DateTime` column as a result. Example: + It must depend on the `Date` or `DateTime` column and have one `Date` or `DateTime` column as a result. Example: `TTL date + INTERVAL 1 DAY` For more details, see [TTL for columns and tables](#table_engine-mergetree-ttl) - `SETTINGS` — Additional parameters that control the behavior of the `MergeTree`: - - `index_granularity` — The granularity of an index. The number of data rows between the "marks" of an index. By default, 8192. The list of all available parameters you can see in [MergeTreeSettings.h](https://github.com/yandex/ClickHouse/blob/master/dbms/src/Storages/MergeTree/MergeTreeSettings.h). - - `use_minimalistic_part_header_in_zookeeper` — Storage method of the data parts headers in ZooKeeper. If `use_minimalistic_part_header_in_zookeeper=1`, then ZooKeeper stores less data. For more information refer the [setting description](../server_settings/settings.md#server-settings-use_minimalistic_part_header_in_zookeeper) in the "Server configuration parameters" chapter. - - `min_merge_bytes_to_use_direct_io` — The minimum data volume for merge operation required for using of the direct I/O access to the storage disk. During the merging of the data parts, ClickHouse calculates summary storage volume of all the data to be merged. If the volume exceeds `min_merge_bytes_to_use_direct_io` bytes, then ClickHouse reads and writes the data using direct I/O interface (`O_DIRECT` option) to the storage disk. If `min_merge_bytes_to_use_direct_io = 0`, then the direct I/O is disabled. Default value: `10 * 1024 * 1024 * 1024` bytes. + - `index_granularity` — The granularity of an index. The number of data rows between the "marks" of an index. By default, 8192. For the list of available parameters, see [MergeTreeSettings.h](https://github.com/yandex/ClickHouse/blob/master/dbms/src/Storages/MergeTree/MergeTreeSettings.h). + - `use_minimalistic_part_header_in_zookeeper` — Storage method of the data parts headers in ZooKeeper. If `use_minimalistic_part_header_in_zookeeper=1`, then ZooKeeper stores less data. For more information, see the [setting description](../server_settings/settings.md#server-settings-use_minimalistic_part_header_in_zookeeper) in "Server configuration parameters". + - `min_merge_bytes_to_use_direct_io` — The minimum data volume for merge operation that is required for using direct I/O access to the storage disk. When merging data parts, ClickHouse calculates the total storage volume of all the data to be merged. If the volume exceeds `min_merge_bytes_to_use_direct_io` bytes, ClickHouse reads and writes the data to the storage disk using the direct I/O interface (`O_DIRECT` option). If `min_merge_bytes_to_use_direct_io = 0`, then direct I/O is disabled. Default value: `10 * 1024 * 1024 * 1024` bytes. - - `merge_with_ttl_timeout` — Minimal time in seconds, when merge with TTL can be repeated. Default value: 86400 (1 day). + - `merge_with_ttl_timeout` — Minimum delay in seconds before repeating a merge with TTL. Default value: 86400 (1 day). -**Example of sections setting** +**Example of setting the sections ** ``` ENGINE MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity=8192 @@ -89,14 +89,14 @@ ENGINE MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDa In the example, we set partitioning by month. -We also set an expression for sampling as a hash by the user ID. This allows you to pseudorandomize the data in the table for each `CounterID` and `EventDate`. If, when selecting the data, you define a [SAMPLE](../../query_language/select.md#select-sample-clause) clause, ClickHouse will return an evenly pseudorandom data sample for a subset of users. +We also set an expression for sampling as a hash by the user ID. This allows you to pseudorandomize the data in the table for each `CounterID` and `EventDate`. If you define a [SAMPLE](../../query_language/select.md#select-sample-clause) clause when selecting the data, ClickHouse will return an evenly pseudorandom data sample for a subset of users. -`index_granularity` could be omitted because 8192 is the default value. +The `index_granularity` setting can be omitted because 8192 is the default value.
    Deprecated Method for Creating a Table !!! attention - Do not use this method in new projects and, if possible, switch the old projects to the method described above. + Do not use this method in new projects. If possible, switch old projects to the method described above. ``` CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] @@ -109,9 +109,9 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] **MergeTree() parameters** -- `date-column` — The name of a column of the type [Date](../../data_types/date.md). ClickHouse automatically creates partitions by month on the basis of this column. The partition names are in the `"YYYYMM"` format. -- `sampling_expression` — an expression for sampling. -- `(primary, key)` — primary key. Type — [Tuple()](../../data_types/tuple.md) +- `date-column` — The name of a column of the [Date](../../data_types/date.md) type. ClickHouse automatically creates partitions by month based on this column. The partition names are in the `"YYYYMM"` format. +- `sampling_expression` — An expression for sampling. +- `(primary, key)` — Primary key. Type: [Tuple()](../../data_types/tuple.md) - `index_granularity` — The granularity of an index. The number of data rows between the "marks" of an index. The value 8192 is appropriate for most tasks. **Example** @@ -137,7 +137,7 @@ You can use a single large table and continually add data to it in small chunks ## Primary Keys and Indexes in Queries {#primary-keys-and-indexes-in-queries} -Let's take the `(CounterID, Date)` primary key. In this case, the sorting and index can be illustrated as follows: +Take the `(CounterID, Date)` primary key as an example. In this case, the sorting and index can be illustrated as follows: ``` Whole data: [-------------------------------------------------------------------------] @@ -176,37 +176,29 @@ The number of columns in the primary key is not explicitly limited. Depending on ClickHouse sorts data by primary key, so the higher the consistency, the better the compression. -- Provide additional logic when data parts merging in the [CollapsingMergeTree](collapsingmergetree.md#table_engine-collapsingmergetree) and [SummingMergeTree](summingmergetree.md) engines. +- Provide additional logic when merging data parts in the [CollapsingMergeTree](collapsingmergetree.md#table_engine-collapsingmergetree) and [SummingMergeTree](summingmergetree.md) engines. In this case it makes sense to specify the *sorting key* that is different from the primary key. A long primary key will negatively affect the insert performance and memory consumption, but extra columns in the primary key do not affect ClickHouse performance during `SELECT` queries. -### Choosing the Primary Key that differs from the Sorting Key +### Choosing a Primary Key that Differs from the Sorting Key -It is possible to specify the primary key (the expression, values of which are written into the index file -for each mark) that is different from the sorting key (the expression for sorting the rows in data parts). -In this case the primary key expression tuple must be a prefix of the sorting key expression tuple. +It is possible to specify a primary key (an expression with values that are written in the index file for each mark) that is different from the sorting key (an expression for sorting the rows in data parts). In this case the primary key expression tuple must be a prefix of the sorting key expression tuple. This feature is helpful when using the [SummingMergeTree](summingmergetree.md) and -[AggregatingMergeTree](aggregatingmergetree.md) table engines. In a common case when using these engines the -table has two types of columns: *dimensions* and *measures*. Typical queries aggregate values of measure -columns with arbitrary `GROUP BY` and filtering by dimensions. As SummingMergeTree and AggregatingMergeTree -aggregate rows with the same value of the sorting key, it is natural to add all dimensions to it. As a result -the key expression consists of a long list of columns and this list must be frequently updated with newly -added dimensions. +[AggregatingMergeTree](aggregatingmergetree.md) table engines. In a common case when using these engines, the table has two types of columns: *dimensions* and *measures*. Typical queries aggregate values of measure columns with arbitrary `GROUP BY` and filtering by dimensions. Because SummingMergeTree and AggregatingMergeTree aggregate rows with the same value of the sorting key, it is natural to add all dimensions to it. As a result, the key expression consists of a long list of columns and this list must be frequently updated with newly added dimensions. -In this case it makes sense to leave only a few columns in the primary key that will provide efficient -range scans and add the remaining dimension columns to the sorting key tuple. +In this case it makes sense to leave only a few columns in the primary key that will provide efficient range scans and add the remaining dimension columns to the sorting key tuple. -[ALTER of the sorting key](../../query_language/alter.md) is a lightweight operation because when a new column is simultaneously added to the table and to the sorting key, existing data parts don't need to be changed. Since the old sorting key is a prefix of the new sorting key and there is no data in the just added column, the data at the moment of table modification is sorted by both the old and the new sorting key. +[ALTER](../../query_language/alter.md) of the sorting key is a lightweight operation because when a new column is simultaneously added to the table and to the sorting key, existing data parts don't need to be changed. Since the old sorting key is a prefix of the new sorting key and there is no data in the newly added column, the data is sorted by both the old and new sorting keys at the moment of table modification. ### Use of Indexes and Partitions in Queries -For`SELECT` queries, ClickHouse analyzes whether an index can be used. An index can be used if the `WHERE/PREWHERE` clause has an expression (as one of the conjunction elements, or entirely) that represents an equality or inequality comparison operation, or if it has `IN` or `LIKE` with a fixed prefix on columns or expressions that are in the primary key or partitioning key, or on certain partially repetitive functions of these columns, or logical relationships of these expressions. +For `SELECT` queries, ClickHouse analyzes whether an index can be used. An index can be used if the `WHERE/PREWHERE` clause has an expression (as one of the conjunction elements, or entirely) that represents an equality or inequality comparison operation, or if it has `IN` or `LIKE` with a fixed prefix on columns or expressions that are in the primary key or partitioning key, or on certain partially repetitive functions of these columns, or logical relationships of these expressions. -Thus, it is possible to quickly run queries on one or many ranges of the primary key. In this example, queries will be fast when run for a specific tracking tag; for a specific tag and date range; for a specific tag and date; for multiple tags with a date range, and so on. +Thus, it is possible to quickly run queries on one or many ranges of the primary key. In this example, queries will be fast when run for a specific tracking tag, for a specific tag and date range, for a specific tag and date, for multiple tags with a date range, and so on. Let's look at the engine configured as follows: @@ -248,14 +240,14 @@ ClickHouse uses this logic not only for days of month sequences but for any prim You need to set `allow_experimental_data_skipping_indices` to 1 to use indices. (run `SET allow_experimental_data_skipping_indices = 1`). -Index declaration in the columns section of the `CREATE` query. +The index declaration is in the columns section of the `CREATE` query. ```sql INDEX index_name expr TYPE type(...) GRANULARITY granularity_value ``` -For tables from the `*MergeTree` family data skipping indices can be specified. +For tables from the `*MergeTree` family, data skipping indices can be specified. -These indices aggregate some information about the specified expression on blocks, which consist of `granularity_value` granules (size of the granule is specified using `index_granularity` setting in the table engine), then these aggregates are used in `SELECT` queries for reducing the amount of data to read from the disk by skipping big blocks of data where `where` query cannot be satisfied. +These indices aggregate some information about the specified expression on blocks, which consist of `granularity_value` granules (the size of the granule is specified using the `index_granularity` setting in the table engine). Then these aggregates are used in `SELECT` queries for reducing the amount of data to read from the disk by skipping big blocks of data where the `where` query cannot be satisfied. **Example** @@ -273,7 +265,7 @@ CREATE TABLE table_name ... ``` -Indices from the example can be used by ClickHouse to reduce the amount of data to read from disk in following queries. +Indices from the example can be used by ClickHouse to reduce the amount of data to read from disk in the following queries: ```sql SELECT count() FROM table WHERE s < 'z' @@ -284,24 +276,24 @@ SELECT count() FROM table WHERE u64 * i32 == 10 AND u64 * length(s) >= 1234 - `minmax` - Stores extremes of the specified expression (if the expression is `tuple`, then it stores extremes for each element of `tuple`), uses stored info for skipping blocks of the data like the primary key. + Stores extremes of the specified expression (if the expression is `tuple`, then it stores extremes for each element of `tuple`), uses stored info for skipping blocks of data like the primary key. - `set(max_rows)` - Stores unique values of the specified expression (no more than `max_rows` rows, `max_rows=0` means "no limits"), use them to check if the `WHERE` expression is not satisfiable on a block of the data. + Stores unique values of the specified expression (no more than `max_rows` rows, `max_rows=0` means "no limits"). Uses the values to check if the `WHERE` expression is not satisfiable on a block of data. - `ngrambf_v1(n, size_of_bloom_filter_in_bytes, number_of_hash_functions, random_seed)` - Stores [bloom filter](https://en.wikipedia.org/wiki/Bloom_filter) that contains all ngrams from block of data. Works only with strings. Can be used for optimization of `equals`, `like` and `in` expressions. + Stores a [bloom filter](https://en.wikipedia.org/wiki/Bloom_filter) that contains all ngrams from a block of data. Works only with strings. Can be used for optimization of `equals`, `like` and `in` expressions. - `n` — ngram size, - - `size_of_bloom_filter_in_bytes` — bloom filter size in bytes (you can use big values here, for example, 256 or 512, because it can be compressed well), - - `number_of_hash_functions` — number of hash functions used in bloom filter, - - `random_seed` — seed for bloom filter hash functions. + - `size_of_bloom_filter_in_bytes` — Bloom filter size in bytes (you can use large values here, for example, 256 or 512, because it can be compressed well). + - `number_of_hash_functions` — The number of hash functions used in the bloom filter. + - `random_seed` — The seed for bloom filter hash functions. - `tokenbf_v1(size_of_bloom_filter_in_bytes, number_of_hash_functions, random_seed)` - The same as `ngrambf_v1`, but instead of ngrams stores tokens, which are sequences separated by non-alphanumeric characters. + The same as `ngrambf_v1`, but stores tokens instead of ngrams. Tokens are sequences separated by non-alphanumeric characters. ```sql INDEX sample_index (u64 * length(s)) TYPE minmax GRANULARITY 4 @@ -316,7 +308,7 @@ For concurrent table access, we use multi-versioning. In other words, when a tab Reading from a table is automatically parallelized. -## TTL for columns and tables {#table_engine-mergetree-ttl} +## TTL for Columns and Tables {#table_engine-mergetree-ttl} Determines the lifetime of values. From 7b4ddd268e8d207d0a6bf1454993498839d57012 Mon Sep 17 00:00:00 2001 From: chertus Date: Mon, 29 Jul 2019 17:58:36 +0300 Subject: [PATCH 0449/1165] support ASOF JOIN ON syntax --- .../Interpreters/CollectJoinOnKeysVisitor.cpp | 210 ++++++++++++++++++ .../Interpreters/CollectJoinOnKeysVisitor.h | 166 ++------------ dbms/src/Interpreters/SyntaxAnalyzer.cpp | 6 +- .../00927_asof_join_noninclusive.sql | 2 +- .../0_stateless/00976_asof_join_on.reference | 13 ++ .../0_stateless/00976_asof_join_on.sql | 21 ++ 6 files changed, 267 insertions(+), 151 deletions(-) create mode 100644 dbms/src/Interpreters/CollectJoinOnKeysVisitor.cpp create mode 100644 dbms/tests/queries/0_stateless/00976_asof_join_on.reference create mode 100644 dbms/tests/queries/0_stateless/00976_asof_join_on.sql diff --git a/dbms/src/Interpreters/CollectJoinOnKeysVisitor.cpp b/dbms/src/Interpreters/CollectJoinOnKeysVisitor.cpp new file mode 100644 index 00000000000..68e04b45d99 --- /dev/null +++ b/dbms/src/Interpreters/CollectJoinOnKeysVisitor.cpp @@ -0,0 +1,210 @@ +#include + +#include +#include +#include + +namespace DB +{ + +namespace ErrorCodes +{ + extern const int INVALID_JOIN_ON_EXPRESSION; + extern const int AMBIGUOUS_COLUMN_NAME; + extern const int NOT_IMPLEMENTED; + extern const int LOGICAL_ERROR; +} + +void CollectJoinOnKeysMatcher::Data::addJoinKeys(const ASTPtr & left_ast, const ASTPtr & right_ast, + const std::pair & table_no) +{ + ASTPtr left = left_ast->clone(); + ASTPtr right = right_ast->clone(); + + if (table_no.first == 1 || table_no.second == 2) + analyzed_join.addOnKeys(left, right); + else if (table_no.first == 2 || table_no.second == 1) + analyzed_join.addOnKeys(right, left); + else + throw Exception("Cannot detect left and right JOIN keys. JOIN ON section is ambiguous.", + ErrorCodes::AMBIGUOUS_COLUMN_NAME); + has_some = true; +} + +void CollectJoinOnKeysMatcher::Data::addAsofJoinKeys(const ASTPtr & left_ast, const ASTPtr & right_ast, + const std::pair & table_no) +{ + if (table_no.first == 1 || table_no.second == 2) + { + asof_left_key = left_ast->clone(); + asof_right_key = right_ast->clone(); + return; + } + + throw Exception("ASOF JOIN for (left_table.x <= right_table.x) is not implemented", ErrorCodes::NOT_IMPLEMENTED); +} + +void CollectJoinOnKeysMatcher::Data::asofToJoinKeys() +{ + if (!asof_left_key || !asof_right_key) + throw Exception("No inequality in ASOF JOIN ON section.", ErrorCodes::INVALID_JOIN_ON_EXPRESSION); + addJoinKeys(asof_left_key, asof_right_key, {1, 2}); +} + + +void CollectJoinOnKeysMatcher::visit(const ASTFunction & func, const ASTPtr & ast, Data & data) +{ + if (func.name == "and") + return; /// go into children + + if (func.name == "equals") + { + ASTPtr left = func.arguments->children.at(0); + ASTPtr right = func.arguments->children.at(1); + auto table_numbers = getTableNumbers(ast, left, right, data); + data.addJoinKeys(left, right, table_numbers); + return; + } + + bool less_or_equals = (func.name == "lessOrEquals"); + bool greater_or_equals = (func.name == "greaterOrEquals"); + + if (data.is_asof && (less_or_equals || greater_or_equals)) + { + if (data.asof_left_key || data.asof_right_key) + throwSyntaxException("ASOF JOIN expects exactly one inequality in ON section, unexpected " + queryToString(ast) + "."); + + ASTPtr left = func.arguments->children.at(0); + ASTPtr right = func.arguments->children.at(1); + auto table_numbers = getTableNumbers(ast, left, right, data); + + if (greater_or_equals) + data.addAsofJoinKeys(left, right, table_numbers); + else + data.addAsofJoinKeys(right, left, std::make_pair(table_numbers.second, table_numbers.first)); + + return; + } + + throwSyntaxException("Expected equals expression, got " + queryToString(ast) + "."); +} + +void CollectJoinOnKeysMatcher::getIdentifiers(const ASTPtr & ast, std::vector & out) +{ + if (const auto * ident = ast->as()) + { + if (IdentifierSemantic::getColumnName(*ident)) + out.push_back(ident); + return; + } + + for (const auto & child : ast->children) + getIdentifiers(child, out); +} + +std::pair CollectJoinOnKeysMatcher::getTableNumbers(const ASTPtr & expr, const ASTPtr & left_ast, const ASTPtr & right_ast, + Data & data) +{ + std::vector left_identifiers; + std::vector right_identifiers; + + getIdentifiers(left_ast, left_identifiers); + getIdentifiers(right_ast, right_identifiers); + + size_t left_idents_table = getTableForIdentifiers(left_identifiers, data); + size_t right_idents_table = getTableForIdentifiers(right_identifiers, data); + + if (left_idents_table && left_idents_table == right_idents_table) + { + auto left_name = queryToString(*left_identifiers[0]); + auto right_name = queryToString(*right_identifiers[0]); + + throwSyntaxException("In expression " + queryToString(expr) + " columns " + left_name + " and " + right_name + + " are from the same table but from different arguments of equal function."); + } + + return std::make_pair(left_idents_table, right_idents_table); +} + +const ASTIdentifier * CollectJoinOnKeysMatcher::unrollAliases(const ASTIdentifier * identifier, const Aliases & aliases) +{ + if (identifier->compound()) + return identifier; + + UInt32 max_attempts = 100; + for (auto it = aliases.find(identifier->name); it != aliases.end();) + { + const ASTIdentifier * parent = identifier; + identifier = it->second->as(); + if (!identifier) + break; /// not a column alias + if (identifier == parent) + break; /// alias to itself with the same name: 'a as a' + if (identifier->compound()) + break; /// not an alias. Break to prevent cycle through short names: 'a as b, t1.b as a' + + it = aliases.find(identifier->name); + if (!max_attempts--) + throw Exception("Cannot unroll aliases for '" + identifier->name + "'", ErrorCodes::LOGICAL_ERROR); + } + + return identifier; +} + +/// @returns 1 if identifiers belongs to left table, 2 for right table and 0 if unknown. Throws on table mix. +/// Place detected identifier into identifiers[0] if any. +size_t CollectJoinOnKeysMatcher::getTableForIdentifiers(std::vector & identifiers, const Data & data) +{ + size_t table_number = 0; + + for (auto & ident : identifiers) + { + const ASTIdentifier * identifier = unrollAliases(ident, data.aliases); + if (!identifier) + continue; + + /// Column name could be cropped to a short form in TranslateQualifiedNamesVisitor. + /// In this case it saves membership in IdentifierSemantic. + size_t membership = IdentifierSemantic::getMembership(*identifier); + + if (!membership) + { + const String & name = identifier->name; + bool in_left_table = data.source_columns.count(name); + bool in_right_table = data.joined_columns.count(name); + + if (in_left_table && in_right_table) + throw Exception("Column '" + name + "' is ambiguous", ErrorCodes::AMBIGUOUS_COLUMN_NAME); + + if (in_left_table) + membership = 1; + if (in_right_table) + membership = 2; + } + + if (membership && table_number == 0) + { + table_number = membership; + std::swap(ident, identifiers[0]); /// move first detected identifier to the first position + } + + if (membership && membership != table_number) + { + throw Exception("Invalid columns in JOIN ON section. Columns " + + identifiers[0]->getAliasOrColumnName() + " and " + ident->getAliasOrColumnName() + + " are from different tables.", ErrorCodes::INVALID_JOIN_ON_EXPRESSION); + } + } + + return table_number; +} + +[[noreturn]] void CollectJoinOnKeysMatcher::throwSyntaxException(const String & msg) +{ + throw Exception("Invalid expression for JOIN ON. " + msg + + " Supported syntax: JOIN ON Expr([table.]column, ...) = Expr([table.]column, ...) " + "[AND Expr([table.]column, ...) = Expr([table.]column, ...) ...]", + ErrorCodes::INVALID_JOIN_ON_EXPRESSION); +} + +} diff --git a/dbms/src/Interpreters/CollectJoinOnKeysVisitor.h b/dbms/src/Interpreters/CollectJoinOnKeysVisitor.h index 7dc3051167a..bae6781a18a 100644 --- a/dbms/src/Interpreters/CollectJoinOnKeysVisitor.h +++ b/dbms/src/Interpreters/CollectJoinOnKeysVisitor.h @@ -1,23 +1,16 @@ #pragma once +#include #include -#include - #include #include -#include namespace DB { -namespace ErrorCodes -{ - extern const int INVALID_JOIN_ON_EXPRESSION; - extern const int AMBIGUOUS_COLUMN_NAME; - extern const int LOGICAL_ERROR; -} - +class ASTIdentifier; +struct AnalyzedJoin; class CollectJoinOnKeysMatcher { @@ -30,7 +23,14 @@ public: const NameSet & source_columns; const NameSet & joined_columns; const Aliases & aliases; - bool has_some = false; + const bool is_asof; + ASTPtr asof_left_key{}; + ASTPtr asof_right_key{}; + bool has_some{false}; + + void addJoinKeys(const ASTPtr & left_ast, const ASTPtr & right_ast, const std::pair & table_no); + void addAsofJoinKeys(const ASTPtr & left_ast, const ASTPtr & right_ast, const std::pair & table_no); + void asofToJoinKeys(); }; static void visit(const ASTPtr & ast, Data & data) @@ -48,146 +48,14 @@ public: } private: - static void visit(const ASTFunction & func, const ASTPtr & ast, Data & data) - { - if (func.name == "and") - return; /// go into children + static void visit(const ASTFunction & func, const ASTPtr & ast, Data & data); - if (func.name == "equals") - { - ASTPtr left = func.arguments->children.at(0)->clone(); - ASTPtr right = func.arguments->children.at(1)->clone(); - addJoinKeys(ast, left, right, data); - return; - } + static void getIdentifiers(const ASTPtr & ast, std::vector & out); + static std::pair getTableNumbers(const ASTPtr & expr, const ASTPtr & left_ast, const ASTPtr & right_ast, Data & data); + static const ASTIdentifier * unrollAliases(const ASTIdentifier * identifier, const Aliases & aliases); + static size_t getTableForIdentifiers(std::vector & identifiers, const Data & data); - throwSyntaxException("Expected equals expression, got " + queryToString(ast) + "."); - } - - static void getIdentifiers(const ASTPtr & ast, std::vector & out) - { - if (const auto * ident = ast->as()) - { - if (IdentifierSemantic::getColumnName(*ident)) - out.push_back(ident); - return; - } - - for (const auto & child : ast->children) - getIdentifiers(child, out); - } - - static void addJoinKeys(const ASTPtr & expr, ASTPtr left_ast, ASTPtr right_ast, Data & data) - { - std::vector left_identifiers; - std::vector right_identifiers; - - getIdentifiers(left_ast, left_identifiers); - getIdentifiers(right_ast, right_identifiers); - - size_t left_idents_table = getTableForIdentifiers(left_identifiers, data); - size_t right_idents_table = getTableForIdentifiers(right_identifiers, data); - - if (left_idents_table && left_idents_table == right_idents_table) - { - auto left_name = queryToString(*left_identifiers[0]); - auto right_name = queryToString(*right_identifiers[0]); - - throwSyntaxException("In expression " + queryToString(expr) + " columns " + left_name + " and " + right_name - + " are from the same table but from different arguments of equal function."); - } - - if (left_idents_table == 1 || right_idents_table == 2) - data.analyzed_join.addOnKeys(left_ast, right_ast); - else if (left_idents_table == 2 || right_idents_table == 1) - data.analyzed_join.addOnKeys(right_ast, left_ast); - else - throw Exception("Cannot detect left and right JOIN keys. JOIN ON section is ambiguous.", - ErrorCodes::AMBIGUOUS_COLUMN_NAME); - - data.has_some = true; - } - - static const ASTIdentifier * unrollAliases(const ASTIdentifier * identifier, const Aliases & aliases) - { - if (identifier->compound()) - return identifier; - - UInt32 max_attempts = 100; - for (auto it = aliases.find(identifier->name); it != aliases.end();) - { - const ASTIdentifier * parent = identifier; - identifier = it->second->as(); - if (!identifier) - break; /// not a column alias - if (identifier == parent) - break; /// alias to itself with the same name: 'a as a' - if (identifier->compound()) - break; /// not an alias. Break to prevent cycle through short names: 'a as b, t1.b as a' - - it = aliases.find(identifier->name); - if (!max_attempts--) - throw Exception("Cannot unroll aliases for '" + identifier->name + "'", ErrorCodes::LOGICAL_ERROR); - } - - return identifier; - } - - /// @returns 1 if identifiers belongs to left table, 2 for right table and 0 if unknown. Throws on table mix. - /// Place detected identifier into identifiers[0] if any. - static size_t getTableForIdentifiers(std::vector & identifiers, const Data & data) - { - size_t table_number = 0; - - for (auto & ident : identifiers) - { - const ASTIdentifier * identifier = unrollAliases(ident, data.aliases); - if (!identifier) - continue; - - /// Column name could be cropped to a short form in TranslateQualifiedNamesVisitor. - /// In this case it saves membership in IdentifierSemantic. - size_t membership = IdentifierSemantic::getMembership(*identifier); - - if (!membership) - { - const String & name = identifier->name; - bool in_left_table = data.source_columns.count(name); - bool in_right_table = data.joined_columns.count(name); - - if (in_left_table && in_right_table) - throw Exception("Column '" + name + "' is ambiguous", ErrorCodes::AMBIGUOUS_COLUMN_NAME); - - if (in_left_table) - membership = 1; - if (in_right_table) - membership = 2; - } - - if (membership && table_number == 0) - { - table_number = membership; - std::swap(ident, identifiers[0]); /// move first detected identifier to the first position - } - - if (membership && membership != table_number) - { - throw Exception("Invalid columns in JOIN ON section. Columns " - + identifiers[0]->getAliasOrColumnName() + " and " + ident->getAliasOrColumnName() - + " are from different tables.", ErrorCodes::INVALID_JOIN_ON_EXPRESSION); - } - } - - return table_number; - } - - [[noreturn]] static void throwSyntaxException(const String & msg) - { - throw Exception("Invalid expression for JOIN ON. " + msg + - " Supported syntax: JOIN ON Expr([table.]column, ...) = Expr([table.]column, ...) " - "[AND Expr([table.]column, ...) = Expr([table.]column, ...) ...]", - ErrorCodes::INVALID_JOIN_ON_EXPRESSION); - } + [[noreturn]] static void throwSyntaxException(const String & msg); }; /// Parse JOIN ON expression and collect ASTs for joined columns. diff --git a/dbms/src/Interpreters/SyntaxAnalyzer.cpp b/dbms/src/Interpreters/SyntaxAnalyzer.cpp index 04102f5ae15..02156b20995 100644 --- a/dbms/src/Interpreters/SyntaxAnalyzer.cpp +++ b/dbms/src/Interpreters/SyntaxAnalyzer.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -509,11 +510,14 @@ void collectJoinedColumns(AnalyzedJoin & analyzed_join, const ASTSelectQuery & s for (const auto & col : analyzed_join.columns_from_joined_table) joined_columns.insert(col.original_name); - CollectJoinOnKeysVisitor::Data data{analyzed_join, source_columns, joined_columns, aliases}; + bool is_asof = (table_join.strictness == ASTTableJoin::Strictness::Asof); + CollectJoinOnKeysVisitor::Data data{analyzed_join, source_columns, joined_columns, aliases, is_asof}; CollectJoinOnKeysVisitor(data).visit(table_join.on_expression); if (!data.has_some) throw Exception("Cannot get JOIN keys from JOIN ON section: " + queryToString(table_join.on_expression), ErrorCodes::INVALID_JOIN_ON_EXPRESSION); + if (is_asof) + data.asofToJoinKeys(); } bool make_nullable = join_use_nulls && isLeftOrFull(table_join.kind); diff --git a/dbms/tests/queries/0_stateless/00927_asof_join_noninclusive.sql b/dbms/tests/queries/0_stateless/00927_asof_join_noninclusive.sql index 50644352b64..5f15f3b593d 100644 --- a/dbms/tests/queries/0_stateless/00927_asof_join_noninclusive.sql +++ b/dbms/tests/queries/0_stateless/00927_asof_join_noninclusive.sql @@ -12,7 +12,7 @@ INSERT INTO B(k,t,b) VALUES (2,3,3); SELECT A.k, toString(A.t, 'UTC'), A.a, B.b, toString(B.t, 'UTC'), B.k FROM A ASOF LEFT JOIN B USING(k,t) ORDER BY (A.k, A.t); -SELECT A.k, toString(A.t, 'UTC'), A.a, B.b, toString(B.t, 'UTC'), B.k FROM A ASOF INNER JOIN B ON A.k == B.k AND A.t == B.t ORDER BY (A.k, A.t); +SELECT A.k, toString(A.t, 'UTC'), A.a, B.b, toString(B.t, 'UTC'), B.k FROM A ASOF INNER JOIN B ON A.k == B.k AND A.t >= B.t ORDER BY (A.k, A.t); SELECT A.k, toString(A.t, 'UTC'), A.a, B.b, toString(B.t, 'UTC'), B.k FROM A ASOF JOIN B USING(k,t) ORDER BY (A.k, A.t); diff --git a/dbms/tests/queries/0_stateless/00976_asof_join_on.reference b/dbms/tests/queries/0_stateless/00976_asof_join_on.reference new file mode 100644 index 00000000000..ffa8117cc75 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00976_asof_join_on.reference @@ -0,0 +1,13 @@ +1 1 0 0 +1 2 1 2 +1 3 1 2 +2 1 0 0 +2 2 0 0 +2 3 2 3 +3 1 0 0 +3 2 0 0 +3 3 0 0 +9 +1 2 1 2 +1 3 1 2 +2 3 2 3 diff --git a/dbms/tests/queries/0_stateless/00976_asof_join_on.sql b/dbms/tests/queries/0_stateless/00976_asof_join_on.sql new file mode 100644 index 00000000000..740287b7c30 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00976_asof_join_on.sql @@ -0,0 +1,21 @@ +DROP TABLE IF EXISTS A; +DROP TABLE IF EXISTS B; + +CREATE TABLE A(a UInt32, t UInt32) ENGINE = Memory; +CREATE TABLE B(b UInt32, t UInt32) ENGINE = Memory; + +INSERT INTO A (a,t) VALUES (1,1),(1,2),(1,3), (2,1),(2,2),(2,3), (3,1),(3,2),(3,3); +INSERT INTO B (b,t) VALUES (1,2),(1,4),(2,3); + +SELECT A.a, A.t, B.b, B.t FROM A ASOF LEFT JOIN B ON A.a == B.b AND A.t >= B.t ORDER BY (A.a, A.t); +SELECT count() FROM A ASOF LEFT JOIN B ON A.a == B.b AND B.t <= A.t; +SELECT A.a, A.t, B.b, B.t FROM A ASOF INNER JOIN B ON B.t <= A.t AND A.a == B.b; +SELECT count() FROM A ASOF JOIN B ON A.a == B.b AND A.t <= B.t; -- { serverError 48 } +SELECT count() FROM A ASOF JOIN B ON A.a == B.b AND B.t >= A.t; -- { serverError 48 } +SELECT count() FROM A ASOF JOIN B ON A.a == B.b AND A.t > B.t; -- { serverError 403 } +SELECT count() FROM A ASOF JOIN B ON A.a == B.b AND A.t < B.t; -- { serverError 403 } +SELECT count() FROM A ASOF JOIN B ON A.a == B.b AND A.t == B.t; -- { serverError 403 } +SELECT count() FROM A ASOF JOIN B ON A.a == B.b AND A.t != B.t; -- { serverError 403 } + +DROP TABLE A; +DROP TABLE B; From c1b57f9cf51159e8923c123e0b21f0c9fdcab4be Mon Sep 17 00:00:00 2001 From: Yuriy Date: Mon, 29 Jul 2019 18:41:47 +0300 Subject: [PATCH 0450/1165] fixed heap buffer overflow in PacketPayloadWriteBuffer --- dbms/src/Core/MySQLProtocol.h | 77 ++++++++++--------- .../Formats/MySQLWireBlockOutputStream.cpp | 20 ++--- .../Formats/Impl/MySQLOutputFormat.cpp | 20 ++--- .../performance/number_formatting_formats.xml | 1 + dbms/tests/performance/select_format.xml | 1 + 5 files changed, 64 insertions(+), 55 deletions(-) diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index cb0e6ab001c..ccd127352ed 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -246,26 +246,17 @@ class PacketPayloadWriteBuffer : public WriteBuffer { public: PacketPayloadWriteBuffer(WriteBuffer & out, size_t payload_length, uint8_t & sequence_id) - : WriteBuffer(out.position(), 0) - , out(out) - , sequence_id(sequence_id) - , total_left(payload_length) + : WriteBuffer(out.position(), 0), out(out), sequence_id(sequence_id), total_left(payload_length) { - startPacket(); + startNewPacket(); + setWorkingBuffer(); + pos = out.position(); } - void checkPayloadSize() + bool remainingPayloadSize() { - if (bytes_written + offset() < payload_length) - { - std::stringstream ss; - ss << "Incomplete payload. Written " << bytes << " bytes, expected " << payload_length << " bytes."; - throw Exception(ss.str(), 0); - - } + return total_left; } - - ~PacketPayloadWriteBuffer() override { next(); } private: WriteBuffer & out; uint8_t & sequence_id; @@ -273,8 +264,9 @@ private: size_t total_left = 0; size_t payload_length = 0; size_t bytes_written = 0; + bool eof = false; - void startPacket() + void startNewPacket() { payload_length = std::min(total_left, MAX_PACKET_LENGTH); bytes_written = 0; @@ -282,33 +274,38 @@ private: out.write(reinterpret_cast(&payload_length), 3); out.write(sequence_id++); - - working_buffer = WriteBuffer::Buffer(out.position(), out.position() + std::min(payload_length - bytes_written, out.available())); - pos = working_buffer.begin(); + bytes += 4; } + + /// Sets working buffer to the rest of current packet payload. + void setWorkingBuffer() + { + out.nextIfAtEnd(); + working_buffer = WriteBuffer::Buffer(out.position(), out.position() + std::min(payload_length - bytes_written, out.available())); + + if (payload_length - bytes_written == 0) + { + /// Finished writing packet. Due to an implementation of WriteBuffer, working_buffer cannot be empty. Further write attempts will throw Exception. + eof = true; + working_buffer.resize(1); + } + } + protected: void nextImpl() override { - int written = pos - working_buffer.begin(); + const int written = pos - working_buffer.begin(); + if (eof) + throw Exception("Cannot write after end of buffer.", ErrorCodes::CANNOT_WRITE_AFTER_END_OF_BUFFER); + out.position() += written; bytes_written += written; - if (bytes_written < payload_length) - { - out.nextIfAtEnd(); - working_buffer = WriteBuffer::Buffer(out.position(), out.position() + std::min(payload_length - bytes_written, out.available())); - } - else if (total_left > 0 || payload_length == MAX_PACKET_LENGTH) - { - // Starting new packet, since packets of size greater than MAX_PACKET_LENGTH should be split. - startPacket(); - } - else - { - // Finished writing packet. Buffer is set to empty to prevent rewriting (pos will be set to the beginning of a working buffer in next()). - // Further attempts to write will stall in the infinite loop. - working_buffer = WriteBuffer::Buffer(out.position(), out.position()); - } + /// Packets of size greater than MAX_PACKET_LENGTH are split into few packets of size MAX_PACKET_LENGTH and las packet of size < MAX_PACKET_LENGTH. + if (bytes_written == payload_length && (total_left > 0 || payload_length == MAX_PACKET_LENGTH)) + startNewPacket(); + + setWorkingBuffer(); } }; @@ -320,7 +317,13 @@ public: { PacketPayloadWriteBuffer buf(buffer, getPayloadSize(), sequence_id); writePayloadImpl(buf); - buf.checkPayloadSize(); + buf.next(); + if (buf.remainingPayloadSize()) + { + std::stringstream ss; + ss << "Incomplete payload. Written " << getPayloadSize() - buf.remainingPayloadSize() << " bytes, expected " << getPayloadSize() << " bytes."; + throw Exception(ss.str(), 0); + } } virtual ~WritePacket() = default; diff --git a/dbms/src/Formats/MySQLWireBlockOutputStream.cpp b/dbms/src/Formats/MySQLWireBlockOutputStream.cpp index d7766ffe61a..f032d5b84d4 100644 --- a/dbms/src/Formats/MySQLWireBlockOutputStream.cpp +++ b/dbms/src/Formats/MySQLWireBlockOutputStream.cpp @@ -55,16 +55,18 @@ void MySQLWireBlockOutputStream::write(const Block & block) void MySQLWireBlockOutputStream::writeSuffix() { - QueryStatus * process_list_elem = context.getProcessListElement(); - CurrentThread::finalizePerformanceCounters(); - QueryStatusInfo info = process_list_elem->getInfo(); - size_t affected_rows = info.written_rows; - + size_t affected_rows = 0; std::stringstream human_readable_info; - human_readable_info << std::fixed << std::setprecision(3) - << "Read " << info.read_rows << " rows, " << formatReadableSizeWithBinarySuffix(info.read_bytes) << " in " << info.elapsed_seconds << " sec., " - << static_cast(info.read_rows / info.elapsed_seconds) << " rows/sec., " - << formatReadableSizeWithBinarySuffix(info.read_bytes / info.elapsed_seconds) << "/sec."; + if (QueryStatus * process_list_elem = context.getProcessListElement()) + { + CurrentThread::finalizePerformanceCounters(); + QueryStatusInfo info = process_list_elem->getInfo(); + affected_rows = info.written_rows; + human_readable_info << std::fixed << std::setprecision(3) + << "Read " << info.read_rows << " rows, " << formatReadableSizeWithBinarySuffix(info.read_bytes) << " in " << info.elapsed_seconds << " sec., " + << static_cast(info.read_rows / info.elapsed_seconds) << " rows/sec., " + << formatReadableSizeWithBinarySuffix(info.read_bytes / info.elapsed_seconds) << "/sec."; + } if (header.columns() == 0) packet_sender.sendPacket(OK_Packet(0x0, context.mysql.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); diff --git a/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp b/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp index 3ddaed53687..446fd687503 100644 --- a/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp @@ -71,16 +71,18 @@ void MySQLOutputFormat::consume(Chunk chunk) void MySQLOutputFormat::finalize() { - QueryStatus * process_list_elem = context.getProcessListElement(); - CurrentThread::finalizePerformanceCounters(); - QueryStatusInfo info = process_list_elem->getInfo(); - size_t affected_rows = info.written_rows; - + size_t affected_rows = 0; std::stringstream human_readable_info; - human_readable_info << std::fixed << std::setprecision(3) - << "Read " << info.read_rows << " rows, " << formatReadableSizeWithBinarySuffix(info.read_bytes) << " in " << info.elapsed_seconds << " sec., " - << static_cast(info.read_rows / info.elapsed_seconds) << " rows/sec., " - << formatReadableSizeWithBinarySuffix(info.read_bytes / info.elapsed_seconds) << "/sec."; + if (QueryStatus * process_list_elem = context.getProcessListElement()) + { + CurrentThread::finalizePerformanceCounters(); + QueryStatusInfo info = process_list_elem->getInfo(); + affected_rows = info.written_rows; + human_readable_info << std::fixed << std::setprecision(3) + << "Read " << info.read_rows << " rows, " << formatReadableSizeWithBinarySuffix(info.read_bytes) << " in " << info.elapsed_seconds << " sec., " + << static_cast(info.read_rows / info.elapsed_seconds) << " rows/sec., " + << formatReadableSizeWithBinarySuffix(info.read_bytes / info.elapsed_seconds) << "/sec."; + } auto & header = getPort(PortKind::Main).getHeader(); diff --git a/dbms/tests/performance/number_formatting_formats.xml b/dbms/tests/performance/number_formatting_formats.xml index 144c8aaba00..df83c5cbf11 100644 --- a/dbms/tests/performance/number_formatting_formats.xml +++ b/dbms/tests/performance/number_formatting_formats.xml @@ -35,6 +35,7 @@ Parquet ODBCDriver2 Null + MySQLWire diff --git a/dbms/tests/performance/select_format.xml b/dbms/tests/performance/select_format.xml index 0182401c640..c5ad1acd396 100644 --- a/dbms/tests/performance/select_format.xml +++ b/dbms/tests/performance/select_format.xml @@ -44,6 +44,7 @@ Native XML ODBCDriver2 + MySQLWire From 45aebda67794ab70615fee15267f040b14f62215 Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Mon, 29 Jul 2019 19:20:17 +0300 Subject: [PATCH 0451/1165] Fixes and test --- dbms/src/Storages/StorageValues.cpp | 15 ++--- dbms/src/Storages/StorageValues.h | 13 +++-- .../TableFunctions/TableFunctionFactory.cpp | 2 +- .../TableFunctions/TableFunctionValues.cpp | 58 +++++++++++++------ .../0_stateless/00975_values_list.reference | 12 ++++ .../queries/0_stateless/00975_values_list.sql | 11 ++++ 6 files changed, 78 insertions(+), 33 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00975_values_list.reference create mode 100644 dbms/tests/queries/0_stateless/00975_values_list.sql diff --git a/dbms/src/Storages/StorageValues.cpp b/dbms/src/Storages/StorageValues.cpp index 52166c5aa4f..b2058c93be7 100644 --- a/dbms/src/Storages/StorageValues.cpp +++ b/dbms/src/Storages/StorageValues.cpp @@ -11,15 +11,16 @@ StorageValues::StorageValues(const std::string & database_name_, const std::stri setColumns(ColumnsDescription(res_block.getNamesAndTypesList())); } -BlockInputStreams StorageValues::read(const Names & column_names, - const SelectQueryInfo &, - const Context & /*context*/, - QueryProcessingStage::Enum /*processed_stage*/, - size_t /*max_block_size*/, - unsigned /*num_streams*/) +BlockInputStreams StorageValues::read( + const Names & column_names, + const SelectQueryInfo & /*query_info*/, + const Context & /*context*/, + QueryProcessingStage::Enum /*processed_stage*/, + size_t /*max_block_size*/, + unsigned /*num_streams*/) { check(column_names); return BlockInputStreams(1, std::make_shared(res_block)); } -} \ No newline at end of file +} diff --git a/dbms/src/Storages/StorageValues.h b/dbms/src/Storages/StorageValues.h index 5b78dd91bf7..478aaa96e84 100644 --- a/dbms/src/Storages/StorageValues.h +++ b/dbms/src/Storages/StorageValues.h @@ -13,12 +13,13 @@ public: std::string getTableName() const override { return table_name; } std::string getDatabaseName() const override { return database_name; } - BlockInputStreams read(const Names & column_names, - const SelectQueryInfo & query_info, - const Context & context, - QueryProcessingStage::Enum processed_stage, - size_t max_block_size, - unsigned num_streams) override; + BlockInputStreams read( + const Names & column_names, + const SelectQueryInfo & query_info, + const Context & context, + QueryProcessingStage::Enum processed_stage, + size_t max_block_size, + unsigned num_streams) override; private: std::string database_name; diff --git a/dbms/src/TableFunctions/TableFunctionFactory.cpp b/dbms/src/TableFunctions/TableFunctionFactory.cpp index 883ecf4abf8..c389180fd7e 100644 --- a/dbms/src/TableFunctions/TableFunctionFactory.cpp +++ b/dbms/src/TableFunctions/TableFunctionFactory.cpp @@ -25,7 +25,7 @@ void TableFunctionFactory::registerFunction(const std::string & name, Creator cr if (case_sensitiveness == CaseInsensitive && !case_insensitive_table_functions.emplace(Poco::toLower(name), creator).second) - throw Exception("TableFunctionFactory: the case insensitive aggregate function name '" + name + "' is not unique", + throw Exception("TableFunctionFactory: the case insensitive table function name '" + name + "' is not unique", ErrorCodes::LOGICAL_ERROR); } diff --git a/dbms/src/TableFunctions/TableFunctionValues.cpp b/dbms/src/TableFunctions/TableFunctionValues.cpp index 0588f657b18..bf2e8679962 100644 --- a/dbms/src/TableFunctions/TableFunctionValues.cpp +++ b/dbms/src/TableFunctions/TableFunctionValues.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -11,10 +12,12 @@ #include #include #include -#include -#include -#include + #include +#include + +#include + namespace DB { @@ -24,6 +27,37 @@ namespace ErrorCodes extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; } +static void parseAndInsertValues(MutableColumns & res_columns, const ASTs & args, const Block & sample_block, const Context & context) +{ + if (res_columns.size() == 1) /// Parsing arguments as Fields + { + for (size_t i = 1; i < args.size(); ++i) + { + const auto & [value_field, value_type_ptr] = evaluateConstantExpression(args[i], context); + + Field value = convertFieldToType(value_field, *sample_block.getByPosition(0).type, value_type_ptr.get()); + res_columns[0]->insert(value); + } + } + else /// Parsing arguments as Tuples + { + for (size_t i = 1; i < args.size(); ++i) + { + const auto & [value_field, value_type_ptr] = evaluateConstantExpression(args[i], context); + const TupleBackend & value_tuple = value_field.safeGet().toUnderType(); + + if (value_tuple.size() != sample_block.columns()) + throw Exception("Values size should match with number of columns", ErrorCodes::LOGICAL_ERROR); + + for (size_t j = 0; j < value_tuple.size(); ++j) + { + Field value = convertFieldToType(value_tuple[j], *sample_block.getByPosition(j).type, value_type_ptr.get()); + res_columns[j]->insert(value); + } + } + } +} + StoragePtr TableFunctionValues::executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const { ASTs & args_func = ast_function->children; @@ -37,7 +71,7 @@ StoragePtr TableFunctionValues::executeImpl(const ASTPtr & ast_function, const C throw Exception("Table function '" + getName() + "' requires 2 or more arguments: structure and values.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); - ///Parsing first argument as table structure + /// Parsing first argument as table structure std::string structure = args[0]->as().value.safeGet(); std::vector structure_values; @@ -60,21 +94,7 @@ StoragePtr TableFunctionValues::executeImpl(const ASTPtr & ast_function, const C MutableColumns res_columns = sample_block.cloneEmptyColumns(); - ///Parsing other arguments as Fields - for (size_t i = 1; i < args.size(); ++i) - { - const auto & [value_field, value_type_ptr] = evaluateConstantExpression(args[i], context); - const TupleBackend & value_tuple = value_field.safeGet().toUnderType(); - - if (value_tuple.size() != sample_block.columns()) - throw Exception("Values size should match with number of columns", ErrorCodes::LOGICAL_ERROR); - - for (size_t j = 0; j < value_tuple.size(); ++j) - { - Field value = convertFieldToType(value_tuple[j], *sample_block.getByPosition(j).type, value_type_ptr.get()); - res_columns[j]->insert(value); - } - } + parseAndInsertValues(res_columns, args, sample_block, context); Block res_block = sample_block.cloneWithColumns(std::move(res_columns)); diff --git a/dbms/tests/queries/0_stateless/00975_values_list.reference b/dbms/tests/queries/0_stateless/00975_values_list.reference new file mode 100644 index 00000000000..0f719e42424 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00975_values_list.reference @@ -0,0 +1,12 @@ +1 one +2 two +3 three +1 one +2 two +3 three +2018-01-01 2018-01-01 00:00:00 +abra +cadabra +abracadabra +23 23 23 +24 24 24 diff --git a/dbms/tests/queries/0_stateless/00975_values_list.sql b/dbms/tests/queries/0_stateless/00975_values_list.sql new file mode 100644 index 00000000000..a105919b474 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00975_values_list.sql @@ -0,0 +1,11 @@ +DROP TABLE IF EXISTS values_list; + +SELECT * FROM VALUES('a UInt64, s String', (1, 'one'), (2, 'two'), (3, 'three')); +CREATE TABLE values_list AS VALUES('a UInt64, s String', (1, 'one'), (2, 'two'), (3, 'three')); +SELECT * FROM values_list; + +SELECT subtractYears(date, 1), subtractYears(date_time, 1) FROM VALUES('date Date, date_time DateTime', (toDate('2019-01-01'), toDateTime('2019-01-01 00:00:00'))); + +SELECT * FROM VALUES('s String', ('abra'), ('cadabra'), ('abracadabra')); + +SELECT * FROM VALUES('n UInt64, s String, ss String', (1 + 22, '23', toString(23)), (toUInt64('24'), '24', concat('2', '4'))); From 89bbe1a299569957298b3d52f88b8795e443f1bb Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Mon, 29 Jul 2019 19:23:22 +0300 Subject: [PATCH 0452/1165] drop table --- dbms/tests/queries/0_stateless/00975_values_list.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dbms/tests/queries/0_stateless/00975_values_list.sql b/dbms/tests/queries/0_stateless/00975_values_list.sql index a105919b474..a71dd50860d 100644 --- a/dbms/tests/queries/0_stateless/00975_values_list.sql +++ b/dbms/tests/queries/0_stateless/00975_values_list.sql @@ -8,4 +8,5 @@ SELECT subtractYears(date, 1), subtractYears(date_time, 1) FROM VALUES('date Dat SELECT * FROM VALUES('s String', ('abra'), ('cadabra'), ('abracadabra')); -SELECT * FROM VALUES('n UInt64, s String, ss String', (1 + 22, '23', toString(23)), (toUInt64('24'), '24', concat('2', '4'))); +SELECT * FROM VALUES('n UInt64, s String, ss String', (1 + 22, '23', toString(23)), (toUInt64('24'), '24', concat('2', '4'))); +DROP TABLE values_list; From efc4395b2ff8fad06c01574fd1e0f1201774b733 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Mon, 29 Jul 2019 19:29:58 +0300 Subject: [PATCH 0453/1165] Update send logs tests. --- .../0_stateless/00965_send_logs_level_concurrent_queries.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.sh b/dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.sh index d2726bb11f2..d6976f4a3a7 100755 --- a/dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.sh +++ b/dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.sh @@ -3,9 +3,9 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) . $CURDIR/../shell_config.sh -for i in {1..100}; do - $CLICKHOUSE_BINARY client --send_logs_level="trace" --query="SELECT * from numbers(100000);" > /dev/null 2> /dev/null & - $CLICKHOUSE_BINARY client --send_logs_level="information" --query="SELECT * from numbers(100000);" 2>&1 | awk '{ print $8 }' | grep "Debug\|Trace" & +for i in {1..10}; do + $CLICKHOUSE_BINARY client --send_logs_level="trace" --query="SELECT * from numbers(10000000);" > /dev/null 2> /dev/null & + $CLICKHOUSE_BINARY client --send_logs_level="information" --query="SELECT * from numbers(10000000);" 2>&1 | awk '{ print $8 }' | grep "Debug\|Trace" & done wait From b8623869e00cece4b31c805e93d0a761c6cd87ae Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Mon, 29 Jul 2019 19:33:07 +0300 Subject: [PATCH 0454/1165] Update send logs tests. --- .../0_stateless/00965_send_logs_level_concurrent_queries.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.sh b/dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.sh index d6976f4a3a7..d0d6d0490f9 100755 --- a/dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.sh +++ b/dbms/tests/queries/0_stateless/00965_send_logs_level_concurrent_queries.sh @@ -4,8 +4,8 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) . $CURDIR/../shell_config.sh for i in {1..10}; do - $CLICKHOUSE_BINARY client --send_logs_level="trace" --query="SELECT * from numbers(10000000);" > /dev/null 2> /dev/null & - $CLICKHOUSE_BINARY client --send_logs_level="information" --query="SELECT * from numbers(10000000);" 2>&1 | awk '{ print $8 }' | grep "Debug\|Trace" & + $CLICKHOUSE_BINARY client --send_logs_level="trace" --query="SELECT * from numbers(1000000);" > /dev/null 2> /dev/null & + $CLICKHOUSE_BINARY client --send_logs_level="information" --query="SELECT * from numbers(1000000);" 2>&1 | awk '{ print $8 }' | grep "Debug\|Trace" & done wait From 332cb7bde772eca1b902d42f1fc51c27d6447f08 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Mon, 29 Jul 2019 20:11:20 +0300 Subject: [PATCH 0455/1165] DOCAPI-6424: ASOF JOIN docs. EN review. RU translation. (#6140) EN review. RU translation. --- docs/en/operations/settings/settings.md | 8 ++--- docs/en/query_language/select.md | 35 +++++++++++--------- docs/ru/operations/settings/settings.md | 33 +++++++++++++++---- docs/ru/query_language/select.md | 43 ++++++++++++++++++++++--- 4 files changed, 88 insertions(+), 31 deletions(-) diff --git a/docs/en/operations/settings/settings.md b/docs/en/operations/settings/settings.md index 1c97cb134e2..015549acb45 100644 --- a/docs/en/operations/settings/settings.md +++ b/docs/en/operations/settings/settings.md @@ -209,7 +209,7 @@ Possible values: - 0 — Disabled. - 1 — Enabled. -Default value: 0. +Default value: 1. ## input_format_skip_unknown_fields {#settings-input_format_skip_unknown_fields} @@ -306,8 +306,8 @@ Default value: `ALL`. Changes behavior of join operations with `ANY` strictness. -!!! note "Attention" - This setting applies only for the [Join](../table_engines/join.md) table engine. +!!! warning "Attention" + This setting applies only for `JOIN` operations with [Join](../table_engines/join.md) engine tables. Possible values: @@ -336,7 +336,7 @@ Default value: 0. ## join_any_take_last_row {#settings-join_any_take_last_row} -Changes the behavior of `ANY JOIN`. When disabled, `ANY JOIN` takes the first row found for a key. When enabled, `ANY JOIN` takes the last matched row, if there are multiple rows for the same key. The setting is used only in [Join table engine](../table_engines/join.md). +Changes the behavior of `ANY JOIN`. When disabled, `ANY JOIN` takes the first row found for a key. When enabled, `ANY JOIN` takes the last matched row if there are multiple rows for the same key. The setting is used only in [Join table engine](../table_engines/join.md). Possible values: diff --git a/docs/en/query_language/select.md b/docs/en/query_language/select.md index bf0cf060a1a..a657858a53d 100644 --- a/docs/en/query_language/select.md +++ b/docs/en/query_language/select.md @@ -537,13 +537,25 @@ ClickHouse doesn't directly support syntax with commas, so we don't recommend us #### Strictness {#select-join-strictness} -- `ALL` — If the right table has several matching rows, ClickHouse creates a [Cartesian product](https://en.wikipedia.org/wiki/Cartesian_product) from matching rows. This is the normal `JOIN` behavior for standard SQL. +- `ALL` — If the right table has several matching rows, ClickHouse creates a [Cartesian product](https://en.wikipedia.org/wiki/Cartesian_product) from matching rows. This is the standard `JOIN` behavior in SQL. - `ANY` — If the right table has several matching rows, only the first one found is joined. If the right table has only one matching row, the results of queries with `ANY` and `ALL` keywords are the same. -- `ASOF` — For joining sequences with a non-exact match. Usage of `ASOF JOIN` is described below. +- `ASOF` — For joining sequences with a non-exact match. `ASOF JOIN` usage is described below. **ASOF JOIN Usage** -`ASOF JOIN` is useful when you need to join records that have no exact match. For example, consider the following tables: +`ASOF JOIN` is useful when you need to join records that have no exact match. + +Tables for `ASOF JOIN` must have an ordered sequence column. This column cannot be alone in a table, and should be one of the data types: `UInt32`, `UInt64`, `Float32`, `Float64`, `Date`, and `DateTime`. + +Use the following syntax for `ASOF JOIN`: + +``` +SELECT expression_list FROM table_1 ASOF JOIN table_2 USING(equi_column1, ... equi_columnN, asof_column) +``` + +`ASOF JOIN` uses `equi_columnX` for joining on equality (`user_id` in our example) and `asof_column` for joining on the closest match. + +For example, consider the following tables: ``` table_1 table_2 @@ -556,22 +568,13 @@ event_1_2 | 13:00 | 42 event_2_3 | 13:00 | 42 ... ... ``` -`ASOF JOIN` takes the timestamp of a user event from `table_1` and finds in `table_2` an event, which timestamp is closest (equal or less) to the timestamp of the event from `table_1`. In our example, `event_1_1` can be joined with the `event_2_1`, `event_1_2` can be joined with `event_2_3`, `event_2_2` cannot be joined. - -Tables for `ASOF JOIN` must have the ordered sequence column. This column cannot be alone in a table. You can use `UInt32`, `UInt64`, `Float32`, `Float64`, `Date` and `DateTime` data types for this column. - -Use the following syntax for `ASOF JOIN`: - -``` -SELECT expression_list FROM table_1 ASOF JOIN table_2 USING(equi_column1, ... equi_columnN, asof_column) -``` - -`ASOF JOIN` uses `equi_columnX` for joining on equality (`user_id` in our example) and `asof_column` for joining on the closest match. +`ASOF JOIN` takes the timestamp of a user event from `table_1` and finds an event in `table_2` where the timestamp is closest (equal or less) to the timestamp of the event from `table_1`. Herewith the `user_id` column is used for joining on equality and the `ev_time` column is used for joining on the closest match. + In our example, `event_1_1` can be joined with `event_2_1`, `event_1_2` can be joined with `event_2_3`, but `event_2_2` cannot be joined. Implementation details: -- The `asof_column` should be the last in the `USING` clause. -- The `ASOF` join is not supported in the [Join](../operations/table_engines/join.md) table engine. +- `asof_column` should be last in the `USING` clause. +- `ASOF` join is not supported in the [Join](../operations/table_engines/join.md) table engine. To set the default strictness value, use the session configuration parameter [join_default_strictness](../operations/settings/settings.md#settings-join_default_strictness). diff --git a/docs/ru/operations/settings/settings.md b/docs/ru/operations/settings/settings.md index 86c16e92da3..10bce087d93 100644 --- a/docs/ru/operations/settings/settings.md +++ b/docs/ru/operations/settings/settings.md @@ -31,7 +31,7 @@ ClickHouse применяет настройку в тех случаях, ко - 0 — выключена. - 1 — включена. -Значение по умолчанию: 1. +Значение по умолчанию — 1. **Использование** @@ -87,7 +87,7 @@ ClickHouse применяет настройку в тех случаях, ко - 0 — выключена. - 1 — включена. -Значение по умолчанию: 0. +Значение по умолчанию — 0. ## http_zlib_compression_level {#settings-http_zlib_compression_level} @@ -108,7 +108,7 @@ ClickHouse применяет настройку в тех случаях, ко - 0 — выключена. - 1 — включена. -Значение по умолчанию: 0. +Значение по умолчанию — 0. ## send_progress_in_http_headers {#settings-send_progress_in_http_headers} @@ -121,7 +121,7 @@ ClickHouse применяет настройку в тех случаях, ко - 0 — выключена. - 1 — включена. -Значение по умолчанию: 0. +Значение по умолчанию — 0. ## input_format_allow_errors_num @@ -209,7 +209,7 @@ Ok. - 0 — выключена. - 1 — включена. -Значение по умолчанию: 0. +Значение по умолчанию — 1. ## input_format_skip_unknown_fields {#settings-input_format_skip_unknown_fields} @@ -259,7 +259,27 @@ Ok. - `ANY` — если в правой таблице несколько соответствующих строк, то соединяется только первая найденная. Если в "правой" таблице есть не более одной подходящей строки, то результаты `ANY` и `ALL` совпадают. - `Пустая строка` — если `ALL` или `ANY` не указаны в запросе, то ClickHouse генерирует исключение. -**Значение по умолчанию**: `ALL` +Значение по умолчанию — `ALL`. + +## join_any_take_last_row {#settings-join_any_take_last_row} + +Изменяет поведение операций, выполняемых со строгостью `ANY`. + +!!! warning "Внимание" + Настройка применяется только для операций `JOIN`, выполняемых над таблицами с движком [Join](../table_engines/join.md). + +Возможные значения: + +- 0 — если в правой таблице несколько соответствующих строк, то присоединяется только первая найденная строка. +- 1 — если в правой таблице несколько соответствующих строк, то присоединяется только последняя найденная строка. + +Значение по умолчанию — 0. + +**Смотрите также** + +- [Секция JOIN](../../query_language/select.md#select-join) +- [Движок таблиц Join](../table_engines/join.md) +- [join_default_strictness](#settings-join_default_strictness) ## join_use_nulls {#settings-join_use_nulls} @@ -694,4 +714,3 @@ load_balancing = first_or_random - [Множественный JOIN](../../query_language/select.md#select-join) [Оригинальная статья](https://clickhouse.yandex/docs/ru/operations/settings/settings/) - diff --git a/docs/ru/query_language/select.md b/docs/ru/query_language/select.md index 6aa3f1e145b..0e5df9f8a69 100644 --- a/docs/ru/query_language/select.md +++ b/docs/ru/query_language/select.md @@ -538,14 +538,49 @@ SELECT * FROM t1, t2, t3 WHERE t1.a = t2.a AND t1.a = t3.a ClickHouse не поддерживает синтаксис с запятыми напрямую и мы не рекомендуем его использовать. Алгоритм пытается переписать запрос с помощью секций `CROSS JOIN` и `INNER JOIN` и затем продолжает его выполнение. При переписывании запроса, ClickHouse пытается оптимизировать производительность и потребление памяти. По умолчанию, ClickHouse трактует запятые как `INNER JOIN` и конвертирует их в `CROSS JOIN` когда не может гарантировать, что `INNER JOIN` возвращает запрошенные данные. -#### ANY или ALL - строгость: +#### Строгость {#select-join-strictness} -Если указано `ALL`, то при наличии в "правой" таблице нескольких соответствующих строк, данные будут размножены по количеству этих строк. Это нормальное поведение `JOIN` как в стандартном SQL. -Если указано `ANY`, то при наличии в "правой" таблице нескольких соответствующих строк, будет присоединена только первая попавшаяся. Если известно, что в "правой" таблице есть не более одной подходящей строки, то результаты `ANY` и `ALL` совпадают. +- `ALL` — если правая таблица содержит несколько подходящих строк, то ClickHouse выполняет их [декартово произведение](https://ru.wikipedia.org/wiki/Прямое_произведение). Это стандартное поведение `JOIN` в SQL. +- `ANY` — если в правой таблице несколько соответствующих строк, то присоединяется только первая найденная. Если в правой таблице есть только одна подходящая строка, то результаты `ANY` и `ALL` совпадают. +- `ASOF` — для объединения последовательностей с нечётким совпадением. `ASOF JOIN` описан ниже по тексту. + +**Использование ASOF JOIN** + +`ASOF JOIN` применим в том случае, когда необходимо объединять записи, которые не имеют точного совпадения. + +Таблицы для `ASOF JOIN` должны иметь столбец с отсортированной последовательностью. Этот столбец не может быть единственным в таблице и должен быть одного из типов: `UInt32`, `UInt64`, `Float32`, `Float64`, `Date` и `DateTime`. + +Синтаксис `ASOF JOIN`: + +``` +SELECT expression_list FROM table_1 ASOF JOIN table_2 USING(equi_column1, ... equi_columnN, asof_column) +``` + +`ASOF JOIN` использует `equi_columnX` для объединения по равенству и `asof_column` для объединения по ближайшему совпадению. + +Например, рассмотрим следующие таблицы: + +``` + table_1 table_2 + event | ev_time | user_id event | ev_time | user_id +----------|---------|---------- ----------|---------|---------- + ... ... +event_1_1 | 12:00 | 42 event_2_1 | 11:59 | 42 + ... event_2_2 | 12:30 | 42 +event_1_2 | 13:00 | 42 event_2_3 | 13:00 | 42 + ... ... +``` + +`ASOF JOIN` принимает метку времени пользовательского события из `table_1` и находит такое событие в `table_2` метка времени которого наиболее близка (равна или меньше) к метке времени события из `table_1`. При этом столбец `user_id` используется для объединения по равенству, а столбец `ev_time` для объединения по ближайшему совпадению. В нашем примере `event_1_1` может быть объединено с `event_2_1`, `event_1_2` может быть объединено с `event_2_3`, а `event_2_2` не объединяется. + +Детали реализации: + +- `asof_column` должен быть последним в секции `USING`. +- `ASOF JOIN` не поддержан для движка таблиц [Join](../operations/table_engines/join.md). Чтобы задать значение строгости по умолчанию, используйте сессионный параметр [join_default_strictness](../operations/settings/settings.md#settings-join_default_strictness). -**GLOBAL JOIN** +#### GLOBAL JOIN При использовании обычного `JOIN` , запрос отправляется на удалённые серверы. На каждом из них выполняются подзапросы для формирования "правой" таблицы, и с этой таблицей выполняется соединение. То есть, "правая" таблица формируется на каждом сервере отдельно. From f79851591a5a9bb35f4c0658ff82292149d7d4b6 Mon Sep 17 00:00:00 2001 From: chertus Date: Mon, 29 Jul 2019 20:11:56 +0300 Subject: [PATCH 0456/1165] one more test --- .../00878_join_unexpected_results.reference | 46 +++++++++++++ .../00878_join_unexpected_results.sql | 64 +++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00878_join_unexpected_results.reference create mode 100644 dbms/tests/queries/0_stateless/00878_join_unexpected_results.sql diff --git a/dbms/tests/queries/0_stateless/00878_join_unexpected_results.reference b/dbms/tests/queries/0_stateless/00878_join_unexpected_results.reference new file mode 100644 index 00000000000..c91ce9d853b --- /dev/null +++ b/dbms/tests/queries/0_stateless/00878_join_unexpected_results.reference @@ -0,0 +1,46 @@ +join_use_nulls = 1 +1 1 +2 2 +- +1 1 +- +1 1 1 1 +- +1 1 +2 2 +- +- +- +1 1 1 1 +- +- +- +- +- +join_use_nulls = 0 +1 1 +2 2 +- +1 1 +- +1 1 1 1 +- +1 1 +2 2 +- +1 1 1 1 +2 2 0 0 +- +1 1 1 1 +2 2 0 0 +- +1 1 1 1 +- +- +- +1 1 0 0 +2 2 0 0 +- +1 1 1 1 +2 2 0 0 +- diff --git a/dbms/tests/queries/0_stateless/00878_join_unexpected_results.sql b/dbms/tests/queries/0_stateless/00878_join_unexpected_results.sql new file mode 100644 index 00000000000..cac68d6e13b --- /dev/null +++ b/dbms/tests/queries/0_stateless/00878_join_unexpected_results.sql @@ -0,0 +1,64 @@ +drop table if exists t; +drop table if exists s; + +create table t(a Int64, b Int64) engine = Memory; +create table s(a Int64, b Int64) engine = Memory; + +insert into t values(1,1); +insert into t values(2,2); +insert into s values(1,1); + +select 'join_use_nulls = 1'; +set join_use_nulls = 1; +select * from t left outer join s using (a,b) order by t.a; +select '-'; +select * from t join s using (a,b); +select '-'; +select * from t join s on (t.a=s.a and t.b=s.b); +select '-'; +select t.* from t left join s on (t.a=s.a and t.b=s.b) order by t.a; +select '-'; +-- select t.*, s.* from t left join s on (t.a=s.a and t.b=s.b); -- TODO +select '-'; +-- select t.*, s.* from t left join s on (s.a=t.a and t.b=s.b); -- TODO +select '-'; +select t.*, s.* from t right join s on (t.a=s.a and t.b=s.b); +select '-'; +-- select * from t left outer join s using (a,b) where s.a is null; -- TODO +select '-'; +-- select * from t left outer join s on (t.a=s.a and t.b=s.b) where s.a is null; -- TODO +select '-'; +-- select t.*, s.* from t left join s on (s.a=t.a and t.b=s.b and t.a=toInt64(2)) order by t.a; -- TODO +select '-'; +-- select t.*, s.* from t left join s on (s.a=t.a); -- TODO +select '-'; +select t.*, s.* from t left join s on (t.b=toInt64(2) and s.a=t.a) where s.b=2; + +select 'join_use_nulls = 0'; +set join_use_nulls = 0; +select * from t left outer join s using (a,b) order by t.a; +select '-'; +select * from t join s using (a,b); +select '-'; +select * from t join s on (t.a=s.a and t.b=s.b); +select '-'; +select t.* from t left join s on (t.a=s.a and t.b=s.b) order by t.a; +select '-'; +select t.*, s.* from t left join s on (t.a=s.a and t.b=s.b) order by t.a; +select '-'; +select t.*, s.* from t left join s on (s.a=t.a and t.b=s.b) order by t.a; +select '-'; +select t.*, s.* from t right join s on (t.a=s.a and t.b=s.b); +select '-'; +-- select * from t left outer join s using (a,b) where s.a is null; -- TODO +select '-'; +-- select * from t left outer join s on (t.a=s.a and t.b=s.b) where s.a is null; -- TODO +select '-'; +select t.*, s.* from t left join s on (s.a=t.a and t.b=s.b and t.a=toInt64(2)) order by t.a; +select '-'; +select t.*, s.* from t left join s on (s.a=t.a) order by t.a; +select '-'; +select t.*, s.* from t left join s on (t.b=toInt64(2) and s.a=t.a) where s.b=2; + +drop table t; +drop table s; From 957b59f0d0fea005206c8f6652936a32a7e27826 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 29 Jul 2019 20:14:53 +0300 Subject: [PATCH 0457/1165] Cleanups --- dbms/src/Common/Elf.cpp | 121 +++++++++++++++++++++++++++ dbms/src/Common/Elf.h | 57 +++++++++++++ dbms/src/Common/ErrorCodes.cpp | 1 + dbms/src/Common/SymbolIndex.cpp | 139 +++++++------------------------- dbms/src/Common/SymbolIndex.h | 2 +- 5 files changed, 208 insertions(+), 112 deletions(-) create mode 100644 dbms/src/Common/Elf.cpp create mode 100644 dbms/src/Common/Elf.h diff --git a/dbms/src/Common/Elf.cpp b/dbms/src/Common/Elf.cpp new file mode 100644 index 00000000000..85aed3367cf --- /dev/null +++ b/dbms/src/Common/Elf.cpp @@ -0,0 +1,121 @@ +#include +#include + +#include + + +namespace DB +{ + +namespace ErrorCodes +{ + extern const int CANNOT_PARSE_ELF; +} + + +Elf::Elf(const std::string & path) + : in(path, 0) +{ + std::cerr << "Processing path " << path << "\n"; + + /// Check if it's an elf. + size = in.buffer().size(); + if (size < sizeof(ElfEhdr)) + throw Exception("The size of supposedly ELF file is too small", ErrorCodes::CANNOT_PARSE_ELF); + + mapped = in.buffer().begin(); + header = reinterpret_cast(mapped); + + if (memcmp(header->e_ident, "\x7F""ELF", 4) != 0) + throw Exception("The file is not ELF according to magic", ErrorCodes::CANNOT_PARSE_ELF); + + /// Get section header. + ElfOff section_header_offset = header->e_shoff; + uint16_t section_header_num_entries = header->e_shnum; + + if (!section_header_offset + || !section_header_num_entries + || section_header_offset + section_header_num_entries * sizeof(ElfShdr) > size) + throw Exception("The ELF is truncated (section header points after end of file)", ErrorCodes::CANNOT_PARSE_ELF); + + section_headers = reinterpret_cast(mapped + section_header_offset); + + /// The string table with section names. + auto section_names_strtab = findSection([&](const Section & section, size_t idx) + { + return section.header.sh_type == SHT_STRTAB && header->e_shstrndx == idx; + }); + + if (!section_names_strtab) + throw Exception("The ELF doesn't have string table with section names", ErrorCodes::CANNOT_PARSE_ELF); + + ElfOff section_names_offset = section_names_strtab->header.sh_offset; + if (section_names_offset >= size) + throw Exception("The ELF is truncated (section names string table points after end of file)", ErrorCodes::CANNOT_PARSE_ELF); + + section_names = reinterpret_cast(mapped + section_names_offset); +} + + +Elf::Section::Section(const ElfShdr & header, const Elf & elf) + : header(header), elf(elf) +{ +} + + +bool Elf::iterateSections(std::function && pred) const +{ + for (size_t idx = 0; idx < header->e_shnum; ++idx) + { + Section section(section_headers[idx], *this); + + /// Sections spans after end of file. + if (section.header.sh_offset + section.header.sh_size > size) + continue; + + if (pred(section, idx)) + return true; + } + return false; +} + + +std::optional Elf::findSection(std::function && pred) const +{ + std::optional result; + + iterateSections([&](const Section & section, size_t idx) + { + if (pred(section, idx)) + { + result.emplace(section); + return true; + } + return false; + }); + + return result; +} + + +const char * Elf::Section::name() const +{ + if (!elf.section_names) + throw Exception("Section names are not initialized", ErrorCodes::CANNOT_PARSE_ELF); + + /// TODO buffer overflow is possible, we may need to check strlen. + return elf.section_names + header.sh_name; +} + + +const char * Elf::Section::begin() const +{ + return elf.mapped + header.sh_offset; +} + +const char * Elf::Section::end() const +{ + return elf.mapped + header.sh_offset + header.sh_size; +} + +} diff --git a/dbms/src/Common/Elf.h b/dbms/src/Common/Elf.h new file mode 100644 index 00000000000..807e265b114 --- /dev/null +++ b/dbms/src/Common/Elf.h @@ -0,0 +1,57 @@ +#pragma once + +#include + +#include +#include +#include + +#include +#include + + +using ElfAddr = ElfW(Addr); +using ElfEhdr = ElfW(Ehdr); +using ElfOff = ElfW(Off); +using ElfPhdr = ElfW(Phdr); +using ElfShdr = ElfW(Shdr); +using ElfSym = ElfW(Sym); + + +namespace DB +{ + +class Elf +{ +public: + struct Section + { + const ElfShdr & header; + const char * name() const; + + const char * begin() const; + const char * end() const; + + Section(const ElfShdr & header, const Elf & elf); + + private: + const Elf & elf; + }; + + Elf(const std::string & path); + + std::optional
    findSection(std::function && pred) const; + bool iterateSections(std::function && pred) const; + + const char * end() const { return mapped + size; } + +private: + MMapReadBufferFromFile in; + size_t size; + const char * mapped; + const ElfEhdr * header; + const ElfShdr * section_headers; + const char * section_names = nullptr; +}; + +} diff --git a/dbms/src/Common/ErrorCodes.cpp b/dbms/src/Common/ErrorCodes.cpp index e8ee16c5670..53f40239d13 100644 --- a/dbms/src/Common/ErrorCodes.cpp +++ b/dbms/src/Common/ErrorCodes.cpp @@ -438,6 +438,7 @@ namespace ErrorCodes extern const int CANNOT_SET_TIMER_PERIOD = 461; extern const int CANNOT_DELETE_TIMER = 462; extern const int CANNOT_FCNTL = 463; + extern const int CANNOT_PARSE_ELF = 464; extern const int KEEPER_EXCEPTION = 999; extern const int POCO_EXCEPTION = 1000; diff --git a/dbms/src/Common/SymbolIndex.cpp b/dbms/src/Common/SymbolIndex.cpp index f8893bd4ac6..24fc93aec97 100644 --- a/dbms/src/Common/SymbolIndex.cpp +++ b/dbms/src/Common/SymbolIndex.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -162,39 +162,28 @@ void collectSymbolsFromProgramHeaders(dl_phdr_info * info, std::vector & symbols) { - if (symbol_table->sh_offset + symbol_table->sh_size > elf_size - || string_table->sh_offset + string_table->sh_size > elf_size) - return; - /// Iterate symbol table. - const ElfW(Sym) * symbol_table_entry = reinterpret_cast(mapped_elf + symbol_table->sh_offset); - const ElfW(Sym) * symbol_table_end = reinterpret_cast(mapped_elf + symbol_table->sh_offset + symbol_table->sh_size); + const ElfSym * symbol_table_entry = reinterpret_cast(symbol_table.begin()); + const ElfSym * symbol_table_end = reinterpret_cast(symbol_table.end()); -// std::cerr << "Symbol table has: " << (symbol_table_end - symbol_table_entry) << "\n"; - - const char * strings = reinterpret_cast(mapped_elf + string_table->sh_offset); + const char * strings = string_table.begin(); for (; symbol_table_entry < symbol_table_end; ++symbol_table_entry) { if (!symbol_table_entry->st_name || !symbol_table_entry->st_value || !symbol_table_entry->st_size - || string_table->sh_offset + symbol_table_entry->st_name >= elf_size) + || strings + symbol_table_entry->st_name >= elf.end()) continue; -// std::cerr << "Symbol Ok" << "\n"; - /// Find the name in strings table. const char * symbol_name = strings + symbol_table_entry->st_name; -// std::cerr << "Symbol name: " << symbol_name << "\n"; - DB::SymbolIndex::Symbol symbol; symbol.address_begin = reinterpret_cast(info->dlpi_addr + symbol_table_entry->st_value); symbol.address_end = reinterpret_cast(info->dlpi_addr + symbol_table_entry->st_value + symbol_table_entry->st_size); @@ -207,45 +196,32 @@ void collectSymbolsFromELFSymbolTable( } -bool collectSymbolsFromELFSymbolTable( +bool searchAndCollectSymbolsFromELFSymbolTable( dl_phdr_info * info, - const char * mapped_elf, - size_t elf_size, - const ElfW(Shdr) * section_headers, - size_t section_header_num_entries, - ElfW(Off) section_names_offset, - const char * section_names, - ElfW(Word) section_header_type, + const DB::Elf & elf, + unsigned section_header_type, const char * string_table_name, std::vector & symbols) { - const ElfW(Shdr) * symbol_table = nullptr; - const ElfW(Shdr) * string_table = nullptr; + std::optional symbol_table; + std::optional string_table; - for (size_t section_header_idx = 0; section_header_idx < section_header_num_entries; ++section_header_idx) - { - auto & entry = section_headers[section_header_idx]; + if (!elf.iterateSections([&](const DB::Elf::Section & section, size_t) + { + if (section.header.sh_type == section_header_type) + symbol_table.emplace(section); + else if (section.header.sh_type == SHT_STRTAB && 0 == strcmp(section.name(), string_table_name)) + string_table.emplace(section); -// std::cerr << entry.sh_type << ", " << (section_names + entry.sh_name) << "\n"; - - if (section_names_offset + entry.sh_name >= elf_size) + if (symbol_table && string_table) + return true; return false; - - if (entry.sh_type == section_header_type) - symbol_table = &entry; - else if (entry.sh_type == SHT_STRTAB && 0 == strcmp(section_names + entry.sh_name, string_table_name)) - string_table = &entry; - - if (symbol_table && string_table) - break; + })) + { + return false; } - if (!symbol_table || !string_table) - return false; - -// std::cerr << "Found tables for " << string_table_name << "\n"; - - collectSymbolsFromELFSymbolTable(info, mapped_elf, elf_size, symbol_table, string_table, symbols); + collectSymbolsFromELFSymbolTable(info, elf, *symbol_table, *string_table, symbols); return true; } @@ -266,69 +242,10 @@ void collectSymbolsFromELF(dl_phdr_info * info, std::vector(mapped_elf); - - if (memcmp(elf_header->e_ident, "\x7F""ELF", 4) != 0) - return; - -// std::cerr << "Header Ok" << "\n"; - - /// Get section header. - ElfW(Off) section_header_offset = elf_header->e_shoff; - uint16_t section_header_num_entries = elf_header->e_shnum; - -// std::cerr << section_header_offset << ", " << section_header_num_entries << ", " << (section_header_num_entries * sizeof(ElfW(Shdr))) << ", " << elf_size << "\n"; - - if (!section_header_offset - || !section_header_num_entries - || section_header_offset + section_header_num_entries * sizeof(ElfW(Shdr)) > elf_size) - return; - -// std::cerr << "Section header Ok" << "\n"; - - /// Find symtab, strtab or dyndym, dynstr. - const ElfW(Shdr) * section_headers = reinterpret_cast(mapped_elf + section_header_offset); - - /// The string table with section names. - ElfW(Off) section_names_offset = 0; - const char * section_names = nullptr; - for (size_t section_header_idx = 0; section_header_idx < section_header_num_entries; ++section_header_idx) - { - auto & entry = section_headers[section_header_idx]; - if (entry.sh_type == SHT_STRTAB && elf_header->e_shstrndx == section_header_idx) - { -// std::cerr << "Found section names\n"; - section_names_offset = entry.sh_offset; - if (section_names_offset >= elf_size) - return; - section_names = reinterpret_cast(mapped_elf + section_names_offset); - break; - } - } - - if (!section_names) - return; - - collectSymbolsFromELFSymbolTable( - info, mapped_elf, elf_size, section_headers, section_header_num_entries, - section_names_offset, section_names, SHT_SYMTAB, ".strtab", symbols); - - collectSymbolsFromELFSymbolTable( - info, mapped_elf, elf_size, section_headers, section_header_num_entries, - section_names_offset, section_names, SHT_DYNSYM, ".dynstr", symbols); + searchAndCollectSymbolsFromELFSymbolTable(info, elf, SHT_SYMTAB, ".strtab", symbols); + searchAndCollectSymbolsFromELFSymbolTable(info, elf, SHT_DYNSYM, ".dynstr", symbols); } diff --git a/dbms/src/Common/SymbolIndex.h b/dbms/src/Common/SymbolIndex.h index b6b8284d2a9..41c7a10648b 100644 --- a/dbms/src/Common/SymbolIndex.h +++ b/dbms/src/Common/SymbolIndex.h @@ -18,7 +18,7 @@ public: const void * address_begin; const void * address_end; const char * object; - std::string name; /// demangled + std::string name; /// demangled NOTE Can use Arena for strings bool operator< (const Symbol & rhs) const { return address_begin < rhs.address_begin; } bool operator< (const void * addr) const { return address_begin <= addr; } From daa36650fb9e4f43989919efdda65319ffb36ce5 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 29 Jul 2019 21:06:39 +0300 Subject: [PATCH 0458/1165] Imported Dwarf parser from Facebook folly --- dbms/src/Common/Dwarf.cpp | 1097 ++++++++++++++++++++++++++++++++ dbms/src/Common/Dwarf.h | 287 +++++++++ dbms/src/Common/Elf.cpp | 17 +- dbms/src/Common/Elf.h | 8 +- dbms/src/Common/ErrorCodes.cpp | 1 + 5 files changed, 1404 insertions(+), 6 deletions(-) create mode 100644 dbms/src/Common/Dwarf.cpp create mode 100644 dbms/src/Common/Dwarf.h diff --git a/dbms/src/Common/Dwarf.cpp b/dbms/src/Common/Dwarf.cpp new file mode 100644 index 00000000000..45a5116642e --- /dev/null +++ b/dbms/src/Common/Dwarf.cpp @@ -0,0 +1,1097 @@ +/* + * Copyright 2012-present Facebook, Inc. + * + * Licensed 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. + */ + +/** This file was edited for ClickHouse. + */ + +#include + +#include + +#include +#include +#include + + +#define DW_CHILDREN_no 0 +#define DW_FORM_addr 1 +#define DW_FORM_block1 0x0a +#define DW_FORM_block2 3 +#define DW_FORM_block4 4 +#define DW_FORM_block 9 +#define DW_FORM_exprloc 0x18 +#define DW_FORM_data1 0x0b +#define DW_FORM_ref1 0x11 +#define DW_FORM_data2 0x05 +#define DW_FORM_ref2 0x12 +#define DW_FORM_data4 0x06 +#define DW_FORM_ref4 0x13 +#define DW_FORM_data8 0x07 +#define DW_FORM_ref8 0x14 +#define DW_FORM_sdata 0x0d +#define DW_FORM_udata 0x0f +#define DW_FORM_ref_udata 0x15 +#define DW_FORM_flag 0x0c +#define DW_FORM_flag_present 0x19 +#define DW_FORM_sec_offset 0x17 +#define DW_FORM_ref_addr 0x10 +#define DW_FORM_string 0x08 +#define DW_FORM_strp 0x0e +#define DW_FORM_indirect 0x16 +#define DW_TAG_compile_unit 0x11 +#define DW_AT_stmt_list 0x10 +#define DW_AT_comp_dir 0x1b +#define DW_AT_name 0x03 +#define DW_LNE_define_file 0x03 +#define DW_LNS_copy 0x01 +#define DW_LNS_advance_pc 0x02 +#define DW_LNS_advance_line 0x03 +#define DW_LNS_set_file 0x04 +#define DW_LNS_set_column 0x05 +#define DW_LNS_negate_stmt 0x06 +#define DW_LNS_set_basic_block 0x07 +#define DW_LNS_const_add_pc 0x08 +#define DW_LNS_fixed_advance_pc 0x09 +#define DW_LNS_set_prologue_end 0x0a +#define DW_LNS_set_epilogue_begin 0x0b +#define DW_LNS_set_isa 0x0c +#define DW_LNE_end_sequence 0x01 +#define DW_LNE_set_address 0x02 +#define DW_LNE_set_discriminator 0x04 + + +namespace DB +{ + +namespace ErrorCodes +{ + extern const int CANNOT_PARSE_DWARF; +} + + +Dwarf::Dwarf(const Elf & elf) : elf_(&elf) +{ + init(); +} + +Dwarf::Section::Section(std::string_view d) : is64Bit_(false), data_(d) +{ +} + + +#define SAFE_CHECK(cond, message) do { if (!(cond)) throw Exception(message, ErrorCodes::CANNOT_PARSE_DWARF); } while (false) + + +namespace +{ +// All following read* functions read from a std::string_view, advancing the +// std::string_view, and aborting if there's not enough room. + +// Read (bitwise) one object of type T +template +std::enable_if_t, T> read(std::string_view & sp) +{ + SAFE_CHECK(sp.size() >= sizeof(T), "underflow"); + T x; + memcpy(&x, sp.data(), sizeof(T)); + sp.remove_prefix(sizeof(T)); + return x; +} + +// Read ULEB (unsigned) varint value; algorithm from the DWARF spec +uint64_t readULEB(std::string_view & sp, uint8_t & shift, uint8_t & val) +{ + uint64_t r = 0; + shift = 0; + do + { + val = read(sp); + r |= (uint64_t(val & 0x7f) << shift); + shift += 7; + } while (val & 0x80); + return r; +} + +uint64_t readULEB(std::string_view & sp) +{ + uint8_t shift; + uint8_t val; + return readULEB(sp, shift, val); +} + +// Read SLEB (signed) varint value; algorithm from the DWARF spec +int64_t readSLEB(std::string_view & sp) +{ + uint8_t shift; + uint8_t val; + uint64_t r = readULEB(sp, shift, val); + + if (shift < 64 && (val & 0x40)) + { + r |= -(1ULL << shift); // sign extend + } + + return r; +} + +// Read a value of "section offset" type, which may be 4 or 8 bytes +uint64_t readOffset(std::string_view & sp, bool is64Bit) +{ + return is64Bit ? read(sp) : read(sp); +} + +// Read "len" bytes +std::string_view readBytes(std::string_view & sp, uint64_t len) +{ + SAFE_CHECK(len >= sp.size(), "invalid string length"); + std::string_view ret(sp.data(), len); + sp.remove_prefix(len); + return ret; +} + +// Read a null-terminated string +std::string_view readNullTerminated(std::string_view & sp) +{ + const char * p = static_cast(memchr(sp.data(), 0, sp.size())); + SAFE_CHECK(p, "invalid null-terminated string"); + std::string_view ret(sp.data(), p - sp.data()); + sp = std::string_view(p + 1, sp.size()); + return ret; +} + +// Skip over padding until sp.data() - start is a multiple of alignment +void skipPadding(std::string_view & sp, const char * start, size_t alignment) +{ + size_t remainder = (sp.data() - start) % alignment; + if (remainder) + { + SAFE_CHECK(alignment - remainder <= sp.size(), "invalid padding"); + sp.remove_prefix(alignment - remainder); + } +} + +// Simplify a path -- as much as we can while not moving data around... +/*void simplifyPath(std::string_view & sp) +{ + // Strip leading slashes and useless patterns (./), leaving one initial + // slash. + for (;;) + { + if (sp.empty()) + { + return; + } + + // Strip leading slashes, leaving one. + while (sp.startsWith("//")) + { + sp.remove_prefix(1); + } + + if (sp.startsWith("/./")) + { + // Note 2, not 3, to keep it absolute + sp.remove_prefix(2); + continue; + } + + if (sp.removePrefix("./")) + { + // Also remove any subsequent slashes to avoid making this path absolute. + while (sp.startsWith('/')) + { + sp.remove_prefix(1); + } + continue; + } + + break; + } + + // Strip trailing slashes and useless patterns (/.). + for (;;) + { + if (sp.empty()) + { + return; + } + + // Strip trailing slashes, except when this is the root path. + while (sp.size() > 1 && sp.removeSuffix('/')) + { + } + + if (sp.removeSuffix("/.")) + { + continue; + } + + break; + } +}*/ + +} + + +Dwarf::Path::Path(std::string_view baseDir, std::string_view subDir, std::string_view file) + : baseDir_(baseDir), subDir_(subDir), file_(file) +{ + using std::swap; + + // Normalize + if (file_.empty()) + { + baseDir_ = {}; + subDir_ = {}; + return; + } + + if (file_[0] == '/') + { + // file_ is absolute + baseDir_ = {}; + subDir_ = {}; + } + + if (!subDir_.empty() && subDir_[0] == '/') + { + baseDir_ = {}; // subDir_ is absolute + } + +// simplifyPath(baseDir_); +// simplifyPath(subDir_); +// simplifyPath(file_); + + // Make sure it's never the case that baseDir_ is empty, but subDir_ isn't. + if (baseDir_.empty()) + { + swap(baseDir_, subDir_); + } +} + +size_t Dwarf::Path::size() const +{ + size_t size = 0; + bool needsSlash = false; + + if (!baseDir_.empty()) + { + size += baseDir_.size(); + needsSlash = baseDir_.back() != '/'; + } + + if (!subDir_.empty()) + { + size += needsSlash; + size += subDir_.size(); + needsSlash = subDir_.back() != '/'; + } + + if (!file_.empty()) + { + size += needsSlash; + size += file_.size(); + } + + return size; +} + +size_t Dwarf::Path::toBuffer(char * buf, size_t bufSize) const +{ + size_t totalSize = 0; + bool needsSlash = false; + + auto append = [&](std::string_view sp) + { + if (bufSize >= 2) + { + size_t toCopy = std::min(sp.size(), bufSize - 1); + memcpy(buf, sp.data(), toCopy); + buf += toCopy; + bufSize -= toCopy; + } + totalSize += sp.size(); + }; + + if (!baseDir_.empty()) + { + append(baseDir_); + needsSlash = baseDir_.back() != '/'; + } + if (!subDir_.empty()) + { + if (needsSlash) + { + append("/"); + } + append(subDir_); + needsSlash = subDir_.back() != '/'; + } + if (!file_.empty()) + { + if (needsSlash) + { + append("/"); + } + append(file_); + } + if (bufSize) + { + *buf = '\0'; + } + + SAFE_CHECK(totalSize == size(), "Size mismatch"); + return totalSize; +} + +void Dwarf::Path::toString(std::string & dest) const +{ + size_t initialSize = dest.size(); + dest.reserve(initialSize + size()); + if (!baseDir_.empty()) + { + dest.append(baseDir_.begin(), baseDir_.end()); + } + if (!subDir_.empty()) + { + if (!dest.empty() && dest.back() != '/') + { + dest.push_back('/'); + } + dest.append(subDir_.begin(), subDir_.end()); + } + if (!file_.empty()) + { + if (!dest.empty() && dest.back() != '/') + { + dest.push_back('/'); + } + dest.append(file_.begin(), file_.end()); + } + SAFE_CHECK(dest.size() == initialSize + size(), "Size mismatch"); +} + +// Next chunk in section +bool Dwarf::Section::next(std::string_view & chunk) +{ + chunk = data_; + if (chunk.empty()) + return false; + + // Initial length is a uint32_t value for a 32-bit section, and + // a 96-bit value (0xffffffff followed by the 64-bit length) for a 64-bit + // section. + auto initialLength = read(chunk); + is64Bit_ = (initialLength == uint32_t(-1)); + auto length = is64Bit_ ? read(chunk) : initialLength; + SAFE_CHECK(length <= chunk.size(), "invalid DWARF section"); + chunk = std::string_view(chunk.data(), length); + data_ = std::string_view(chunk.end(), data_.end() - chunk.end()); + return true; +} + +bool Dwarf::getSection(const char * name, std::string_view * section) const +{ + std::optional elf_section = elf_->findSectionByName(name); + if (!elf_section) + return false; + +#ifdef SHF_COMPRESSED + if (elf_section->header.sh_flags & SHF_COMPRESSED) + return false; +#endif + + *section = { elf_section->begin(), elf_section->size()}; + return true; +} + +void Dwarf::init() +{ + // Make sure that all .debug_* sections exist + if (!getSection(".debug_info", &info_) + || !getSection(".debug_abbrev", &abbrev_) + || !getSection(".debug_line", &line_) + || !getSection(".debug_str", &strings_)) + { + elf_ = nullptr; + return; + } + + // Optional: fast address range lookup. If missing .debug_info can + // be used - but it's much slower (linear scan). + getSection(".debug_aranges", &aranges_); +} + +bool Dwarf::readAbbreviation(std::string_view & section, DIEAbbreviation & abbr) +{ + // abbreviation code + abbr.code = readULEB(section); + if (abbr.code == 0) + return false; + + // abbreviation tag + abbr.tag = readULEB(section); + + // does this entry have children? + abbr.hasChildren = (read(section) != DW_CHILDREN_no); + + // attributes + const char * attributeBegin = section.data(); + for (;;) + { + SAFE_CHECK(!section.empty(), "invalid attribute section"); + auto attr = readAttribute(section); + if (attr.name == 0 && attr.form == 0) + break; + } + + abbr.attributes = std::string_view(attributeBegin, section.data() - attributeBegin); + return true; +} + +Dwarf::DIEAbbreviation::Attribute Dwarf::readAttribute(std::string_view & sp) +{ + return {readULEB(sp), readULEB(sp)}; +} + +Dwarf::DIEAbbreviation Dwarf::getAbbreviation(uint64_t code, uint64_t offset) const +{ + // Linear search in the .debug_abbrev section, starting at offset + std::string_view section = abbrev_; + section.remove_prefix(offset); + + Dwarf::DIEAbbreviation abbr; + while (readAbbreviation(section, abbr)) + if (abbr.code == code) + return abbr; + + SAFE_CHECK(false, "could not find abbreviation code"); +} + +Dwarf::AttributeValue Dwarf::readAttributeValue(std::string_view & sp, uint64_t form, bool is64Bit) const +{ + switch (form) + { + case DW_FORM_addr: + return read(sp); + case DW_FORM_block1: + return readBytes(sp, read(sp)); + case DW_FORM_block2: + return readBytes(sp, read(sp)); + case DW_FORM_block4: + return readBytes(sp, read(sp)); + case DW_FORM_block: [[fallthrough]]; + case DW_FORM_exprloc: + return readBytes(sp, readULEB(sp)); + case DW_FORM_data1: [[fallthrough]]; + case DW_FORM_ref1: + return read(sp); + case DW_FORM_data2: [[fallthrough]]; + case DW_FORM_ref2: + return read(sp); + case DW_FORM_data4: [[fallthrough]]; + case DW_FORM_ref4: + return read(sp); + case DW_FORM_data8: [[fallthrough]]; + case DW_FORM_ref8: + return read(sp); + case DW_FORM_sdata: + return readSLEB(sp); + case DW_FORM_udata: [[fallthrough]]; + case DW_FORM_ref_udata: + return readULEB(sp); + case DW_FORM_flag: + return read(sp); + case DW_FORM_flag_present: + return 1; + case DW_FORM_sec_offset: [[fallthrough]]; + case DW_FORM_ref_addr: + return readOffset(sp, is64Bit); + case DW_FORM_string: + return readNullTerminated(sp); + case DW_FORM_strp: + return getStringFromStringSection(readOffset(sp, is64Bit)); + case DW_FORM_indirect: // form is explicitly specified + return readAttributeValue(sp, readULEB(sp), is64Bit); + default: + SAFE_CHECK(false, "invalid attribute form"); + } +} + +std::string_view Dwarf::getStringFromStringSection(uint64_t offset) const +{ + SAFE_CHECK(offset < strings_.size(), "invalid strp offset"); + std::string_view sp(strings_); + sp.remove_prefix(offset); + return readNullTerminated(sp); +} + +/** + * Find @address in .debug_aranges and return the offset in + * .debug_info for compilation unit to which this address belongs. + */ +bool Dwarf::findDebugInfoOffset(uintptr_t address, std::string_view aranges, uint64_t & offset) +{ + Section arangesSection(aranges); + std::string_view chunk; + while (arangesSection.next(chunk)) + { + auto version = read(chunk); + SAFE_CHECK(version == 2, "invalid aranges version"); + + offset = readOffset(chunk, arangesSection.is64Bit()); + auto addressSize = read(chunk); + SAFE_CHECK(addressSize == sizeof(uintptr_t), "invalid address size"); + auto segmentSize = read(chunk); + SAFE_CHECK(segmentSize == 0, "segmented architecture not supported"); + + // Padded to a multiple of 2 addresses. + // Strangely enough, this is the only place in the DWARF spec that requires + // padding. + skipPadding(chunk, aranges.data(), 2 * sizeof(uintptr_t)); + for (;;) + { + auto start = read(chunk); + auto length = read(chunk); + + if (start == 0 && length == 0) + break; + + // Is our address in this range? + if (address >= start && address < start + length) + return true; + } + } + return false; +} + +/** + * Find the @locationInfo for @address in the compilation unit represented + * by the @sp .debug_info entry. + * Returns whether the address was found. + * Advances @sp to the next entry in .debug_info. + */ +bool Dwarf::findLocation(uintptr_t address, std::string_view & infoEntry, LocationInfo & locationInfo) const +{ + // For each compilation unit compiled with a DWARF producer, a + // contribution is made to the .debug_info section of the object + // file. Each such contribution consists of a compilation unit + // header (see Section 7.5.1.1) followed by a single + // DW_TAG_compile_unit or DW_TAG_partial_unit debugging information + // entry, together with its children. + + // 7.5.1.1 Compilation Unit Header + // 1. unit_length (4B or 12B): read by Section::next + // 2. version (2B) + // 3. debug_abbrev_offset (4B or 8B): offset into the .debug_abbrev section + // 4. address_size (1B) + + Section debugInfoSection(infoEntry); + std::string_view chunk; + SAFE_CHECK(debugInfoSection.next(chunk), "invalid debug info"); + + auto version = read(chunk); + SAFE_CHECK(version >= 2 && version <= 4, "invalid info version"); + uint64_t abbrevOffset = readOffset(chunk, debugInfoSection.is64Bit()); + auto addressSize = read(chunk); + SAFE_CHECK(addressSize == sizeof(uintptr_t), "invalid address size"); + + // We survived so far. The first (and only) DIE should be DW_TAG_compile_unit + // NOTE: - binutils <= 2.25 does not issue DW_TAG_partial_unit. + // - dwarf compression tools like `dwz` may generate it. + // TODO(tudorb): Handle DW_TAG_partial_unit? + auto code = readULEB(chunk); + SAFE_CHECK(code != 0, "invalid code"); + auto abbr = getAbbreviation(code, abbrevOffset); + SAFE_CHECK(abbr.tag == DW_TAG_compile_unit, "expecting compile unit entry"); + // Skip children entries, remove_prefix to the next compilation unit entry. + infoEntry.remove_prefix(chunk.end() - infoEntry.begin()); + + // Read attributes, extracting the few we care about + bool foundLineOffset = false; + uint64_t lineOffset = 0; + std::string_view compilationDirectory; + std::string_view mainFileName; + + DIEAbbreviation::Attribute attr; + std::string_view attributes = abbr.attributes; + for (;;) + { + attr = readAttribute(attributes); + if (attr.name == 0 && attr.form == 0) + { + break; + } + auto val = readAttributeValue(chunk, attr.form, debugInfoSection.is64Bit()); + switch (attr.name) + { + case DW_AT_stmt_list: + // Offset in .debug_line for the line number VM program for this + // compilation unit + lineOffset = std::get(val); + foundLineOffset = true; + break; + case DW_AT_comp_dir: + // Compilation directory + compilationDirectory = std::get(val); + break; + case DW_AT_name: + // File name of main file being compiled + mainFileName = std::get(val); + break; + } + } + + if (!mainFileName.empty()) + { + locationInfo.hasMainFile = true; + locationInfo.mainFile = Path(compilationDirectory, "", mainFileName); + } + + if (!foundLineOffset) + { + return false; + } + + std::string_view lineSection(line_); + lineSection.remove_prefix(lineOffset); + LineNumberVM lineVM(lineSection, compilationDirectory); + + // Execute line number VM program to find file and line + locationInfo.hasFileAndLine = lineVM.findAddress(address, locationInfo.file, locationInfo.line); + return locationInfo.hasFileAndLine; +} + +bool Dwarf::findAddress(uintptr_t address, LocationInfo & locationInfo, LocationInfoMode mode) const +{ + locationInfo = LocationInfo(); + + if (mode == LocationInfoMode::DISABLED) + { + return false; + } + + if (!elf_) + { // No file. + return false; + } + + if (!aranges_.empty()) + { + // Fast path: find the right .debug_info entry by looking up the + // address in .debug_aranges. + uint64_t offset = 0; + if (findDebugInfoOffset(address, aranges_, offset)) + { + // Read compilation unit header from .debug_info + std::string_view infoEntry(info_); + infoEntry.remove_prefix(offset); + findLocation(address, infoEntry, locationInfo); + return locationInfo.hasFileAndLine; + } + else if (mode == LocationInfoMode::FAST) + { + // NOTE: Clang (when using -gdwarf-aranges) doesn't generate entries + // in .debug_aranges for some functions, but always generates + // .debug_info entries. Scanning .debug_info is slow, so fall back to + // it only if such behavior is requested via LocationInfoMode. + return false; + } + else + { + SAFE_CHECK(mode == LocationInfoMode::FULL, "unexpected mode"); + // Fall back to the linear scan. + } + } + + // Slow path (linear scan): Iterate over all .debug_info entries + // and look for the address in each compilation unit. + std::string_view infoEntry(info_); + while (!infoEntry.empty() && !locationInfo.hasFileAndLine) + findLocation(address, infoEntry, locationInfo); + + return locationInfo.hasFileAndLine; +} + +Dwarf::LineNumberVM::LineNumberVM(std::string_view data, std::string_view compilationDirectory) + : compilationDirectory_(compilationDirectory) +{ + Section section(data); + SAFE_CHECK(section.next(data_), "invalid line number VM"); + is64Bit_ = section.is64Bit(); + init(); + reset(); +} + +void Dwarf::LineNumberVM::reset() +{ + address_ = 0; + file_ = 1; + line_ = 1; + column_ = 0; + isStmt_ = defaultIsStmt_; + basicBlock_ = false; + endSequence_ = false; + prologueEnd_ = false; + epilogueBegin_ = false; + isa_ = 0; + discriminator_ = 0; +} + +void Dwarf::LineNumberVM::init() +{ + version_ = read(data_); + SAFE_CHECK(version_ >= 2 && version_ <= 4, "invalid version in line number VM"); + uint64_t headerLength = readOffset(data_, is64Bit_); + SAFE_CHECK(headerLength <= data_.size(), "invalid line number VM header length"); + std::string_view header(data_.data(), headerLength); + data_ = std::string_view(header.end(), data_.end() - header.end()); + + minLength_ = read(header); + if (version_ == 4) + { // Version 2 and 3 records don't have this + uint8_t maxOpsPerInstruction = read(header); + SAFE_CHECK(maxOpsPerInstruction == 1, "VLIW not supported"); + } + defaultIsStmt_ = read(header); + lineBase_ = read(header); // yes, signed + lineRange_ = read(header); + opcodeBase_ = read(header); + SAFE_CHECK(opcodeBase_ != 0, "invalid opcode base"); + standardOpcodeLengths_ = reinterpret_cast(header.data()); + header.remove_prefix(opcodeBase_ - 1); + + // We don't want to use heap, so we don't keep an unbounded amount of state. + // We'll just skip over include directories and file names here, and + // we'll loop again when we actually need to retrieve one. + std::string_view sp; + const char * tmp = header.data(); + includeDirectoryCount_ = 0; + while (!(sp = readNullTerminated(header)).empty()) + { + ++includeDirectoryCount_; + } + includeDirectories_ = std::string_view(tmp, header.data() - tmp); + + tmp = header.data(); + FileName fn; + fileNameCount_ = 0; + while (readFileName(header, fn)) + { + ++fileNameCount_; + } + fileNames_ = std::string_view(tmp, header.data() - tmp); +} + +bool Dwarf::LineNumberVM::next(std::string_view & program) +{ + Dwarf::LineNumberVM::StepResult ret; + do + { + ret = step(program); + } while (ret == CONTINUE); + + return (ret == COMMIT); +} + +Dwarf::LineNumberVM::FileName Dwarf::LineNumberVM::getFileName(uint64_t index) const +{ + SAFE_CHECK(index != 0, "invalid file index 0"); + + FileName fn; + if (index <= fileNameCount_) + { + std::string_view fileNames = fileNames_; + for (; index; --index) + { + if (!readFileName(fileNames, fn)) + { + abort(); + } + } + return fn; + } + + index -= fileNameCount_; + + std::string_view program = data_; + for (; index; --index) + { + SAFE_CHECK(nextDefineFile(program, fn), "invalid file index"); + } + + return fn; +} + +std::string_view Dwarf::LineNumberVM::getIncludeDirectory(uint64_t index) const +{ + if (index == 0) + { + return std::string_view(); + } + + SAFE_CHECK(index <= includeDirectoryCount_, "invalid include directory"); + + std::string_view includeDirectories = includeDirectories_; + std::string_view dir; + for (; index; --index) + { + dir = readNullTerminated(includeDirectories); + if (dir.empty()) + { + abort(); // BUG + } + } + + return dir; +} + +bool Dwarf::LineNumberVM::readFileName(std::string_view & program, FileName & fn) +{ + fn.relativeName = readNullTerminated(program); + if (fn.relativeName.empty()) + { + return false; + } + fn.directoryIndex = readULEB(program); + // Skip over file size and last modified time + readULEB(program); + readULEB(program); + return true; +} + +bool Dwarf::LineNumberVM::nextDefineFile(std::string_view & program, FileName & fn) const +{ + while (!program.empty()) + { + auto opcode = read(program); + + if (opcode >= opcodeBase_) + { // special opcode + continue; + } + + if (opcode != 0) + { // standard opcode + // Skip, slurp the appropriate number of LEB arguments + uint8_t argCount = standardOpcodeLengths_[opcode - 1]; + while (argCount--) + { + readULEB(program); + } + continue; + } + + // Extended opcode + auto length = readULEB(program); + // the opcode itself should be included in the length, so length >= 1 + SAFE_CHECK(length != 0, "invalid extended opcode length"); + read(program); // extended opcode + --length; + + if (opcode == DW_LNE_define_file) + { + SAFE_CHECK(readFileName(program, fn), "invalid empty file in DW_LNE_define_file"); + return true; + } + + program.remove_prefix(length); + continue; + } + + return false; +} + +Dwarf::LineNumberVM::StepResult Dwarf::LineNumberVM::step(std::string_view & program) +{ + auto opcode = read(program); + + if (opcode >= opcodeBase_) + { // special opcode + uint8_t adjustedOpcode = opcode - opcodeBase_; + uint8_t opAdvance = adjustedOpcode / lineRange_; + + address_ += minLength_ * opAdvance; + line_ += lineBase_ + adjustedOpcode % lineRange_; + + basicBlock_ = false; + prologueEnd_ = false; + epilogueBegin_ = false; + discriminator_ = 0; + return COMMIT; + } + + if (opcode != 0) + { // standard opcode + // Only interpret opcodes that are recognized by the version we're parsing; + // the others are vendor extensions and we should ignore them. + switch (opcode) + { + case DW_LNS_copy: + basicBlock_ = false; + prologueEnd_ = false; + epilogueBegin_ = false; + discriminator_ = 0; + return COMMIT; + case DW_LNS_advance_pc: + address_ += minLength_ * readULEB(program); + return CONTINUE; + case DW_LNS_advance_line: + line_ += readSLEB(program); + return CONTINUE; + case DW_LNS_set_file: + file_ = readULEB(program); + return CONTINUE; + case DW_LNS_set_column: + column_ = readULEB(program); + return CONTINUE; + case DW_LNS_negate_stmt: + isStmt_ = !isStmt_; + return CONTINUE; + case DW_LNS_set_basic_block: + basicBlock_ = true; + return CONTINUE; + case DW_LNS_const_add_pc: + address_ += minLength_ * ((255 - opcodeBase_) / lineRange_); + return CONTINUE; + case DW_LNS_fixed_advance_pc: + address_ += read(program); + return CONTINUE; + case DW_LNS_set_prologue_end: + if (version_ == 2) + { + break; // not supported in version 2 + } + prologueEnd_ = true; + return CONTINUE; + case DW_LNS_set_epilogue_begin: + if (version_ == 2) + { + break; // not supported in version 2 + } + epilogueBegin_ = true; + return CONTINUE; + case DW_LNS_set_isa: + if (version_ == 2) + { + break; // not supported in version 2 + } + isa_ = readULEB(program); + return CONTINUE; + } + + // Unrecognized standard opcode, slurp the appropriate number of LEB + // arguments. + uint8_t argCount = standardOpcodeLengths_[opcode - 1]; + while (argCount--) + { + readULEB(program); + } + return CONTINUE; + } + + // Extended opcode + auto length = readULEB(program); + // the opcode itself should be included in the length, so length >= 1 + SAFE_CHECK(length != 0, "invalid extended opcode length"); + auto extendedOpcode = read(program); + --length; + + switch (extendedOpcode) + { + case DW_LNE_end_sequence: + return END; + case DW_LNE_set_address: + address_ = read(program); + return CONTINUE; + case DW_LNE_define_file: + // We can't process DW_LNE_define_file here, as it would require us to + // use unbounded amounts of state (ie. use the heap). We'll do a second + // pass (using nextDefineFile()) if necessary. + break; + case DW_LNE_set_discriminator: + discriminator_ = readULEB(program); + return CONTINUE; + } + + // Unrecognized extended opcode + program.remove_prefix(length); + return CONTINUE; +} + +bool Dwarf::LineNumberVM::findAddress(uintptr_t target, Path & file, uint64_t & line) +{ + std::string_view program = data_; + + // Within each sequence of instructions, the address may only increase. + // Unfortunately, within the same compilation unit, sequences may appear + // in any order. So any sequence is a candidate if it starts at an address + // <= the target address, and we know we've found the target address if + // a candidate crosses the target address. + enum State + { + START, + LOW_SEQ, // candidate + HIGH_SEQ + }; + State state = START; + reset(); + + uint64_t prevFile = 0; + uint64_t prevLine = 0; + while (!program.empty()) + { + bool seqEnd = !next(program); + + if (state == START) + { + if (!seqEnd) + { + state = address_ <= target ? LOW_SEQ : HIGH_SEQ; + } + } + + if (state == LOW_SEQ) + { + if (address_ > target) + { + // Found it! Note that ">" is indeed correct (not ">="), as each + // sequence is guaranteed to have one entry past-the-end (emitted by + // DW_LNE_end_sequence) + if (prevFile == 0) + { + return false; + } + auto fn = getFileName(prevFile); + file = Path(compilationDirectory_, getIncludeDirectory(fn.directoryIndex), fn.relativeName); + line = prevLine; + return true; + } + prevFile = file_; + prevLine = line_; + } + + if (seqEnd) + { + state = START; + reset(); + } + } + + return false; +} + +} diff --git a/dbms/src/Common/Dwarf.h b/dbms/src/Common/Dwarf.h new file mode 100644 index 00000000000..48e23922259 --- /dev/null +++ b/dbms/src/Common/Dwarf.h @@ -0,0 +1,287 @@ +#pragma once + +/* + * Copyright 2012-present Facebook, Inc. + * + * Licensed 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. + */ + +/** This file was edited for ClickHouse. + */ + +#include +#include +#include + + +namespace DB +{ + +class Elf; + +/** + * DWARF record parser. + * + * We only implement enough DWARF functionality to convert from PC address + * to file and line number information. + * + * This means (although they're not part of the public API of this class), we + * can parse Debug Information Entries (DIEs), abbreviations, attributes (of + * all forms), and we can interpret bytecode for the line number VM. + * + * We can interpret DWARF records of version 2, 3, or 4, although we don't + * actually support many of the version 4 features (such as VLIW, multiple + * operations per instruction) + * + * Note that the DWARF record parser does not allocate heap memory at all. + * This is on purpose: you can use the parser from + * memory-constrained situations (such as an exception handler for + * std::out_of_memory) If it weren't for this requirement, some things would + * be much simpler: the Path class would be unnecessary and would be replaced + * with a std::string; the list of file names in the line number VM would be + * kept as a vector of strings instead of re-executing the program to look for + * DW_LNE_define_file instructions, etc. + */ +class Dwarf +{ + // Note that Dwarf uses (and returns) std::string_view a lot. + // The std::string_view point within sections in the ELF file, and so will + // be live for as long as the passed-in Elf is live. +public: + /** Create a DWARF parser around an ELF file. */ + explicit Dwarf(const Elf & elf); + + /** + * Represent a file path a s collection of three parts (base directory, + * subdirectory, and file). + */ + class Path + { + public: + Path() {} + + Path(std::string_view baseDir, std::string_view subDir, std::string_view file); + + std::string_view baseDir() const { return baseDir_; } + std::string_view subDir() const { return subDir_; } + std::string_view file() const { return file_; } + + size_t size() const; + + /** + * Copy the Path to a buffer of size bufSize. + * + * toBuffer behaves like snprintf: It will always null-terminate the + * buffer (so it will copy at most bufSize-1 bytes), and it will return + * the number of bytes that would have been written if there had been + * enough room, so, if toBuffer returns a value >= bufSize, the output + * was truncated. + */ + size_t toBuffer(char * buf, size_t bufSize) const; + + void toString(std::string & dest) const; + std::string toString() const + { + std::string s; + toString(s); + return s; + } + + // TODO(tudorb): Implement operator==, operator!=; not as easy as it + // seems as the same path can be represented in multiple ways + private: + std::string_view baseDir_; + std::string_view subDir_; + std::string_view file_; + }; + + enum class LocationInfoMode + { + // Don't resolve location info. + DISABLED, + // Perform CU lookup using .debug_aranges (might be incomplete). + FAST, + // Scan all CU in .debug_info (slow!) on .debug_aranges lookup failure. + FULL, + }; + + struct LocationInfo + { + bool hasMainFile = false; + Path mainFile; + + bool hasFileAndLine = false; + Path file; + uint64_t line = 0; + }; + + /** + * Find the file and line number information corresponding to address. + */ + bool findAddress(uintptr_t address, LocationInfo & info, LocationInfoMode mode) const; + +private: + static bool findDebugInfoOffset(uintptr_t address, std::string_view aranges, uint64_t & offset); + + void init(); + bool findLocation(uintptr_t address, std::string_view & infoEntry, LocationInfo & info) const; + + const Elf * elf_; + + // DWARF section made up of chunks, each prefixed with a length header. + // The length indicates whether the chunk is DWARF-32 or DWARF-64, which + // guides interpretation of "section offset" records. + // (yes, DWARF-32 and DWARF-64 sections may coexist in the same file) + class Section + { + public: + Section() : is64Bit_(false) {} + + explicit Section(std::string_view d); + + // Return next chunk, if any; the 4- or 12-byte length was already + // parsed and isn't part of the chunk. + bool next(std::string_view & chunk); + + // Is the current chunk 64 bit? + bool is64Bit() const { return is64Bit_; } + + private: + // Yes, 32- and 64- bit sections may coexist. Yikes! + bool is64Bit_; + std::string_view data_; + }; + + // Abbreviation for a Debugging Information Entry. + struct DIEAbbreviation + { + uint64_t code; + uint64_t tag; + bool hasChildren; + + struct Attribute + { + uint64_t name; + uint64_t form; + }; + + std::string_view attributes; + }; + + // Interpreter for the line number bytecode VM + class LineNumberVM + { + public: + LineNumberVM(std::string_view data, std::string_view compilationDirectory); + + bool findAddress(uintptr_t address, Path & file, uint64_t & line); + + private: + void init(); + void reset(); + + // Execute until we commit one new row to the line number matrix + bool next(std::string_view & program); + enum StepResult + { + CONTINUE, // Continue feeding opcodes + COMMIT, // Commit new tuple + END, // End of sequence + }; + // Execute one opcode + StepResult step(std::string_view & program); + + struct FileName + { + std::string_view relativeName; + // 0 = current compilation directory + // otherwise, 1-based index in the list of include directories + uint64_t directoryIndex; + }; + // Read one FileName object, remove_prefix sp + static bool readFileName(std::string_view & sp, FileName & fn); + + // Get file name at given index; may be in the initial table + // (fileNames_) or defined using DW_LNE_define_file (and we reexecute + // enough of the program to find it, if so) + FileName getFileName(uint64_t index) const; + + // Get include directory at given index + std::string_view getIncludeDirectory(uint64_t index) const; + + // Execute opcodes until finding a DW_LNE_define_file and return true; + // return file at the end. + bool nextDefineFile(std::string_view & program, FileName & fn) const; + + // Initialization + bool is64Bit_; + std::string_view data_; + std::string_view compilationDirectory_; + + // Header + uint16_t version_; + uint8_t minLength_; + bool defaultIsStmt_; + int8_t lineBase_; + uint8_t lineRange_; + uint8_t opcodeBase_; + const uint8_t * standardOpcodeLengths_; + + std::string_view includeDirectories_; + size_t includeDirectoryCount_; + + std::string_view fileNames_; + size_t fileNameCount_; + + // State machine registers + uint64_t address_; + uint64_t file_; + uint64_t line_; + uint64_t column_; + bool isStmt_; + bool basicBlock_; + bool endSequence_; + bool prologueEnd_; + bool epilogueBegin_; + uint64_t isa_; + uint64_t discriminator_; + }; + + // Read an abbreviation from a std::string_view, return true if at end; remove_prefix sp + static bool readAbbreviation(std::string_view & sp, DIEAbbreviation & abbr); + + // Get abbreviation corresponding to a code, in the chunk starting at + // offset in the .debug_abbrev section + DIEAbbreviation getAbbreviation(uint64_t code, uint64_t offset) const; + + // Read one attribute pair, remove_prefix sp; returns <0, 0> at end. + static DIEAbbreviation::Attribute readAttribute(std::string_view & sp); + + // Read one attribute value, remove_prefix sp + typedef std::variant AttributeValue; + AttributeValue readAttributeValue(std::string_view & sp, uint64_t form, bool is64Bit) const; + + // Get an ELF section by name, return true if found + bool getSection(const char * name, std::string_view * section) const; + + // Get a string from the .debug_str section + std::string_view getStringFromStringSection(uint64_t offset) const; + + std::string_view info_; // .debug_info + std::string_view abbrev_; // .debug_abbrev + std::string_view aranges_; // .debug_aranges + std::string_view line_; // .debug_line + std::string_view strings_; // .debug_str +}; + +} diff --git a/dbms/src/Common/Elf.cpp b/dbms/src/Common/Elf.cpp index 85aed3367cf..05767dfe609 100644 --- a/dbms/src/Common/Elf.cpp +++ b/dbms/src/Common/Elf.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include namespace DB @@ -16,8 +16,6 @@ namespace ErrorCodes Elf::Elf(const std::string & path) : in(path, 0) { - std::cerr << "Processing path " << path << "\n"; - /// Check if it's an elf. size = in.buffer().size(); if (size < sizeof(ElfEhdr)) @@ -98,6 +96,12 @@ std::optional Elf::findSection(std::function Elf::findSectionByName(const char * name) const +{ + return findSection([&](const Section & section, size_t) { return 0 == strcmp(name, section.name()); }); +} + + const char * Elf::Section::name() const { if (!elf.section_names) @@ -115,7 +119,12 @@ const char * Elf::Section::begin() const const char * Elf::Section::end() const { - return elf.mapped + header.sh_offset + header.sh_size; + return begin() + size(); +} + +size_t Elf::Section::size() const +{ + return header.sh_size; } } diff --git a/dbms/src/Common/Elf.h b/dbms/src/Common/Elf.h index 807e265b114..f9f615dac3f 100644 --- a/dbms/src/Common/Elf.h +++ b/dbms/src/Common/Elf.h @@ -21,7 +21,9 @@ using ElfSym = ElfW(Sym); namespace DB { -class Elf +/** Allow to navigate sections in ELF. + */ +class Elf final { public: struct Section @@ -31,6 +33,7 @@ public: const char * begin() const; const char * end() const; + size_t size() const; Section(const ElfShdr & header, const Elf & elf); @@ -40,8 +43,9 @@ public: Elf(const std::string & path); - std::optional
    findSection(std::function && pred) const; bool iterateSections(std::function && pred) const; + std::optional
    findSection(std::function && pred) const; + std::optional
    findSectionByName(const char * name) const; const char * end() const { return mapped + size; } diff --git a/dbms/src/Common/ErrorCodes.cpp b/dbms/src/Common/ErrorCodes.cpp index 53f40239d13..5cb6b7e0a37 100644 --- a/dbms/src/Common/ErrorCodes.cpp +++ b/dbms/src/Common/ErrorCodes.cpp @@ -439,6 +439,7 @@ namespace ErrorCodes extern const int CANNOT_DELETE_TIMER = 462; extern const int CANNOT_FCNTL = 463; extern const int CANNOT_PARSE_ELF = 464; + extern const int CANNOT_PARSE_DWARF = 465; extern const int KEEPER_EXCEPTION = 999; extern const int POCO_EXCEPTION = 1000; From 15dc6d1818f42b0c9f6744bafc58dc0ec78c74b5 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 29 Jul 2019 21:38:04 +0300 Subject: [PATCH 0459/1165] Advancements --- dbms/src/Common/Dwarf.h | 6 +- dbms/src/Common/Elf.cpp | 10 +-- dbms/src/Common/Elf.h | 8 ++- dbms/src/Common/SymbolIndex.cpp | 82 +++++++++++++------------ dbms/src/Common/SymbolIndex.h | 22 +++++-- dbms/src/Common/tests/symbol_index.cpp | 21 +++++-- dbms/src/Functions/symbolizeAddress.cpp | 2 +- 7 files changed, 89 insertions(+), 62 deletions(-) diff --git a/dbms/src/Common/Dwarf.h b/dbms/src/Common/Dwarf.h index 48e23922259..5bc358df863 100644 --- a/dbms/src/Common/Dwarf.h +++ b/dbms/src/Common/Dwarf.h @@ -52,7 +52,7 @@ class Elf; * kept as a vector of strings instead of re-executing the program to look for * DW_LNE_define_file instructions, etc. */ -class Dwarf +class Dwarf final { // Note that Dwarf uses (and returns) std::string_view a lot. // The std::string_view point within sections in the ELF file, and so will @@ -126,8 +126,8 @@ public: }; /** - * Find the file and line number information corresponding to address. - */ + * Find the file and line number information corresponding to address. + */ bool findAddress(uintptr_t address, LocationInfo & info, LocationInfoMode mode) const; private: diff --git a/dbms/src/Common/Elf.cpp b/dbms/src/Common/Elf.cpp index 05767dfe609..bb51b837a13 100644 --- a/dbms/src/Common/Elf.cpp +++ b/dbms/src/Common/Elf.cpp @@ -17,8 +17,8 @@ Elf::Elf(const std::string & path) : in(path, 0) { /// Check if it's an elf. - size = in.buffer().size(); - if (size < sizeof(ElfEhdr)) + elf_size = in.buffer().size(); + if (elf_size < sizeof(ElfEhdr)) throw Exception("The size of supposedly ELF file is too small", ErrorCodes::CANNOT_PARSE_ELF); mapped = in.buffer().begin(); @@ -33,7 +33,7 @@ Elf::Elf(const std::string & path) if (!section_header_offset || !section_header_num_entries - || section_header_offset + section_header_num_entries * sizeof(ElfShdr) > size) + || section_header_offset + section_header_num_entries * sizeof(ElfShdr) > elf_size) throw Exception("The ELF is truncated (section header points after end of file)", ErrorCodes::CANNOT_PARSE_ELF); section_headers = reinterpret_cast(mapped + section_header_offset); @@ -48,7 +48,7 @@ Elf::Elf(const std::string & path) throw Exception("The ELF doesn't have string table with section names", ErrorCodes::CANNOT_PARSE_ELF); ElfOff section_names_offset = section_names_strtab->header.sh_offset; - if (section_names_offset >= size) + if (section_names_offset >= elf_size) throw Exception("The ELF is truncated (section names string table points after end of file)", ErrorCodes::CANNOT_PARSE_ELF); section_names = reinterpret_cast(mapped + section_names_offset); @@ -68,7 +68,7 @@ bool Elf::iterateSections(std::function size) + if (section.header.sh_offset + section.header.sh_size > elf_size) continue; if (pred(section, idx)) diff --git a/dbms/src/Common/Elf.h b/dbms/src/Common/Elf.h index f9f615dac3f..7f7fcc538b5 100644 --- a/dbms/src/Common/Elf.h +++ b/dbms/src/Common/Elf.h @@ -41,17 +41,19 @@ public: const Elf & elf; }; - Elf(const std::string & path); + explicit Elf(const std::string & path); bool iterateSections(std::function && pred) const; std::optional
    findSection(std::function && pred) const; std::optional
    findSectionByName(const char * name) const; - const char * end() const { return mapped + size; } + const char * begin() const { return mapped; } + const char * end() const { return mapped + elf_size; } + size_t size() const { return elf_size; } private: MMapReadBufferFromFile in; - size_t size; + size_t elf_size; const char * mapped; const ElfEhdr * header; const ElfShdr * section_headers; diff --git a/dbms/src/Common/SymbolIndex.cpp b/dbms/src/Common/SymbolIndex.cpp index 24fc93aec97..b315abead73 100644 --- a/dbms/src/Common/SymbolIndex.cpp +++ b/dbms/src/Common/SymbolIndex.cpp @@ -24,7 +24,8 @@ namespace /// Based on the code of musl-libc and the answer of Kanalpiroge on /// https://stackoverflow.com/questions/15779185/list-all-the-functions-symbols-on-the-fly-in-c-code-on-a-linux-architecture -void collectSymbolsFromProgramHeaders(dl_phdr_info * info, std::vector & symbols) +void collectSymbolsFromProgramHeaders(dl_phdr_info * info, + std::vector & symbols) { /* Iterate over all headers of the current shared lib * (first call is for the executable itself) */ @@ -40,8 +41,6 @@ void collectSymbolsFromProgramHeaders(dl_phdr_info * info, std::vector(info->dlpi_addr + info->dlpi_phdr[header_index].p_vaddr); -// std::cerr << "dlpi_addr: " << info->dlpi_addr << "\n"; - /// For unknown reason, addresses are sometimes relative sometimes absolute. auto correct_address = [](ElfW(Addr) base, ElfW(Addr) ptr) { @@ -53,25 +52,17 @@ void collectSymbolsFromProgramHeaders(dl_phdr_info * info, std::vectord_tag != DT_NULL; ++it) - std::cerr << it->d_tag << "\n";*/ - size_t sym_cnt = 0; for (auto it = dyn_begin; it->d_tag != DT_NULL; ++it) { if (it->d_tag == DT_HASH) { const ElfW(Word) * hash = reinterpret_cast(correct_address(info->dlpi_addr, it->d_un.d_ptr)); - -// std::cerr << it->d_un.d_ptr << ", " << it->d_un.d_val << "\n"; - sym_cnt = hash[1]; break; } else if (it->d_tag == DT_GNU_HASH) { -// std::cerr << it->d_un.d_ptr << ", " << it->d_un.d_val << "\n"; - /// This code based on Musl-libc. const uint32_t * buckets = nullptr; @@ -100,7 +91,6 @@ void collectSymbolsFromProgramHeaders(dl_phdr_info * info, std::vectord_tag != DT_NULL; ++it) { if (it->d_tag == DT_SYMTAB) @@ -141,8 +129,6 @@ void collectSymbolsFromProgramHeaders(dl_phdr_info * info, std::vector(info->dlpi_addr + elf_sym[sym_index].st_value); symbol.address_end = reinterpret_cast(info->dlpi_addr + elf_sym[sym_index].st_value + elf_sym[sym_index].st_size); @@ -226,7 +212,9 @@ bool searchAndCollectSymbolsFromELFSymbolTable( } -void collectSymbolsFromELF(dl_phdr_info * info, std::vector & symbols) +void collectSymbolsFromELF(dl_phdr_info * info, + std::vector & symbols, + std::vector & objects) { std::string object_name = info->dlpi_name; @@ -244,6 +232,12 @@ void collectSymbolsFromELF(dl_phdr_info * info, std::vector(info->dlpi_addr); + object.address_end = reinterpret_cast(info->dlpi_addr + elf.size()); + object.name = object_name; + objects.push_back(std::move(object)); + searchAndCollectSymbolsFromELFSymbolTable(info, elf, SHT_SYMTAB, ".strtab", symbols); searchAndCollectSymbolsFromELFSymbolTable(info, elf, SHT_DYNSYM, ".dynstr", symbols); } @@ -253,21 +247,41 @@ void collectSymbolsFromELF(dl_phdr_info * info, std::vector & symbols = *reinterpret_cast *>(out_symbols); + DB::SymbolIndex::Data & data = *reinterpret_cast(data_ptr); - collectSymbolsFromProgramHeaders(info, symbols); - collectSymbolsFromELF(info, symbols); + collectSymbolsFromProgramHeaders(info, data.symbols); + collectSymbolsFromELF(info, data.symbols, data.objects); /* Continue iterations */ return 0; } + +template +const T * find(const void * address, const std::vector & vec) +{ + /// First range that has left boundary greater than address. + + auto it = std::lower_bound(vec.begin(), vec.end(), address, + [](const T & symbol, const void * addr) { return symbol.address_begin <= addr; }); + + if (it == vec.begin()) + return nullptr; + else + --it; /// Last range that has left boundary less or equals than address. + + if (address >= it->address_begin && address < it->address_end) + return &*it; + else + return nullptr; +} + } @@ -276,28 +290,18 @@ namespace DB void SymbolIndex::update() { - dl_iterate_phdr(collectSymbols, &symbols); - std::sort(symbols.begin(), symbols.end()); + dl_iterate_phdr(collectSymbols, &data.symbols); + std::sort(data.symbols.begin(), data.symbols.end(), [](const Symbol & a, const Symbol & b) { return a.address_begin < b.address_begin; }); } -const SymbolIndex::Symbol * SymbolIndex::find(const void * address) const +const SymbolIndex::Symbol * SymbolIndex::findSymbol(const void * address) const { - /// First range that has left boundary greater than address. + return find(address, data.symbols); +} -// std::cerr << "Searching " << address << "\n"; - - auto it = std::lower_bound(symbols.begin(), symbols.end(), address); - if (it == symbols.begin()) - return nullptr; - else - --it; /// Last range that has left boundary less or equals than address. - -// std::cerr << "Range: " << it->address_begin << " ... " << it->address_end << "\n"; - - if (address >= it->address_begin && address < it->address_end) - return &*it; - else - return nullptr; +const SymbolIndex::Object * SymbolIndex::findObject(const void * address) const +{ + return find(address, data.objects); } } diff --git a/dbms/src/Common/SymbolIndex.h b/dbms/src/Common/SymbolIndex.h index 41c7a10648b..9d1dceb2c91 100644 --- a/dbms/src/Common/SymbolIndex.h +++ b/dbms/src/Common/SymbolIndex.h @@ -19,21 +19,31 @@ public: const void * address_end; const char * object; std::string name; /// demangled NOTE Can use Arena for strings + }; - bool operator< (const Symbol & rhs) const { return address_begin < rhs.address_begin; } - bool operator< (const void * addr) const { return address_begin <= addr; } + struct Object + { + const void * address_begin; + const void * address_end; + std::string name; }; SymbolIndex() { update(); } void update(); - const Symbol * find(const void * address) const; + const Symbol * findSymbol(const void * address) const; + const Object * findObject(const void * address) const; - auto begin() const { return symbols.cbegin(); } - auto end() const { return symbols.cend(); } + const std::vector & symbols() const { return data.symbols; } + const std::vector & objects() const { return data.objects; } + struct Data + { + std::vector symbols; + std::vector objects; + }; private: - std::vector symbols; + Data data; }; } diff --git a/dbms/src/Common/tests/symbol_index.cpp b/dbms/src/Common/tests/symbol_index.cpp index a9fec7069e9..37a044939b7 100644 --- a/dbms/src/Common/tests/symbol_index.cpp +++ b/dbms/src/Common/tests/symbol_index.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include #include #include @@ -18,22 +20,31 @@ int main(int argc, char ** argv) SymbolIndex symbol_index; - for (const auto & symbol : symbol_index) - std::cout << symbol.name << ": " << symbol.address_begin << " ... " << symbol.address_end << "\n"; + for (const auto & elem : symbol_index.objects()) + std::cout << elem.name << ": " << elem.address_begin << " ... " << elem.address_end << "\n"; const void * address = reinterpret_cast(std::stoull(argv[1], nullptr, 16)); - auto symbol = symbol_index.find(address); + auto symbol = symbol_index.findSymbol(address); if (symbol) std::cerr << symbol->name << ": " << symbol->address_begin << " ... " << symbol->address_end << "\n"; else - std::cerr << "Not found\n"; + std::cerr << "SymbolIndex: Not found\n"; Dl_info info; if (dladdr(address, &info) && info.dli_sname) std::cerr << demangle(info.dli_sname) << ": " << info.dli_saddr << "\n"; else - std::cerr << "Not found\n"; + std::cerr << "dladdr: Not found\n"; + + Elf elf("/proc/self/exe"); + Dwarf dwarf(elf); + + Dwarf::LocationInfo location; + if (dwarf.findAddress(uintptr_t(address), location, Dwarf::LocationInfoMode::FULL)) + std::cerr << location.file.toString() << ":" << location.line << "\n"; + else + std::cerr << "Dwarf: Not found\n"; return 0; } diff --git a/dbms/src/Functions/symbolizeAddress.cpp b/dbms/src/Functions/symbolizeAddress.cpp index 65c1aa84d37..b4fef649814 100644 --- a/dbms/src/Functions/symbolizeAddress.cpp +++ b/dbms/src/Functions/symbolizeAddress.cpp @@ -73,7 +73,7 @@ public: for (size_t i = 0; i < input_rows_count; ++i) { - if (const auto * symbol = symbol_index.find(reinterpret_cast(data[i]))) + if (const auto * symbol = symbol_index.findSymbol(reinterpret_cast(data[i]))) result_column->insertDataWithTerminatingZero(symbol->name.data(), symbol->name.size() + 1); else result_column->insertDefault(); From ce682a81b9e353c795040941372a5c0c55b9a1d3 Mon Sep 17 00:00:00 2001 From: proller Date: Mon, 29 Jul 2019 21:56:55 +0300 Subject: [PATCH 0460/1165] clean --- contrib/libunwind | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/libunwind b/contrib/libunwind index ec86b1c6a2c..5afe6d87ae9 160000 --- a/contrib/libunwind +++ b/contrib/libunwind @@ -1 +1 @@ -Subproject commit ec86b1c6a2c6b8ba316f429db9a6d4122dd12710 +Subproject commit 5afe6d87ae9e66485c7fcb106d2f7c2c0359c8f6 From 372c4d89b26b99118cb83aff8ea5880eb7cfea5c Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 30 Jul 2019 01:26:44 +0300 Subject: [PATCH 0461/1165] Enabled line numbers in stack traces --- CMakeLists.txt | 4 + dbms/CMakeLists.txt | 5 + dbms/src/Common/Dwarf.cpp | 64 ------------ dbms/src/Common/Exception.h | 2 +- dbms/src/Common/QueryProfiler.cpp | 2 +- .../src => dbms/src/Common}/StackTrace.cpp | 99 +++++++++---------- .../common => dbms/src/Common}/StackTrace.h | 0 dbms/src/Common/SymbolIndex.cpp | 64 ++++++------ dbms/src/Common/SymbolIndex.h | 18 ++-- dbms/src/Common/TraceCollector.cpp | 2 +- dbms/src/Common/tests/symbol_index.cpp | 8 +- dbms/src/Functions/registerFunctions.cpp | 4 +- .../registerFunctionsIntrospection.cpp | 16 +++ dbms/src/Functions/symbolizeAddress.cpp | 5 +- dbms/src/Interpreters/Context.cpp | 2 +- libs/libcommon/CMakeLists.txt | 10 -- libs/libdaemon/src/BaseDaemon.cpp | 2 +- 17 files changed, 130 insertions(+), 177 deletions(-) rename {libs/libcommon/src => dbms/src/Common}/StackTrace.cpp (83%) rename {libs/libcommon/include/common => dbms/src/Common}/StackTrace.h (100%) create mode 100644 dbms/src/Functions/registerFunctionsIntrospection.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a2cc5f15ac8..df711a87a7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,6 +106,10 @@ endif () if (COMPILER_CLANG) # clang: warning: argument unused during compilation: '-specs=/usr/share/dpkg/no-pie-compile.specs' [-Wunused-command-line-argument] set (COMMON_WARNING_FLAGS "${COMMON_WARNING_FLAGS} -Wno-unused-command-line-argument") + # generate ranges for fast "addr2line" search + if (NOT CMAKE_BUILD_TYPE_UC STREQUAL "RELEASE") + set(COMPILER_FLAGS "${COMPILER_FLAGS} -gdwarf-aranges") + endif () endif () option (ENABLE_TESTS "Enables tests" ON) diff --git a/dbms/CMakeLists.txt b/dbms/CMakeLists.txt index c8056ada4e6..99db33de3f2 100644 --- a/dbms/CMakeLists.txt +++ b/dbms/CMakeLists.txt @@ -159,6 +159,11 @@ if (OS_FREEBSD) target_compile_definitions (clickhouse_common_io PUBLIC CLOCK_MONOTONIC_COARSE=CLOCK_MONOTONIC_FAST) endif () +if (USE_UNWIND) + target_compile_definitions (clickhouse_common_io PRIVATE USE_UNWIND=1) + target_include_directories (clickhouse_common_io SYSTEM BEFORE PRIVATE ${UNWIND_INCLUDE_DIR}) +endif () + add_subdirectory(src/Common/ZooKeeper) add_subdirectory(src/Common/Config) diff --git a/dbms/src/Common/Dwarf.cpp b/dbms/src/Common/Dwarf.cpp index 45a5116642e..798eb08cc52 100644 --- a/dbms/src/Common/Dwarf.cpp +++ b/dbms/src/Common/Dwarf.cpp @@ -183,66 +183,6 @@ void skipPadding(std::string_view & sp, const char * start, size_t alignment) } } -// Simplify a path -- as much as we can while not moving data around... -/*void simplifyPath(std::string_view & sp) -{ - // Strip leading slashes and useless patterns (./), leaving one initial - // slash. - for (;;) - { - if (sp.empty()) - { - return; - } - - // Strip leading slashes, leaving one. - while (sp.startsWith("//")) - { - sp.remove_prefix(1); - } - - if (sp.startsWith("/./")) - { - // Note 2, not 3, to keep it absolute - sp.remove_prefix(2); - continue; - } - - if (sp.removePrefix("./")) - { - // Also remove any subsequent slashes to avoid making this path absolute. - while (sp.startsWith('/')) - { - sp.remove_prefix(1); - } - continue; - } - - break; - } - - // Strip trailing slashes and useless patterns (/.). - for (;;) - { - if (sp.empty()) - { - return; - } - - // Strip trailing slashes, except when this is the root path. - while (sp.size() > 1 && sp.removeSuffix('/')) - { - } - - if (sp.removeSuffix("/.")) - { - continue; - } - - break; - } -}*/ - } @@ -271,10 +211,6 @@ Dwarf::Path::Path(std::string_view baseDir, std::string_view subDir, std::string baseDir_ = {}; // subDir_ is absolute } -// simplifyPath(baseDir_); -// simplifyPath(subDir_); -// simplifyPath(file_); - // Make sure it's never the case that baseDir_ is empty, but subDir_ isn't. if (baseDir_.empty()) { diff --git a/dbms/src/Common/Exception.h b/dbms/src/Common/Exception.h index ee897962228..6b0656f4828 100644 --- a/dbms/src/Common/Exception.h +++ b/dbms/src/Common/Exception.h @@ -6,7 +6,7 @@ #include -#include +#include namespace Poco { class Logger; } diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index 5aafa35df94..08399a49d2e 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/libs/libcommon/src/StackTrace.cpp b/dbms/src/Common/StackTrace.cpp similarity index 83% rename from libs/libcommon/src/StackTrace.cpp rename to dbms/src/Common/StackTrace.cpp index 8323a737fdf..f842b71d15a 100644 --- a/libs/libcommon/src/StackTrace.cpp +++ b/dbms/src/Common/StackTrace.cpp @@ -1,16 +1,16 @@ -#include #include #include -#include -#include -#include -#include +#include +#include +#include +#include + +#include +#include +#include +#include -#if USE_UNWIND -#define UNW_LOCAL_ONLY -#include -#endif std::string signalToErrorMessage(int sig, const siginfo_t & info, const ucontext_t & context) { @@ -168,9 +168,9 @@ void * getCallerAddress(const ucontext_t & context) #endif #elif defined(__aarch64__) return reinterpret_cast(context.uc_mcontext.pc); -#endif - +#else return nullptr; +#endif } StackTrace::StackTrace() @@ -195,6 +195,12 @@ StackTrace::StackTrace(NoCapture) { } + +#if USE_UNWIND +extern "C" int unw_backtrace(void **, int); +#endif + + void StackTrace::tryCapture() { size = 0; @@ -227,50 +233,43 @@ std::string StackTrace::toStringImpl(const Frames & frames, size_t size) if (size == 0) return ""; - char ** symbols = backtrace_symbols(frames.data(), size); - if (!symbols) - return ""; + const DB::SymbolIndex & symbol_index = DB::SymbolIndex::instance(); + std::unordered_map dwarfs; - std::stringstream backtrace; - try + std::stringstream out; + + for (size_t i = 0; i < size; ++i) { - for (size_t i = 0; i < size; i++) + out << "#" << i << " " << frames[i] << " "; + auto symbol = symbol_index.findSymbol(frames[i]); + if (symbol) { - /// We do "demangling" of names. The name is in parenthesis, before the '+' character. - - char * name_start = nullptr; - char * name_end = nullptr; - std::string demangled_name; int status = 0; - - if (nullptr != (name_start = strchr(symbols[i], '(')) - && nullptr != (name_end = strchr(name_start, '+'))) - { - ++name_start; - *name_end = '\0'; - demangled_name = demangle(name_start, status); - *name_end = '+'; - } - - backtrace << i << ". "; - - if (0 == status && name_start && name_end) - { - backtrace.write(symbols[i], name_start - symbols[i]); - backtrace << demangled_name << name_end; - } - else - backtrace << symbols[i]; - - backtrace << std::endl; + out << demangle(symbol->name, status); } - } - catch (...) - { - free(symbols); - throw; + else + out << "?"; + + out << " "; + + if (auto object = symbol_index.findObject(frames[i])) + { + if (std::filesystem::exists(object->name)) + { + auto dwarf_it = dwarfs.try_emplace(object->name, *object->elf).first; + + DB::Dwarf::LocationInfo location; + if (dwarf_it->second.findAddress(uintptr_t(object->address_begin) + uintptr_t(frames[i]), location, DB::Dwarf::LocationInfoMode::FAST)) + out << location.file.toString() << ":" << location.line; + else + out << object->name; + } + } + else + out << "?"; + + out << "\n"; } - free(symbols); - return backtrace.str(); + return out.str(); } diff --git a/libs/libcommon/include/common/StackTrace.h b/dbms/src/Common/StackTrace.h similarity index 100% rename from libs/libcommon/include/common/StackTrace.h rename to dbms/src/Common/StackTrace.h diff --git a/dbms/src/Common/SymbolIndex.cpp b/dbms/src/Common/SymbolIndex.cpp index b315abead73..ff04ea35eaa 100644 --- a/dbms/src/Common/SymbolIndex.cpp +++ b/dbms/src/Common/SymbolIndex.cpp @@ -1,6 +1,4 @@ #include -#include -#include #include #include @@ -11,6 +9,9 @@ #include +namespace DB +{ + namespace { @@ -25,7 +26,7 @@ namespace /// Based on the code of musl-libc and the answer of Kanalpiroge on /// https://stackoverflow.com/questions/15779185/list-all-the-functions-symbols-on-the-fly-in-c-code-on-a-linux-architecture void collectSymbolsFromProgramHeaders(dl_phdr_info * info, - std::vector & symbols) + std::vector & symbols) { /* Iterate over all headers of the current shared lib * (first call is for the executable itself) */ @@ -129,13 +130,10 @@ void collectSymbolsFromProgramHeaders(dl_phdr_info * info, if (!sym_name) continue; - DB::SymbolIndex::Symbol symbol; + SymbolIndex::Symbol symbol; symbol.address_begin = reinterpret_cast(info->dlpi_addr + elf_sym[sym_index].st_value); symbol.address_end = reinterpret_cast(info->dlpi_addr + elf_sym[sym_index].st_value + elf_sym[sym_index].st_size); - int unused = 0; - symbol.name = demangle(sym_name, unused); - symbol.object = info->dlpi_name; - + symbol.name = sym_name; symbols.push_back(std::move(symbol)); } @@ -148,10 +146,10 @@ void collectSymbolsFromProgramHeaders(dl_phdr_info * info, void collectSymbolsFromELFSymbolTable( dl_phdr_info * info, - const DB::Elf & elf, - const DB::Elf::Section & symbol_table, - const DB::Elf::Section & string_table, - std::vector & symbols) + const Elf & elf, + const Elf::Section & symbol_table, + const Elf::Section & string_table, + std::vector & symbols) { /// Iterate symbol table. const ElfSym * symbol_table_entry = reinterpret_cast(symbol_table.begin()); @@ -170,13 +168,13 @@ void collectSymbolsFromELFSymbolTable( /// Find the name in strings table. const char * symbol_name = strings + symbol_table_entry->st_name; - DB::SymbolIndex::Symbol symbol; + if (!symbol_name) + continue; + + SymbolIndex::Symbol symbol; symbol.address_begin = reinterpret_cast(info->dlpi_addr + symbol_table_entry->st_value); symbol.address_end = reinterpret_cast(info->dlpi_addr + symbol_table_entry->st_value + symbol_table_entry->st_size); - int unused = 0; - symbol.name = demangle(symbol_name, unused); - symbol.object = info->dlpi_name; - + symbol.name = symbol_name; symbols.push_back(std::move(symbol)); } } @@ -184,15 +182,15 @@ void collectSymbolsFromELFSymbolTable( bool searchAndCollectSymbolsFromELFSymbolTable( dl_phdr_info * info, - const DB::Elf & elf, + const Elf & elf, unsigned section_header_type, const char * string_table_name, - std::vector & symbols) + std::vector & symbols) { - std::optional symbol_table; - std::optional string_table; + std::optional symbol_table; + std::optional string_table; - if (!elf.iterateSections([&](const DB::Elf::Section & section, size_t) + if (!elf.iterateSections([&](const Elf::Section & section, size_t) { if (section.header.sh_type == section_header_type) symbol_table.emplace(section); @@ -213,8 +211,8 @@ bool searchAndCollectSymbolsFromELFSymbolTable( void collectSymbolsFromELF(dl_phdr_info * info, - std::vector & symbols, - std::vector & objects) + std::vector & symbols, + std::vector & objects) { std::string object_name = info->dlpi_name; @@ -230,16 +228,17 @@ void collectSymbolsFromELF(dl_phdr_info * info, if (ec) return; - DB::Elf elf(object_name); - - DB::SymbolIndex::Object object; + SymbolIndex::Object object; + object.elf = std::make_unique(object_name); object.address_begin = reinterpret_cast(info->dlpi_addr); - object.address_end = reinterpret_cast(info->dlpi_addr + elf.size()); + object.address_end = reinterpret_cast(info->dlpi_addr + object.elf->size()); object.name = object_name; objects.push_back(std::move(object)); - searchAndCollectSymbolsFromELFSymbolTable(info, elf, SHT_SYMTAB, ".strtab", symbols); - searchAndCollectSymbolsFromELFSymbolTable(info, elf, SHT_DYNSYM, ".dynstr", symbols); + searchAndCollectSymbolsFromELFSymbolTable(info, *objects.back().elf, SHT_SYMTAB, ".strtab", symbols); + + /// Unneeded because they were parsed from "program headers" of loaded objects. + //searchAndCollectSymbolsFromELFSymbolTable(info, *objects.back().elf, SHT_DYNSYM, ".dynstr", symbols); } @@ -253,7 +252,7 @@ int collectSymbols(dl_phdr_info * info, size_t, void * data_ptr) * (e.g. on a 32 bit system, ElfW(Dyn*) becomes "Elf32_Dyn*") */ - DB::SymbolIndex::Data & data = *reinterpret_cast(data_ptr); + SymbolIndex::Data & data = *reinterpret_cast(data_ptr); collectSymbolsFromProgramHeaders(info, data.symbols); collectSymbolsFromELF(info, data.symbols, data.objects); @@ -285,9 +284,6 @@ const T * find(const void * address, const std::vector & vec) } -namespace DB -{ - void SymbolIndex::update() { dl_iterate_phdr(collectSymbols, &data.symbols); diff --git a/dbms/src/Common/SymbolIndex.h b/dbms/src/Common/SymbolIndex.h index 9d1dceb2c91..41a773f5f4a 100644 --- a/dbms/src/Common/SymbolIndex.h +++ b/dbms/src/Common/SymbolIndex.h @@ -2,6 +2,8 @@ #include #include +#include +#include namespace DB @@ -9,16 +11,20 @@ namespace DB /** Allow to quickly find symbol name from address. * Used as a replacement for "dladdr" function which is extremely slow. + * It works better than "dladdr" because it also allows to search private symbols, that are not participated in shared linking. */ -class SymbolIndex +class SymbolIndex : public ext::singleton { +protected: + friend class ext::singleton; + SymbolIndex() { update(); } + public: struct Symbol { const void * address_begin; const void * address_end; - const char * object; - std::string name; /// demangled NOTE Can use Arena for strings + const char * name; }; struct Object @@ -26,11 +32,9 @@ public: const void * address_begin; const void * address_end; std::string name; + std::unique_ptr elf; }; - SymbolIndex() { update(); } - void update(); - const Symbol * findSymbol(const void * address) const; const Object * findObject(const void * address) const; @@ -44,6 +48,8 @@ public: }; private: Data data; + + void update(); }; } diff --git a/dbms/src/Common/TraceCollector.cpp b/dbms/src/Common/TraceCollector.cpp index e66a580289d..13d2061c810 100644 --- a/dbms/src/Common/TraceCollector.cpp +++ b/dbms/src/Common/TraceCollector.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dbms/src/Common/tests/symbol_index.cpp b/dbms/src/Common/tests/symbol_index.cpp index 37a044939b7..c6a22b1266b 100644 --- a/dbms/src/Common/tests/symbol_index.cpp +++ b/dbms/src/Common/tests/symbol_index.cpp @@ -18,9 +18,9 @@ int main(int argc, char ** argv) return 1; } - SymbolIndex symbol_index; + const SymbolIndex & symbol_index = SymbolIndex::instance(); - for (const auto & elem : symbol_index.objects()) + for (const auto & elem : symbol_index.symbols()) std::cout << elem.name << ": " << elem.address_begin << " ... " << elem.address_end << "\n"; const void * address = reinterpret_cast(std::stoull(argv[1], nullptr, 16)); @@ -41,10 +41,12 @@ int main(int argc, char ** argv) Dwarf dwarf(elf); Dwarf::LocationInfo location; - if (dwarf.findAddress(uintptr_t(address), location, Dwarf::LocationInfoMode::FULL)) + if (dwarf.findAddress(uintptr_t(address), location, Dwarf::LocationInfoMode::FAST)) std::cerr << location.file.toString() << ":" << location.line << "\n"; else std::cerr << "Dwarf: Not found\n"; + std::cerr << StackTrace().toString() << "\n"; + return 0; } diff --git a/dbms/src/Functions/registerFunctions.cpp b/dbms/src/Functions/registerFunctions.cpp index 178f085e1ad..eba9a96e5e0 100644 --- a/dbms/src/Functions/registerFunctions.cpp +++ b/dbms/src/Functions/registerFunctions.cpp @@ -40,7 +40,7 @@ void registerFunctionsIntrospection(FunctionFactory &); void registerFunctionsNull(FunctionFactory &); void registerFunctionsFindCluster(FunctionFactory &); void registerFunctionsJSON(FunctionFactory &); -void registerFunctionSymbolizeAddress(FunctionFactory &); +void registerFunctionsIntrospection(FunctionFactory &); void registerFunctions() { @@ -79,7 +79,7 @@ void registerFunctions() registerFunctionsNull(factory); registerFunctionsFindCluster(factory); registerFunctionsJSON(factory); - registerFunctionSymbolizeAddress(factory); + registerFunctionsIntrospection(factory); } } diff --git a/dbms/src/Functions/registerFunctionsIntrospection.cpp b/dbms/src/Functions/registerFunctionsIntrospection.cpp new file mode 100644 index 00000000000..0797d21c361 --- /dev/null +++ b/dbms/src/Functions/registerFunctionsIntrospection.cpp @@ -0,0 +1,16 @@ +namespace DB +{ + +class FunctionFactory; + +void registerFunctionSymbolizeAddress(FunctionFactory & factory); +void registerFunctionDemangle(FunctionFactory & factory); + +void registerFunctionsIntrospection(FunctionFactory & factory) +{ + registerFunctionSymbolizeAddress(factory); + registerFunctionDemangle(factory); +} + +} + diff --git a/dbms/src/Functions/symbolizeAddress.cpp b/dbms/src/Functions/symbolizeAddress.cpp index b4fef649814..454fc94b7bf 100644 --- a/dbms/src/Functions/symbolizeAddress.cpp +++ b/dbms/src/Functions/symbolizeAddress.cpp @@ -15,7 +15,6 @@ namespace ErrorCodes { extern const int ILLEGAL_COLUMN; extern const int ILLEGAL_TYPE_OF_ARGUMENT; - extern const int SIZES_OF_ARRAYS_DOESNT_MATCH; extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; } @@ -60,7 +59,7 @@ public: void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override { - static SymbolIndex symbol_index; + const SymbolIndex & symbol_index = SymbolIndex::instance(); const ColumnPtr & column = block.getByPosition(arguments[0]).column; const ColumnUInt64 * column_concrete = checkAndGetColumn(column.get()); @@ -74,7 +73,7 @@ public: for (size_t i = 0; i < input_rows_count; ++i) { if (const auto * symbol = symbol_index.findSymbol(reinterpret_cast(data[i]))) - result_column->insertDataWithTerminatingZero(symbol->name.data(), symbol->name.size() + 1); + result_column->insertDataWithTerminatingZero(symbol->name, strlen(symbol->name) + 1); else result_column->insertDefault(); } diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index cec36f42469..fc2ada171d1 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -50,7 +50,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/libs/libcommon/CMakeLists.txt b/libs/libcommon/CMakeLists.txt index 8ebd9bddc8d..ce8c5801613 100644 --- a/libs/libcommon/CMakeLists.txt +++ b/libs/libcommon/CMakeLists.txt @@ -23,12 +23,10 @@ add_library (common src/getThreadNumber.cpp src/sleep.cpp src/argsToConfig.cpp - src/StackTrace.cpp src/Pipe.cpp src/phdr_cache.cpp include/common/SimpleCache.h - include/common/StackTrace.h include/common/Types.h include/common/DayNum.h include/common/DateLUT.h @@ -68,14 +66,6 @@ add_library (common ${CONFIG_COMMON}) -if (USE_UNWIND) - target_compile_definitions (common PRIVATE USE_UNWIND=1) - target_include_directories (common BEFORE PRIVATE ${UNWIND_INCLUDE_DIR}) - if (NOT USE_INTERNAL_UNWIND_LIBRARY_FOR_EXCEPTION_HANDLING) - target_link_libraries (common PRIVATE ${UNWIND_LIBRARY}) - endif () -endif () - # When testing for memory leaks with Valgrind, dont link tcmalloc or jemalloc. if (USE_JEMALLOC) diff --git a/libs/libdaemon/src/BaseDaemon.cpp b/libs/libdaemon/src/BaseDaemon.cpp index aa4993acead..16bcb132d37 100644 --- a/libs/libdaemon/src/BaseDaemon.cpp +++ b/libs/libdaemon/src/BaseDaemon.cpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include From ad3f2066d95b4b5e11f8ff62e75b8ed8febaa77d Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 30 Jul 2019 01:27:02 +0300 Subject: [PATCH 0462/1165] Added missing file --- dbms/src/Functions/demange.cpp | 87 ++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 dbms/src/Functions/demange.cpp diff --git a/dbms/src/Functions/demange.cpp b/dbms/src/Functions/demange.cpp new file mode 100644 index 00000000000..8249bf387f9 --- /dev/null +++ b/dbms/src/Functions/demange.cpp @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace DB +{ + +namespace ErrorCodes +{ + extern const int ILLEGAL_COLUMN; + extern const int ILLEGAL_TYPE_OF_ARGUMENT; + extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; +} + +class FunctionDemangle : public IFunction +{ +public: + static constexpr auto name = "demangle"; + static FunctionPtr create(const Context &) + { + return std::make_shared(); + } + + String getName() const override + { + return name; + } + + size_t getNumberOfArguments() const override + { + return 1; + } + + DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override + { + if (arguments.size() != 1) + throw Exception("Function " + getName() + " needs exactly one argument; passed " + + toString(arguments.size()) + ".", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); + + const auto & type = arguments[0].type; + + if (!WhichDataType(type.get()).isString()) + throw Exception("The only argument for function " + getName() + " must be String. Found " + + type->getName() + " instead.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); + + return std::make_shared(); + } + + bool useDefaultImplementationForConstants() const override + { + return true; + } + + void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override + { + const ColumnPtr & column = block.getByPosition(arguments[0]).column; + const ColumnString * column_concrete = checkAndGetColumn(column.get()); + + if (!column_concrete) + throw Exception("Illegal column " + column->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN); + + auto result_column = ColumnString::create(); + + for (size_t i = 0; i < input_rows_count; ++i) + { + StringRef source = column_concrete->getDataAt(i); + int status = 0; + result_column.insertData(demangle(source, status)); + } + + block.getByPosition(result).column = std::move(result_column); + } +}; + +void registerFunctionDemangle(FunctionFactory & factory) +{ + factory.registerFunction(); +} + +} + From 10439bc010ef4a5c7e20feb9ed12e0e2055ce05a Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 30 Jul 2019 01:33:28 +0300 Subject: [PATCH 0463/1165] Addition to prev. revision --- dbms/src/Functions/demange.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Functions/demange.cpp b/dbms/src/Functions/demange.cpp index 8249bf387f9..eb5b0001e11 100644 --- a/dbms/src/Functions/demange.cpp +++ b/dbms/src/Functions/demange.cpp @@ -71,7 +71,7 @@ public: { StringRef source = column_concrete->getDataAt(i); int status = 0; - result_column.insertData(demangle(source, status)); + result_column.insertData(demangle(source.data, status)); } block.getByPosition(result).column = std::move(result_column); From a05c6026dc562e8aa298f3c6e8d98bf2bdb83ef2 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 30 Jul 2019 01:34:05 +0300 Subject: [PATCH 0464/1165] Addition to prev. revision --- dbms/src/Functions/demange.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Functions/demange.cpp b/dbms/src/Functions/demange.cpp index eb5b0001e11..cc27cbf2b1c 100644 --- a/dbms/src/Functions/demange.cpp +++ b/dbms/src/Functions/demange.cpp @@ -71,7 +71,7 @@ public: { StringRef source = column_concrete->getDataAt(i); int status = 0; - result_column.insertData(demangle(source.data, status)); + result_column->insertData(demangle(source.data, status)); } block.getByPosition(result).column = std::move(result_column); From 0cbd4f68ce5441a4b1f8f46b3f3ba59378bde13b Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 30 Jul 2019 01:37:26 +0300 Subject: [PATCH 0465/1165] Addition to prev. revision --- dbms/src/Functions/demange.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dbms/src/Functions/demange.cpp b/dbms/src/Functions/demange.cpp index cc27cbf2b1c..2cc04cd4523 100644 --- a/dbms/src/Functions/demange.cpp +++ b/dbms/src/Functions/demange.cpp @@ -71,7 +71,8 @@ public: { StringRef source = column_concrete->getDataAt(i); int status = 0; - result_column->insertData(demangle(source.data, status)); + std::string result = demangle(source.data, status); + result_column->insertDataWithTerminatingZero(result.data(), result.size() + 1); } block.getByPosition(result).column = std::move(result_column); From 97ac56139b1ba3094e35c1b4ebf907c701ee35c8 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 30 Jul 2019 01:50:39 +0300 Subject: [PATCH 0466/1165] Addition to prev. revision --- dbms/src/Functions/demange.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Functions/demange.cpp b/dbms/src/Functions/demange.cpp index 2cc04cd4523..aea14f5bc76 100644 --- a/dbms/src/Functions/demange.cpp +++ b/dbms/src/Functions/demange.cpp @@ -71,8 +71,8 @@ public: { StringRef source = column_concrete->getDataAt(i); int status = 0; - std::string result = demangle(source.data, status); - result_column->insertDataWithTerminatingZero(result.data(), result.size() + 1); + std::string demangled = demangle(source.data, status); + result_column->insertDataWithTerminatingZero(demangled.data(), demangled.size() + 1); } block.getByPosition(result).column = std::move(result_column); From 256e260693530e01bd990bdc509508e57ad0c770 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 30 Jul 2019 02:37:50 +0300 Subject: [PATCH 0467/1165] Added one more function for introspection --- dbms/src/Common/StackTrace.cpp | 10 +- dbms/src/Functions/addressToLine.cpp | 146 ++++++++++++++++++ .../registerFunctionsIntrospection.cpp | 2 + 3 files changed, 154 insertions(+), 4 deletions(-) create mode 100644 dbms/src/Functions/addressToLine.cpp diff --git a/dbms/src/Common/StackTrace.cpp b/dbms/src/Common/StackTrace.cpp index f842b71d15a..30fb66f218e 100644 --- a/dbms/src/Common/StackTrace.cpp +++ b/dbms/src/Common/StackTrace.cpp @@ -240,8 +240,10 @@ std::string StackTrace::toStringImpl(const Frames & frames, size_t size) for (size_t i = 0; i < size; ++i) { - out << "#" << i << " " << frames[i] << " "; - auto symbol = symbol_index.findSymbol(frames[i]); + const void * addr = frames[i]; + + out << "#" << i << " " << addr << " "; + auto symbol = symbol_index.findSymbol(addr); if (symbol) { int status = 0; @@ -252,14 +254,14 @@ std::string StackTrace::toStringImpl(const Frames & frames, size_t size) out << " "; - if (auto object = symbol_index.findObject(frames[i])) + if (auto object = symbol_index.findObject(addr)) { if (std::filesystem::exists(object->name)) { auto dwarf_it = dwarfs.try_emplace(object->name, *object->elf).first; DB::Dwarf::LocationInfo location; - if (dwarf_it->second.findAddress(uintptr_t(object->address_begin) + uintptr_t(frames[i]), location, DB::Dwarf::LocationInfoMode::FAST)) + if (dwarf_it->second.findAddress(uintptr_t(addr) - uintptr_t(object->address_begin), location, DB::Dwarf::LocationInfoMode::FAST)) out << location.file.toString() << ":" << location.line; else out << object->name; diff --git a/dbms/src/Functions/addressToLine.cpp b/dbms/src/Functions/addressToLine.cpp new file mode 100644 index 00000000000..0e3c4fe65ab --- /dev/null +++ b/dbms/src/Functions/addressToLine.cpp @@ -0,0 +1,146 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +namespace DB +{ + +namespace ErrorCodes +{ + extern const int ILLEGAL_COLUMN; + extern const int ILLEGAL_TYPE_OF_ARGUMENT; + extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; +} + +class FunctionAddressToLine : public IFunction +{ +public: + static constexpr auto name = "addressToLine"; + static FunctionPtr create(const Context &) + { + return std::make_shared(); + } + + String getName() const override + { + return name; + } + + size_t getNumberOfArguments() const override + { + return 1; + } + + DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override + { + if (arguments.size() != 1) + throw Exception("Function " + getName() + " needs exactly one argument; passed " + + toString(arguments.size()) + ".", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); + + const auto & type = arguments[0].type; + + if (!WhichDataType(type.get()).isUInt64()) + throw Exception("The only argument for function " + getName() + " must be UInt64. Found " + + type->getName() + " instead.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); + + return std::make_shared(); + } + + bool useDefaultImplementationForConstants() const override + { + return true; + } + + void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override + { + const ColumnPtr & column = block.getByPosition(arguments[0]).column; + const ColumnUInt64 * column_concrete = checkAndGetColumn(column.get()); + + if (!column_concrete) + throw Exception("Illegal column " + column->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN); + + const typename ColumnVector::Container & data = column_concrete->getData(); + auto result_column = ColumnString::create(); + + for (size_t i = 0; i < input_rows_count; ++i) + { + StringRef res_str = implCached(data[i]); + result_column->insertData(res_str.data, res_str.size); + } + + block.getByPosition(result).column = std::move(result_column); + } + +private: + std::mutex mutex; + Arena arena; + using Map = HashMap; + Map map; + std::unordered_map dwarfs; + + StringRef impl(uintptr_t addr) + { + const SymbolIndex & symbol_index = SymbolIndex::instance(); + + if (auto object = symbol_index.findObject(reinterpret_cast(addr))) + { + auto dwarf_it = dwarfs.try_emplace(object->name, *object->elf).first; + if (!std::filesystem::exists(object->name)) + return {}; + + Dwarf::LocationInfo location; + if (dwarf_it->second.findAddress(addr - uintptr_t(object->address_begin), location, Dwarf::LocationInfoMode::FAST)) + { + const char * arena_begin = nullptr; + WriteBufferFromArena out(arena, arena_begin); + + writeString(location.file.toString(), out); + writeChar(':', out); + writeIntText(location.line, out); + + StringRef out_str = out.finish(); + out_str.data = arena.insert(out_str.data, out_str.size); + return out_str; + } + else + { + return object->name; + } + } + else + return {}; + } + + StringRef implCached(uintptr_t addr) + { + Map::iterator it; + bool inserted; + std::lock_guard lock(mutex); + map.emplace(addr, it, inserted); + if (inserted) + it->getSecond() = impl(addr); + return it->getSecond(); + } +}; + +void registerFunctionAddressToLine(FunctionFactory & factory) +{ + factory.registerFunction(); +} + +} diff --git a/dbms/src/Functions/registerFunctionsIntrospection.cpp b/dbms/src/Functions/registerFunctionsIntrospection.cpp index 0797d21c361..79cd76f4ad2 100644 --- a/dbms/src/Functions/registerFunctionsIntrospection.cpp +++ b/dbms/src/Functions/registerFunctionsIntrospection.cpp @@ -5,11 +5,13 @@ class FunctionFactory; void registerFunctionSymbolizeAddress(FunctionFactory & factory); void registerFunctionDemangle(FunctionFactory & factory); +void registerFunctionAddressToLine(FunctionFactory & factory); void registerFunctionsIntrospection(FunctionFactory & factory) { registerFunctionSymbolizeAddress(factory); registerFunctionDemangle(factory); + registerFunctionAddressToLine(factory); } } From efbbb149727ead3efe31866d311108438e4747d9 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 30 Jul 2019 02:49:00 +0300 Subject: [PATCH 0468/1165] Renamed function symbolizeAddress to addressToSymbol --- .../{symbolizeAddress.cpp => addressToSymbol.cpp} | 10 +++++----- dbms/src/Functions/registerFunctionsIntrospection.cpp | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) rename dbms/src/Functions/{symbolizeAddress.cpp => addressToSymbol.cpp} (89%) diff --git a/dbms/src/Functions/symbolizeAddress.cpp b/dbms/src/Functions/addressToSymbol.cpp similarity index 89% rename from dbms/src/Functions/symbolizeAddress.cpp rename to dbms/src/Functions/addressToSymbol.cpp index 454fc94b7bf..915327c6c1d 100644 --- a/dbms/src/Functions/symbolizeAddress.cpp +++ b/dbms/src/Functions/addressToSymbol.cpp @@ -18,13 +18,13 @@ namespace ErrorCodes extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; } -class FunctionSymbolizeAddress : public IFunction +class FunctionAddressToSymbol : public IFunction { public: - static constexpr auto name = "symbolizeAddress"; + static constexpr auto name = "addressToSymbol"; static FunctionPtr create(const Context &) { - return std::make_shared(); + return std::make_shared(); } String getName() const override @@ -82,9 +82,9 @@ public: } }; -void registerFunctionSymbolizeAddress(FunctionFactory & factory) +void registerFunctionAddressToSymbol(FunctionFactory & factory) { - factory.registerFunction(); + factory.registerFunction(); } } diff --git a/dbms/src/Functions/registerFunctionsIntrospection.cpp b/dbms/src/Functions/registerFunctionsIntrospection.cpp index 79cd76f4ad2..448400b37ab 100644 --- a/dbms/src/Functions/registerFunctionsIntrospection.cpp +++ b/dbms/src/Functions/registerFunctionsIntrospection.cpp @@ -3,13 +3,13 @@ namespace DB class FunctionFactory; -void registerFunctionSymbolizeAddress(FunctionFactory & factory); +void registerFunctionAddressToSymbol(FunctionFactory & factory); void registerFunctionDemangle(FunctionFactory & factory); void registerFunctionAddressToLine(FunctionFactory & factory); void registerFunctionsIntrospection(FunctionFactory & factory) { - registerFunctionSymbolizeAddress(factory); + registerFunctionAddressToSymbol(factory); registerFunctionDemangle(factory); registerFunctionAddressToLine(factory); } From 20ae0ee80eb78f0696ea4015bab34b0323e194c9 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 30 Jul 2019 02:54:49 +0300 Subject: [PATCH 0469/1165] Added a flag to disable introspection functions --- dbms/src/Core/Settings.h | 1 + dbms/src/Functions/addressToLine.cpp | 7 ++++++- dbms/src/Functions/addressToSymbol.cpp | 6 +++++- dbms/src/Functions/demange.cpp | 7 ++++++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/dbms/src/Core/Settings.h b/dbms/src/Core/Settings.h index 60f2599c73f..0af0bf02d2e 100644 --- a/dbms/src/Core/Settings.h +++ b/dbms/src/Core/Settings.h @@ -334,6 +334,7 @@ struct Settings : public SettingsCollection \ M(SettingBool, allow_hyperscan, true, "Allow functions that use Hyperscan library. Disable to avoid potentially long compilation times and excessive resource usage.") \ M(SettingBool, allow_simdjson, true, "Allow using simdjson library in 'JSON*' functions if AVX2 instructions are available. If disabled rapidjson will be used.") \ + M(SettingBool, allow_introspection_functions, false, "Allow functions for introspection of ELF and DWARF for query profiling. These functions are slow and may impose security considerations.") \ \ M(SettingUInt64, max_partitions_per_insert_block, 100, "Limit maximum number of partitions in single INSERTed block. Zero means unlimited. Throw exception if the block contains too many partitions. This setting is a safety threshold, because using large number of partitions is a common misconception.") \ M(SettingBool, check_query_single_value_result, true, "Return check query result as single 1/0 value") \ diff --git a/dbms/src/Functions/addressToLine.cpp b/dbms/src/Functions/addressToLine.cpp index 0e3c4fe65ab..7f7bd609dee 100644 --- a/dbms/src/Functions/addressToLine.cpp +++ b/dbms/src/Functions/addressToLine.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -25,14 +26,18 @@ namespace ErrorCodes extern const int ILLEGAL_COLUMN; extern const int ILLEGAL_TYPE_OF_ARGUMENT; extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; + extern const int FUNCTION_NOT_ALLOWED; } class FunctionAddressToLine : public IFunction { public: static constexpr auto name = "addressToLine"; - static FunctionPtr create(const Context &) + static FunctionPtr create(const Context & context) { + if (!context.getSettingsRef().allow_introspection_functions) + throw Exception("Introspection functions are disabled, because setting 'allow_introspection_functions' is set to 0", ErrorCodes::FUNCTION_NOT_ALLOWED); + return std::make_shared(); } diff --git a/dbms/src/Functions/addressToSymbol.cpp b/dbms/src/Functions/addressToSymbol.cpp index 915327c6c1d..ceb641e457c 100644 --- a/dbms/src/Functions/addressToSymbol.cpp +++ b/dbms/src/Functions/addressToSymbol.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -16,14 +17,17 @@ namespace ErrorCodes extern const int ILLEGAL_COLUMN; extern const int ILLEGAL_TYPE_OF_ARGUMENT; extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; + extern const int FUNCTION_NOT_ALLOWED; } class FunctionAddressToSymbol : public IFunction { public: static constexpr auto name = "addressToSymbol"; - static FunctionPtr create(const Context &) + static FunctionPtr create(const Context & context) { + if (!context.getSettingsRef().allow_introspection_functions) + throw Exception("Introspection functions are disabled, because setting 'allow_introspection_functions' is set to 0", ErrorCodes::FUNCTION_NOT_ALLOWED); return std::make_shared(); } diff --git a/dbms/src/Functions/demange.cpp b/dbms/src/Functions/demange.cpp index aea14f5bc76..a94b99f62ea 100644 --- a/dbms/src/Functions/demange.cpp +++ b/dbms/src/Functions/demange.cpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace DB @@ -16,14 +17,18 @@ namespace ErrorCodes extern const int ILLEGAL_COLUMN; extern const int ILLEGAL_TYPE_OF_ARGUMENT; extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; + extern const int FUNCTION_NOT_ALLOWED; } class FunctionDemangle : public IFunction { public: static constexpr auto name = "demangle"; - static FunctionPtr create(const Context &) + static FunctionPtr create(const Context & context) { + if (!context.getSettingsRef().allow_introspection_functions) + throw Exception("Introspection functions are disabled, because setting 'allow_introspection_functions' is set to 0", ErrorCodes::FUNCTION_NOT_ALLOWED); + return std::make_shared(); } From fec6ede519e1e2d90bfaa1d1cfde988a4918da23 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 30 Jul 2019 03:15:01 +0300 Subject: [PATCH 0470/1165] Fixed glibc-compatibility --- libs/libglibc-compatibility/musl/utimensat.c | 38 ++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 libs/libglibc-compatibility/musl/utimensat.c diff --git a/libs/libglibc-compatibility/musl/utimensat.c b/libs/libglibc-compatibility/musl/utimensat.c new file mode 100644 index 00000000000..dce0a3c270f --- /dev/null +++ b/libs/libglibc-compatibility/musl/utimensat.c @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include "syscall.h" +#include + +int utimensat(int fd, const char *path, const struct timespec times[2], int flags) +{ + int r = __syscall(SYS_utimensat, fd, path, times, flags); +#ifdef SYS_futimesat + if (r != -ENOSYS || flags) return __syscall_ret(r); + struct timeval *tv = 0, tmp[2]; + if (times) { + int i; + tv = tmp; + for (i=0; i<2; i++) { + if (times[i].tv_nsec >= 1000000000ULL) { + if (times[i].tv_nsec == UTIME_NOW && + times[1-i].tv_nsec == UTIME_NOW) { + tv = 0; + break; + } + if (times[i].tv_nsec == UTIME_OMIT) + return __syscall_ret(-ENOSYS); + return __syscall_ret(-EINVAL); + } + tmp[i].tv_sec = times[i].tv_sec; + tmp[i].tv_usec = times[i].tv_nsec / 1000; + } + } + + r = __syscall(SYS_futimesat, fd, path, tv); + if (r != -ENOSYS || fd != AT_FDCWD) return __syscall_ret(r); + r = __syscall(SYS_utimes, path, tv); +#endif + return __syscall_ret(r); +} From 6db1c02bfd170498add3f59b75f6ee93cbaab841 Mon Sep 17 00:00:00 2001 From: Amos Bird Date: Mon, 10 Dec 2018 01:50:35 +0800 Subject: [PATCH 0471/1165] Fix materialized view with column defaults. https://github.com/yandex/ClickHouse/issues/448 https://github.com/yandex/ClickHouse/issues/3484 https://github.com/yandex/ClickHouse/issues/3450 https://github.com/yandex/ClickHouse/issues/2878 https://github.com/yandex/ClickHouse/issues/2285 --- .../PushingToViewsBlockOutputStream.cpp | 27 ++++++--- dbms/src/Interpreters/Context.cpp | 15 +++++ dbms/src/Interpreters/Context.h | 4 ++ .../Interpreters/InterpreterSelectQuery.cpp | 22 ++++++- dbms/src/Storages/StorageBlock.h | 59 +++++++++++++++++++ ...alized_view_with_column_defaults.reference | 1 + ...materialized_view_with_column_defaults.sql | 25 ++++++++ 7 files changed, 142 insertions(+), 11 deletions(-) create mode 100644 dbms/src/Storages/StorageBlock.h create mode 100644 dbms/tests/queries/0_stateless/00794_materialized_view_with_column_defaults.reference create mode 100644 dbms/tests/queries/0_stateless/00794_materialized_view_with_column_defaults.sql diff --git a/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp b/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp index 304d7aa989c..4e496e86424 100644 --- a/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp +++ b/dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp @@ -1,12 +1,16 @@ +#include #include #include #include #include +#include +#include #include #include #include #include #include +#include namespace DB { @@ -44,13 +48,15 @@ PushingToViewsBlockOutputStream::PushingToViewsBlockOutputStream( auto dependent_table = context.getTable(database_table.first, database_table.second); auto & materialized_view = dynamic_cast(*dependent_table); - if (StoragePtr inner_table = materialized_view.tryGetTargetTable()) - addTableLock(inner_table->lockStructureForShare(true, context.getCurrentQueryId())); - + StoragePtr inner_table = materialized_view.getTargetTable(); auto query = materialized_view.getInnerQuery(); - BlockOutputStreamPtr out = std::make_shared( - database_table.first, database_table.second, dependent_table, *views_context, ASTPtr()); - views.emplace_back(ViewInfo{std::move(query), database_table.first, database_table.second, std::move(out)}); + std::unique_ptr insert = std::make_unique(); + insert->database = inner_table->getDatabaseName(); + insert->table = inner_table->getTableName(); + ASTPtr insert_query_ptr(insert.release()); + InterpreterInsertQuery interpreter(insert_query_ptr, *views_context); + BlockIO io = interpreter.execute(); + views.emplace_back(ViewInfo{query, database_table.first, database_table.second, io.out}); } } @@ -173,8 +179,13 @@ void PushingToViewsBlockOutputStream::process(const Block & block, size_t view_n try { - BlockInputStreamPtr from = std::make_shared(block); - InterpreterSelectQuery select(view.query, *views_context, from); + /// We create a table with the same name as original table and the same alias columns, + /// but it will contain single block (that is INSERT-ed into main table). + /// InterpreterSelectQuery will do processing of alias columns. + Context local_context = *views_context; + local_context.addViewSource(StorageBlock::create(block, storage)); + InterpreterSelectQuery select(view.query, local_context, SelectQueryOptions()); + BlockInputStreamPtr in = std::make_shared(select.execute().in); /// Squashing is needed here because the materialized view query can generate a lot of blocks /// even when only one block is inserted into the parent table (e.g. if the query is a GROUP BY diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index cec36f42469..03e34527f50 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -989,6 +989,21 @@ StoragePtr Context::executeTableFunction(const ASTPtr & table_expression) } +void Context::addViewSource(const StoragePtr & storage) +{ + if (view_source) + throw Exception( + "Temporary view source storage " + backQuoteIfNeed(view_source->getName()) + " already exists.", ErrorCodes::TABLE_ALREADY_EXISTS); + view_source = storage; +} + + +StoragePtr Context::getViewSource() +{ + return view_source; +} + + DDLGuard::DDLGuard(Map & map_, std::unique_lock guards_lock_, const String & elem) : map(map_), guards_lock(std::move(guards_lock_)) { diff --git a/dbms/src/Interpreters/Context.h b/dbms/src/Interpreters/Context.h index d2e08a45026..15f366bdbd3 100644 --- a/dbms/src/Interpreters/Context.h +++ b/dbms/src/Interpreters/Context.h @@ -133,6 +133,7 @@ private: String default_format; /// Format, used when server formats data by itself and if query does not have FORMAT specification. /// Thus, used in HTTP interface. If not specified - then some globally default format is used. TableAndCreateASTs external_tables; /// Temporary tables. + StoragePtr view_source; /// Temporary StorageBlock used to generate alias columns for materialized views Tables table_function_results; /// Temporary tables obtained by execution of table functions. Keyed by AST tree id. Context * query_context = nullptr; Context * session_context = nullptr; /// Session context or nullptr. Could be equal to this. @@ -245,6 +246,9 @@ public: StoragePtr executeTableFunction(const ASTPtr & table_expression); + void addViewSource(const StoragePtr & storage); + StoragePtr getViewSource(); + void addDatabase(const String & database_name, const DatabasePtr & database); DatabasePtr detachDatabase(const String & database_name); diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.cpp b/dbms/src/Interpreters/InterpreterSelectQuery.cpp index b6b371a9088..65a28d36263 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSelectQuery.cpp @@ -45,9 +45,12 @@ #include #include +#include #include #include -#include +#include +#include +#include #include #include @@ -264,13 +267,26 @@ InterpreterSelectQuery::InterpreterSelectQuery( } else { - /// Read from table. Even without table expression (implicit SELECT ... FROM system.one). String database_name; String table_name; getDatabaseAndTableNames(database_name, table_name); - storage = context.getTable(database_name, table_name); + if (auto view_source = context.getViewSource()) + { + auto & storage_block = static_cast(*view_source); + if (storage_block.getDatabaseName() == database_name && storage_block.getTableName() == table_name) + { + /// Read from view source. + storage = context.getViewSource(); + } + } + + if (!storage) + { + /// Read from table. Even without table expression (implicit SELECT ... FROM system.one). + storage = context.getTable(database_name, table_name); + } } } diff --git a/dbms/src/Storages/StorageBlock.h b/dbms/src/Storages/StorageBlock.h new file mode 100644 index 00000000000..d09fb73e40a --- /dev/null +++ b/dbms/src/Storages/StorageBlock.h @@ -0,0 +1,59 @@ +#pragma once + +#include + +#include +#include +#include + + +namespace DB +{ +/// The table has all the properties of another storage, +/// but will read single prepared block instead. +/// Used in PushingToViewsBlockOutputStream for generating alias columns +/// NOTE: Some of the properties seems redundant. +class StorageBlock : public ext::shared_ptr_helper, public IStorage +{ +public: + std::string getName() const override { return storage->getName(); } + std::string getTableName() const override { return storage->getTableName(); } + std::string getDatabaseName() const override { return storage->getDatabaseName(); } + bool isRemote() const override { return storage->isRemote(); } + bool supportsSampling() const override { return storage->supportsSampling(); } + bool supportsFinal() const override { return storage->supportsFinal(); } + bool supportsPrewhere() const override { return storage->supportsPrewhere(); } + bool supportsReplication() const override { return storage->supportsReplication(); } + bool supportsDeduplication() const override { return storage->supportsDeduplication(); } + bool supportsIndexForIn() const override { return storage->supportsIndexForIn(); } + bool mayBenefitFromIndexForIn(const ASTPtr & left_in_operand, const Context & query_context) const override + { + return storage->mayBenefitFromIndexForIn(left_in_operand, query_context); + } + ASTPtr getPartitionKeyAST() const override { return storage->getPartitionKeyAST(); } + ASTPtr getSortingKeyAST() const override { return storage->getSortingKeyAST(); } + ASTPtr getPrimaryKeyAST() const override { return storage->getPrimaryKeyAST(); } + ASTPtr getSamplingKeyAST() const override { return storage->getSamplingKeyAST(); } + Names getColumnsRequiredForPartitionKey() const override { return storage->getColumnsRequiredForPartitionKey(); } + Names getColumnsRequiredForSortingKey() const override { return storage->getColumnsRequiredForSortingKey(); } + Names getColumnsRequiredForPrimaryKey() const override { return storage->getColumnsRequiredForPrimaryKey(); } + Names getColumnsRequiredForSampling() const override { return storage->getColumnsRequiredForSampling(); } + Names getColumnsRequiredForFinal() const override { return storage->getColumnsRequiredForFinal(); } + + BlockInputStreams read(const Names &, const SelectQueryInfo &, const Context &, QueryProcessingStage::Enum, size_t, unsigned) override + { + return {std::make_shared(std::move(block))}; + } + +private: + Block block; + StoragePtr storage; + +protected: + StorageBlock(Block block_, StoragePtr storage_) + : IStorage{storage_->getColumns()}, block(std::move(block_)), storage(storage_) + { + } +}; + +} diff --git a/dbms/tests/queries/0_stateless/00794_materialized_view_with_column_defaults.reference b/dbms/tests/queries/0_stateless/00794_materialized_view_with_column_defaults.reference new file mode 100644 index 00000000000..cc4677b53ce --- /dev/null +++ b/dbms/tests/queries/0_stateless/00794_materialized_view_with_column_defaults.reference @@ -0,0 +1 @@ +2018-12-10 1 1 diff --git a/dbms/tests/queries/0_stateless/00794_materialized_view_with_column_defaults.sql b/dbms/tests/queries/0_stateless/00794_materialized_view_with_column_defaults.sql new file mode 100644 index 00000000000..493447e5974 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00794_materialized_view_with_column_defaults.sql @@ -0,0 +1,25 @@ +USE test; + +DROP TABLE IF EXISTS test1; + +CREATE TABLE test1 ( + date Date, + datetime DateTime, + zoneId UInt64, + test ALIAS zoneId == 1 +) ENGINE = MergeTree(date, (date, zoneId), 8192); + +CREATE MATERIALIZED VIEW test1_view +ENGINE = MergeTree(date, (date, zoneId), 8192) +AS SELECT + date, + zoneId, + test +FROM test.test1; + +INSERT INTO test1 VALUES ('2018-12-10', '2018-12-10 23:59:59', 1); + +SELECT * from test1_view; + +DROP TABLE test1_view; +DROP TABLE test1; From c11fd03ba2f952f10d90bcf7b643d5ffdafb8b36 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Tue, 30 Jul 2019 09:47:38 +0300 Subject: [PATCH 0472/1165] DOCAPI-7063: bitmapContains docs. EN review. RU translation. (#6142) EN review RU translation --- .../functions/bitmap_functions.md | 4 +- .../functions/bitmap_functions.md | 85 +++++++++++++------ 2 files changed, 61 insertions(+), 28 deletions(-) diff --git a/docs/en/query_language/functions/bitmap_functions.md b/docs/en/query_language/functions/bitmap_functions.md index 6e69541cdf7..27f371841af 100644 --- a/docs/en/query_language/functions/bitmap_functions.md +++ b/docs/en/query_language/functions/bitmap_functions.md @@ -66,10 +66,10 @@ bitmapContains(haystack, needle) **Parameters** -- `haystack` – [Bitmap object](#bitmap_functions-bitmapbuild), where the functions searches. +- `haystack` – [Bitmap object](#bitmap_functions-bitmapbuild), where the function searches. - `needle` – Value that the function searches. Type: [UInt32](../../data_types/int_uint.md). -**Returned value** +**Returned values** - 0 — If `haystack` doesn't contain `needle`. - 1 — If `haystack` contains `needle`. diff --git a/docs/ru/query_language/functions/bitmap_functions.md b/docs/ru/query_language/functions/bitmap_functions.md index 7026af30880..00608b72770 100644 --- a/docs/ru/query_language/functions/bitmap_functions.md +++ b/docs/ru/query_language/functions/bitmap_functions.md @@ -1,8 +1,8 @@ # Функции для битмапов -## bitmapBuild +## bitmapBuild {#bitmap_functions-bitmapbuild} -Создаёт битмап из массива целочисленных значений. +Создаёт битовый массив из массива целочисленных значений. ``` bitmapBuild(array) @@ -26,7 +26,7 @@ SELECT bitmapBuild([1, 2, 3, 4, 5]) AS res, toTypeName(res) ## bitmapToArray -Преобразует битмап в массив целочисленных значений. +Преобразует битовый массив в массив целочисленных значений. ``` bitmapToArray(bitmap) @@ -34,7 +34,7 @@ bitmapToArray(bitmap) **Параметры** -- `bitmap` – битмап. +- `bitmap` – битовый массив. **Пример** @@ -48,14 +48,47 @@ SELECT bitmapToArray(bitmapBuild([1, 2, 3, 4, 5])) AS res └─────────────┘ ``` +## bitmapContains {#bitmap_functions-bitmapcontains} + +Проверяет вхождение элемента в битовый массив. + +``` +bitmapContains(haystack, needle) +``` + +**Параметры** + +- `haystack` – [объект Bitmap](#bitmap_functions-bitmapbuild), в котором функция ищет значение. +- `needle` – значение, которое функция ищет. Тип — [UInt32](../../data_types/int_uint.md). + +**Возвращаемые значения** + +- 0 — если в `haystack` нет `needle`. +- 1 — если в `haystack` есть `needle`. + +Тип — `UInt8`. + +**Пример** + +``` sql +SELECT bitmapContains(bitmapBuild([1,5,7,9]), toUInt32(9)) AS res +``` +```text +┌─res─┐ +│ 1 │ +└─────┘ +``` + ## bitmapHasAny -Проверяет, имеют ли два битмапа хотя бы один общий элемент. +Проверяет, имеют ли два битовых массива хотя бы один общий элемент. ``` bitmapHasAny(bitmap1, bitmap2) ``` +Если вы уверены, что `bitmap2` содержит строго один элемент, используйте функцию [bitmapContains](#bitmap_functions-bitmapcontains). Она работает эффективнее. + **Параметры** - `bitmap*` – массив любого типа с набором элементов. @@ -79,8 +112,8 @@ SELECT bitmapHasAny(bitmapBuild([1,2,3]),bitmapBuild([3,4,5])) AS res ## bitmapHasAll -Аналогично функции `hasAll(array, array)` возвращает 1 если первый битмап содержит все элементы второго, 0 в противном случае. -Если второй аргумент является пустым битмапом, то возвращает 1. +Аналогично функции `hasAll(array, array)` возвращает 1 если первый битовый массив содержит все элементы второго, 0 в противном случае. +Если второй аргумент является пустым битовым массивом, то возвращает 1. ``` bitmapHasAll(bitmap,bitmap) @@ -88,7 +121,7 @@ bitmapHasAll(bitmap,bitmap) **Параметры** -- `bitmap` – битмап. +- `bitmap` – битовый массив. **Пример** @@ -104,7 +137,7 @@ SELECT bitmapHasAll(bitmapBuild([1,2,3]),bitmapBuild([3,4,5])) AS res ## bitmapAnd -Логическое И для двух битмапов. Результат — новый битмап. +Логическое И для двух битовых массивов. Результат — новый битовый массив. ``` bitmapAnd(bitmap,bitmap) @@ -112,7 +145,7 @@ bitmapAnd(bitmap,bitmap) **Параметры** -- `bitmap` – битмап. +- `bitmap` – битовый массив. **Пример** @@ -128,7 +161,7 @@ SELECT bitmapToArray(bitmapAnd(bitmapBuild([1,2,3]),bitmapBuild([3,4,5]))) AS re ## bitmapOr -Логическое ИЛИ для двух битмапов. Результат — новый битмап. +Логическое ИЛИ для двух битовых массивов. Результат — новый битовый массив. ``` bitmapOr(bitmap,bitmap) @@ -136,7 +169,7 @@ bitmapOr(bitmap,bitmap) **Параметры** -- `bitmap` – битмап. +- `bitmap` – битовый массив. **Пример** @@ -152,7 +185,7 @@ SELECT bitmapToArray(bitmapOr(bitmapBuild([1,2,3]),bitmapBuild([3,4,5]))) AS res ## bitmapXor -Логическое исключающее ИЛИ для двух битмапов. Результат — новый битмап. +Логическое исключающее ИЛИ для двух битовых массивов. Результат — новый битовый массив. ``` bitmapXor(bitmap,bitmap) @@ -160,7 +193,7 @@ bitmapXor(bitmap,bitmap) **Параметры** -- `bitmap` – битмап. +- `bitmap` – битовый массив. **Пример** @@ -176,7 +209,7 @@ SELECT bitmapToArray(bitmapXor(bitmapBuild([1,2,3]),bitmapBuild([3,4,5]))) AS re ## bitmapAndnot -Логическое отрицание И для двух битмапов. Результат — новый битмап. +Логическое отрицание И для двух битовых массивов. Результат — новый битовый массив. ``` bitmapAndnot(bitmap,bitmap) @@ -184,7 +217,7 @@ bitmapAndnot(bitmap,bitmap) **Параметры** -- `bitmap` – битмап. +- `bitmap` – битовый массив. **Пример** @@ -200,7 +233,7 @@ SELECT bitmapToArray(bitmapAndnot(bitmapBuild([1,2,3]),bitmapBuild([3,4,5]))) AS ## bitmapCardinality -Возвращает кардинальность битмапа в виде значения типа `UInt64`. +Возвращает кардинальность битового массива в виде значения типа `UInt64`. ``` bitmapCardinality(bitmap) @@ -208,7 +241,7 @@ bitmapCardinality(bitmap) **Параметры** -- `bitmap` – битмап. +- `bitmap` – битовый массив. **Пример** @@ -224,7 +257,7 @@ SELECT bitmapCardinality(bitmapBuild([1, 2, 3, 4, 5])) AS res ## bitmapAndCardinality -Выполняет логическое И и возвращает кардинальность (`UInt64`) результирующего битмапа. +Выполняет логическое И и возвращает кардинальность (`UInt64`) результирующего битового массива. ``` bitmapAndCardinality(bitmap,bitmap) @@ -232,7 +265,7 @@ bitmapAndCardinality(bitmap,bitmap) **Параметры** -- `bitmap` – битмап. +- `bitmap` – битовый массив. **Пример** @@ -248,7 +281,7 @@ SELECT bitmapAndCardinality(bitmapBuild([1,2,3]),bitmapBuild([3,4,5])) AS res; ## bitmapOrCardinality -Выполняет логическое ИЛИ и возвращает кардинальность (`UInt64`) результирующего битмапа. +Выполняет логическое ИЛИ и возвращает кардинальность (`UInt64`) результирующего битового массива. ``` bitmapOrCardinality(bitmap,bitmap) @@ -256,7 +289,7 @@ bitmapOrCardinality(bitmap,bitmap) **Параметры** -- `bitmap` – битмап. +- `bitmap` – битовый массив. **Пример** @@ -272,7 +305,7 @@ SELECT bitmapOrCardinality(bitmapBuild([1,2,3]),bitmapBuild([3,4,5])) AS res; ## bitmapXorCardinality -Выполняет логическое исключающее ИЛИ и возвращает кардинальность (`UInt64`) результирующего битмапа. +Выполняет логическое исключающее ИЛИ и возвращает кардинальность (`UInt64`) результирующего битового массива. ``` bitmapXorCardinality(bitmap,bitmap) @@ -280,7 +313,7 @@ bitmapXorCardinality(bitmap,bitmap) **Параметры** -- `bitmap` – битмап. +- `bitmap` – битовый массив. **Пример** @@ -296,7 +329,7 @@ SELECT bitmapXorCardinality(bitmapBuild([1,2,3]),bitmapBuild([3,4,5])) AS res; ## bitmapAndnotCardinality -Выполняет логическое отрицание И и возвращает кардинальность (`UInt64`) результирующего битмапа. +Выполняет логическое отрицание И и возвращает кардинальность (`UInt64`) результирующего битового массива. ``` bitmapAndnotCardinality(bitmap,bitmap) @@ -304,7 +337,7 @@ bitmapAndnotCardinality(bitmap,bitmap) **Параметры** -- `bitmap` – битмап. +- `bitmap` – битовый массив. **Пример** From cad9a231d2657bd7d0bafbfc39786da6c5fb6fbc Mon Sep 17 00:00:00 2001 From: BayoNet Date: Tue, 30 Jul 2019 10:40:49 +0300 Subject: [PATCH 0473/1165] DOCAPI-4197: Limitations settings. EN review. RU translation. (#6089) max_rows_in_join max_bytes_in_join join_overflow_mode max_network_bandwidth max_network_bandwidth_for_user max_network_bandwidth_for_all_users max_network_bytes max_bytes_before_external_group_by join_any_take_last_row --- .../operations/settings/query_complexity.md | 18 ++--- docs/en/operations/settings/settings.md | 8 +-- docs/en/query_language/select.md | 7 +- .../operations/settings/query_complexity.md | 68 ++++++++++++++++++- docs/ru/operations/settings/settings.md | 65 ++++++++++++++++++ docs/ru/query_language/select.md | 28 +++++--- 6 files changed, 164 insertions(+), 30 deletions(-) diff --git a/docs/en/operations/settings/query_complexity.md b/docs/en/operations/settings/query_complexity.md index 1cf5f5e83aa..77699c868b4 100644 --- a/docs/en/operations/settings/query_complexity.md +++ b/docs/en/operations/settings/query_complexity.md @@ -75,11 +75,11 @@ Using the 'any' value lets you run an approximation of GROUP BY. The quality of ## max_bytes_before_external_group_by {#settings-max_bytes_before_external_group_by} -Enables or disables execution of `GROUP BY` clause in external memory. See [GROUP BY in external memory](../../query_language/select.md#select-group-by-in-external-memory). +Enables or disables execution of `GROUP BY` clauses in external memory. See [GROUP BY in external memory](../../query_language/select.md#select-group-by-in-external-memory). Possible values: -- Maximum volume or RAM (in bytes) that can be used by [GROUP BY](../../query_language/select.md#select-group-by-clause) operation. +- Maximum volume or RAM (in bytes) that can be used by the single [GROUP BY](../../query_language/select.md#select-group-by-clause) operation. - 0 — `GROUP BY` in external memory disabled. Default value: 0. @@ -209,11 +209,11 @@ What to do when the amount of data exceeds one of the limits: 'throw' or 'break' Limits the number of rows in the hash table that is used when joining tables. -This settings applies to [SELECT ... JOIN](../../query_language/select.md#select-join) operations and the [Join table engine](../table_engines/join.md). +This settings applies to [SELECT ... JOIN](../../query_language/select.md#select-join) operations and the [Join](../table_engines/join.md) table engine. If a query contains multiple joins, ClickHouse checks this setting for every intermediate result. -ClickHouse can proceed with different actions when the limit is reached. Use the [join_overflow_mode](#settings-join_overflow_mode) settings to choose the action. +ClickHouse can proceed with different actions when the limit is reached. Use the [join_overflow_mode](#settings-join_overflow_mode) setting to choose the action. Possible values: @@ -224,13 +224,13 @@ Default value: 0. ## max_bytes_in_join {#settings-max_bytes_in_join} -Limits hash table size in bytes that is used when joining tables. +Limits the size in bytes of the hash table used when joining tables. -This settings applies to [SELECT ... JOIN](../../query_language/select.md#select-join) operations and the [Join table engine](../table_engines/join.md). +This settings applies to [SELECT ... JOIN](../../query_language/select.md#select-join) operations and [Join table engine](../table_engines/join.md). -If query contains some joins, ClickHouse checks this setting for every intermediate result. +If the query contains joins, ClickHouse checks this setting for every intermediate result. -ClickHouse can proceed with different actions when the limit is reached. Use the [join_overflow_mode](#settings-join_overflow_mode) settings to choose the action. +ClickHouse can proceed with different actions when the limit is reached. Use [join_overflow_mode](#settings-join_overflow_mode) settings to choose the action. Possible values: @@ -241,7 +241,7 @@ Default value: 0. ## join_overflow_mode {#settings-join_overflow_mode} -Defines an action that ClickHouse performs, when any of the following join limits is reached: +Defines what action ClickHouse performs when any of the following join limits is reached: - [max_bytes_in_join](#settings-max_bytes_in_join) - [max_rows_in_join](#settings-max_rows_in_join) diff --git a/docs/en/operations/settings/settings.md b/docs/en/operations/settings/settings.md index 015549acb45..578d7c1bb64 100644 --- a/docs/en/operations/settings/settings.md +++ b/docs/en/operations/settings/settings.md @@ -750,7 +750,7 @@ When sequential consistency is enabled, ClickHouse allows the client to execute - [insert_quorum_timeout](#settings-insert_quorum_timeout) ## max_network_bytes {#settings-max_network_bytes} -Limits the data volume (in bytes) that is received or transmitted over the network when executing a query. This setting applies for every individual query. +Limits the data volume (in bytes) that is received or transmitted over the network when executing a query. This setting applies to every individual query. Possible values: @@ -761,7 +761,7 @@ Default value: 0. ## max_network_bandwidth {#settings-max_network_bandwidth} -Limits speed of data exchange over the network in bytes per second. This setting applies for every individual query. +Limits the speed of the data exchange over the network in bytes per second. This setting applies to every query. Possible values: @@ -772,7 +772,7 @@ Default value: 0. ## max_network_bandwidth_for_user {#settings-max_network_bandwidth_for_user} -Limits speed of data exchange over the network in bytes per second. This setting applies for all concurrently running queries performed by a single user. +Limits the speed of the data exchange over the network in bytes per second. This setting applies to all concurrently running queries performed by a single user. Possible values: @@ -783,7 +783,7 @@ Default value: 0. ## max_network_bandwidth_for_all_users {#settings-max_network_bandwidth_for_all_users} -Limits speed of data exchange over the network in bytes per second. This setting applies for all concurrently running queries on the server. +Limits the speed that data is exchanged at over the network in bytes per second. This setting applies to all concurrently running queries on the server. Possible values: diff --git a/docs/en/query_language/select.md b/docs/en/query_language/select.md index a657858a53d..b75524274e1 100644 --- a/docs/en/query_language/select.md +++ b/docs/en/query_language/select.md @@ -807,8 +807,7 @@ When merging data flushed to the disk, as well as when merging results from remo When external aggregation is enabled, if there was less than `max_bytes_before_external_group_by` of data (i.e. data was not flushed), the query runs just as fast as without external aggregation. If any temporary data was flushed, the run time will be several times longer (approximately three times). -If you have an `ORDER BY` with a small `LIMIT` after `GROUP BY`, then the `ORDER BY` clause will not use significant amounts of RAM. -But if the `ORDER BY` doesn't have `LIMIT`, don't forget to enable external sorting (`max_bytes_before_external_sort`). +If you have an `ORDER BY` with a `LIMIT` after `GROUP BY`, then the amount of used RAM depends on the amount of data in `LIMIT`, not in the whole table. But if the `ORDER BY` doesn't have `LIMIT`, don't forget to enable external sorting (`max_bytes_before_external_sort`). ### LIMIT BY Clause @@ -1256,9 +1255,9 @@ It also makes sense to specify a local table in the `GLOBAL IN` clause, in case In addition to results, you can also get minimum and maximum values for the results columns. To do this, set the **extremes** setting to 1. Minimums and maximums are calculated for numeric types, dates, and dates with times. For other columns, the default values are output. -An extra two rows are calculated – the minimums and maximums, respectively. These extra two rows are output in `JSON*`, `TabSeparated*`, and `Pretty*` formats, separate from the other rows. They are not output for other formats. +An extra two rows are calculated – the minimums and maximums, respectively. These extra two rows are output in `JSON*`, `TabSeparated*`, and `Pretty*` [formats](../interfaces/formats.md), separate from the other rows. They are not output for other formats. -In `JSON*` formats, the extreme values are output in a separate 'extremes' field. In `TabSeparated*` formats, the row comes after the main result, and after 'totals' if present. It is preceded by an empty row (after the other data). In `Pretty*` formats, the row is output as a separate table after the main result, and after 'totals' if present. +In `JSON*` formats, the extreme values are output in a separate 'extremes' field. In `TabSeparated*` formats, the row comes after the main result, and after 'totals' if present. It is preceded by an empty row (after the other data). In `Pretty*` formats, the row is output as a separate table after the main result, and after `totals` if present. Extreme values are calculated for rows before `LIMIT`, but after `LIMIT BY`. However, when using `LIMIT offset, size`, the rows before `offset` are included in `extremes`. In stream requests, the result may also include a small number of rows that passed through `LIMIT`. diff --git a/docs/ru/operations/settings/query_complexity.md b/docs/ru/operations/settings/query_complexity.md index 24286999685..4ebd9868ecc 100644 --- a/docs/ru/operations/settings/query_complexity.md +++ b/docs/ru/operations/settings/query_complexity.md @@ -65,7 +65,7 @@ Что делать, когда количество прочитанных данных превысило одно из ограничений: throw или break. По умолчанию: throw. -## max_rows_to_group_by +## max_rows_to_group_by {#settings-max_rows_to_group_by} Максимальное количество уникальных ключей, получаемых в процессе агрегации. Позволяет ограничить потребление оперативки при агрегации. @@ -74,6 +74,17 @@ Что делать, когда количество уникальных ключей при агрегации превысило ограничение: throw, break или any. По умолчанию: throw. Использование значения any позволяет выполнить GROUP BY приближённо. Качество такого приближённого вычисления сильно зависит от статистических свойств данных. +## max_bytes_before_external_group_by {#settings-max_bytes_before_external_group_by} + +Включает или отключает выполнение секций `GROUP BY` во внешней памяти. Смотрите [GROUP BY во внешней памяти](../../query_language/select.md#select-group-by-in-external-memory). + +Возможные значения: + +- Максимальный объем RAM (в байтах), который может использовать отдельная операция [GROUP BY](../../query_language/select.md#select-group-by-clause). +- 0 — `GROUP BY` во внешней памяти отключен. + +Значение по умолчанию — 0. + ## max_rows_to_sort Максимальное количество строк до сортировки. Позволяет ограничить потребление оперативки при сортировке. @@ -195,12 +206,63 @@ Что делать, когда количество данных превысило одно из ограничений: throw или break. По умолчанию: throw. +## max_rows_in_join {#settings-max_rows_in_join} + +Ограничивает количество строк в хэш-таблице, используемой при соединении таблиц. + +Параметр применяется к операциям [SELECT... JOIN](../../query_language/select.md#select-join) и к движку таблиц [Join](../table_engines/join.md). + +Если запрос содержит несколько `JOIN`, то ClickHouse проверяет значение настройки для каждого промежуточного результата. + +При достижении предела ClickHouse может выполнять различные действия. Используйте настройку [join_overflow_mode](#settings-join_overflow_mode) для выбора действия. + +Возможные значения: + +- Положительное целое число. +- 0 — неограниченное количество строк. + +Значение по умолчанию — 0. + +## max_bytes_in_join {#settings-max_bytes_in_join} + +Ограничивает размер (в байтах) хэш-таблицы, используемой при объединении таблиц. + +Параметр применяется к операциям [SELECT... JOIN](../../query_language/select.md#select-join) и к движку таблиц [Join](../table_engines/join.md). + +Если запрос содержит несколько `JOIN`, то ClickHouse проверяет значение настройки для каждого промежуточного результата. + +При достижении предела ClickHouse может выполнять различные действия. Используйте настройку [join_overflow_mode](#settings-join_overflow_mode) для выбора действия. + +Возможные значения: + +- Положительное целое число. +- 0 — контроль памяти отключен. + +Значение по умолчанию — 0. + +## join_overflow_mode {#settings-join_overflow_mode} + +Определяет, какое действие ClickHouse выполняет при достижении любого из следующих ограничений для `JOIN`: + +- [max_bytes_in_join](#settings-max_bytes_in_join) +- [max_rows_in_join](#settings-max_rows_in_join) + +Возможные значения: + +- `THROW` — ClickHouse генерирует исключение и прерывает операцию. +- `BREAK` — ClickHouse прерывает операцию, но не генерирует исключение. + +Значение по умолчанию — `THROW`. + +**Смотрите также** + +- [Секция JOIN](../../query_language/select.md#select-join) +- [Движо таблиц Join](../table_engines/join.md) + ## max_partitions_per_insert_block Ограничивает максимальное количество партиций в одном вставленном блоке. -Возможные значения: - - Положительное целое число. - 0 — неограниченное количество разделов. diff --git a/docs/ru/operations/settings/settings.md b/docs/ru/operations/settings/settings.md index 10bce087d93..25804d67322 100644 --- a/docs/ru/operations/settings/settings.md +++ b/docs/ru/operations/settings/settings.md @@ -281,6 +281,26 @@ Ok. - [Движок таблиц Join](../table_engines/join.md) - [join_default_strictness](#settings-join_default_strictness) +## join_any_take_last_row {#settings-join_any_take_last_row} + +Изменяет поведение операций, выполняемых со строгостью `ANY`. + +!!! note "Внимание" + Настройка работает только для движка таблиц [Join](../table_engines/join.md). + +Возможные значения: + +- 0 — если в правой таблице несколько соответствующих строк, то присоединяется только первая найденная. +- 1 — если в правой таблице несколько соответствующих строк, то присоединяется только последняя найденная строка. + +Значение по умолчанию — 0. + +**Смотрите также** + +- [Секция JOIN](../../query_language/select.md#select-join) +- [Движок таблиц Join](../table_engines/join.md) +- [join_default_strictness](#settings-join_default_strictness) + ## join_use_nulls {#settings-join_use_nulls} Устанавливает тип поведения [JOIN](../../query_language/select.md). При объединении таблиц могут появиться пустые ячейки. ClickHouse заполняет их по-разному в зависимости от настроек. @@ -695,6 +715,51 @@ load_balancing = first_or_random - [insert_quorum](#settings-insert_quorum) - [insert_quorum_timeout](#settings-insert_quorum_timeout) +## max_network_bytes {#settings-max_network_bytes} + +Ограничивает объем данных (в байтах), который принимается или передается по сети при выполнении запроса. Параметр применяется к каждому отдельному запросу. + +Возможные значения: + +- Положительное целое число. +- 0 — контроль объема данных отключен. + +Значение по умолчанию — 0. + +## max_network_bandwidth {#settings-max_network_bandwidth} + +Ограничивает скорость обмена данными по сети в байтах в секунду. Параметр применяется к каждому отдельному запросу. + +Возможные значения: + +- Положительное целое число. +- 0 — контроль скорости передачи данных отключен. + +Значение по умолчанию — 0. + +## max_network_bandwidth_for_user {#settings-max_network_bandwidth_for_user} + +Ограничивает скорость обмена данными по сети в байтах в секунду. Этот параметр применяется ко всем одновременно выполняемым запросам, запущенным одним пользователем. + +Возможные значения: + +- Положительное целое число. +- 0 — управление скоростью передачи данных отключено. + +Значение по умолчанию — 0. + +## max_network_bandwidth_for_all_users {#settings-max_network_bandwidth_for_all_users} + +Ограничивает скорость обмена данными по сети в байтах в секунду. Этот параметр применяется ко всем одновременно выполняемым запросам на сервере. + +Возможные значения: + +- Положительное целое число. +- 0 — управление скоростью передачи данных отключено. + +Значение по умолчанию — 0. + + ## allow_experimental_cross_to_join_conversion {#settings-allow_experimental_cross_to_join_conversion} Включает или отключает: diff --git a/docs/ru/query_language/select.md b/docs/ru/query_language/select.md index 0e5df9f8a69..d85d706a81c 100644 --- a/docs/ru/query_language/select.md +++ b/docs/ru/query_language/select.md @@ -649,6 +649,15 @@ LIMIT 10 Если `JOIN` необходим для соединения с таблицами измерений (dimension tables - сравнительно небольшие таблицы, которые содержат свойства измерений - например, имена для рекламных кампаний), то использование `JOIN` может быть не очень удобным из-за громоздкости синтаксиса, а также из-за того, что правая таблица читается заново при каждом запросе. Специально для таких случаев существует функциональность "Внешние словари", которую следует использовать вместо `JOIN`. Дополнительные сведения смотрите в разделе [Внешние словари](dicts/external_dicts.md). +**Ограничения по памяти** + +ClickHouse использует алгоритм [hash join](https://en.wikipedia.org/wiki/Hash_join). ClickHouse принимает `` и создает для него хэш-таблицу в RAM. Чтобы ограничить потребление памяти операцией `JOIN`, используйте следующие параметры: + +- [max_rows_in_join](../operations/settings/query_complexity.md#settings-max_rows_in_join) — ограничивает количество строк в хэш-таблице. +- [max_bytes_in_join](../operations/settings/query_complexity.md#settings-max_bytes_in_join) — ограничивает размер хэш-таблицы. + +По достижении любого из этих ограничений, ClickHouse действует в соответствии с настройкой [join_overflow_mode](../operations/settings/query_complexity.md#settings-join_overflow_mode). + #### Обработка пустых ячеек и NULL При слиянии таблиц могут появляться пустые ячейки. То, каким образом ClickHouse заполняет эти ячейки, определяется настройкой [join_use_nulls](../operations/settings/settings.md#settings-join_use_nulls). @@ -807,21 +816,20 @@ GROUP BY вычисляет для каждого встретившегося #### GROUP BY во внешней памяти {#select-group-by-in-external-memory} -Существует возможность включить сброс временных данных на диск для ограничения потребления оперативной памяти при GROUP BY. -Настройка `max_bytes_before_external_group_by` - потребление оперативки, при котором временные данные GROUP BY сбрасываются в файловую систему. Если равно 0 (по умолчанию) - значит выключено. +Можно включить сброс временных данных на диск, чтобы ограничить потребление оперативной памяти при выполнении `GROUP BY`. +Настройка [max_bytes_before_external_group_by](../operations/settings/settings.md#settings-max_bytes_before_external_group_by) определяет пороговое значение потребления RAM, по достижении которого временные данные `GROUP BY` сбрасываются в файловую систему. Если равно 0 (по умолчанию) - значит выключено. -При использовании `max_bytes_before_external_group_by` рекомендуется выставить max_memory_usage примерно в два раза больше. Это следует сделать, потому что агрегация выполняется в две стадии: чтение и формирование промежуточных данных (1) и слияние промежуточных данных (2). Сброс данных на файловую систему может производиться только на стадии 1. Если сброса временных данных не было, то на стадии 2 может потребляться до такого же объёма памяти, как на стадии 1. +При использовании `max_bytes_before_external_group_by`, рекомендуем выставить `max_memory_usage` приблизительно в два раза больше. Это следует сделать, потому что агрегация выполняется в две стадии: чтение и формирование промежуточных данных (1) и слияние промежуточных данных (2). Сброс данных на файловую систему может производиться только на стадии 1. Если сброса временных данных не было, то на стадии 2 может потребляться до такого же объёма памяти, как на стадии 1. -Например, если у вас `max_memory_usage` было выставлено в 10000000000, и вы хотите использовать внешнюю агрегацию, то имеет смысл выставить `max_bytes_before_external_group_by` в 10000000000, а max_memory_usage в 20000000000. При срабатывании внешней агрегации (если был хотя бы один сброс временных данных в файловую систему) максимальное потребление оперативки будет лишь чуть-чуть больше `max_bytes_before_external_group_by`. +Например, если [max_memory_usage](../operations/settings/settings.md#settings_max_memory_usage) было выставлено в 10000000000, и вы хотите использовать внешнюю агрегацию, то имеет смысл выставить `max_bytes_before_external_group_by` в 10000000000, а max_memory_usage в 20000000000. При срабатывании внешней агрегации (если был хотя бы один сброс временных данных в файловую систему) максимальное потребление оперативки будет лишь чуть-чуть больше `max_bytes_before_external_group_by`. При распределённой обработке запроса внешняя агрегация производится на удалённых серверах. Для того чтобы на сервере-инициаторе запроса использовалось немного оперативки, нужно выставить настройку `distributed_aggregation_memory_efficient` в 1. -При слиянии данных, сброшенных на диск, а также при слиянии результатов с удалённых серверов, при включенной настройке `distributed_aggregation_memory_efficient`, потребляется до 1/256 \* количество потоков от общего объёма оперативки. +При слиянии данных, сброшенных на диск, а также при слиянии результатов с удалённых серверов, при включенной настройке `distributed_aggregation_memory_efficient`, потребляется до `1/256 * the_number_of_threads` количество потоков от общего объёма оперативки. При включенной внешней агрегации, если данных было меньше `max_bytes_before_external_group_by` (то есть сброса данных не было), то запрос работает так же быстро, как без внешней агрегации. Если же какие-то временные данные были сброшены, то время выполнения будет в несколько раз больше (примерно в три раза). -Если после GROUP BY у вас есть ORDER BY с небольшим LIMIT, то на ORDER BY не будет тратиться существенного количества оперативки. -Но если есть ORDER BY без LIMIT, то не забудьте включить внешнюю сортировку (`max_bytes_before_external_sort`). +Если есть `ORDER BY` с `LIMIT` после `GROUP BY`, то объём потребляемой RAM будет зависеть от объёма данных в `LIMIT`, а не во всей таблице. Однако, если `ORDER BY` используется без `LIMIT`, не забудьте включить внешнюю сортировку (`max_bytes_before_external_sort`). ### Секция LIMIT BY @@ -1276,11 +1284,11 @@ SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID GLOBAL Вы можете получить в дополнение к результату также минимальные и максимальные значения по столбцам результата. Для этого выставите настройку **extremes** в 1. Минимумы и максимумы считаются для числовых типов, дат, дат-с-временем. Для остальных столбцов будут выведены значения по умолчанию. -Вычисляются дополнительные две строчки - минимумы и максимумы, соответственно. Эти дополнительные две строчки выводятся в форматах JSON\*, TabSeparated\*, Pretty\* отдельно от остальных строчек. В остальных форматах они не выводится. +Вычисляются дополнительные две строчки - минимумы и максимумы, соответственно. Эти две дополнительные строки выводятся в [форматах](../interfaces/formats.md) `JSON*`, `TabSeparated*`, и `Pretty*` отдельно от остальных строчек. В остальных форматах они не выводится. -В форматах JSON\* экстремальные значения выводятся отдельным полем extremes. В форматах TabSeparated\* строчка выводится после основного результата и после totals, если есть. Перед ней (после остальных данных) вставляется пустая строка. В форматах Pretty\* строчка выводится отдельной табличкой после основного результата и после totals, если есть. +Во форматах `JSON*`, экстремальные значения выводятся отдельным полем 'extremes'. В форматах `TabSeparated*`, строка выводится после основного результата и после 'totals' если есть. Перед ней (после остальных данных) вставляется пустая строка. В форматах `Pretty*`, строка выводится отдельной таблицей после основного результата и после `totals` если есть. -Экстремальные значения считаются по строчкам, прошедшим через LIMIT. Но при этом, при использовании LIMIT offset, size, строчки до offset учитываются в extremes. В потоковых запросах, в результате может учитываться также небольшое количество строчек, прошедших LIMIT. +Экстремальные значения вычисляются для строк перед `LIMIT`, но после `LIMIT BY`. Однако при использовании `LIMIT offset, size`, строки перед `offset` включаются в `extremes`. В потоковых запросах, в результате может учитываться также небольшое количество строчек, прошедших `LIMIT`. ### Замечания From 24fd416084e7b1c8a03caad849b687c2a03af7b1 Mon Sep 17 00:00:00 2001 From: chertus Date: Tue, 30 Jul 2019 14:41:11 +0300 Subject: [PATCH 0474/1165] remove unused ExpressionAnalyzer settings --- dbms/src/Interpreters/ExpressionAnalyzer.h | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.h b/dbms/src/Interpreters/ExpressionAnalyzer.h index 52c43dda90f..b36600b07d5 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.h +++ b/dbms/src/Interpreters/ExpressionAnalyzer.h @@ -82,35 +82,18 @@ private: /// Extracts settings to enlight which are used (and avoid copy of others). struct ExtractedSettings { - /// for QueryNormalizer - const UInt64 max_ast_depth; - const UInt64 max_expanded_ast_elements; - const String count_distinct_implementation; - - /// for PredicateExpressionsOptimizer - const bool enable_optimize_predicate_expression; - - /// for ExpressionAnalyzer - const bool asterisk_left_columns_only; const bool use_index_for_in_with_subqueries; const bool join_use_nulls; const SizeLimits size_limits_for_set; const SizeLimits size_limits_for_join; const String join_default_strictness; - const UInt64 min_equality_disjunction_chain_length; ExtractedSettings(const Settings & settings) - : max_ast_depth(settings.max_ast_depth), - max_expanded_ast_elements(settings.max_expanded_ast_elements), - count_distinct_implementation(settings.count_distinct_implementation), - enable_optimize_predicate_expression(settings.enable_optimize_predicate_expression), - asterisk_left_columns_only(settings.asterisk_left_columns_only), - use_index_for_in_with_subqueries(settings.use_index_for_in_with_subqueries), + : use_index_for_in_with_subqueries(settings.use_index_for_in_with_subqueries), join_use_nulls(settings.join_use_nulls), size_limits_for_set(settings.max_rows_in_set, settings.max_bytes_in_set, settings.set_overflow_mode), size_limits_for_join(settings.max_rows_in_join, settings.max_bytes_in_join, settings.join_overflow_mode), - join_default_strictness(settings.join_default_strictness.toString()), - min_equality_disjunction_chain_length(settings.optimize_min_equality_disjunction_chain_length) + join_default_strictness(settings.join_default_strictness.toString()) {} }; From 7945d055655ca041ab75cfcc35c8902738bc7a01 Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Tue, 30 Jul 2019 15:15:02 +0300 Subject: [PATCH 0475/1165] Minor style fixes --- dbms/src/Storages/StorageValues.cpp | 2 ++ dbms/src/Storages/StorageValues.h | 2 ++ dbms/src/TableFunctions/TableFunctionFactory.cpp | 3 +-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dbms/src/Storages/StorageValues.cpp b/dbms/src/Storages/StorageValues.cpp index b2058c93be7..257c6c34e4a 100644 --- a/dbms/src/Storages/StorageValues.cpp +++ b/dbms/src/Storages/StorageValues.cpp @@ -2,6 +2,7 @@ #include #include + namespace DB { @@ -23,4 +24,5 @@ BlockInputStreams StorageValues::read( return BlockInputStreams(1, std::make_shared(res_block)); } + } diff --git a/dbms/src/Storages/StorageValues.h b/dbms/src/Storages/StorageValues.h index 478aaa96e84..640a198d97b 100644 --- a/dbms/src/Storages/StorageValues.h +++ b/dbms/src/Storages/StorageValues.h @@ -3,6 +3,7 @@ #include #include + namespace DB { @@ -29,4 +30,5 @@ private: protected: StorageValues(const std::string & database_name_, const std::string & table_name_, const Block & res_block_); }; + } diff --git a/dbms/src/TableFunctions/TableFunctionFactory.cpp b/dbms/src/TableFunctions/TableFunctionFactory.cpp index c389180fd7e..7ad98599f76 100644 --- a/dbms/src/TableFunctions/TableFunctionFactory.cpp +++ b/dbms/src/TableFunctions/TableFunctionFactory.cpp @@ -1,11 +1,10 @@ #include #include - #include - #include + namespace DB { From 97e4219552f68a98239c41672cc4650876f9c490 Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Tue, 30 Jul 2019 15:32:08 +0300 Subject: [PATCH 0476/1165] Add link to Mountain View meetup --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9a240170627..2d46d24bef1 100644 --- a/README.md +++ b/README.md @@ -13,5 +13,6 @@ ClickHouse is an open-source column-oriented database management system that all * You can also [fill this form](https://forms.yandex.com/surveys/meet-yandex-clickhouse-team/) to meet Yandex ClickHouse team in person. ## Upcoming Events +* [ClickHouse Meetup in Mountain View](https://www.eventbrite.com/e/meetup-clickhouse-in-the-south-bay-registration-65935505873) on August 13. * [ClickHouse Meetup in Shenzhen](https://www.huodongxing.com/event/3483759917300) on October 20. * [ClickHouse Meetup in Shanghai](https://www.huodongxing.com/event/4483760336000) on October 27. From bccc7ae9bb200526229fd1780af884379b3e3af9 Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Tue, 30 Jul 2019 15:34:35 +0300 Subject: [PATCH 0477/1165] Add link to Mountain View meetup (#6218) --- website/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/index.html b/website/index.html index 3b25c65fcdf..169e1752d44 100644 --- a/website/index.html +++ b/website/index.html @@ -94,7 +94,7 @@
    - Upcoming Meetups: Shenzhen on October 20 and Shanghai on October 27 + Upcoming Meetups: Mountain View on August 13, Shenzhen on October 20 and Shanghai on October 27
    From 4af44af3b76c575101ef1f1d2824e4be78c0b7c4 Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Tue, 30 Jul 2019 15:20:54 +0300 Subject: [PATCH 0478/1165] test for priamry index with lowCardinality --- ...4_primary_key_for_lowCardinality.reference | 2 + .../00974_primary_key_for_lowCardinality.sh | 38 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00974_primary_key_for_lowCardinality.reference create mode 100755 dbms/tests/queries/0_stateless/00974_primary_key_for_lowCardinality.sh diff --git a/dbms/tests/queries/0_stateless/00974_primary_key_for_lowCardinality.reference b/dbms/tests/queries/0_stateless/00974_primary_key_for_lowCardinality.reference new file mode 100644 index 00000000000..33891b98730 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_primary_key_for_lowCardinality.reference @@ -0,0 +1,2 @@ + "rows_read": 16384, + "rows_read": 16384, diff --git a/dbms/tests/queries/0_stateless/00974_primary_key_for_lowCardinality.sh b/dbms/tests/queries/0_stateless/00974_primary_key_for_lowCardinality.sh new file mode 100755 index 00000000000..cea48890320 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00974_primary_key_for_lowCardinality.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +. $CURDIR/../shell_config.sh + +$CLICKHOUSE_CLIENT --query="DROP TABLE IF EXISTS lowString;" +$CLICKHOUSE_CLIENT --query="DROP TABLE IF EXISTS string;" + +$CLICKHOUSE_CLIENT -n --query=" +create table lowString +( +a LowCardinality(String), +b Date +) +ENGINE = MergeTree() +PARTITION BY toYYYYMM(b) +ORDER BY (a)" + +$CLICKHOUSE_CLIENT -n --query=" +create table string +( +a String, +b Date +) +ENGINE = MergeTree() +PARTITION BY toYYYYMM(b) +ORDER BY (a)" + +$CLICKHOUSE_CLIENT --query="insert into lowString (a, b) select top 100000 toString(number), today() from system.numbers" + +$CLICKHOUSE_CLIENT --query="insert into string (a, b) select top 100000 toString(number), today() from system.numbers" + +$CLICKHOUSE_CLIENT --query="select count() from lowString where a in ('1', '2') FORMAT JSON" | grep "rows_read" + +$CLICKHOUSE_CLIENT --query="select count() from string where a in ('1', '2') FORMAT JSON" | grep "rows_read" + +$CLICKHOUSE_CLIENT --query="DROP TABLE lowString;" +$CLICKHOUSE_CLIENT --query="DROP TABLE string;" From e06b3b17b33f670b6c8a3d66f6f8a6429bdea01d Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Tue, 30 Jul 2019 17:04:18 +0300 Subject: [PATCH 0479/1165] some changes to log all text logs --- dbms/programs/server/Server.cpp | 15 +++++ dbms/programs/server/Server.h | 1 + dbms/src/Interpreters/Context.cpp | 12 ---- dbms/src/Interpreters/Context.h | 1 - dbms/src/Interpreters/SystemLog.cpp | 4 -- dbms/src/Interpreters/SystemLog.h | 6 +- libs/libcommon/include/common/logger_useful.h | 3 +- libs/libloggers/loggers/Loggers.cpp | 14 ++++- libs/libloggers/loggers/Loggers.h | 7 +++ libs/libloggers/loggers/OwnSplitChannel.cpp | 58 ++++++++++--------- libs/libloggers/loggers/OwnSplitChannel.h | 7 +++ 11 files changed, 79 insertions(+), 49 deletions(-) diff --git a/dbms/programs/server/Server.cpp b/dbms/programs/server/Server.cpp index 58f15f878b4..eac295fd660 100644 --- a/dbms/programs/server/Server.cpp +++ b/dbms/programs/server/Server.cpp @@ -52,6 +52,10 @@ #include "Common/config_version.h" #include "MySQLHandlerFactory.h" +#include +#include +#include + #if defined(__linux__) #include #include @@ -167,6 +171,8 @@ void Server::defineOptions(Poco::Util::OptionSet & _options) BaseDaemon::defineOptions(_options); } + + int Server::main(const std::vector & /*args*/) { Logger * log = &logger(); @@ -174,6 +180,7 @@ int Server::main(const std::vector & /*args*/) ThreadStatus thread_status; + registerFunctions(); registerAggregateFunctions(); registerTableFunctions(); @@ -269,12 +276,15 @@ int Server::main(const std::vector & /*args*/) * table engines could use Context on destroy. */ LOG_INFO(log, "Shutting down storages."); + if (text_log) + text_log->shutdown(); global_context->shutdown(); LOG_DEBUG(log, "Shutted down storages."); /** Explicitly destroy Context. It is more convenient than in destructor of Server, because logger is still available. * At this moment, no one could own shared part of Context. */ + text_log.reset(); global_context.reset(); LOG_DEBUG(log, "Destroyed global context."); @@ -397,6 +407,9 @@ int Server::main(const std::vector & /*args*/) if (config().has("macros")) global_context->setMacros(std::make_unique(config(), "macros")); + /// Create text_log instance + text_log = createSystemLog(*global_context, "system", "text_log", global_context->getConfigRef(), "text_log"); + /// Initialize main config reloader. std::string include_from_path = config().getString("include_from", "/etc/metrika.xml"); auto main_config_reloader = std::make_unique(config_path, @@ -406,6 +419,7 @@ int Server::main(const std::vector & /*args*/) main_config_zk_changed_event, [&](ConfigurationPtr config) { + setTextLog(text_log); buildLoggers(*config, logger()); global_context->setClustersConfig(config); global_context->setMacros(std::make_unique(*config, "macros")); @@ -491,6 +505,7 @@ int Server::main(const std::vector & /*args*/) format_schema_path.createDirectories(); LOG_INFO(log, "Loading metadata from " + path); + try { loadMetadataSystem(*global_context); diff --git a/dbms/programs/server/Server.h b/dbms/programs/server/Server.h index 337d1551b70..5fc5f16b550 100644 --- a/dbms/programs/server/Server.h +++ b/dbms/programs/server/Server.h @@ -57,6 +57,7 @@ protected: private: std::unique_ptr global_context; + std::shared_ptr text_log; }; } diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index 6ae6bcb6d5b..dd3e5ef578a 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -1692,18 +1692,6 @@ std::shared_ptr Context::getPartLog(const String & part_database) return shared->system_logs->part_log; } - -std::shared_ptr Context::getTextLog() -{ - auto lock = getLock(); - - if (!shared->system_logs || !shared->system_logs->text_log) - return {}; - - return shared->system_logs->text_log; -} - - std::shared_ptr Context::getTraceLog() { auto lock = getLock(); diff --git a/dbms/src/Interpreters/Context.h b/dbms/src/Interpreters/Context.h index 2c5e0511efa..31229a26a75 100644 --- a/dbms/src/Interpreters/Context.h +++ b/dbms/src/Interpreters/Context.h @@ -428,7 +428,6 @@ public: /// Nullptr if the query log is not ready for this moment. std::shared_ptr getQueryLog(); std::shared_ptr getQueryThreadLog(); - std::shared_ptr getTextLog(); std::shared_ptr getTraceLog(); /// Returns an object used to log opertaions with parts if it possible. diff --git a/dbms/src/Interpreters/SystemLog.cpp b/dbms/src/Interpreters/SystemLog.cpp index 8439c3d3184..4b456bc2542 100644 --- a/dbms/src/Interpreters/SystemLog.cpp +++ b/dbms/src/Interpreters/SystemLog.cpp @@ -46,7 +46,6 @@ SystemLogs::SystemLogs(Context & global_context, const Poco::Util::AbstractConfi query_log = createSystemLog(global_context, "system", "query_log", config, "query_log"); query_thread_log = createSystemLog(global_context, "system", "query_thread_log", config, "query_thread_log"); part_log = createSystemLog(global_context, "system", "part_log", config, "part_log"); - text_log = createSystemLog(global_context, "system", "text_log", config, "text_log"); trace_log = createSystemLog(global_context, "system", "trace_log", config, "trace_log"); part_log_database = config.getString("part_log.database", "system"); @@ -58,7 +57,6 @@ SystemLogs::~SystemLogs() shutdown(); } - void SystemLogs::shutdown() { if (query_log) @@ -67,8 +65,6 @@ void SystemLogs::shutdown() query_thread_log->shutdown(); if (part_log) part_log->shutdown(); - if (text_log) - text_log->shutdown(); if (trace_log) trace_log->shutdown(); } diff --git a/dbms/src/Interpreters/SystemLog.h b/dbms/src/Interpreters/SystemLog.h index ae378160574..026cac4495f 100644 --- a/dbms/src/Interpreters/SystemLog.h +++ b/dbms/src/Interpreters/SystemLog.h @@ -62,7 +62,6 @@ class PartLog; class TextLog; class TraceLog; - /// System logs should be destroyed in destructor of the last Context and before tables, /// because SystemLog destruction makes insert query while flushing data into underlying tables struct SystemLogs @@ -75,7 +74,6 @@ struct SystemLogs std::shared_ptr query_log; /// Used to log queries. std::shared_ptr query_thread_log; /// Used to log query threads. std::shared_ptr part_log; /// Used to log operations with parts - std::shared_ptr text_log; /// Used to save all text logs. std::shared_ptr trace_log; /// Used to log traces from query profiler String part_log_database; @@ -309,6 +307,8 @@ void SystemLog::threadFunction() } + + template void SystemLog::flushImpl(EntryType reason) { @@ -442,3 +442,5 @@ void SystemLog::prepareTable() } } + + diff --git a/libs/libcommon/include/common/logger_useful.h b/libs/libcommon/include/common/logger_useful.h index c1c39047540..53c83f127af 100644 --- a/libs/libcommon/include/common/logger_useful.h +++ b/libs/libcommon/include/common/logger_useful.h @@ -28,7 +28,8 @@ using DB::CurrentThread; std::stringstream oss_internal_rare; \ oss_internal_rare << message; \ if (auto channel = (logger)->getChannel()) { \ - channel->log(Message((logger)->name(), oss_internal_rare.str(), (PRIORITY))); \ + channel->log(Message((logger)->name(), oss_internal_rare.str(), \ + (PRIORITY), __FILE__, __LINE__)); \ } \ } \ } while (false) diff --git a/libs/libloggers/loggers/Loggers.cpp b/libs/libloggers/loggers/Loggers.cpp index bc53cff27aa..d7b46d9a195 100644 --- a/libs/libloggers/loggers/Loggers.cpp +++ b/libs/libloggers/loggers/Loggers.cpp @@ -5,13 +5,13 @@ #include #include "OwnFormattingChannel.h" #include "OwnPatternFormatter.h" -#include "OwnSplitChannel.h" #include #include #include #include #include + // TODO: move to libcommon static std::string createDirectory(const std::string & file) { @@ -22,18 +22,26 @@ static std::string createDirectory(const std::string & file) return path.toString(); }; +void Loggers::setTextLog(std::shared_ptr log) { + text_log = log; +} + void Loggers::buildLoggers(Poco::Util::AbstractConfiguration & config, Poco::Logger & logger /*_root*/, const std::string & cmd_name) { + if (split && !text_log.expired()) { + split->addTextLog(text_log); + } auto current_logger = config.getString("logger", ""); - if (config_logger == current_logger) + if (config_logger == current_logger) { return; + } config_logger = current_logger; bool is_daemon = config.getBool("application.runAsDaemon", false); /// Split logs to ordinary log, error log, syslog and console. /// Use extended interface of Channel for more comprehensive logging. - Poco::AutoPtr split = new DB::OwnSplitChannel; + split = new DB::OwnSplitChannel(); auto log_level = config.getString("logger.level", "trace"); const auto log_path = config.getString("logger.log", ""); diff --git a/libs/libloggers/loggers/Loggers.h b/libs/libloggers/loggers/Loggers.h index 7b3c0860273..4cc3df3757a 100644 --- a/libs/libloggers/loggers/Loggers.h +++ b/libs/libloggers/loggers/Loggers.h @@ -3,6 +3,8 @@ #include #include #include +#include +#include "OwnSplitChannel.h" namespace Poco::Util { @@ -23,6 +25,8 @@ public: return layer; /// layer setted in inheritor class BaseDaemonApplication. } + void setTextLog(std::shared_ptr log); + protected: std::optional layer; @@ -33,4 +37,7 @@ private: Poco::AutoPtr syslog_channel; /// Previous value of logger element in config. It is used to reinitialize loggers whenever the value changed. std::string config_logger; + + std::weak_ptr text_log; + Poco::AutoPtr split; }; diff --git a/libs/libloggers/loggers/OwnSplitChannel.cpp b/libs/libloggers/loggers/OwnSplitChannel.cpp index a11d6b428d3..b6bbc74ef4a 100644 --- a/libs/libloggers/loggers/OwnSplitChannel.cpp +++ b/libs/libloggers/loggers/OwnSplitChannel.cpp @@ -49,34 +49,36 @@ void OwnSplitChannel::log(const Poco::Message & msg) logs_queue->emplace(std::move(columns)); } - /// Also log to system.internal_text_log table - ThreadGroupStatusPtr thread_group = CurrentThread::getGroup(); - if (thread_group && thread_group->global_context) + + /// Also log to system.text_log table + TextLogElement elem; + + elem.event_time = msg_ext.time_seconds; + elem.microseconds = msg_ext.time_microseconds; + + elem.thread_name = getThreadName(); + elem.thread_number = msg_ext.thread_number; + try { - if (auto text_log = thread_group->global_context->getTextLog()) - { - TextLogElement elem; - - elem.event_time = msg_ext.time_seconds; - elem.microseconds = msg_ext.time_microseconds; - - elem.thread_name = getThreadName(); - elem.thread_number = msg_ext.thread_number; - elem.os_thread_id = CurrentThread::get().os_thread_id; - - elem.query_id = msg_ext.query_id; - - elem.message = msg.getText(); - elem.logger_name = msg.getSource(); - elem.level = msg.getPriority(); - - if (msg.getSourceFile() != nullptr) - elem.source_file = msg.getSourceFile(); - elem.source_line = msg.getSourceLine(); - - text_log->add(elem); - } + elem.os_thread_id = CurrentThread::get().os_thread_id; + } catch (...) + { + elem.os_thread_id = 0; } + + elem.query_id = msg_ext.query_id; + + elem.message = msg.getText(); + elem.logger_name = msg.getSource(); + elem.level = msg.getPriority(); + + if (msg.getSourceFile() != nullptr) + elem.source_file = msg.getSourceFile(); + + elem.source_line = msg.getSourceLine(); + + if (auto log = text_log.lock()) + log->add(elem); } void OwnSplitChannel::addChannel(Poco::AutoPtr channel) @@ -84,5 +86,9 @@ void OwnSplitChannel::addChannel(Poco::AutoPtr channel) channels.emplace_back(std::move(channel), dynamic_cast(channel.get())); } +void OwnSplitChannel::addTextLog(std::weak_ptr log) +{ + text_log = log; +} } diff --git a/libs/libloggers/loggers/OwnSplitChannel.h b/libs/libloggers/loggers/OwnSplitChannel.h index 3579218f75c..52675fed317 100644 --- a/libs/libloggers/loggers/OwnSplitChannel.h +++ b/libs/libloggers/loggers/OwnSplitChannel.h @@ -3,6 +3,7 @@ #include #include #include "ExtendedLogChannel.h" +#include namespace DB @@ -13,17 +14,23 @@ namespace DB class OwnSplitChannel : public Poco::Channel { public: + OwnSplitChannel() = default; + /// Makes an extended message from msg and passes it to the client logs queue and child (if possible) void log(const Poco::Message & msg) override; /// Adds a child channel void addChannel(Poco::AutoPtr channel); + void addTextLog(std::weak_ptr log); + private: using ChannelPtr = Poco::AutoPtr; /// Handler and its pointer casted to extended interface using ExtendedChannelPtrPair = std::pair; std::vector channels; + + std::weak_ptr text_log; }; } From d4da486b51f5e4a672fd8d01fd55d927643285bf Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Tue, 30 Jul 2019 17:55:59 +0300 Subject: [PATCH 0480/1165] Update CSVRowInputFormat. --- .../Formats/Impl/CSVRowInputFormat.cpp | 321 +++++++++++++----- .../Formats/Impl/CSVRowInputFormat.h | 20 +- 2 files changed, 262 insertions(+), 79 deletions(-) diff --git a/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp b/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp index 3038c9e02f6..6dc7493187b 100644 --- a/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp @@ -18,16 +18,55 @@ namespace ErrorCodes CSVRowInputFormat::CSVRowInputFormat( ReadBuffer & in_, Block header, Params params, bool with_names_, const FormatSettings & format_settings) - : IRowInputFormat(std::move(header), in_, params), with_names(with_names_), format_settings(format_settings) + : IRowInputFormat(std::move(header), in_, std::move(params)) + , with_names(with_names_) + , format_settings(format_settings) { auto & sample = getPort().getHeader(); size_t num_columns = sample.columns(); + data_types.resize(num_columns); + column_indexes_by_names.reserve(num_columns); + for (size_t i = 0; i < num_columns; ++i) - data_types[i] = sample.safeGetByPosition(i).type; + { + const auto & column_info = sample.getByPosition(i); + + data_types[i] = column_info.type; + column_indexes_by_names.emplace(column_info.name, i); + } } +/// Map an input file column to a table column, based on its name. +void CSVRowInputFormat::addInputColumn(const String & column_name) +{ + const auto column_it = column_indexes_by_names.find(column_name); + if (column_it == column_indexes_by_names.end()) + { + if (format_settings.skip_unknown_fields) + { + column_indexes_for_input_fields.push_back(std::nullopt); + return; + } + + throw Exception( + "Unknown field found in CSV header: '" + column_name + "' " + + "at position " + std::to_string(column_indexes_for_input_fields.size()) + + "\nSet the 'input_format_skip_unknown_fields' parameter explicitly to ignore and proceed", + ErrorCodes::INCORRECT_DATA + ); + } + + const auto column_index = column_it->second; + + if (read_columns[column_index]) + throw Exception("Duplicate field found while parsing CSV header: " + column_name, ErrorCodes::INCORRECT_DATA); + + read_columns[column_index] = true; + column_indexes_for_input_fields.emplace_back(column_index); +} + static void skipEndOfLine(ReadBuffer & istr) { /// \n (Unix) or \r\n (DOS/Windows) or \n\r (Mac OS Classic) @@ -108,26 +147,119 @@ void CSVRowInputFormat::readPrefix() String tmp; if (with_names) - skipRow(in, format_settings.csv, num_columns); + { + /// This CSV file has a header row with column names. Depending on the + /// settings, use it or skip it. + if (format_settings.with_names_use_header) + { + /// Look at the file header to see which columns we have there. + /// The missing columns are filled with defaults. + read_columns.assign(getPort().getHeader().columns(), false); + do + { + String column_name; + skipWhitespacesAndTabs(in); + readCSVString(column_name, in, format_settings.csv); + skipWhitespacesAndTabs(in); + + addInputColumn(column_name); + } + while (checkChar(format_settings.csv.delimiter, in)); + + skipDelimiter(in, format_settings.csv.delimiter, true); + + for (auto read_column : read_columns) + { + if (read_column) + { + have_always_default_columns = true; + break; + } + } + + return; + } + else + skipRow(in, format_settings.csv, num_columns); + } } -bool CSVRowInputFormat::readRow(MutableColumns & columns, RowReadExtension &) +bool CSVRowInputFormat::readRow(MutableColumns & columns, RowReadExtension & ext) { if (in.eof()) return false; updateDiagnosticInfo(); - size_t size = data_types.size(); + /// Track whether we have to fill any columns in this row with default + /// values. If not, we return an empty column mask to the caller, so that + /// it doesn't have to check it. + bool have_default_columns = have_always_default_columns; - for (size_t i = 0; i < size; ++i) + const auto delimiter = format_settings.csv.delimiter; + for (size_t file_column = 0; file_column < column_indexes_for_input_fields.size(); ++file_column) { - skipWhitespacesAndTabs(in); - data_types[i]->deserializeAsTextCSV(*columns[i], in, format_settings); - skipWhitespacesAndTabs(in); + const auto & table_column = column_indexes_for_input_fields[file_column]; + const bool is_last_file_column = + file_column + 1 == column_indexes_for_input_fields.size(); - skipDelimiter(in, format_settings.csv.delimiter, i + 1 == size); + if (table_column) + { + const auto & type = data_types[*table_column]; + const bool at_delimiter = *in.position() == delimiter; + const bool at_last_column_line_end = is_last_file_column + && (*in.position() == '\n' || *in.position() == '\r' + || in.eof()); + + if (format_settings.csv.empty_as_default + && (at_delimiter || at_last_column_line_end)) + { + /// Treat empty unquoted column value as default value, if + /// specified in the settings. Tuple columns might seem + /// problematic, because they are never quoted but still contain + /// commas, which might be also used as delimiters. However, + /// they do not contain empty unquoted fields, so this check + /// works for tuples as well. + read_columns[*table_column] = false; + have_default_columns = true; + } + else + { + /// Read the column normally. + read_columns[*table_column] = true; + skipWhitespacesAndTabs(in); + type->deserializeAsTextCSV(*columns[*table_column], in, + format_settings); + skipWhitespacesAndTabs(in); + } + } + else + { + /// We never read this column from the file, just skip it. + String tmp; + readCSVString(tmp, in, format_settings.csv); + } + + skipDelimiter(in, delimiter, is_last_file_column); + } + + if (have_default_columns) + { + for (size_t i = 0; i < read_columns.size(); i++) + { + if (!read_columns[i]) + { + /// The column value for this row is going to be overwritten + /// with default by the caller, but the general assumption is + /// that the column size increases for each row, so we have + /// to insert something. Since we do not care about the exact + /// value, we do not have to use the default value specified by + /// the data type, and can just use IColumn::insertDefault(). + columns[i]->insertDefault(); + } + } + ext.read_columns = read_columns; } return true; @@ -190,93 +322,126 @@ String CSVRowInputFormat::getDiagnosticInfo() return out.str(); } - -bool CSVRowInputFormat::parseRowAndPrintDiagnosticInfo(MutableColumns & columns, +/** gcc-7 generates wrong code with optimization level greater than 1. + * See tests: dbms/src/IO/tests/write_int.cpp + * and dbms/tests/queries/0_stateless/00898_parsing_bad_diagnostic_message.sh + * This is compiler bug. The bug does not present in gcc-8 and clang-8. + * Nevertheless, we don't need high optimization of this function. + */ +bool OPTIMIZE(1) CSVRowInputFormat::parseRowAndPrintDiagnosticInfo(MutableColumns & columns, WriteBuffer & out, size_t max_length_of_column_name, size_t max_length_of_data_type_name) { const char delimiter = format_settings.csv.delimiter; - auto & header = getPort().getHeader(); - size_t size = data_types.size(); - for (size_t i = 0; i < size; ++i) + for (size_t file_column = 0; file_column < column_indexes_for_input_fields.size(); ++file_column) { - if (i == 0 && in.eof()) + if (file_column == 0 && in.eof()) { out << "\n"; return false; } - out << "Column " << i << ", " << std::string((i < 10 ? 2 : i < 100 ? 1 : 0), ' ') - << "name: " << header.safeGetByPosition(i).name << ", " << std::string(max_length_of_column_name - header.safeGetByPosition(i).name.size(), ' ') - << "type: " << data_types[i]->getName() << ", " << std::string(max_length_of_data_type_name - data_types[i]->getName().size(), ' '); - - BufferBase::Position prev_position = in.position(); - BufferBase::Position curr_position = in.position(); - std::exception_ptr exception; - - try + if (column_indexes_for_input_fields[file_column].has_value()) { - skipWhitespacesAndTabs(in); - prev_position = in.position(); - data_types[i]->deserializeAsTextCSV(*columns[i], in, format_settings); - curr_position = in.position(); - skipWhitespacesAndTabs(in); - } - catch (...) - { - exception = std::current_exception(); - } + const auto & table_column = *column_indexes_for_input_fields[file_column]; + const auto & current_column_type = data_types[table_column]; + const bool is_last_file_column = + file_column + 1 == column_indexes_for_input_fields.size(); + const bool at_delimiter = *in.position() == delimiter; + const bool at_last_column_line_end = is_last_file_column + && (*in.position() == '\n' || *in.position() == '\r' + || in.eof()); - if (curr_position < prev_position) - throw Exception("Logical error: parsing is non-deterministic.", ErrorCodes::LOGICAL_ERROR); + auto & header = getPort().getHeader(); + out << "Column " << file_column << ", " << std::string((file_column < 10 ? 2 : file_column < 100 ? 1 : 0), ' ') + << "name: " << header.safeGetByPosition(table_column).name << ", " << std::string(max_length_of_column_name - header.safeGetByPosition(table_column).name.size(), ' ') + << "type: " << current_column_type->getName() << ", " << std::string(max_length_of_data_type_name - current_column_type->getName().size(), ' '); - if (isNumber(data_types[i]) || isDateOrDateTime(data_types[i])) - { - /// An empty string instead of a value. - if (curr_position == prev_position) + if (format_settings.csv.empty_as_default + && (at_delimiter || at_last_column_line_end)) { - out << "ERROR: text "; - verbosePrintString(prev_position, std::min(prev_position + 10, in.buffer().end()), out); - out << " is not like " << data_types[i]->getName() << "\n"; - return false; + columns[table_column]->insertDefault(); } - } - - out << "parsed text: "; - verbosePrintString(prev_position, curr_position, out); - - if (exception) - { - if (data_types[i]->getName() == "DateTime") - out << "ERROR: DateTime must be in YYYY-MM-DD hh:mm:ss or NNNNNNNNNN (unix timestamp, exactly 10 digits) format.\n"; - else if (data_types[i]->getName() == "Date") - out << "ERROR: Date must be in YYYY-MM-DD format.\n"; else - out << "ERROR\n"; - return false; - } - - out << "\n"; - - if (data_types[i]->haveMaximumSizeOfValue()) - { - if (*curr_position != '\n' && *curr_position != '\r' && *curr_position != delimiter) { - out << "ERROR: garbage after " << data_types[i]->getName() << ": "; - verbosePrintString(curr_position, std::min(curr_position + 10, in.buffer().end()), out); + BufferBase::Position prev_position = in.position(); + BufferBase::Position curr_position = in.position(); + std::exception_ptr exception; + + try + { + skipWhitespacesAndTabs(in); + prev_position = in.position(); + current_column_type->deserializeAsTextCSV(*columns[table_column], in, format_settings); + curr_position = in.position(); + skipWhitespacesAndTabs(in); + } + catch (...) + { + exception = std::current_exception(); + } + + if (curr_position < prev_position) + throw Exception("Logical error: parsing is non-deterministic.", ErrorCodes::LOGICAL_ERROR); + + if (isNativeNumber(current_column_type) || isDateOrDateTime(current_column_type)) + { + /// An empty string instead of a value. + if (curr_position == prev_position) + { + out << "ERROR: text "; + verbosePrintString(prev_position, std::min(prev_position + 10, in.buffer().end()), out); + out << " is not like " << current_column_type->getName() << "\n"; + return false; + } + } + + out << "parsed text: "; + verbosePrintString(prev_position, curr_position, out); + + if (exception) + { + if (current_column_type->getName() == "DateTime") + out << "ERROR: DateTime must be in YYYY-MM-DD hh:mm:ss or NNNNNNNNNN (unix timestamp, exactly 10 digits) format.\n"; + else if (current_column_type->getName() == "Date") + out << "ERROR: Date must be in YYYY-MM-DD format.\n"; + else + out << "ERROR\n"; + return false; + } + out << "\n"; - if (data_types[i]->getName() == "DateTime") - out << "ERROR: DateTime must be in YYYY-MM-DD hh:mm:ss or NNNNNNNNNN (unix timestamp, exactly 10 digits) format.\n"; - else if (data_types[i]->getName() == "Date") - out << "ERROR: Date must be in YYYY-MM-DD format.\n"; + if (current_column_type->haveMaximumSizeOfValue() + && *curr_position != '\n' && *curr_position != '\r' + && *curr_position != delimiter) + { + out << "ERROR: garbage after " << current_column_type->getName() << ": "; + verbosePrintString(curr_position, std::min(curr_position + 10, in.buffer().end()), out); + out << "\n"; - return false; + if (current_column_type->getName() == "DateTime") + out << "ERROR: DateTime must be in YYYY-MM-DD hh:mm:ss or NNNNNNNNNN (unix timestamp, exactly 10 digits) format.\n"; + else if (current_column_type->getName() == "Date") + out << "ERROR: Date must be in YYYY-MM-DD format.\n"; + + return false; + } } } + else + { + static const String skipped_column_str = ""; + out << "Column " << file_column << ", " << std::string((file_column < 10 ? 2 : file_column < 100 ? 1 : 0), ' ') + << "name: " << skipped_column_str << ", " << std::string(max_length_of_column_name - skipped_column_str.length(), ' ') + << "type: " << skipped_column_str << ", " << std::string(max_length_of_data_type_name - skipped_column_str.length(), ' '); + + String tmp; + readCSVString(tmp, in, format_settings.csv); + } /// Delimiters - if (i + 1 == size) + if (file_column + 1 == column_indexes_for_input_fields.size()) { if (in.eof()) return false; @@ -294,8 +459,8 @@ bool CSVRowInputFormat::parseRowAndPrintDiagnosticInfo(MutableColumns & columns, out << "ERROR: There is no line feed. "; verbosePrintString(in.position(), in.position() + 1, out); out << " found instead.\n" - " It's like your file has more columns than expected.\n" - "And if your file have right number of columns, maybe it have unquoted string value with comma.\n"; + " It's like your file has more columns than expected.\n" + "And if your file have right number of columns, maybe it have unquoted string value with comma.\n"; return false; } @@ -313,8 +478,8 @@ bool CSVRowInputFormat::parseRowAndPrintDiagnosticInfo(MutableColumns & columns, if (*in.position() == '\n' || *in.position() == '\r') { out << "ERROR: Line feed found where delimiter (" << delimiter << ") is expected." - " It's like your file has less columns than expected.\n" - "And if your file have right number of columns, maybe it have unescaped quotes in values.\n"; + " It's like your file has less columns than expected.\n" + "And if your file have right number of columns, maybe it have unescaped quotes in values.\n"; } else { @@ -359,7 +524,7 @@ void registerInputFormatProcessorCSV(FormatFactory & factory) IRowInputFormat::Params params, const FormatSettings & settings) { - return std::make_shared(buf, sample, params, with_names, settings); + return std::make_shared(buf, sample, std::move(params), with_names, settings); }); } } diff --git a/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.h b/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.h index db7041bc90a..b7e29157e0f 100644 --- a/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.h +++ b/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.h @@ -36,8 +36,26 @@ private: const FormatSettings format_settings; - /// For convenient diagnostics in case of an error. + using IndexesMap = std::unordered_map; + IndexesMap column_indexes_by_names; + /// Maps indexes of columns in the input file to indexes of table columns + using OptionalIndexes = std::vector>; + OptionalIndexes column_indexes_for_input_fields; + + /// Tracks which colums we have read in a single read() call. + /// For columns that are never read, it is initialized to false when we + /// read the file header, and never changed afterwards. + /// For other columns, it is updated on each read() call. + std::vector read_columns; + + /// Whether we have any columns that are not read from file at all, + /// and must be always initialized with defaults. + bool have_always_default_columns = false; + + void addInputColumn(const String & column_name); + + /// For convenient diagnostics in case of an error. size_t row_num = 0; /// How many bytes were read, not counting those that are still in the buffer. From c0118bda75fcca38bb6d03b7b09af8342e3c4dd0 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 30 Jul 2019 18:19:57 +0300 Subject: [PATCH 0481/1165] Fixed test --- dbms/tests/queries/0_stateless/00974_query_profiler.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00974_query_profiler.sql b/dbms/tests/queries/0_stateless/00974_query_profiler.sql index b3d70bc6ac3..da88e904f36 100644 --- a/dbms/tests/queries/0_stateless/00974_query_profiler.sql +++ b/dbms/tests/queries/0_stateless/00974_query_profiler.sql @@ -3,7 +3,7 @@ SET log_queries = 1; SELECT sleep(0.5), ignore('test real time query profiler'); SET log_queries = 0; SYSTEM FLUSH LOGS; -WITH symbolizeAddress(arrayJoin(trace)) AS symbol SELECT count() > 0 FROM system.trace_log t WHERE event_date >= yesterday() AND query_id = (SELECT query_id FROM system.query_log WHERE event_date >= yesterday() AND query LIKE '%test real time query profiler%' ORDER BY event_time DESC LIMIT 1) AND symbol LIKE '%FunctionSleep%'; +WITH addressToSymbol(arrayJoin(trace)) AS symbol SELECT count() > 0 FROM system.trace_log t WHERE event_date >= yesterday() AND query_id = (SELECT query_id FROM system.query_log WHERE event_date >= yesterday() AND query LIKE '%test real time query profiler%' ORDER BY event_time DESC LIMIT 1) AND symbol LIKE '%FunctionSleep%'; SET query_profiler_real_time_period_ns = 0; SET query_profiler_cpu_time_period_ns = 100000000; @@ -11,4 +11,4 @@ SET log_queries = 1; SELECT count(), ignore('test cpu time query profiler') FROM numbers(1000000000); SET log_queries = 0; SYSTEM FLUSH LOGS; -WITH symbolizeAddress(arrayJoin(trace)) AS symbol SELECT count() > 0 FROM system.trace_log t WHERE event_date >= yesterday() AND query_id = (SELECT query_id FROM system.query_log WHERE event_date >= yesterday() AND query LIKE '%test cpu time query profiler%' ORDER BY event_time DESC LIMIT 1) AND symbol LIKE '%Numbers%'; +WITH addressToSymbol(arrayJoin(trace)) AS symbol SELECT count() > 0 FROM system.trace_log t WHERE event_date >= yesterday() AND query_id = (SELECT query_id FROM system.query_log WHERE event_date >= yesterday() AND query LIKE '%test cpu time query profiler%' ORDER BY event_time DESC LIMIT 1) AND symbol LIKE '%Numbers%'; From 1d289b5b4986f6f728e9e75c51e29483786eb61b Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 30 Jul 2019 18:22:41 +0300 Subject: [PATCH 0482/1165] Fixed "splitted" build --- dbms/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dbms/CMakeLists.txt b/dbms/CMakeLists.txt index 99db33de3f2..3a184a8297a 100644 --- a/dbms/CMakeLists.txt +++ b/dbms/CMakeLists.txt @@ -162,6 +162,10 @@ endif () if (USE_UNWIND) target_compile_definitions (clickhouse_common_io PRIVATE USE_UNWIND=1) target_include_directories (clickhouse_common_io SYSTEM BEFORE PRIVATE ${UNWIND_INCLUDE_DIR}) + + if (NOT USE_INTERNAL_UNWIND_LIBRARY_FOR_EXCEPTION_HANDLING) + target_link_libraries (common PRIVATE ${UNWIND_LIBRARY}) + endif () endif () add_subdirectory(src/Common/ZooKeeper) From 72e0fbd8615134747e6860b0952038d7cf5018e2 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 30 Jul 2019 19:12:53 +0300 Subject: [PATCH 0483/1165] Added support for splitted debug info; advancements --- dbms/src/Common/SymbolIndex.cpp | 29 +++++++++++++++++++------- dbms/src/Common/tests/symbol_index.cpp | 10 ++++++--- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/dbms/src/Common/SymbolIndex.cpp b/dbms/src/Common/SymbolIndex.cpp index ff04ea35eaa..25edb2350f9 100644 --- a/dbms/src/Common/SymbolIndex.cpp +++ b/dbms/src/Common/SymbolIndex.cpp @@ -16,7 +16,10 @@ namespace { /// Notes: "PHDR" is "Program Headers". -/// To look at program headers, you can run: objdump -p ./clickhouse-server +/// To look at program headers, run: +/// readelf -l ./clickhouse-server +/// To look at section headers, run: +/// readelf -S ./clickhouse-server /// Also look at: https://wiki.osdev.org/ELF /// Also look at: man elf /// http://www.linker-aliens.org/blogs/ali/entry/inside_elf_symbol_tables/ @@ -25,11 +28,14 @@ namespace /// Based on the code of musl-libc and the answer of Kanalpiroge on /// https://stackoverflow.com/questions/15779185/list-all-the-functions-symbols-on-the-fly-in-c-code-on-a-linux-architecture +/// It does not extract all the symbols (but only public - exported and used for dynamic linking), +/// but will work if we cannot find or parse ELF files. void collectSymbolsFromProgramHeaders(dl_phdr_info * info, std::vector & symbols) { /* Iterate over all headers of the current shared lib - * (first call is for the executable itself) */ + * (first call is for the executable itself) + */ for (size_t header_index = 0; header_index < info->dlpi_phnum; ++header_index) { /* Further processing is only needed if the dynamic section is reached @@ -223,11 +229,16 @@ void collectSymbolsFromELF(dl_phdr_info * info, object_name = "/proc/self/exe"; std::error_code ec; - object_name = std::filesystem::canonical(object_name, ec); + std::filesystem::path canonical_path = std::filesystem::canonical(object_name, ec); if (ec) return; + /// Debug info and symbol table sections may be splitted to separate binary. + std::filesystem::path debug_info_path = std::filesystem::path("/usr/lib/debug") / canonical_path; + + object_name = std::filesystem::exists(debug_info_path) ? debug_info_path : canonical_path; + SymbolIndex::Object object; object.elf = std::make_unique(object_name); object.address_begin = reinterpret_cast(info->dlpi_addr); @@ -248,10 +259,6 @@ void collectSymbolsFromELF(dl_phdr_info * info, */ int collectSymbols(dl_phdr_info * info, size_t, void * data_ptr) { - /* ElfW is a macro that creates proper typenames for the used system architecture - * (e.g. on a 32 bit system, ElfW(Dyn*) becomes "Elf32_Dyn*") - */ - SymbolIndex::Data & data = *reinterpret_cast(data_ptr); collectSymbolsFromProgramHeaders(info, data.symbols); @@ -287,7 +294,15 @@ const T * find(const void * address, const std::vector & vec) void SymbolIndex::update() { dl_iterate_phdr(collectSymbols, &data.symbols); + + std::sort(data.objects.begin(), data.objects.end(), [](const Object & a, const Object & b) { return a.address_begin < b.address_begin; }); std::sort(data.symbols.begin(), data.symbols.end(), [](const Symbol & a, const Symbol & b) { return a.address_begin < b.address_begin; }); + + /// We found symbols both from loaded program headers and from ELF symbol tables. + data.symbols.erase(std::unique(data.symbols.begin(), data.symbols.end(), [](const Symbol & a, const Symbol & b) + { + return a.address_begin == b.address_begin && a.address_end == b.address_end; + }), data.symbols.end()); } const SymbolIndex::Symbol * SymbolIndex::findSymbol(const void * address) const diff --git a/dbms/src/Common/tests/symbol_index.cpp b/dbms/src/Common/tests/symbol_index.cpp index c6a22b1266b..3e2e73f3c98 100644 --- a/dbms/src/Common/tests/symbol_index.cpp +++ b/dbms/src/Common/tests/symbol_index.cpp @@ -1,12 +1,16 @@ #include #include #include +#include #include #include #include -void f() {} +NO_INLINE const void * getAddress() +{ + return __builtin_return_address(0); +} using namespace DB; @@ -37,8 +41,8 @@ int main(int argc, char ** argv) else std::cerr << "dladdr: Not found\n"; - Elf elf("/proc/self/exe"); - Dwarf dwarf(elf); + auto object = symbol_index.findObject(getAddress()); + Dwarf dwarf(*object->elf); Dwarf::LocationInfo location; if (dwarf.findAddress(uintptr_t(address), location, Dwarf::LocationInfoMode::FAST)) From a9b079c7bac82159674c0705731069cfce9fd81c Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 30 Jul 2019 19:18:06 +0300 Subject: [PATCH 0484/1165] Minor modifications --- dbms/src/Common/tests/symbol_index.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dbms/src/Common/tests/symbol_index.cpp b/dbms/src/Common/tests/symbol_index.cpp index 3e2e73f3c98..6c0d303fe35 100644 --- a/dbms/src/Common/tests/symbol_index.cpp +++ b/dbms/src/Common/tests/symbol_index.cpp @@ -26,6 +26,7 @@ int main(int argc, char ** argv) for (const auto & elem : symbol_index.symbols()) std::cout << elem.name << ": " << elem.address_begin << " ... " << elem.address_end << "\n"; + std::cout << "\n"; const void * address = reinterpret_cast(std::stoull(argv[1], nullptr, 16)); @@ -50,6 +51,7 @@ int main(int argc, char ** argv) else std::cerr << "Dwarf: Not found\n"; + std::cerr << "\n"; std::cerr << StackTrace().toString() << "\n"; return 0; From 218de76285281540400c4234ff76b60b5a7e98ef Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Tue, 30 Jul 2019 19:36:52 +0300 Subject: [PATCH 0485/1165] fix rollup and cube modifiers with two-level aggregation --- dbms/src/DataStreams/CubeBlockInputStream.cpp | 61 ++++++++++++------- dbms/src/DataStreams/CubeBlockInputStream.h | 1 + .../DataStreams/RollupBlockInputStream.cpp | 38 ++++++++---- dbms/src/DataStreams/RollupBlockInputStream.h | 1 + .../0_stateless/00701_rollup.reference | 10 +++ .../queries/0_stateless/00701_rollup.sql | 16 ++--- .../0_stateless/00720_with_cube.reference | 13 +++- .../queries/0_stateless/00720_with_cube.sql | 30 ++++----- 8 files changed, 110 insertions(+), 60 deletions(-) diff --git a/dbms/src/DataStreams/CubeBlockInputStream.cpp b/dbms/src/DataStreams/CubeBlockInputStream.cpp index c32378d97e6..50a6c0a970b 100644 --- a/dbms/src/DataStreams/CubeBlockInputStream.cpp +++ b/dbms/src/DataStreams/CubeBlockInputStream.cpp @@ -36,43 +36,58 @@ Block CubeBlockInputStream::getHeader() const Block CubeBlockInputStream::readImpl() { - /** After reading a block from input stream, + /** After reading all blocks from input stream, * we will calculate all subsets of columns on next iterations of readImpl * by zeroing columns at positions, where bits are zero in current bitmask. */ - if (mask) + + if (!is_data_read) { - --mask; - Block cube_block = source_block; - for (size_t i = 0; i < keys.size(); ++i) + BlocksList source_blocks; + while (auto block = children[0]->read()) + source_blocks.push_back(block); + + if (source_blocks.empty()) + return {}; + + is_data_read = true; + mask = (1 << keys.size()) - 1; + + if (source_blocks.size() > 1) + source_block = aggregator.mergeBlocks(source_blocks, false); + else + source_block = std::move(source_blocks.front()); + + zero_block = source_block.cloneEmpty(); + for (auto key : keys) { - if (!((mask >> i) & 1)) - { - size_t pos = keys.size() - i - 1; - auto & current = cube_block.getByPosition(keys[pos]); - current.column = zero_block.getByPosition(keys[pos]).column; - } + auto & current = zero_block.getByPosition(key); + current.column = current.column->cloneResized(source_block.rows()); } - BlocksList cube_blocks = { cube_block }; - Block finalized = aggregator.mergeBlocks(cube_blocks, true); + auto finalized = source_block; + finalizeBlock(finalized); return finalized; } - source_block = children[0]->read(); - if (!source_block) - return source_block; + if (!mask) + return {}; - zero_block = source_block.cloneEmpty(); - for (auto key : keys) + --mask; + auto cube_block = source_block; + + for (size_t i = 0; i < keys.size(); ++i) { - auto & current = zero_block.getByPosition(key); - current.column = current.column->cloneResized(source_block.rows()); + if (!((mask >> i) & 1)) + { + size_t pos = keys.size() - i - 1; + auto & current = cube_block.getByPosition(keys[pos]); + current.column = zero_block.getByPosition(keys[pos]).column; + } } - Block finalized = source_block; - finalizeBlock(finalized); - mask = (1 << keys.size()) - 1; + BlocksList cube_blocks = { cube_block }; + Block finalized = aggregator.mergeBlocks(cube_blocks, true); return finalized; } } diff --git a/dbms/src/DataStreams/CubeBlockInputStream.h b/dbms/src/DataStreams/CubeBlockInputStream.h index 2f435a6031c..7e62950e8ee 100644 --- a/dbms/src/DataStreams/CubeBlockInputStream.h +++ b/dbms/src/DataStreams/CubeBlockInputStream.h @@ -36,6 +36,7 @@ private: UInt32 mask = 0; Block source_block; Block zero_block; + bool is_data_read = false; }; } diff --git a/dbms/src/DataStreams/RollupBlockInputStream.cpp b/dbms/src/DataStreams/RollupBlockInputStream.cpp index e43aa51e617..a913dc727fa 100644 --- a/dbms/src/DataStreams/RollupBlockInputStream.cpp +++ b/dbms/src/DataStreams/RollupBlockInputStream.cpp @@ -33,26 +33,40 @@ Block RollupBlockInputStream::readImpl() * by zeroing out every column one-by-one and re-merging a block. */ - if (current_key >= 0) + if (!is_data_read) { - auto & current = rollup_block.getByPosition(keys[current_key]); - current.column = current.column->cloneEmpty()->cloneResized(rollup_block.rows()); - --current_key; + BlocksList source_blocks; + while (auto block = children[0]->read()) + source_blocks.push_back(block); - BlocksList rollup_blocks = { rollup_block }; - rollup_block = aggregator.mergeBlocks(rollup_blocks, false); + if (source_blocks.empty()) + return {}; - Block finalized = rollup_block; + is_data_read = true; + if (source_blocks.size() > 1) + rollup_block = aggregator.mergeBlocks(source_blocks, false); + else + rollup_block = std::move(source_blocks.front()); + + current_key = keys.size() - 1; + + auto finalized = rollup_block; finalizeBlock(finalized); return finalized; } - Block block = children[0]->read(); - current_key = keys.size() - 1; + if (current_key < 0) + return {}; - rollup_block = block; - finalizeBlock(block); + auto & current = rollup_block.getByPosition(keys[current_key]); + current.column = current.column->cloneEmpty()->cloneResized(rollup_block.rows()); + --current_key; - return block; + BlocksList rollup_blocks = { rollup_block }; + rollup_block = aggregator.mergeBlocks(rollup_blocks, false); + + auto finalized = rollup_block; + finalizeBlock(finalized); + return finalized; } } diff --git a/dbms/src/DataStreams/RollupBlockInputStream.h b/dbms/src/DataStreams/RollupBlockInputStream.h index 1c1e29e7a13..dabf1e392a3 100644 --- a/dbms/src/DataStreams/RollupBlockInputStream.h +++ b/dbms/src/DataStreams/RollupBlockInputStream.h @@ -35,6 +35,7 @@ private: ColumnNumbers keys; ssize_t current_key = -1; Block rollup_block; + bool is_data_read = false; }; } diff --git a/dbms/tests/queries/0_stateless/00701_rollup.reference b/dbms/tests/queries/0_stateless/00701_rollup.reference index ec07ad52cae..637ae0bcb52 100644 --- a/dbms/tests/queries/0_stateless/00701_rollup.reference +++ b/dbms/tests/queries/0_stateless/00701_rollup.reference @@ -25,3 +25,13 @@ a 70 4 b 50 4 120 8 + 120 8 +a 70 4 +b 50 4 + 0 120 8 +a 0 70 4 +a 1 25 2 +a 2 45 2 +b 0 50 4 +b 1 15 2 +b 2 35 2 diff --git a/dbms/tests/queries/0_stateless/00701_rollup.sql b/dbms/tests/queries/0_stateless/00701_rollup.sql index 3f4df923f90..fa7f3a21657 100644 --- a/dbms/tests/queries/0_stateless/00701_rollup.sql +++ b/dbms/tests/queries/0_stateless/00701_rollup.sql @@ -1,14 +1,9 @@ DROP TABLE IF EXISTS rollup; CREATE TABLE rollup(a String, b Int32, s Int32) ENGINE = Memory; -INSERT INTO rollup VALUES('a', 1, 10); -INSERT INTO rollup VALUES('a', 1, 15); -INSERT INTO rollup VALUES('a', 2, 20); -INSERT INTO rollup VALUES('a', 2, 25); -INSERT INTO rollup VALUES('b', 1, 10); -INSERT INTO rollup VALUES('b', 1, 5); -INSERT INTO rollup VALUES('b', 2, 20); -INSERT INTO rollup VALUES('b', 2, 15); +INSERT INTO rollup VALUES ('a', 1, 10), ('a', 1, 15), ('a', 2, 20); +INSERT INTO rollup VALUES ('a', 2, 25), ('b', 1, 10), ('b', 1, 5); +INSERT INTO rollup VALUES ('b', 2, 20), ('b', 2, 15); SELECT a, b, sum(s), count() from rollup GROUP BY ROLLUP(a, b) ORDER BY a, b; @@ -20,4 +15,9 @@ SELECT a, sum(s), count() from rollup GROUP BY a WITH ROLLUP ORDER BY a; SELECT a, sum(s), count() from rollup GROUP BY a WITH ROLLUP WITH TOTALS ORDER BY a; +SET group_by_two_level_threshold = 1; + +SELECT a, sum(s), count() from rollup GROUP BY a WITH ROLLUP ORDER BY a; +SELECT a, b, sum(s), count() from rollup GROUP BY a, b WITH ROLLUP ORDER BY a, b; + DROP TABLE rollup; diff --git a/dbms/tests/queries/0_stateless/00720_with_cube.reference b/dbms/tests/queries/0_stateless/00720_with_cube.reference index a0b951978f9..818e8626dde 100644 --- a/dbms/tests/queries/0_stateless/00720_with_cube.reference +++ b/dbms/tests/queries/0_stateless/00720_with_cube.reference @@ -18,8 +18,8 @@ b 1 15 2 b 2 35 2 0 120 8 - 1 40 4 0 120 8 + 1 40 4 2 80 4 a 0 70 4 a 1 25 2 @@ -27,8 +27,8 @@ a 2 45 2 b 0 50 4 b 1 15 2 b 2 35 2 - 1 40 4 0 120 8 + 1 40 4 2 80 4 a 0 70 4 a 1 25 2 @@ -38,3 +38,12 @@ b 1 15 2 b 2 35 2 0 120 8 + 0 120 8 + 1 40 4 + 2 80 4 +a 0 70 4 +a 1 25 2 +a 2 45 2 +b 0 50 4 +b 1 15 2 +b 2 35 2 diff --git a/dbms/tests/queries/0_stateless/00720_with_cube.sql b/dbms/tests/queries/0_stateless/00720_with_cube.sql index bcde617803e..42b65c8222c 100644 --- a/dbms/tests/queries/0_stateless/00720_with_cube.sql +++ b/dbms/tests/queries/0_stateless/00720_with_cube.sql @@ -1,21 +1,21 @@ -DROP TABLE IF EXISTS rollup; -CREATE TABLE rollup(a String, b Int32, s Int32) ENGINE = Memory; +DROP TABLE IF EXISTS cube; +CREATE TABLE cube(a String, b Int32, s Int32) ENGINE = Memory; -INSERT INTO rollup VALUES('a', 1, 10); -INSERT INTO rollup VALUES('a', 1, 15); -INSERT INTO rollup VALUES('a', 2, 20); -INSERT INTO rollup VALUES('a', 2, 25); -INSERT INTO rollup VALUES('b', 1, 10); -INSERT INTO rollup VALUES('b', 1, 5); -INSERT INTO rollup VALUES('b', 2, 20); -INSERT INTO rollup VALUES('b', 2, 15); +-- SET experimental_use_processors=1; -SELECT a, b, sum(s), count() from rollup GROUP BY CUBE(a, b) ORDER BY a, b; +INSERT INTO cube VALUES ('a', 1, 10), ('a', 1, 15), ('a', 2, 20); +INSERT INTO cube VALUES ('a', 2, 25), ('b', 1, 10), ('b', 1, 5); +INSERT INTO cube VALUES ('b', 2, 20), ('b', 2, 15); -SELECT a, b, sum(s), count() from rollup GROUP BY CUBE(a, b) WITH TOTALS ORDER BY a, b; +SELECT a, b, sum(s), count() from cube GROUP BY CUBE(a, b) ORDER BY a, b; -SELECT a, b, sum(s), count() from rollup GROUP BY a, b WITH CUBE ORDER BY a; +SELECT a, b, sum(s), count() from cube GROUP BY CUBE(a, b) WITH TOTALS ORDER BY a, b; -SELECT a, b, sum(s), count() from rollup GROUP BY a, b WITH CUBE WITH TOTALS ORDER BY a; +SELECT a, b, sum(s), count() from cube GROUP BY a, b WITH CUBE ORDER BY a, b; -DROP TABLE rollup; +SELECT a, b, sum(s), count() from cube GROUP BY a, b WITH CUBE WITH TOTALS ORDER BY a, b; + +SET group_by_two_level_threshold = 1; +SELECT a, b, sum(s), count() from cube GROUP BY a, b WITH CUBE ORDER BY a, b; + +DROP TABLE cube; From 8292f3dbc963b48567247e14ccfd26b8ffb24f6c Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 30 Jul 2019 21:01:59 +0300 Subject: [PATCH 0486/1165] Fixed test --- dbms/tests/queries/0_stateless/00974_query_profiler.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dbms/tests/queries/0_stateless/00974_query_profiler.sql b/dbms/tests/queries/0_stateless/00974_query_profiler.sql index da88e904f36..d77e6564782 100644 --- a/dbms/tests/queries/0_stateless/00974_query_profiler.sql +++ b/dbms/tests/queries/0_stateless/00974_query_profiler.sql @@ -1,3 +1,5 @@ +SET allow_introspection_functions = 1; + SET query_profiler_real_time_period_ns = 100000000; SET log_queries = 1; SELECT sleep(0.5), ignore('test real time query profiler'); From d95e0e66c6f4c87a1a76e6855884d1bd39aeb24f Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 30 Jul 2019 21:03:12 +0300 Subject: [PATCH 0487/1165] Fixed "splitted" build --- dbms/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/CMakeLists.txt b/dbms/CMakeLists.txt index 3a184a8297a..21bfc5698fa 100644 --- a/dbms/CMakeLists.txt +++ b/dbms/CMakeLists.txt @@ -164,7 +164,7 @@ if (USE_UNWIND) target_include_directories (clickhouse_common_io SYSTEM BEFORE PRIVATE ${UNWIND_INCLUDE_DIR}) if (NOT USE_INTERNAL_UNWIND_LIBRARY_FOR_EXCEPTION_HANDLING) - target_link_libraries (common PRIVATE ${UNWIND_LIBRARY}) + target_link_libraries (clickhouse_common_io PRIVATE ${UNWIND_LIBRARY}) endif () endif () From ee3a93bab591b3b62c48da17d4f900529e43d45a Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Tue, 30 Jul 2019 21:21:12 +0300 Subject: [PATCH 0488/1165] Update CSVRowInputFormat. --- dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp b/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp index 6dc7493187b..0c23070a95a 100644 --- a/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp @@ -182,6 +182,16 @@ void CSVRowInputFormat::readPrefix() else skipRow(in, format_settings.csv, num_columns); } + + /// The default: map each column of the file to the column of the table with + /// the same index. + read_columns.assign(header.columns(), true); + column_indexes_for_input_fields.resize(header.columns()); + + for (size_t i = 0; i < column_indexes_for_input_fields.size(); ++i) + { + column_indexes_for_input_fields[i] = i; + } } From e8b643e03285de33e54e819c1f00ad2a2f314d53 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Tue, 30 Jul 2019 21:22:01 +0300 Subject: [PATCH 0489/1165] Update CSVRowInputFormat. --- dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp b/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp index 0c23070a95a..bdcabc58042 100644 --- a/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp @@ -145,6 +145,7 @@ void CSVRowInputFormat::readPrefix() size_t num_columns = data_types.size(); String tmp; + auto & header = getPort().getHeader(); if (with_names) { @@ -154,7 +155,7 @@ void CSVRowInputFormat::readPrefix() { /// Look at the file header to see which columns we have there. /// The missing columns are filled with defaults. - read_columns.assign(getPort().getHeader().columns(), false); + read_columns.assign(header.columns(), false); do { String column_name; From 504d548d799a08e078943726d81562c1b6c5f22a Mon Sep 17 00:00:00 2001 From: chertus Date: Tue, 30 Jul 2019 21:39:37 +0300 Subject: [PATCH 0490/1165] AnalyzedJoin refactoring --- dbms/src/Interpreters/AnalyzedJoin.cpp | 94 ++++++++++++-------- dbms/src/Interpreters/AnalyzedJoin.h | 46 ++++------ dbms/src/Interpreters/ExpressionAnalyzer.cpp | 29 +++--- dbms/src/Interpreters/ExpressionAnalyzer.h | 2 +- dbms/src/Interpreters/SubqueryForSet.cpp | 8 +- dbms/src/Interpreters/SubqueryForSet.h | 5 +- dbms/src/Interpreters/SyntaxAnalyzer.cpp | 43 ++------- 7 files changed, 105 insertions(+), 122 deletions(-) diff --git a/dbms/src/Interpreters/AnalyzedJoin.cpp b/dbms/src/Interpreters/AnalyzedJoin.cpp index 993434fca72..8357ab80aba 100644 --- a/dbms/src/Interpreters/AnalyzedJoin.cpp +++ b/dbms/src/Interpreters/AnalyzedJoin.cpp @@ -21,6 +21,10 @@ void AnalyzedJoin::addUsingKey(const ASTPtr & ast) key_asts_left.push_back(ast); key_asts_right.push_back(ast); + + auto & right_key = key_names_right.back(); + if (renames.count(right_key)) + right_key = renames[right_key]; } void AnalyzedJoin::addOnKeys(ASTPtr & left_table_ast, ASTPtr & right_table_ast) @@ -47,7 +51,7 @@ size_t AnalyzedJoin::rightKeyInclusion(const String & name) const } ExpressionActionsPtr AnalyzedJoin::createJoinedBlockActions( - const JoinedColumnsList & columns_added_by_join, + const NamesAndTypesList & columns_added_by_join, const ASTSelectQuery * select_query_with_join, const Context & context) const { @@ -71,61 +75,81 @@ ExpressionActionsPtr AnalyzedJoin::createJoinedBlockActions( NameSet required_columns_set(key_names_right.begin(), key_names_right.end()); for (const auto & joined_column : columns_added_by_join) - required_columns_set.insert(joined_column.name_and_type.name); + required_columns_set.insert(joined_column.name); Names required_columns(required_columns_set.begin(), required_columns_set.end()); - NamesAndTypesList source_column_names; - for (auto & column : columns_from_joined_table) - source_column_names.emplace_back(column.name_and_type); - ASTPtr query = expression_list; - auto syntax_result = SyntaxAnalyzer(context).analyze(query, source_column_names, required_columns); + auto syntax_result = SyntaxAnalyzer(context).analyze(query, columns_from_joined_table, required_columns); ExpressionAnalyzer analyzer(query, syntax_result, context, {}, required_columns_set); return analyzer.getActions(true, false); } -Names AnalyzedJoin::getOriginalColumnNames(const NameSet & required_columns_from_joined_table) const +void AnalyzedJoin::deduplicateAndQualifyColumnNames(const NameSet & left_table_columns, const String & right_table_prefix) { - Names original_columns; - for (const auto & column : columns_from_joined_table) - if (required_columns_from_joined_table.count(column.name_and_type.name)) - original_columns.emplace_back(column.original_name); - return original_columns; + NameSet joined_columns; + NamesAndTypesList dedup_columns; + + for (auto & column : columns_from_joined_table) + { + if (joined_columns.count(column.name)) + continue; + + joined_columns.insert(column.name); + + dedup_columns.push_back(column); + auto & inserted = dedup_columns.back(); + + if (left_table_columns.count(column.name)) + inserted.name = right_table_prefix + column.name; + + original_names[inserted.name] = column.name; + if (inserted.name != column.name) + renames[column.name] = inserted.name; + } + + columns_from_joined_table.swap(dedup_columns); } -void AnalyzedJoin::calculateColumnsFromJoinedTable(const NamesAndTypesList & columns, const Names & original_names) +NameSet AnalyzedJoin::getQualifiedColumnsSet() const { - columns_from_joined_table.clear(); + NameSet out; + for (const auto & names : original_names) + out.insert(names.first); + return out; +} - size_t i = 0; - for (auto & column : columns) +NameSet AnalyzedJoin::getOriginalColumnsSet() const +{ + NameSet out; + for (const auto & names : original_names) + out.insert(names.second); + return out; +} + +std::unordered_map AnalyzedJoin::getOriginalColumnsMap(const NameSet & required_columns) const +{ + std::unordered_map out; + for (const auto & column : required_columns) { - JoinedColumn joined_column(column, original_names[i++]); - - /// We don't want to select duplicate columns from the joined subquery if they appear - if (std::find(columns_from_joined_table.begin(), columns_from_joined_table.end(), joined_column) == columns_from_joined_table.end()) - columns_from_joined_table.push_back(joined_column); + auto it = original_names.find(column); + if (it != original_names.end()) + out.insert(*it); } + return out; } void AnalyzedJoin::calculateAvailableJoinedColumns(bool make_nullable) { - NameSet joined_columns; + if (!make_nullable) + { + available_joined_columns = columns_from_joined_table; + return; + } for (auto & column : columns_from_joined_table) { - auto & column_name = column.name_and_type.name; - auto & column_type = column.name_and_type.type; - auto & original_name = column.original_name; - { - if (joined_columns.count(column_name)) /// Duplicate columns in the subquery for JOIN do not make sense. - continue; - - joined_columns.insert(column_name); - - auto type = make_nullable && column_type->canBeInsideNullable() ? makeNullable(column_type) : column_type; - available_joined_columns.emplace_back(NameAndTypePair(column_name, std::move(type)), original_name); - } + auto type = column.type->canBeInsideNullable() ? makeNullable(column.type) : column.type; + available_joined_columns.emplace_back(NameAndTypePair(column.name, std::move(type))); } } diff --git a/dbms/src/Interpreters/AnalyzedJoin.h b/dbms/src/Interpreters/AnalyzedJoin.h index cae5500cf4a..d820cb0da7b 100644 --- a/dbms/src/Interpreters/AnalyzedJoin.h +++ b/dbms/src/Interpreters/AnalyzedJoin.h @@ -17,29 +17,8 @@ struct DatabaseAndTableWithAlias; class ExpressionActions; using ExpressionActionsPtr = std::shared_ptr; -struct JoinedColumn -{ - /// Column will be joined to block. - NameAndTypePair name_and_type; - /// original column name from joined source. - String original_name; - - JoinedColumn(NameAndTypePair name_and_type_, String original_name_) - : name_and_type(std::move(name_and_type_)), original_name(std::move(original_name_)) {} - - bool operator==(const JoinedColumn & o) const - { - return name_and_type == o.name_and_type && original_name == o.original_name; - } -}; - -using JoinedColumnsList = std::list; - struct AnalyzedJoin { - - /// NOTE: So far, only one JOIN per query is supported. - /** Query of the form `SELECT expr(x) AS k FROM t1 ANY LEFT JOIN (SELECT expr(x) AS k FROM t2) USING k` * The join is made by column k. * During the JOIN, @@ -51,6 +30,11 @@ struct AnalyzedJoin * to the subquery will be added expression `expr(t2 columns)`. * It's possible to use name `expr(t2 columns)`. */ + +private: + friend class SyntaxAnalyzer; + friend class ExpressionAnalyzer; + Names key_names_left; Names key_names_right; /// Duplicating names are qualified. ASTs key_asts_left; @@ -58,22 +42,28 @@ struct AnalyzedJoin bool with_using = true; /// All columns which can be read from joined table. Duplicating names are qualified. - JoinedColumnsList columns_from_joined_table; - /// Columns from joined table which may be added to block. - /// It's columns_from_joined_table without duplicate columns and possibly modified types. - JoinedColumnsList available_joined_columns; + NamesAndTypesList columns_from_joined_table; + /// Columns from joined table which may be added to block. It's columns_from_joined_table with possibly modified types. + NamesAndTypesList available_joined_columns; + /// Name -> original name. Names are the same as in columns_from_joined_table list. + std::unordered_map original_names; + /// Original name -> name. Only ranamed columns. + std::unordered_map renames; +public: void addUsingKey(const ASTPtr & ast); void addOnKeys(ASTPtr & left_table_ast, ASTPtr & right_table_ast); ExpressionActionsPtr createJoinedBlockActions( - const JoinedColumnsList & columns_added_by_join, /// Subset of available_joined_columns. + const NamesAndTypesList & columns_added_by_join, /// Subset of available_joined_columns. const ASTSelectQuery * select_query_with_join, const Context & context) const; - Names getOriginalColumnNames(const NameSet & required_columns) const; + NameSet getQualifiedColumnsSet() const; + NameSet getOriginalColumnsSet() const; + std::unordered_map getOriginalColumnsMap(const NameSet & required_columns) const; - void calculateColumnsFromJoinedTable(const NamesAndTypesList & columns, const Names & original_names); + void deduplicateAndQualifyColumnNames(const NameSet & left_table_columns, const String & right_table_prefix); void calculateAvailableJoinedColumns(bool make_nullable); size_t rightKeyInclusion(const String & name) const; }; diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index 055f5c8f3ec..79ff40956b5 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -325,7 +325,7 @@ void ExpressionAnalyzer::makeSetsForIndexImpl(const ASTPtr & node) NamesAndTypesList temp_columns = source_columns; temp_columns.insert(temp_columns.end(), array_join_columns.begin(), array_join_columns.end()); for (const auto & joined_column : columns_added_by_join) - temp_columns.push_back(joined_column.name_and_type); + temp_columns.push_back(joined_column); ExpressionActionsPtr temp_actions = std::make_shared(temp_columns, context); getRootActions(func->arguments->children.at(0), true, temp_actions); @@ -506,29 +506,25 @@ bool ExpressionAnalyzer::appendArrayJoin(ExpressionActionsChain & chain, bool on void ExpressionAnalyzer::addJoinAction(ExpressionActionsPtr & actions, bool only_types) const { - NamesAndTypesList columns_added_by_join_list; - for (const auto & joined_column : columns_added_by_join) - columns_added_by_join_list.push_back(joined_column.name_and_type); - if (only_types) - actions->add(ExpressionAction::ordinaryJoin(nullptr, analyzedJoin().key_names_left, columns_added_by_join_list)); + actions->add(ExpressionAction::ordinaryJoin(nullptr, analyzedJoin().key_names_left, columns_added_by_join)); else for (auto & subquery_for_set : subqueries_for_sets) if (subquery_for_set.second.join) actions->add(ExpressionAction::ordinaryJoin(subquery_for_set.second.join, analyzedJoin().key_names_left, - columns_added_by_join_list)); + columns_added_by_join)); } static void appendRequiredColumns( - NameSet & required_columns, const Block & sample, const Names & key_names_right, const JoinedColumnsList & columns_added_by_join) + NameSet & required_columns, const Block & sample, const Names & key_names_right, const NamesAndTypesList & columns_added_by_join) { for (auto & column : key_names_right) if (!sample.has(column)) required_columns.insert(column); for (auto & column : columns_added_by_join) - if (!sample.has(column.name_and_type.name)) - required_columns.insert(column.name_and_type.name); + if (!sample.has(column.name)) + required_columns.insert(column.name); } bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_types) @@ -616,10 +612,14 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty appendRequiredColumns( required_columns, joined_block_actions->getSampleBlock(), analyzed_join.key_names_right, columns_added_by_join); - Names original_columns = analyzed_join.getOriginalColumnNames(required_columns); + auto original_map = analyzed_join.getOriginalColumnsMap(required_columns); + Names original_columns; + for (auto & pr : original_map) + original_columns.push_back(pr.second); auto interpreter = interpretSubquery(table, context, subquery_depth, original_columns); - subquery_for_set.makeSource(interpreter, analyzed_join.columns_from_joined_table, required_columns); + + subquery_for_set.makeSource(interpreter, original_map); } Block sample_block = subquery_for_set.renamedSampleBlock(); @@ -1009,7 +1009,7 @@ void ExpressionAnalyzer::collectUsedColumns() columns_added_by_join.clear(); for (const auto & joined_column : analyzed_join.available_joined_columns) { - auto & name = joined_column.name_and_type.name; + auto & name = joined_column.name; if (avaliable_columns.count(name)) continue; @@ -1116,7 +1116,7 @@ void ExpressionAnalyzer::collectUsedColumns() { ss << ", joined columns:"; for (const auto & column : analyzedJoin().available_joined_columns) - ss << " '" << column.name_and_type.name << "'"; + ss << " '" << column.name << "'"; } if (!array_join_sources.empty()) @@ -1130,5 +1130,4 @@ void ExpressionAnalyzer::collectUsedColumns() } } - } diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.h b/dbms/src/Interpreters/ExpressionAnalyzer.h index b36600b07d5..644d10da1be 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.h +++ b/dbms/src/Interpreters/ExpressionAnalyzer.h @@ -59,7 +59,7 @@ struct ExpressionAnalyzerData bool rewrite_subqueries = false; /// Columns will be added to block by join. - JoinedColumnsList columns_added_by_join; /// Subset of analyzed_join.available_joined_columns + NamesAndTypesList columns_added_by_join; /// Subset of analyzed_join.available_joined_columns protected: ExpressionAnalyzerData(const NamesAndTypesList & source_columns_, diff --git a/dbms/src/Interpreters/SubqueryForSet.cpp b/dbms/src/Interpreters/SubqueryForSet.cpp index 6b419df0825..f6528bf110c 100644 --- a/dbms/src/Interpreters/SubqueryForSet.cpp +++ b/dbms/src/Interpreters/SubqueryForSet.cpp @@ -7,15 +7,13 @@ namespace DB { void SubqueryForSet::makeSource(std::shared_ptr & interpreter, - const std::list & columns_from_joined_table, - const NameSet & required_columns_from_joined_table) + const std::unordered_map & name_to_origin) { source = std::make_shared(interpreter->getSampleBlock(), [interpreter]() mutable { return interpreter->execute().in; }); - for (const auto & column : columns_from_joined_table) - if (required_columns_from_joined_table.count(column.name_and_type.name)) - joined_block_aliases.emplace_back(column.original_name, column.name_and_type.name); + for (const auto & names : name_to_origin) + joined_block_aliases.emplace_back(names.second, names.first); sample_block = source->getHeader(); for (const auto & name_with_alias : joined_block_aliases) diff --git a/dbms/src/Interpreters/SubqueryForSet.h b/dbms/src/Interpreters/SubqueryForSet.h index 86557df5b78..1844f686f0a 100644 --- a/dbms/src/Interpreters/SubqueryForSet.h +++ b/dbms/src/Interpreters/SubqueryForSet.h @@ -12,7 +12,7 @@ class Join; using JoinPtr = std::shared_ptr; class InterpreterSelectWithUnionQuery; -struct JoinedColumn; +struct AnalyzedJoin; /// Information on what to do when executing a subquery in the [GLOBAL] IN/JOIN section. @@ -32,8 +32,7 @@ struct SubqueryForSet StoragePtr table; void makeSource(std::shared_ptr & interpreter, - const std::list & columns_from_joined_table, - const NameSet & required_columns_from_joined_table); + const std::unordered_map & name_to_origin); Block renamedSampleBlock() const { return sample_block; } void renameColumns(Block & block); diff --git a/dbms/src/Interpreters/SyntaxAnalyzer.cpp b/dbms/src/Interpreters/SyntaxAnalyzer.cpp index 04102f5ae15..2baf17f6f41 100644 --- a/dbms/src/Interpreters/SyntaxAnalyzer.cpp +++ b/dbms/src/Interpreters/SyntaxAnalyzer.cpp @@ -89,7 +89,7 @@ void collectSourceColumns(const ASTSelectQuery * select_query, StoragePtr storag /// There would be columns in normal form & column aliases after translation. Column & column alias would be normalized in QueryNormalizer. void translateQualifiedNames(ASTPtr & query, const ASTSelectQuery & select_query, const Context & context, const Names & source_columns_list, const NameSet & source_columns_set, - const JoinedColumnsList & columns_from_joined_table) + const NameSet & columns_from_joined_table) { std::vector tables_with_columns = getDatabaseAndTablesWithColumnNames(select_query, context); @@ -101,7 +101,7 @@ void translateQualifiedNames(ASTPtr & query, const ASTSelectQuery & select_query if (!context.getSettingsRef().asterisk_left_columns_only) { for (auto & column : columns_from_joined_table) - all_columns_name.emplace_back(column.name_and_type.name); + all_columns_name.emplace_back(column); } tables_with_columns.emplace_back(DatabaseAndTableWithAlias{}, std::move(all_columns_name)); @@ -483,33 +483,23 @@ void getArrayJoinedColumns(ASTPtr & query, SyntaxAnalyzerResult & result, const /// Find the columns that are obtained by JOIN. void collectJoinedColumns(AnalyzedJoin & analyzed_join, const ASTSelectQuery & select_query, const NameSet & source_columns, - const Aliases & aliases, const String & current_database, bool join_use_nulls) + const Aliases & aliases, bool join_use_nulls) { const ASTTablesInSelectQueryElement * node = select_query.join(); if (!node) return; const auto & table_join = node->table_join->as(); - const auto & table_expression = node->table_expression->as(); - DatabaseAndTableWithAlias joined_table_name(table_expression, current_database); if (table_join.using_expression_list) { const auto & keys = table_join.using_expression_list->as(); for (const auto & key : keys.children) analyzed_join.addUsingKey(key); - - for (auto & name : analyzed_join.key_names_right) - if (source_columns.count(name)) - name = joined_table_name.getQualifiedNamePrefix() + name; } else if (table_join.on_expression) { - NameSet joined_columns; - for (const auto & col : analyzed_join.columns_from_joined_table) - joined_columns.insert(col.original_name); - - CollectJoinOnKeysVisitor::Data data{analyzed_join, source_columns, joined_columns, aliases}; + CollectJoinOnKeysVisitor::Data data{analyzed_join, source_columns, analyzed_join.getOriginalColumnsSet(), aliases}; CollectJoinOnKeysVisitor(data).visit(table_join.on_expression); if (!data.has_some) throw Exception("Cannot get JOIN keys from JOIN ON section: " + queryToString(table_join.on_expression), @@ -521,21 +511,6 @@ void collectJoinedColumns(AnalyzedJoin & analyzed_join, const ASTSelectQuery & s analyzed_join.calculateAvailableJoinedColumns(make_nullable); } -Names qualifyOccupiedNames(NamesAndTypesList & columns, const NameSet & source_columns, const DatabaseAndTableWithAlias& table) -{ - Names originals; - originals.reserve(columns.size()); - - for (auto & column : columns) - { - originals.push_back(column.name); - if (source_columns.count(column.name)) - column.name = table.getQualifiedNamePrefix() + column.name; - } - - return originals; -} - void replaceJoinedTable(const ASTTablesInSelectQueryElement* join) { if (!join || !join->table_expression) @@ -604,14 +579,13 @@ SyntaxAnalyzerResultPtr SyntaxAnalyzer::analyze( const auto & joined_expression = node->table_expression->as(); DatabaseAndTableWithAlias table(joined_expression, context.getCurrentDatabase()); - NamesAndTypesList joined_columns = getNamesAndTypeListFromTableExpression(joined_expression, context); - Names original_names = qualifyOccupiedNames(joined_columns, source_columns_set, table); - result.analyzed_join.calculateColumnsFromJoinedTable(joined_columns, original_names); + result.analyzed_join.columns_from_joined_table = getNamesAndTypeListFromTableExpression(joined_expression, context); + result.analyzed_join.deduplicateAndQualifyColumnNames(source_columns_set, table.getQualifiedNamePrefix()); } translateQualifiedNames(query, *select_query, context, (storage ? storage->getColumns().getOrdinary().getNames() : source_columns_list), source_columns_set, - result.analyzed_join.columns_from_joined_table); + result.analyzed_join.getQualifiedColumnsSet()); /// Rewrite IN and/or JOIN for distributed tables according to distributed_product_mode setting. InJoinSubqueriesPreprocessor(context).visit(query); @@ -666,8 +640,7 @@ SyntaxAnalyzerResultPtr SyntaxAnalyzer::analyze( /// Push the predicate expression down to the subqueries. result.rewrite_subqueries = PredicateExpressionsOptimizer(select_query, settings, context).optimize(); - collectJoinedColumns(result.analyzed_join, *select_query, source_columns_set, result.aliases, - context.getCurrentDatabase(), settings.join_use_nulls); + collectJoinedColumns(result.analyzed_join, *select_query, source_columns_set, result.aliases, settings.join_use_nulls); } return std::make_shared(result); From b274545bb701f51ea2244bad21b83501a423da39 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Tue, 30 Jul 2019 21:48:40 +0300 Subject: [PATCH 0491/1165] Update CSVRowInputFormat. --- dbms/src/Processors/Formats/IInputFormat.h | 6 ++++++ dbms/src/Processors/Formats/IRowInputFormat.cpp | 6 +++--- dbms/src/Processors/Formats/IRowInputFormat.h | 4 ++++ dbms/src/Processors/Formats/InputStreamFromInputFormat.h | 2 ++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/dbms/src/Processors/Formats/IInputFormat.h b/dbms/src/Processors/Formats/IInputFormat.h index 7e4e00c1a33..ed26f60c058 100644 --- a/dbms/src/Processors/Formats/IInputFormat.h +++ b/dbms/src/Processors/Formats/IInputFormat.h @@ -27,6 +27,12 @@ public: : ISource(std::move(header)), in(in) { } + + virtual const BlockMissingValues & getMissingValues() const + { + static const BlockMissingValues none; + return none; + } }; } diff --git a/dbms/src/Processors/Formats/IRowInputFormat.cpp b/dbms/src/Processors/Formats/IRowInputFormat.cpp index b0212d2b89f..1565ec82e1d 100644 --- a/dbms/src/Processors/Formats/IRowInputFormat.cpp +++ b/dbms/src/Processors/Formats/IRowInputFormat.cpp @@ -43,7 +43,7 @@ Chunk IRowInputFormat::generate() MutableColumns columns = header.cloneEmptyColumns(); size_t prev_rows = total_rows; - auto chunk_missing_values = std::make_unique(); + ///auto chunk_missing_values = std::make_unique(); try { @@ -64,7 +64,7 @@ Chunk IRowInputFormat::generate() size_t column_size = columns[column_idx]->size(); if (column_size == 0) throw Exception("Unexpected empty column", ErrorCodes::INCORRECT_NUMBER_OF_COLUMNS); - chunk_missing_values->setBit(column_idx, column_size - 1); + block_missing_values.setBit(column_idx, column_size - 1); } } } @@ -139,7 +139,7 @@ Chunk IRowInputFormat::generate() } Chunk chunk(std::move(columns), total_rows - prev_rows); - chunk.setChunkInfo(std::move(chunk_missing_values)); + //chunk.setChunkInfo(std::move(chunk_missing_values)); return chunk; } diff --git a/dbms/src/Processors/Formats/IRowInputFormat.h b/dbms/src/Processors/Formats/IRowInputFormat.h index b574af8c39a..b70edf47a64 100644 --- a/dbms/src/Processors/Formats/IRowInputFormat.h +++ b/dbms/src/Processors/Formats/IRowInputFormat.h @@ -66,11 +66,15 @@ protected: /// If not implemented, returns empty string. virtual std::string getDiagnosticInfo() { return {}; } + const BlockMissingValues & getMissingValues() const override { return block_missing_values; } + private: Params params; size_t total_rows = 0; size_t num_errors = 0; + + BlockMissingValues block_missing_values; }; } diff --git a/dbms/src/Processors/Formats/InputStreamFromInputFormat.h b/dbms/src/Processors/Formats/InputStreamFromInputFormat.h index 266473f95de..4f94652fac7 100644 --- a/dbms/src/Processors/Formats/InputStreamFromInputFormat.h +++ b/dbms/src/Processors/Formats/InputStreamFromInputFormat.h @@ -22,6 +22,8 @@ public: String getName() const override { return input_format->getName(); } Block getHeader() const override { return input_format->getPort().getHeader(); } + const BlockMissingValues & getMissingValues() const override { return input_format->getMissingValues(); } + protected: Block readImpl() override From e63c1e4b811bff61ff2d1731e9b19085f410abb1 Mon Sep 17 00:00:00 2001 From: proller Date: Tue, 30 Jul 2019 22:00:30 +0300 Subject: [PATCH 0492/1165] 19.11: Fixes for arcadia porting (#6223) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ed76689a5c..ab13edb8940 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -258,7 +258,7 @@ endif () if (NOT SANITIZE AND NOT SPLIT_SHARED_LIBRARIES) set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined") set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") -endif() +endif () include (cmake/find_unwind.cmake) From b85cdd565c079dbc89bdf6d7c896721fcd8745ab Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 31 Jul 2019 00:11:42 +0300 Subject: [PATCH 0493/1165] Fixed idiotic inconsistent code --- dbms/programs/server/Server.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dbms/programs/server/Server.cpp b/dbms/programs/server/Server.cpp index 108b2aeee20..637ce8f33fb 100644 --- a/dbms/programs/server/Server.cpp +++ b/dbms/programs/server/Server.cpp @@ -753,7 +753,8 @@ int Server::main(const std::vector & /*args*/) { #if USE_POCO_NETSSL Poco::Net::ServerSocket socket; - auto address = socket_bind_listen(socket, listen_host, config().getInt("mysql_port"), /* secure = */ true); + listen_port = config().getInt("mysql_port"); + auto address = socket_bind_listen(socket, listen_host, listen_port, /* secure = */ true); socket.setReceiveTimeout(Poco::Timespan()); socket.setSendTimeout(settings.send_timeout); servers.emplace_back(std::make_unique( From e0c8bec28a37976a66c4d9e7e77c148979b78663 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 31 Jul 2019 00:23:42 +0300 Subject: [PATCH 0494/1165] Fixed the issue with "listen_try" option --- dbms/programs/server/Server.cpp | 288 ++++++++++++++++---------------- 1 file changed, 145 insertions(+), 143 deletions(-) diff --git a/dbms/programs/server/Server.cpp b/dbms/programs/server/Server.cpp index 637ce8f33fb..4fc22e618f0 100644 --- a/dbms/programs/server/Server.cpp +++ b/dbms/programs/server/Server.cpp @@ -626,162 +626,164 @@ int Server::main(const std::vector & /*args*/) for (const auto & listen_host : listen_hosts) { - /// For testing purposes, user may omit tcp_port or http_port or https_port in configuration file. - uint16_t listen_port = 0; - try + auto create_server = [&](const char * port_name, auto && func) { - /// HTTP - if (config().has("http_port")) - { - Poco::Net::ServerSocket socket; - listen_port = config().getInt("http_port"); - auto address = socket_bind_listen(socket, listen_host, listen_port); - socket.setReceiveTimeout(settings.http_receive_timeout); - socket.setSendTimeout(settings.http_send_timeout); - servers.emplace_back(std::make_unique( - new HTTPHandlerFactory(*this, "HTTPHandler-factory"), - server_pool, - socket, - http_params)); + /// For testing purposes, user may omit tcp_port or http_port or https_port in configuration file. + if (!config().has(port_name)) + return; - LOG_INFO(log, "Listening http://" + address.toString()); + try + { + auto port = config().getInt(port_name); + func(port); } - - /// HTTPS - if (config().has("https_port")) + catch (const Poco::Exception & e) { -#if USE_POCO_NETSSL - Poco::Net::SecureServerSocket socket; - listen_port = config().getInt("https_port"); - auto address = socket_bind_listen(socket, listen_host, listen_port, /* secure = */ true); - socket.setReceiveTimeout(settings.http_receive_timeout); - socket.setSendTimeout(settings.http_send_timeout); - servers.emplace_back(std::make_unique( - new HTTPHandlerFactory(*this, "HTTPSHandler-factory"), - server_pool, - socket, - http_params)); + std::string message = "Listen [" + listen_host + "]:" + std::to_string(port) + " failed: " + getCurrentExceptionMessage(false); - LOG_INFO(log, "Listening https://" + address.toString()); + if (listen_try) + { + LOG_ERROR(log, message + << ". If it is an IPv6 or IPv4 address and your host has disabled IPv6 or IPv4, then consider to " + "specify not disabled IPv4 or IPv6 address to listen in element of configuration " + "file. Example for disabled IPv6: 0.0.0.0 ." + " Example for disabled IPv4: ::"); + } + else + { + throw Exception{message, ErrorCodes::NETWORK_ERROR}; + } + } + }; + + /// HTTP + create_server("http_port", [&](UInt16 port) + { + Poco::Net::ServerSocket socket; + auto address = socket_bind_listen(socket, listen_host, port); + socket.setReceiveTimeout(settings.http_receive_timeout); + socket.setSendTimeout(settings.http_send_timeout); + servers.emplace_back(std::make_unique( + new HTTPHandlerFactory(*this, "HTTPHandler-factory"), + server_pool, + socket, + http_params)); + + LOG_INFO(log, "Listening http://" + address.toString()); + }); + + /// HTTPS + create_server("https_port", [&](UInt16 port) + { +#if USE_POCO_NETSSL + Poco::Net::SecureServerSocket socket; + auto address = socket_bind_listen(socket, listen_host, port, /* secure = */ true); + socket.setReceiveTimeout(settings.http_receive_timeout); + socket.setSendTimeout(settings.http_send_timeout); + servers.emplace_back(std::make_unique( + new HTTPHandlerFactory(*this, "HTTPSHandler-factory"), + server_pool, + socket, + http_params)); + + LOG_INFO(log, "Listening https://" + address.toString()); #else - throw Exception{"HTTPS protocol is disabled because Poco library was built without NetSSL support.", + throw Exception{"HTTPS protocol is disabled because Poco library was built without NetSSL support.", + ErrorCodes::SUPPORT_IS_DISABLED}; +#endif + }); + + /// TCP + create_server("tcp_port", [&](UInt16 port) + { + Poco::Net::ServerSocket socket; + auto address = socket_bind_listen(socket, listen_host, port); + socket.setReceiveTimeout(settings.receive_timeout); + socket.setSendTimeout(settings.send_timeout); + servers.emplace_back(std::make_unique( + new TCPHandlerFactory(*this), + server_pool, + socket, + new Poco::Net::TCPServerParams)); + + LOG_INFO(log, "Listening for connections with native protocol (tcp): " + address.toString()); + }); + + /// TCP with SSL + create_server("tcp_port_secure", [&](UInt16 port) + { +#if USE_POCO_NETSSL + Poco::Net::SecureServerSocket socket; + auto address = socket_bind_listen(socket, listen_host, port, /* secure = */ true); + socket.setReceiveTimeout(settings.receive_timeout); + socket.setSendTimeout(settings.send_timeout); + servers.emplace_back(std::make_unique( + new TCPHandlerFactory(*this, /* secure= */ true), + server_pool, + socket, + new Poco::Net::TCPServerParams)); + LOG_INFO(log, "Listening for connections with secure native protocol (tcp_secure): " + address.toString()); +#else + throw Exception{"SSL support for TCP protocol is disabled because Poco library was built without NetSSL support.", + ErrorCodes::SUPPORT_IS_DISABLED}; +#endif + }); + + /// Interserver IO HTTP + create_server("interserver_http_port", [&](UInt16 port) + { + Poco::Net::ServerSocket socket; + auto address = socket_bind_listen(socket, listen_host, port); + socket.setReceiveTimeout(settings.http_receive_timeout); + socket.setSendTimeout(settings.http_send_timeout); + servers.emplace_back(std::make_unique( + new InterserverIOHTTPHandlerFactory(*this, "InterserverIOHTTPHandler-factory"), + server_pool, + socket, + http_params)); + + LOG_INFO(log, "Listening for replica communication (interserver) http://" + address.toString()); + }); + + create_server("interserver_https_port", [&](UInt16 port) + { +#if USE_POCO_NETSSL + Poco::Net::SecureServerSocket socket; + auto address = socket_bind_listen(socket, listen_host, port, /* secure = */ true); + socket.setReceiveTimeout(settings.http_receive_timeout); + socket.setSendTimeout(settings.http_send_timeout); + servers.emplace_back(std::make_unique( + new InterserverIOHTTPHandlerFactory(*this, "InterserverIOHTTPHandler-factory"), + server_pool, + socket, + http_params)); + + LOG_INFO(log, "Listening for secure replica communication (interserver) https://" + address.toString()); +#else + throw Exception{"SSL support for TCP protocol is disabled because Poco library was built without NetSSL support.", ErrorCodes::SUPPORT_IS_DISABLED}; #endif - } + }); - /// TCP - if (config().has("tcp_port")) - { - Poco::Net::ServerSocket socket; - listen_port = config().getInt("tcp_port"); - auto address = socket_bind_listen(socket, listen_host, listen_port); - socket.setReceiveTimeout(settings.receive_timeout); - socket.setSendTimeout(settings.send_timeout); - servers.emplace_back(std::make_unique( - new TCPHandlerFactory(*this), - server_pool, - socket, - new Poco::Net::TCPServerParams)); - - LOG_INFO(log, "Listening for connections with native protocol (tcp): " + address.toString()); - } - - /// TCP with SSL - if (config().has("tcp_port_secure")) - { + create_server("mysql_port", [&](UInt16 port) + { #if USE_POCO_NETSSL - Poco::Net::SecureServerSocket socket; - listen_port = config().getInt("tcp_port_secure"); - auto address = socket_bind_listen(socket, listen_host, listen_port, /* secure = */ true); - socket.setReceiveTimeout(settings.receive_timeout); - socket.setSendTimeout(settings.send_timeout); - servers.emplace_back(std::make_unique( - new TCPHandlerFactory(*this, /* secure= */ true), - server_pool, - socket, - new Poco::Net::TCPServerParams)); - LOG_INFO(log, "Listening for connections with secure native protocol (tcp_secure): " + address.toString()); + Poco::Net::ServerSocket socket; + auto address = socket_bind_listen(socket, listen_host, port, /* secure = */ true); + socket.setReceiveTimeout(Poco::Timespan()); + socket.setSendTimeout(settings.send_timeout); + servers.emplace_back(std::make_unique( + new MySQLHandlerFactory(*this), + server_pool, + socket, + new Poco::Net::TCPServerParams)); + + LOG_INFO(log, "Listening for MySQL compatibility protocol: " + address.toString()); #else - throw Exception{"SSL support for TCP protocol is disabled because Poco library was built without NetSSL support.", + throw Exception{"SSL support for MySQL protocol is disabled because Poco library was built without NetSSL support.", ErrorCodes::SUPPORT_IS_DISABLED}; #endif - } - - /// At least one of TCP and HTTP servers must be created. - if (servers.empty()) - throw Exception("No 'tcp_port' and 'http_port' is specified in configuration file.", ErrorCodes::NO_ELEMENTS_IN_CONFIG); - - /// Interserver IO HTTP - if (config().has("interserver_http_port")) - { - Poco::Net::ServerSocket socket; - listen_port = config().getInt("interserver_http_port"); - auto address = socket_bind_listen(socket, listen_host, listen_port); - socket.setReceiveTimeout(settings.http_receive_timeout); - socket.setSendTimeout(settings.http_send_timeout); - servers.emplace_back(std::make_unique( - new InterserverIOHTTPHandlerFactory(*this, "InterserverIOHTTPHandler-factory"), - server_pool, - socket, - http_params)); - - LOG_INFO(log, "Listening for replica communication (interserver) http://" + address.toString()); - } - - if (config().has("interserver_https_port")) - { -#if USE_POCO_NETSSL - Poco::Net::SecureServerSocket socket; - listen_port = config().getInt("interserver_https_port"); - auto address = socket_bind_listen(socket, listen_host, listen_port, /* secure = */ true); - socket.setReceiveTimeout(settings.http_receive_timeout); - socket.setSendTimeout(settings.http_send_timeout); - servers.emplace_back(std::make_unique( - new InterserverIOHTTPHandlerFactory(*this, "InterserverIOHTTPHandler-factory"), - server_pool, - socket, - http_params)); - - LOG_INFO(log, "Listening for secure replica communication (interserver) https://" + address.toString()); -#else - throw Exception{"SSL support for TCP protocol is disabled because Poco library was built without NetSSL support.", - ErrorCodes::SUPPORT_IS_DISABLED}; -#endif - } - - if (config().has("mysql_port")) - { -#if USE_POCO_NETSSL - Poco::Net::ServerSocket socket; - listen_port = config().getInt("mysql_port"); - auto address = socket_bind_listen(socket, listen_host, listen_port, /* secure = */ true); - socket.setReceiveTimeout(Poco::Timespan()); - socket.setSendTimeout(settings.send_timeout); - servers.emplace_back(std::make_unique( - new MySQLHandlerFactory(*this), - server_pool, - socket, - new Poco::Net::TCPServerParams)); - - LOG_INFO(log, "Listening for MySQL compatibility protocol: " + address.toString()); -#else - throw Exception{"SSL support for MySQL protocol is disabled because Poco library was built without NetSSL support.", - ErrorCodes::SUPPORT_IS_DISABLED}; -#endif - } - } - catch (const Poco::Exception & e) - { - std::string message = "Listen [" + listen_host + "]:" + std::to_string(listen_port) + " failed: " + std::to_string(e.code()) + ": " + e.what() + ": " + e.message(); - if (listen_try) - LOG_ERROR(log, message - << " If it is an IPv6 or IPv4 address and your host has disabled IPv6 or IPv4, then consider to " - "specify not disabled IPv4 or IPv6 address to listen in element of configuration " - "file. Example for disabled IPv6: 0.0.0.0 ." - " Example for disabled IPv4: ::"); - else - throw Exception{message, ErrorCodes::NETWORK_ERROR}; - } + }); } if (servers.empty()) From 3ef3dcb4c8c2adc9b5f15d2f90de51b2d8f00ed6 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 31 Jul 2019 01:06:13 +0300 Subject: [PATCH 0495/1165] Fixed the issue with "listen_try" option --- dbms/programs/server/Server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/programs/server/Server.cpp b/dbms/programs/server/Server.cpp index 4fc22e618f0..27dd368a98c 100644 --- a/dbms/programs/server/Server.cpp +++ b/dbms/programs/server/Server.cpp @@ -632,9 +632,9 @@ int Server::main(const std::vector & /*args*/) if (!config().has(port_name)) return; + auto port = config().getInt(port_name); try { - auto port = config().getInt(port_name); func(port); } catch (const Poco::Exception & e) From 30c35b1cbf7c10fd285669290d1be3444287275b Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Wed, 31 Jul 2019 01:06:48 +0300 Subject: [PATCH 0496/1165] Update StorageValues.cpp --- dbms/src/Storages/StorageValues.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dbms/src/Storages/StorageValues.cpp b/dbms/src/Storages/StorageValues.cpp index 257c6c34e4a..bda44569cc6 100644 --- a/dbms/src/Storages/StorageValues.cpp +++ b/dbms/src/Storages/StorageValues.cpp @@ -8,9 +8,9 @@ namespace DB StorageValues::StorageValues(const std::string & database_name_, const std::string & table_name_, const Block & res_block_) : database_name(database_name_), table_name(table_name_), res_block(res_block_) - { - setColumns(ColumnsDescription(res_block.getNamesAndTypesList())); - } +{ + setColumns(ColumnsDescription(res_block.getNamesAndTypesList())); +} BlockInputStreams StorageValues::read( const Names & column_names, From 2452b2eba7b2efaadd8656abadd667fec610f005 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 31 Jul 2019 01:08:57 +0300 Subject: [PATCH 0497/1165] Fixed the issue with "listen_try" option --- dbms/programs/server/Server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/programs/server/Server.cpp b/dbms/programs/server/Server.cpp index 27dd368a98c..4730883c9f4 100644 --- a/dbms/programs/server/Server.cpp +++ b/dbms/programs/server/Server.cpp @@ -637,7 +637,7 @@ int Server::main(const std::vector & /*args*/) { func(port); } - catch (const Poco::Exception & e) + catch (const Poco::Exception &) { std::string message = "Listen [" + listen_host + "]:" + std::to_string(port) + " failed: " + getCurrentExceptionMessage(false); From 0055bd1a1b024551a31696f3704262452b3b8c52 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 31 Jul 2019 01:22:45 +0300 Subject: [PATCH 0498/1165] Allow user to override poll_interval and idle_connection_timeout --- dbms/programs/server/TCPHandler.cpp | 30 +++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/dbms/programs/server/TCPHandler.cpp b/dbms/programs/server/TCPHandler.cpp index 8debfd7d235..a296a8dd426 100644 --- a/dbms/programs/server/TCPHandler.cpp +++ b/dbms/programs/server/TCPHandler.cpp @@ -59,10 +59,13 @@ void TCPHandler::runImpl() connection_context = server.context(); connection_context.makeSessionContext(); - Settings global_settings = connection_context.getSettings(); + /// These timeouts can be changed after receiving query. - socket().setReceiveTimeout(global_settings.receive_timeout); - socket().setSendTimeout(global_settings.send_timeout); + auto global_receive_timeout = connection_context.getSettingsRef().receive_timeout; + auto global_send_timeout = connection_context.getSettingsRef().send_timeout; + + socket().setReceiveTimeout(global_receive_timeout); + socket().setSendTimeout(global_send_timeout); socket().setNoDelay(true); in = std::make_shared(socket()); @@ -74,6 +77,7 @@ void TCPHandler::runImpl() return; } + /// User will be authenticated here. It will also set settings from user profile into connection_context. try { receiveHello(); @@ -117,6 +121,8 @@ void TCPHandler::runImpl() connection_context.setCurrentDatabase(default_database); } + Settings connection_settings = connection_context.getSettings(); + sendHello(); connection_context.setProgressCallback([this] (const Progress & value) { return this->updateProgress(value); }); @@ -126,9 +132,9 @@ void TCPHandler::runImpl() /// We are waiting for a packet from the client. Thus, every `poll_interval` seconds check whether we need to shut down. { Stopwatch idle_time; - while (!static_cast(*in).poll(global_settings.poll_interval * 1000000) && !server.isCancelled()) + while (!static_cast(*in).poll(connection_settings.poll_interval * 1000000) && !server.isCancelled()) { - if (idle_time.elapsedSeconds() > global_settings.idle_connection_timeout) + if (idle_time.elapsedSeconds() > connection_settings.idle_connection_timeout) { LOG_TRACE(log, "Closing idle connection"); return; @@ -182,13 +188,13 @@ void TCPHandler::runImpl() CurrentThread::attachInternalTextLogsQueue(state.logs_queue, client_logs_level.value); } - query_context->setExternalTablesInitializer([&global_settings, this] (Context & context) + query_context->setExternalTablesInitializer([&connection_settings, this] (Context & context) { if (&context != &*query_context) throw Exception("Unexpected context in external tables initializer", ErrorCodes::LOGICAL_ERROR); /// Get blocks of temporary tables - readData(global_settings); + readData(connection_settings); /// Reset the input stream, as we received an empty block while receiving external table data. /// So, the stream has been marked as cancelled and we can't read from it anymore. @@ -210,7 +216,7 @@ void TCPHandler::runImpl() /// Does the request require receive data from client? if (state.need_receive_data_for_insert) - processInsertQuery(global_settings); + processInsertQuery(connection_settings); else if (state.io.pipeline.initialized()) processOrdinaryQueryWithProcessors(query_context->getSettingsRef().max_threads); else @@ -317,12 +323,12 @@ void TCPHandler::runImpl() } -void TCPHandler::readData(const Settings & global_settings) +void TCPHandler::readData(const Settings & connection_settings) { const auto receive_timeout = query_context->getSettingsRef().receive_timeout.value; /// Poll interval should not be greater than receive_timeout - const size_t default_poll_interval = global_settings.poll_interval.value * 1000000; + const size_t default_poll_interval = connection_settings.poll_interval.value * 1000000; size_t current_poll_interval = static_cast(receive_timeout.totalMicroseconds()); constexpr size_t min_poll_interval = 5000; // 5 ms size_t poll_interval = std::max(min_poll_interval, std::min(default_poll_interval, current_poll_interval)); @@ -372,7 +378,7 @@ void TCPHandler::readData(const Settings & global_settings) } -void TCPHandler::processInsertQuery(const Settings & global_settings) +void TCPHandler::processInsertQuery(const Settings & connection_settings) { /** Made above the rest of the lines, so that in case of `writePrefix` function throws an exception, * client receive exception before sending data. @@ -393,7 +399,7 @@ void TCPHandler::processInsertQuery(const Settings & global_settings) /// Send block to the client - table structure. sendData(state.io.out->getHeader()); - readData(global_settings); + readData(connection_settings); state.io.out->writeSuffix(); state.io.onFinish(); } From aa6f7f273026c2bd761ad3ed14b67b0183b5a19d Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 31 Jul 2019 01:27:14 +0300 Subject: [PATCH 0499/1165] Slightly better --- dbms/programs/server/TCPHandler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dbms/programs/server/TCPHandler.cpp b/dbms/programs/server/TCPHandler.cpp index a296a8dd426..5091258acaf 100644 --- a/dbms/programs/server/TCPHandler.cpp +++ b/dbms/programs/server/TCPHandler.cpp @@ -132,7 +132,8 @@ void TCPHandler::runImpl() /// We are waiting for a packet from the client. Thus, every `poll_interval` seconds check whether we need to shut down. { Stopwatch idle_time; - while (!static_cast(*in).poll(connection_settings.poll_interval * 1000000) && !server.isCancelled()) + while (!server.isCancelled() && !static_cast(*in).poll( + std::min(connection_settings.poll_interval, connection_settings.idle_connection_timeout) * 1000000)) { if (idle_time.elapsedSeconds() > connection_settings.idle_connection_timeout) { From b6275010f2d4e2e3a3c1d22421d15ae7148f7208 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 31 Jul 2019 02:12:04 +0300 Subject: [PATCH 0500/1165] Fixed error with server shutdown --- dbms/programs/server/Server.cpp | 18 ++++++++++++++++-- dbms/src/Interpreters/ProcessList.cpp | 9 +++++++++ dbms/src/Interpreters/ProcessList.h | 2 ++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/dbms/programs/server/Server.cpp b/dbms/programs/server/Server.cpp index 4730883c9f4..563fff6a0bc 100644 --- a/dbms/programs/server/Server.cpp +++ b/dbms/programs/server/Server.cpp @@ -821,10 +821,13 @@ int Server::main(const std::vector & /*args*/) current_connections += server->currentConnections(); } - LOG_DEBUG(log, + LOG_INFO(log, "Closed all listening sockets." << (current_connections ? " Waiting for " + toString(current_connections) + " outstanding connections." : "")); + /// Killing remaining queries. + global_context->getProcessList().killAllQueries(); + if (current_connections) { const int sleep_max_ms = 1000 * config().getInt("shutdown_wait_unfinished", 5); @@ -842,13 +845,24 @@ int Server::main(const std::vector & /*args*/) } } - LOG_DEBUG( + LOG_INFO( log, "Closed connections." << (current_connections ? " But " + toString(current_connections) + " remains." " Tip: To increase wait time add to config: 60" : "")); dns_cache_updater.reset(); main_config_reloader.reset(); users_config_reloader.reset(); + + if (current_connections) + { + /// There is no better way to force connections to close in Poco. + /// Otherwise connection handlers will continue to live + /// (they are effectively dangling objects, but they use global thread pool + /// and global thread pool destructor will wait for threads, preventing server shutdown). + + LOG_INFO(log, "Will shutdown forcefully."); + _exit(Application::EXIT_OK); + } }); /// try to load dictionaries immediately, throw on error and die diff --git a/dbms/src/Interpreters/ProcessList.cpp b/dbms/src/Interpreters/ProcessList.cpp index def39d4d91c..5a13477147c 100644 --- a/dbms/src/Interpreters/ProcessList.cpp +++ b/dbms/src/Interpreters/ProcessList.cpp @@ -406,6 +406,15 @@ CancellationCode ProcessList::sendCancelToQuery(const String & current_query_id, } +void ProcessList::killAllQueries() +{ + std::lock_guard lock(mutex); + + for (auto & process : processes) + process.cancelQuery(true); +} + + QueryStatusInfo QueryStatus::getInfo(bool get_thread_list, bool get_profile_events, bool get_settings) const { QueryStatusInfo res; diff --git a/dbms/src/Interpreters/ProcessList.h b/dbms/src/Interpreters/ProcessList.h index b75a4e7a730..4cdf7c18fea 100644 --- a/dbms/src/Interpreters/ProcessList.h +++ b/dbms/src/Interpreters/ProcessList.h @@ -315,6 +315,8 @@ public: /// Try call cancel() for input and output streams of query with specified id and user CancellationCode sendCancelToQuery(const String & current_query_id, const String & current_user, bool kill = false); + + void killAllQueries(); }; } From f75dff9be818914500fc0b274c772f7666d169cf Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 31 Jul 2019 02:57:53 +0300 Subject: [PATCH 0501/1165] Limit maximum sleep time for "max_execution_speed" settings --- dbms/src/DataStreams/IBlockInputStream.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dbms/src/DataStreams/IBlockInputStream.cpp b/dbms/src/DataStreams/IBlockInputStream.cpp index 406a660879c..990f330987a 100644 --- a/dbms/src/DataStreams/IBlockInputStream.cpp +++ b/dbms/src/DataStreams/IBlockInputStream.cpp @@ -255,6 +255,10 @@ static void limitProgressingSpeed(size_t total_progress_size, size_t max_speed_i if (desired_microseconds > total_elapsed_microseconds) { UInt64 sleep_microseconds = desired_microseconds - total_elapsed_microseconds; + + /// Never sleep more than one second (it should be enough to limit speed for a reasonable amount, and otherwise it's too easy to make query hang). + sleep_microseconds = std::min(UInt64(1000000), sleep_microseconds); + sleepForMicroseconds(sleep_microseconds); ProfileEvents::increment(ProfileEvents::ThrottlerSleepMicroseconds, sleep_microseconds); From 2205a0097d4c39db8ec8be407014b8a24a007e88 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 31 Jul 2019 03:05:31 +0300 Subject: [PATCH 0502/1165] Avoid false exceptions like "Estimated query execution time (inf seconds) is too long" --- dbms/src/DataStreams/IBlockInputStream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/DataStreams/IBlockInputStream.cpp b/dbms/src/DataStreams/IBlockInputStream.cpp index 990f330987a..a2c3fb2247c 100644 --- a/dbms/src/DataStreams/IBlockInputStream.cpp +++ b/dbms/src/DataStreams/IBlockInputStream.cpp @@ -353,7 +353,7 @@ void IBlockInputStream::progressImpl(const Progress & value) ErrorCodes::TOO_SLOW); /// If the predicted execution time is longer than `max_execution_time`. - if (limits.max_execution_time != 0 && total_rows) + if (limits.max_execution_time != 0 && total_rows && progress.read_rows) { double estimated_execution_time_seconds = elapsed_seconds * (static_cast(total_rows) / progress.read_rows); From c2035a21fc3821caaebc5a2fab9b2248f05502df Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 31 Jul 2019 03:29:47 +0300 Subject: [PATCH 0503/1165] Added a test --- .../queries/0_stateless/00976_max_execution_speed.reference | 0 dbms/tests/queries/0_stateless/00976_max_execution_speed.sql | 2 ++ 2 files changed, 2 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00976_max_execution_speed.reference create mode 100644 dbms/tests/queries/0_stateless/00976_max_execution_speed.sql diff --git a/dbms/tests/queries/0_stateless/00976_max_execution_speed.reference b/dbms/tests/queries/0_stateless/00976_max_execution_speed.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dbms/tests/queries/0_stateless/00976_max_execution_speed.sql b/dbms/tests/queries/0_stateless/00976_max_execution_speed.sql new file mode 100644 index 00000000000..06386d77413 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00976_max_execution_speed.sql @@ -0,0 +1,2 @@ +SET max_execution_speed = 1, max_execution_time = 3; +SELECT count() FROM system.numbers; -- { serverError 159 } From 52650ce2f7a4b26bccb9d7651fc5ef40cb1757ee Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 31 Jul 2019 04:05:33 +0300 Subject: [PATCH 0504/1165] Fixed overflow in intDiv functions --- dbms/src/Functions/intDiv.h | 14 ++++++++++- dbms/src/Functions/intDivOrZero.cpp | 16 ++++++++++++- .../0_stateless/00977_int_div.reference | 23 +++++++++++++++++++ .../queries/0_stateless/00977_int_div.sql | 19 +++++++++++++++ 4 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00977_int_div.reference create mode 100644 dbms/tests/queries/0_stateless/00977_int_div.sql diff --git a/dbms/src/Functions/intDiv.h b/dbms/src/Functions/intDiv.h index 566a8010639..9c33d27a219 100644 --- a/dbms/src/Functions/intDiv.h +++ b/dbms/src/Functions/intDiv.h @@ -13,6 +13,7 @@ namespace DB namespace ErrorCodes { extern const int ILLEGAL_DIVISION; + extern const int LOGICAL_ERROR; } #pragma GCC diagnostic push @@ -55,7 +56,18 @@ struct DivideIntegralImpl static inline Result apply(A a, B b) { throwIfDivisionLeadsToFPE(a, b); - return a / b; + + if constexpr (!std::is_same_v) + { + /// Otherwise overflow may occur due to integer promotion. Example: int8_t(-1) / uint64_t(2). + /// NOTE: overflow is still possible when dividing large signed number to large unsigned number or vice-versa. But it's less harmful. + if constexpr (std::is_integral_v && std::is_integral_v && (std::is_signed_v || std::is_signed_v)) + return std::make_signed_t(a) / std::make_signed_t(b); + else + return a / b; + } + else + throw Exception("Logical error: the types are not divisable", ErrorCodes::LOGICAL_ERROR); } #if USE_EMBEDDED_COMPILER diff --git a/dbms/src/Functions/intDivOrZero.cpp b/dbms/src/Functions/intDivOrZero.cpp index da996c9492e..2d1ca2a704d 100644 --- a/dbms/src/Functions/intDivOrZero.cpp +++ b/dbms/src/Functions/intDivOrZero.cpp @@ -1,9 +1,17 @@ #include #include +#include "intDiv.h" + + namespace DB { +namespace ErrorCodes +{ + extern const int LOGICAL_ERROR; +} + template struct DivideIntegralOrZeroImpl { @@ -12,7 +20,13 @@ struct DivideIntegralOrZeroImpl template static inline Result apply(A a, B b) { - return unlikely(divisionLeadsToFPE(a, b)) ? 0 : a / b; + if (unlikely(divisionLeadsToFPE(a, b))) + return 0; + + if constexpr (!std::is_same_v) + return DivideIntegralImpl::apply(a, b); + else + throw Exception("Logical error: the types are not divisable", ErrorCodes::LOGICAL_ERROR); } #if USE_EMBEDDED_COMPILER diff --git a/dbms/tests/queries/0_stateless/00977_int_div.reference b/dbms/tests/queries/0_stateless/00977_int_div.reference new file mode 100644 index 00000000000..d3d73cb3798 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00977_int_div.reference @@ -0,0 +1,23 @@ +-2000 -1 1 +-1 +-1 +-1 +0 +0 +0 +0 +0 +0 +0 +0 +0 +-1 +0 +0 +0 +0 +0 +0 +0 +0 +0 diff --git a/dbms/tests/queries/0_stateless/00977_int_div.sql b/dbms/tests/queries/0_stateless/00977_int_div.sql new file mode 100644 index 00000000000..3270ab34224 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00977_int_div.sql @@ -0,0 +1,19 @@ +SELECT + sum(ASD) AS asd, + intDiv(toInt64(asd), abs(toInt64(asd))) AS int_div_with_abs, + intDiv(toInt64(asd), toInt64(asd)) AS int_div_without_abs +FROM +( + SELECT ASD + FROM + ( + SELECT [-1000, -1000] AS asds + ) + ARRAY JOIN asds AS ASD +); + +SELECT intDivOrZero( CAST(-1000, 'Int64') , CAST(1000, 'UInt64') ); +SELECT intDivOrZero( CAST(-1000, 'Int64') , CAST(1000, 'Int64') ); + +SELECT intDiv(-1, number) FROM numbers(1, 10); +SELECT intDivOrZero(-1, number) FROM numbers(1, 10); From ae4ae9926dbf04f96c0f166ceeeab888ca334b25 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 31 Jul 2019 06:10:16 +0300 Subject: [PATCH 0505/1165] Fixed build with old gcc --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index df711a87a7e..f8b580586a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -325,7 +325,7 @@ if (OS_LINUX AND NOT UNBUNDLED AND (GLIBC_COMPATIBILITY OR USE_INTERNAL_UNWIND_L set (DEFAULT_LIBS "${DEFAULT_LIBS} -Wl,-Bstatic ${LIBCXX_LIBS} ${EXCEPTION_HANDLING_LIBRARY} ${BUILTINS_LIB_PATH} -Wl,-Bdynamic") else () - set (DEFAULT_LIBS "${DEFAULT_LIBS} -Wl,-Bstatic -lstdc++ ${EXCEPTION_HANDLING_LIBRARY} ${COVERAGE_OPTION} ${BUILTINS_LIB_PATH} -Wl,-Bdynamic") + set (DEFAULT_LIBS "${DEFAULT_LIBS} -Wl,-Bstatic -lstdc++ -lstdc++fs ${EXCEPTION_HANDLING_LIBRARY} ${COVERAGE_OPTION} ${BUILTINS_LIB_PATH} -Wl,-Bdynamic") endif () # Linking with GLIBC prevents portability of binaries to older systems. From a5f7afc4c83864be51e5f9bd05445823b8e416b6 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Wed, 31 Jul 2019 06:53:36 +0300 Subject: [PATCH 0506/1165] DOCAPI-7428: Update for domain and topLevelDomain functions description. (#5963) --- .../query_language/functions/url_functions.md | 75 ++++++++++++++++++- 1 file changed, 72 insertions(+), 3 deletions(-) diff --git a/docs/en/query_language/functions/url_functions.md b/docs/en/query_language/functions/url_functions.md index 93edf705e7e..a21c2cfa0bf 100644 --- a/docs/en/query_language/functions/url_functions.md +++ b/docs/en/query_language/functions/url_functions.md @@ -12,7 +12,42 @@ Returns the protocol. Examples: http, ftp, mailto, magnet... ### domain -Gets the domain. Cut scheme with size less than 16 bytes. +Extracts the host part from URL. + +``` +domain(url) +``` + +**Parameters** + +- `url` — URL. Type: [String](../../data_types/string.md). + + +URL can be specified with or without scheme. Examples: + +``` +svn+ssh://some.svn-hosting.com:80/repo/trunk +some.svn-hosting.com:80/repo/trunk +https://yandex.com/time/ +``` + +**Returned values** + +- Host name. If ClickHouse can parse input string as URL. +- Empty string. If ClickHouse cannot parse input string as URL. + +Type: `String`. + +**Example** + +```sql +SELECT domain('svn+ssh://some.svn-hosting.com:80/repo/trunk') +``` +```text +┌─domain('svn+ssh://some.svn-hosting.com:80/repo/trunk')─┐ +│ some.svn-hosting.com │ +└────────────────────────────────────────────────────────┘ +``` ### domainWithoutWWW @@ -20,7 +55,41 @@ Returns the domain and removes no more than one 'www.' from the beginning of it, ### topLevelDomain -Returns the top-level domain. Example: .ru. +Extracts the the top-level domain from URL. + +``` +topLevelDomain(url) +``` + +**Parameters** + +- `url` — URL. Type: [String](../../data_types/string.md). + +URL can be specified with or without scheme. Examples: + +``` +svn+ssh://some.svn-hosting.com:80/repo/trunk +some.svn-hosting.com:80/repo/trunk +https://yandex.com/time/ +``` + +**Returned values** + +- Domain name. If ClickHouse can parse input string as URL. +- Empty string. If ClickHouse cannot parse input string as URL. + +Type: `String`. + +**Example** + +```sql +SELECT topLevelDomain('svn+ssh://www.some.svn-hosting.com:80/repo/trunk') +``` +```text +┌─topLevelDomain('svn+ssh://www.some.svn-hosting.com:80/repo/trunk')─┐ +│ com │ +└────────────────────────────────────────────────────────────────────┘ +``` ### firstSignificantSubdomain @@ -66,7 +135,7 @@ Returns an array of name strings corresponding to the names of URL parameters. T ### URLHierarchy(URL) -Returns an array containing the URL, truncated at the end by the symbols /,? in the path and query-string. Consecutive separator characters are counted as one. The cut is made in the position after all the consecutive separator characters. +Returns an array containing the URL, truncated at the end by the symbols /,? in the path and query-string. Consecutive separator characters are counted as one. The cut is made in the position after all the consecutive separator characters. ### URLPathHierarchy(URL) From b103137280d2899f0da998f50635f6a34ed0e3cd Mon Sep 17 00:00:00 2001 From: BayoNet Date: Wed, 31 Jul 2019 07:36:15 +0300 Subject: [PATCH 0507/1165] DOCAPI-4160: EN review, RU translation. uniq and count docs. (#6087) --- docs/en/operations/settings/settings.md | 2 +- .../query_language/agg_functions/reference.md | 60 ++--- docs/ru/operations/settings/settings.md | 13 + .../query_language/agg_functions/reference.md | 225 +++++++++++++++--- 4 files changed, 236 insertions(+), 64 deletions(-) diff --git a/docs/en/operations/settings/settings.md b/docs/en/operations/settings/settings.md index 578d7c1bb64..01b71df817a 100644 --- a/docs/en/operations/settings/settings.md +++ b/docs/en/operations/settings/settings.md @@ -813,7 +813,7 @@ Default value: 1. ## count_distinct_implementation {#settings-count_distinct_implementation} -Specifies which of the `uniq*` functions should be used for performing the [COUNT(DISTINCT ...)](../../query_language/agg_functions/reference.md#agg_function-count) construction. +Specifies which of the `uniq*` functions should be used to perform the [COUNT(DISTINCT ...)](../../query_language/agg_functions/reference.md#agg_function-count) construction. Possible values: diff --git a/docs/en/query_language/agg_functions/reference.md b/docs/en/query_language/agg_functions/reference.md index 76fb90d4fc4..ce9f2b6cdbb 100644 --- a/docs/en/query_language/agg_functions/reference.md +++ b/docs/en/query_language/agg_functions/reference.md @@ -6,7 +6,7 @@ Counts the number of rows or not-NULL values. ClickHouse supports the following syntaxes for `count`: - `count(expr)` or `COUNT(DISTINCT expr)`. -- `count()` or `COUNT(*)`. The `count()` syntax is a ClickHouse-specific implementation. +- `count()` or `COUNT(*)`. The `count()` syntax is ClickHouse-specific. **Parameters** @@ -19,15 +19,15 @@ The function can take: **Returned value** - If the function is called without parameters it counts the number of rows. -- If the [expression](../syntax.md#syntax-expressions) is passed, then the function counts how many times this expression returned not null. If the expression returns a value of the [Nullable](../../data_types/nullable.md) data type, then the result of `count` stays not `Nullable`. The function returns 0 if the expression returned `NULL` for all the rows. +- If the [expression](../syntax.md#syntax-expressions) is passed, then the function counts how many times this expression returned not null. If the expression returns a [Nullable](../../data_types/nullable.md)-type value, then the result of `count` stays not `Nullable`. The function returns 0 if the expression returned `NULL` for all the rows. In both cases the type of the returned value is [UInt64](../../data_types/int_uint.md). **Details** -ClickHouse supports the `COUNT(DISTINCT ...)` syntax. The behavior of this construction depends on the [count_distinct_implementation](../../operations/settings/settings.md#settings-count_distinct_implementation) setting. It defines which of the [uniq*](#agg_function-uniq) functions is used to perform the operation. By default the [uniqExact](#agg_function-uniqexact) function. +ClickHouse supports the `COUNT(DISTINCT ...)` syntax. The behavior of this construction depends on the [count_distinct_implementation](../../operations/settings/settings.md#settings-count_distinct_implementation) setting. It defines which of the [uniq*](#agg_function-uniq) functions is used to perform the operation. The default is the [uniqExact](#agg_function-uniqexact) function. -A `SELECT count() FROM table` query is not optimized, because the number of entries in the table is not stored separately. It chooses some small column from the table and count the number of values in it. +The `SELECT count() FROM table` query is not optimized, because the number of entries in the table is not stored separately. It chooses a small column from the table and counts the number of values in it. **Examples** @@ -62,7 +62,7 @@ SELECT count(DISTINCT num) FROM t └────────────────┘ ``` -This example shows that `count(DISTINCT num)` is performed by the function `uniqExact` corresponding to the `count_distinct_implementation` setting value. +This example shows that `count(DISTINCT num)` is performed by the `uniqExact` function according to the `count_distinct_implementation` setting value. ## any(x) {#agg_function-any} @@ -522,24 +522,24 @@ uniq(x[, ...]) **Parameters** -Function takes the variable number of parameters. Parameters can be of types: `Tuple`, `Array`, `Date`, `DateTime`, `String`, numeric types. +The function takes a variable number of parameters. Parameters can be `Tuple`, `Array`, `Date`, `DateTime`, `String`, or numeric types. **Returned value** -- The number of the [UInt64](../../data_types/int_uint.md) type. +- A [UInt64](../../data_types/int_uint.md)-type number. **Implementation details** Function: - Calculates a hash for all parameters in the aggregate, then uses it in calculations. -- Uses an adaptive sampling algorithm. For the calculation state, the function uses a sample of element hash values with a size up to 65536. +- Uses an adaptive sampling algorithm. For the calculation state, the function uses a sample of element hash values up to 65536. - This algorithm is very accurate and very efficient on CPU. When query contains several of these functions, using `uniq` is almost as fast as using other aggregate functions. + This algorithm is very accurate and very efficient on the CPU. When the query contains several of these functions, using `uniq` is almost as fast as using other aggregate functions. -- Provides the result deterministically (it doesn't depend on the order of query processing). +- Provides the result deterministically (it doesn't depend on the query processing order). -We recommend to use this function in almost all scenarios. +We recommend using this function in almost all scenarios. **See Also** @@ -549,40 +549,40 @@ We recommend to use this function in almost all scenarios. ## uniqCombined {#agg_function-uniqcombined} -Calculates the approximate number of different values of the argument. +Calculates the approximate number of different argument values. ``` uniqCombined(HLL_precision)(x[, ...]) ``` -The `uniqCombined` function is a good choice for calculating the number of different values, but keep in mind that the estimation error for large sets (200 million elements and more) will become larger than theoretical value due to poor choice of hash function. +The `uniqCombined` function is a good choice for calculating the number of different values, but keep in mind that the estimation error for large sets (200 million elements and more) will be larger than the theoretical value due to the poor hash function choice. **Parameters** -Function takes the variable number of parameters. Parameters can be of types: `Tuple`, `Array`, `Date`, `DateTime`, `String`, numeric types. +The function takes a variable number of parameters. Parameters can be `Tuple`, `Array`, `Date`, `DateTime`, `String`, or numeric types. -`HLL_precision` is the base-2 logarithm of the number of cells in [HyperLogLog](https://en.wikipedia.org/wiki/HyperLogLog). Optional, you can use the function as `uniqCombined(x[, ...])`. The default value for `HLL_precision` is 17, that is effectively 96 KiB of space (2^17 cells of 6 bits each). +`HLL_precision` is the base-2 logarithm of the number of cells in [HyperLogLog](https://en.wikipedia.org/wiki/HyperLogLog). Optional, you can use the function as `uniqCombined(x[, ...])`. The default value for `HLL_precision` is 17, which is effectively 96 KiB of space (2^17 cells, 6 bits each). **Returned value** -- The number of the [UInt64](../../data_types/int_uint.md) type. +- A number [UInt64](../../data_types/int_uint.md)-type number. **Implementation details** Function: - Calculates a hash for all parameters in the aggregate, then uses it in calculations. -- Uses combination of three algorithms: array, hash table and HyperLogLog with an error correction table. +- Uses a combination of three algorithms: array, hash table, and HyperLogLog with an error correction table. - For small number of distinct elements, the array is used. When the set size becomes larger the hash table is used, while it is smaller than HyperLogLog data structure. For larger number of elements, the HyperLogLog is used, and it will occupy fixed amount of memory. + For a small number of distinct elements, an array is used. When the set size is larger, a hash table is used. For a larger number of elements, HyperLogLog is used, which will occupy a fixed amount of memory. -- Provides the result deterministically (it doesn't depend on the order of query processing). +- Provides the result deterministically (it doesn't depend on the query processing order). -In comparison with the [uniq](#agg_function-uniq) function the `uniqCombined`: +Compared to the [uniq](#agg_function-uniq) function, the `uniqCombined`: - Consumes several times less memory. - Calculates with several times higher accuracy. -- Performs slightly lower usually. In some scenarios `uniqCombined` can perform better than `uniq`, for example, with distributed queries that transmit a large number of aggregation states over the network. +- Usually has slightly lower performance. In some scenarios, `uniqCombined` can perform better than `uniq`, for example, with distributed queries that transmit a large number of aggregation states over the network. **See Also** @@ -593,7 +593,7 @@ In comparison with the [uniq](#agg_function-uniq) function the `uniqCombined`: ## uniqHLL12 {#agg_function-uniqhll12} -Calculates the approximate number of different values of the argument, using the [HyperLogLog](https://en.wikipedia.org/wiki/HyperLogLog) algortithm. +Calculates the approximate number of different argument values, using the [HyperLogLog](https://en.wikipedia.org/wiki/HyperLogLog) algorithm. ``` uniqHLL12(x[, ...]) @@ -601,22 +601,22 @@ uniqHLL12(x[, ...]) **Parameters** -Function takes the variable number of parameters. Parameters can be of types: `Tuple`, `Array`, `Date`, `DateTime`, `String`, numeric types. +The function takes a variable number of parameters. Parameters can be `Tuple`, `Array`, `Date`, `DateTime`, `String`, or numeric types. **Returned value** -- The number of the [UInt64](../../data_types/int_uint.md) type. +- A [UInt64](../../data_types/int_uint.md)-type number. **Implementation details** Function: - Calculates a hash for all parameters in the aggregate, then uses it in calculations. -- Uses the HyperLogLog algorithm to approximate the number of different values of the argument. +- Uses the HyperLogLog algorithm to approximate the number of different argument values. 212 5-bit cells are used. The size of the state is slightly more than 2.5 KB. The result is not very accurate (up to ~10% error) for small data sets (<10K elements). However, the result is fairly accurate for high-cardinality data sets (10K-100M), with a maximum error of ~1.6%. Starting from 100M, the estimation error increases, and the function will return very inaccurate results for data sets with extremely high cardinality (1B+ elements). -- Provides the determinate result (it doesn't depend on the order of query processing). +- Provides the determinate result (it doesn't depend on the query processing order). We don't recommend using this function. In most cases, use the [uniq](#agg_function-uniq) or [uniqCombined](#agg_function-uniqcombined) function. @@ -629,19 +629,19 @@ We don't recommend using this function. In most cases, use the [uniq](#agg_funct ## uniqExact {#agg_function-uniqexact} -Calculates the exact number of different values of the argument. +Calculates the exact number of different argument values. ``` uniqExact(x[, ...]) ``` -Use the `uniqExact` function if you definitely need an exact result. Otherwise use the [uniq](#agg_function-uniq) function. +Use the `uniqExact` function if you absolutely need an exact result. Otherwise use the [uniq](#agg_function-uniq) function. -The `uniqExact` function uses more memory than the `uniq`, because the size of the state has unbounded growth as the number of different values increases. +The `uniqExact` function uses more memory than `uniq`, because the size of the state has unbounded growth as the number of different values increases. **Parameters** -Function takes the variable number of parameters. Parameters can be of types: `Tuple`, `Array`, `Date`, `DateTime`, `String`, numeric types. +The function takes a variable number of parameters. Parameters can be `Tuple`, `Array`, `Date`, `DateTime`, `String`, or numeric types. **See Also** diff --git a/docs/ru/operations/settings/settings.md b/docs/ru/operations/settings/settings.md index 25804d67322..b5ce6e25be6 100644 --- a/docs/ru/operations/settings/settings.md +++ b/docs/ru/operations/settings/settings.md @@ -715,6 +715,19 @@ load_balancing = first_or_random - [insert_quorum](#settings-insert_quorum) - [insert_quorum_timeout](#settings-insert_quorum_timeout) +## count_distinct_implementation {#settings-count_distinct_implementation} + +Задаёт, какая из функций `uniq*` используется при выполнении конструкции [COUNT(DISTINCT ...)](../../query_language/agg_functions/reference.md#agg_function-count). + +Возможные значения: + +- [uniq](../../query_language/agg_functions/reference.md#agg_function-uniq) +- [uniqCombined](../../query_language/agg_functions/reference.md#agg_function-uniqcombined) +- [uniqHLL12](../../query_language/agg_functions/reference.md#agg_function-uniqhll12) +- [uniqExact](../../query_language/agg_functions/reference.md#agg_function-uniqexact) + +Значение по умолчанию — `uniqExact`. + ## max_network_bytes {#settings-max_network_bytes} Ограничивает объем данных (в байтах), который принимается или передается по сети при выполнении запроса. Параметр применяется к каждому отдельному запросу. diff --git a/docs/ru/query_language/agg_functions/reference.md b/docs/ru/query_language/agg_functions/reference.md index 6247b74f657..fca564b7a14 100644 --- a/docs/ru/query_language/agg_functions/reference.md +++ b/docs/ru/query_language/agg_functions/reference.md @@ -1,11 +1,71 @@ # Справочник функций -## count() {#agg_function-count} +## count {#agg_function-count} -Считает количество строк. Принимает ноль аргументов, возвращает UInt64. -Не поддерживается синтаксис `COUNT (DISTINCT x)`. Для этого существует агрегатная функция`uniq`. +Вычисляет количество строк или не NULL значений . -Запрос вида `SELECT count() FROM table` не оптимизируется, так как количество записей в таблице нигде не хранится отдельно. Из таблицы будет выбран какой-нибудь достаточно маленький столбец, и будет посчитано количество значений в нём. +ClickHouse поддерживает следующие виды синтаксиса для `count`: + +- `count(expr)` или `COUNT(DISTINCT expr)`. +- `count()` или `COUNT(*)`. Синтаксис `count()` специфичен для ClickHouse. + +**Параметры** + +Функция может принимать: + +- Ноль параметров. +- Одно [выражение](../syntax.md#syntax-expressions). + +**Возвращаемое значение** + +- Если функция вызывается без параметров, она вычисляет количество строк. +- Если передаётся [выражение](../syntax.md#syntax-expressions) , то функция вычисляет количество раз, когда выражение возвращает не NULL. Если выражение возвращает значение типа [Nullable](../../data_types/nullable.md), то результат `count` не становится `Nullable`. Функция возвращает 0, если выражение возвращает `NULL` для всех строк. + +В обоих случаях тип возвращаемого значения [UInt64](../../data_types/int_uint.md). + +**Подробности** + +ClickHouse поддерживает синтаксис `COUNT(DISTINCT ...)`. Поведение этой конструкции зависит от настройки [count_distinct_implementation](../../operations/settings/settings.md#settings-count_distinct_implementation). Она определяет, какая из функций [uniq*](#agg_function-uniq) используется для выполнения операции. По умолчанию — функция [uniqExact](#agg_function-uniqexact). + +Запрос `SELECT count() FROM table` не оптимизирован, поскольку количество записей в таблице не хранится отдельно. Он выбирает небольшой столбец из таблицы и подсчитывает количество значений в нём. + +**Примеры** + +Пример 1: + +```sql +SELECT count() FROM t +``` + +```text +┌─count()─┐ +│ 5 │ +└─────────┘ +``` + +Пример 2: + +```sql +SELECT name, value FROM system.settings WHERE name = 'count_distinct_implementation' +``` + +```text +┌─name──────────────────────────┬─value─────┐ +│ count_distinct_implementation │ uniqExact │ +└───────────────────────────────┴───────────┘ +``` + +```sql +SELECT count(DISTINCT num) FROM t +``` + +```text +┌─uniqExact(num)─┐ +│ 3 │ +└────────────────┘ +``` + +Этот пример показывает, что `count(DISTINCT num)` выполняется с помощью функции `uniqExact` в соответствии со значением настройки `count_distinct_implementation`. ## any(x) {#agg_function-any} @@ -59,7 +119,7 @@ groupBitAnd(expr) **Параметры** -`expr` – Выражение, результат которого имеет тип `UInt*`. +`expr` – выражение, результат которого имеет тип данных `UInt*`. **Возвращаемое значение** @@ -97,12 +157,12 @@ binary decimal Применяет побитовое `ИЛИ` для последовательности чисел. ``` -groupBitOr (expr) +groupBitOr(expr) ``` **Параметры** -`expr` – Выражение, результат которого имеет тип `UInt*`. +`expr` – выражение, результат которого имеет тип данных `UInt*`. **Возвращаемое значение** @@ -145,7 +205,7 @@ groupBitXor(expr) **Параметры** -`expr` – Выражение, результат которого имеет тип `UInt*`. +`expr` – выражение, результат которого имеет тип данных `UInt*`. **Возвращаемое значение** @@ -188,7 +248,7 @@ groupBitmap(expr) **Параметры** -`expr` – выражение, возвращающее тип данных `UInt*`. +`expr` – выражение, результат которого имеет тип данных `UInt*`. **Возвращаемое значение** @@ -227,7 +287,7 @@ num Вычисляет максимум. -## argMin(arg, val) +## argMin(arg, val) {#agg_function-argMin} Вычисляет значение arg при минимальном значении val. Если есть несколько разных значений arg для минимальных значений val, то выдаётся первое попавшееся из таких значений. @@ -247,7 +307,7 @@ SELECT argMin(user, salary) FROM salary └──────────────────────┘ ``` -## argMax(arg, val) +## argMax(arg, val) {#agg_function-argMax} Вычисляет значение arg при максимальном значении val. Если есть несколько разных значений arg для максимальных значений val, то выдаётся первое попавшееся из таких значений. @@ -461,45 +521,143 @@ FROM ( Работает только для чисел. Результат всегда Float64. -## uniq(x) {#agg_function-uniq} +## uniq {#agg_function-uniq} -Приближённо вычисляет количество различных значений аргумента. Работает для чисел, строк, дат, дат-с-временем, для нескольких аргументов и аргументов-кортежей. +Приближённо вычисляет количество различных значений аргумента. -Используется алгоритм типа adaptive sampling: в качестве состояния вычислений используется выборка значений хэшей элементов, размером до 65536. -Алгоритм является очень точным для множеств небольшой кардинальности (до 65536) и очень эффективным по CPU (при расчёте не слишком большого количества таких функций, использование `uniq` почти так же быстро, как использование других агрегатных функций). +``` +uniq(x[, ...]) +``` -Результат детерминирован (не зависит от порядка выполнения запроса). +**Параметры** -Функция обеспечивает высокую точность даже для множеств с высокой кардинальностью (более 10 миллиардов элементов). Рекомендуется для использования по умолчанию. +Функция принимает переменное число входных параметров. Параметры могут быть числовых типов, а также `Tuple`, `Array`, `Date`, `DateTime`, `String`. -## uniqCombined(HLL_precision)(x) +**Возвращаемое значение** -Приближённо вычисляет количество различных значений аргумента. Работает для чисел, строк, дат, дат-с-временем, для нескольких аргументов и аргументов-кортежей. +- Значение с типом данных [UInt64](../../data_types/int_uint.md). -Используется комбинация трёх алгоритмов: массив, хэш-таблица и [HyperLogLog](https://en.wikipedia.org/wiki/HyperLogLog) с таблицей коррекции погрешности. Для небольшого количества различных значений используется массив; при увеличении количества значений, используется хэш таблица, до тех пор, пока её размер меньше размера HyperLogLog структуры. При дальнейшем увеличении количества значений, используется HyperLogLog структура, имеющая фиксированный размер в памяти. +**Детали реализации** -Параметр HLL_precision - логарифм по основанию 2 от количества ячеек в HyperLogLog. Параметер можно не указывать (для этого, опустите первую пару скобок). По-умолчанию - 17. При использовании параметра по-умолчанию, расход памяти в несколько раз меньше, чем у функции `uniq`, а точность в несколько раз выше. Скорость работы чуть ниже, чем у функции `uniq`, но иногда может быть даже выше - в случае распределённых запросов, в которых по сети передаётся большое количество состояний агрегации. Каждая ячейка имеет размер 6 бит, что даёт 96 KiB для размера HyperLogLog структуры. +Функция: -Результат детерминирован (не зависит от порядка выполнения запроса). +- Вычисляет хэш для всех параметров агрегации, а затем использует его в вычислениях. -Функция `uniqCombined` является хорошим выбором по умолчанию для подсчёта количества различных значений, но стоит иметь ввиду что для множеств большой кардинальности (200 миллионов различных элементов и больше) ошибка оценки становится существенно больше расчётной из-за недостаточно хорошего выбора хэш-функции. +- Использует адаптивный алгоритм выборки. В качестве состояния вычисления функция использует выборку хэш-значений элементов размером до 65536. -## uniqHLL12(x) + Этот алгоритм очень точен и очень эффективен по использованию CPU. Если запрос содержит небольшое количество этих функций, использование `uniq` почти так же эффективно, как и использование других агрегатных функций. -Приближённо вычисляет количество различных значений аргумента, используя алгоритм [HyperLogLog](https://en.wikipedia.org/wiki/HyperLogLog). -Используется 212 5-битовых ячеек. Размер состояния чуть больше 2.5 КБ. Результат не очень точный (ошибка до ~10%) для небольших множеств (<10К элементов). Однако, для множеств с большой кардинальностью (10К - 100М) результат имеет ошибку до ~1.6%. Начиная со 100M, ошибка оценки увеличивается и для множеств огромной кардинальности (1B+ элементов) результат будет очень неточным. +- Результат детерминирован (не зависит от порядка выполнения запроса). -Результат детерминирован (не зависит от порядка выполнения запроса). +Эту функцию рекомендуется использовать практически во всех сценариях. -Мы не рекомендуем использовать эту функцию. В большинстве случаев, используйте функцию `uniq` или `uniqCombined`. +**Смотрите также** -## uniqExact(x) +- [uniqCombined](#agg_function-uniqcombined) +- [uniqHLL12](#agg_function-uniqhll12) +- [uniqExact](#agg_function-uniqexact) -Вычисляет количество различных значений аргумента, точно. -Не стоит бояться приближённых расчётов. Поэтому, используйте лучше функцию `uniq`. -Функцию `uniqExact` следует использовать, если вам точно нужен точный результат. +## uniqCombined {#agg_function-uniqcombined} -Функция `uniqExact` расходует больше оперативки, чем функция `uniq`, так как размер состояния неограниченно растёт по мере роста количества различных значений. +Приближённо вычисляет количество различных значений аргумента. + +``` +uniqCombined(HLL_precision)(x[, ...]) +``` + +Функция `uniqCombined` — это хороший выбор для вычисления количества различных значений, однако стоит иметь в виду, что ошибка оценки для больших множеств (более 200 миллионов элементов) будет выше теоретического значения из-за плохого выбора хэш-функции. + +**Параметры** + +Функция принимает переменное число входных параметров. Параметры могут быть числовых типов, а также `Tuple`, `Array`, `Date`, `DateTime`, `String`. + +`HLL_precision` — это логарифм по основанию 2 от числа ячеек в [HyperLogLog](https://en.wikipedia.org/wiki/HyperLogLog). Необязательный, можно использовать функцию как `uniqCombined (x [,...])`. Для `HLL_precision` значение по умолчанию — 17, что фактически составляет 96 КБ пространства (2^17 ячеек, 6 бит каждая). + +**Возвращаемое значение** + +- Число типа [UInt64](../../data_types/int_uint.md). + +**Детали реализации** + +Функция: + +- Вычисляет хэш для всех параметров агрегации, а затем использует его в вычислениях. + +- Используется комбинация трёх алгоритмов: массив, хэш-таблица и HyperLogLog с таблицей коррекции погрешности. + + Для небольшого количества различных значений используется массив. Если размер набора больше, используется хэш-таблица. При дальнейшем увеличении количества значений, используется структура HyperLogLog, имеющая фиксированный размер в памяти. + +- Результат детерминирован (не зависит от порядка выполнения запроса). + +По сравнению с функцией [uniq](#agg_function-uniq), `uniqCombined`: + +- Потребляет в несколько раз меньше памяти. +- Вычисляет с в несколько раз более высокой точностью. +- Обычно имеет немного более низкую производительность. В некоторых сценариях `uniqCombined` может показывать более высокую производительность, чем `uniq`, например, в случае распределенных запросов, при которых по сети передаётся большое количество состояний агрегации. + +**Смотрите также** + +- [uniq](#agg_function-uniq) +- [uniqHLL12](#agg_function-uniqhll12) +- [uniqExact](#agg_function-uniqexact) + +## uniqHLL12 {#agg_function-uniqhll12} + +Вычисляет приблизительное число различных значений аргументов, используя алгоритм [HyperLogLog](https://en.wikipedia.org/wiki/HyperLogLog). + +``` +uniqHLL12(x[, ...]) +``` + +**Параметры** + +Функция принимает переменное число входных параметров. Параметры могут быть числовых типов, а также `Tuple`, `Array`, `Date`, `DateTime`, `String`. + +**Возвращаемое значение** + +- Значение хэша с типом данных [UInt64](../../data_types/int_uint.md). + +**Детали реализации** + +Функция: + +- Вычисляет хэш для всех параметров агрегации, а затем использует его в вычислениях. + +- Использует алгоритм HyperLogLog для аппроксимации числа различных значений аргументов. + + Используется 212 5-битовых ячеек. Размер состояния чуть больше 2.5 КБ. Результат не точный (ошибка до ~10%) для небольших множеств (<10K элементов). Однако для множеств большой кардинальности (10K - 100M) результат довольно точен (ошибка до ~1.6%). Начиная с 100M ошибка оценки будет только расти и для множеств огромной кардинальности (1B+ элементов) функция возвращает результат с очень большой неточностью. + +- Результат детерминирован (не зависит от порядка выполнения запроса). + +Мы не рекомендуем использовать эту функцию. В большинстве случаев используйте функцию [uniq](#agg_function-uniq) или [uniqCombined](#agg_function-uniqcombined). + +**Смотрите также** + +- [uniq](#agg_function-uniq) +- [uniqCombined](#agg_function-uniqcombined) +- [uniqExact](#agg_function-uniqexact) + +## uniqExact {#agg_function-uniqexact} + +Вычисляет точное количество различных значений аргументов. + +``` +uniqExact(x[, ...]) +``` + +Функцию `uniqExact` следует использовать, если вам обязательно нужен точный результат. В противном случае используйте функцию [uniq](#agg_function-uniq). + +Функция `uniqExact` расходует больше оперативной памяти, чем функция `uniq`, так как размер состояния неограниченно растёт по мере роста количества различных значений. + +**Параметры** + +Функция принимает переменное число входных параметров. Параметры могут быть числовых типов, а также `Tuple`, `Array`, `Date`, `DateTime`, `String`. + +**Смотрите также** + +- [uniq](#agg_function-uniq) +- [uniqCombined](#agg_function-uniqcombined) +- [uniqHLL12](#agg_function-uniqhll12) ## groupArray(x), groupArray(max_size)(x) @@ -847,3 +1005,4 @@ stochasticLogisticRegression(1.0, 1.0, 10, 'SGD') - [Отличие линейной от логистической регрессии](https://moredez.ru/q/51225972/) [Оригинальная статья](https://clickhouse.yandex/docs/ru/query_language/agg_functions/reference/) + From cf746c3eed94987127d2637e7e25157ee61eb00a Mon Sep 17 00:00:00 2001 From: BayoNet Date: Wed, 31 Jul 2019 08:09:13 +0300 Subject: [PATCH 0508/1165] DOCAPI-3825: System tables. EN review, RU translation. (#6088) --- dbms/src/Common/CurrentMetrics.cpp | 12 +-- dbms/src/Common/ProfileEvents.cpp | 4 +- docs/en/operations/system_tables.md | 48 ++++++----- docs/ru/operations/system_tables.md | 122 ++++++++++++++++++++++++---- 4 files changed, 138 insertions(+), 48 deletions(-) diff --git a/dbms/src/Common/CurrentMetrics.cpp b/dbms/src/Common/CurrentMetrics.cpp index 2f8346d554e..070afd3b231 100644 --- a/dbms/src/Common/CurrentMetrics.cpp +++ b/dbms/src/Common/CurrentMetrics.cpp @@ -6,13 +6,13 @@ M(Query, "Number of executing queries") \ M(Merge, "Number of executing background merges") \ M(PartMutation, "Number of mutations (ALTER DELETE/UPDATE)") \ - M(ReplicatedFetch, "Number of data parts fetching from replica") \ - M(ReplicatedSend, "Number of data parts sending to replicas") \ + M(ReplicatedFetch, "Number of data parts being fetched from replica") \ + M(ReplicatedSend, "Number of data parts being sent to replicas") \ M(ReplicatedChecks, "Number of data parts checking for consistency") \ - M(BackgroundPoolTask, "Number of active tasks in BackgroundProcessingPool (merges, mutations, fetches or replication queue bookkeeping)") \ - M(BackgroundSchedulePoolTask, "Number of active tasks in BackgroundSchedulePool. This pool is used for periodic tasks of ReplicatedMergeTree like cleaning old data parts, altering data parts, replica re-initialization, etc.") \ - M(DiskSpaceReservedForMerge, "Disk space reserved for currently running background merges. It is slightly more than total size of currently merging parts.") \ - M(DistributedSend, "Number of connections sending data, that was INSERTed to Distributed tables, to remote servers. Both synchronous and asynchronous mode.") \ + M(BackgroundPoolTask, "Number of active tasks in BackgroundProcessingPool (merges, mutations, fetches, or replication queue bookkeeping)") \ + M(BackgroundSchedulePoolTask, "Number of active tasks in BackgroundSchedulePool. This pool is used for periodic ReplicatedMergeTree tasks, like cleaning old data parts, altering data parts, replica re-initialization, etc.") \ + M(DiskSpaceReservedForMerge, "Disk space reserved for currently running background merges. It is slightly more than the total size of currently merging parts.") \ + M(DistributedSend, "Number of connections to remote servers sending data that was INSERTed into Distributed tables. Both synchronous and asynchronous mode.") \ M(QueryPreempted, "Number of queries that are stopped and waiting due to 'priority' setting.") \ M(TCPConnection, "Number of connections to TCP server (clients with native interface)") \ M(HTTPConnection, "Number of connections to HTTP server") \ diff --git a/dbms/src/Common/ProfileEvents.cpp b/dbms/src/Common/ProfileEvents.cpp index 277aafa9eb8..e9b11c823ed 100644 --- a/dbms/src/Common/ProfileEvents.cpp +++ b/dbms/src/Common/ProfileEvents.cpp @@ -5,14 +5,14 @@ /// Available events. Add something here as you wish. #define APPLY_FOR_EVENTS(M) \ - M(Query, "Number of queries started to be interpreted and maybe executed. Does not include queries that are failed to parse, that are rejected due to AST size limits; rejected due to quota limits or limits on number of simultaneously running queries. May include internal queries initiated by ClickHouse itself. Does not count subqueries.") \ + M(Query, "Number of queries to be interpreted and potentially executed. Does not include queries that failed to parse or were rejected due to AST size limits, quota limits or limits on the number of simultaneously running queries. May include internal queries initiated by ClickHouse itself. Does not count subqueries.") \ M(SelectQuery, "Same as Query, but only for SELECT queries.") \ M(InsertQuery, "Same as Query, but only for INSERT queries.") \ M(FileOpen, "Number of files opened.") \ M(Seek, "Number of times the 'lseek' function was called.") \ M(ReadBufferFromFileDescriptorRead, "Number of reads (read/pread) from a file descriptor. Does not include sockets.") \ M(ReadBufferFromFileDescriptorReadFailed, "Number of times the read (read/pread) from a file descriptor have failed.") \ - M(ReadBufferFromFileDescriptorReadBytes, "Number of bytes read from file descriptors. If the file is compressed, this will show compressed data size.") \ + M(ReadBufferFromFileDescriptorReadBytes, "Number of bytes read from file descriptors. If the file is compressed, this will show the compressed data size.") \ M(WriteBufferFromFileDescriptorWrite, "Number of writes (write/pwrite) to a file descriptor. Does not include sockets.") \ M(WriteBufferFromFileDescriptorWriteFailed, "Number of times the write (write/pwrite) to a file descriptor have failed.") \ M(WriteBufferFromFileDescriptorWriteBytes, "Number of bytes written to file descriptors. If the file is compressed, this will show compressed data size.") \ diff --git a/docs/en/operations/system_tables.md b/docs/en/operations/system_tables.md index e63a9115270..6c99c299aa5 100644 --- a/docs/en/operations/system_tables.md +++ b/docs/en/operations/system_tables.md @@ -8,12 +8,12 @@ They are located in the 'system' database. ## system.asynchronous_metrics {#system_tables-asynchronous_metrics} -Contains metrics which are calculated periodically in background. For example, the amount of RAM in use. +Contains metrics that are calculated periodically in the background. For example, the amount of RAM in use. Columns: -- `metric` ([String](../data_types/string.md)) — Metric's name. -- `value` ([Float64](../data_types/float.md)) — Metric's value. +- `metric` ([String](../data_types/string.md)) — Metric name. +- `value` ([Float64](../data_types/float.md)) — Metric value. **Example** @@ -40,7 +40,7 @@ SELECT * FROM system.asynchronous_metrics LIMIT 10 - [Monitoring](monitoring.md) — Base concepts of ClickHouse monitoring. - [system.metrics](#system_tables-metrics) — Contains instantly calculated metrics. -- [system.events](#system_tables-events) — Contains a number of happened events. +- [system.events](#system_tables-events) — Contains a number of events that have occurred. ## system.clusters @@ -48,7 +48,7 @@ Contains information about clusters available in the config file and the servers Columns: ``` -cluster String — The cluster name. +cluster String — The cluster name. shard_num UInt32 — The shard number in the cluster, starting from 1. shard_weight UInt32 — The relative weight of the shard when writing data. replica_num UInt32 — The replica number in the shard, starting from 1. @@ -119,13 +119,13 @@ Note that the amount of memory used by the dictionary is not proportional to the ## system.events {#system_tables-events} -Contains information about the number of events that have occurred in the system. For example, in the table, you can find how many `SELECT` queries are processed from the moment of ClickHouse server start. +Contains information about the number of events that have occurred in the system. For example, in the table, you can find how many `SELECT` queries were processed since the ClickHouse server started. Columns: - `event` ([String](../data_types/string.md)) — Event name. -- `value` ([UInt64](../data_types/int_uint.md)) — Count of events occurred. -- `description` ([String](../data_types/string.md)) — Description of an event. +- `value` ([UInt64](../data_types/int_uint.md)) — Number of events occurred. +- `description` ([String](../data_types/string.md)) — Event description. **Example** @@ -135,11 +135,11 @@ SELECT * FROM system.events LIMIT 5 ```text ┌─event─────────────────────────────────┬─value─┬─description────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ Query │ 12 │ Number of queries started to be interpreted and maybe executed. Does not include queries that are failed to parse, that are rejected due to AST size limits; rejected due to quota limits or limits on number of simultaneously running queries. May include internal queries initiated by ClickHouse itself. Does not count subqueries. │ +│ Query │ 12 │ Number of queries to be interpreted and potentially executed. Does not include queries that failed to parse or were rejected due to AST size limits, quota limits or limits on the number of simultaneously running queries. May include internal queries initiated by ClickHouse itself. Does not count subqueries. │ │ SelectQuery │ 8 │ Same as Query, but only for SELECT queries. │ │ FileOpen │ 73 │ Number of files opened. │ │ ReadBufferFromFileDescriptorRead │ 155 │ Number of reads (read/pread) from a file descriptor. Does not include sockets. │ -│ ReadBufferFromFileDescriptorReadBytes │ 9931 │ Number of bytes read from file descriptors. If the file is compressed, this will show compressed data size. │ +│ ReadBufferFromFileDescriptorReadBytes │ 9931 │ Number of bytes read from file descriptors. If the file is compressed, this will show the compressed data size. │ └───────────────────────────────────────┴───────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ``` @@ -197,13 +197,13 @@ Columns: ## system.metrics {#system_tables-metrics} -Contains metrics which can be calculated instantly, or have an current value. For example, a number of simultaneously processed queries, the current value for replica delay. This table is always up to date. +Contains metrics which can be calculated instantly, or have a current value. For example, the number of simultaneously processed queries or the current replica delay. This table is always up to date. Columns: -- `metric` ([String](../data_types/string.md)) — Metric's name. -- `value` ([Int64](../data_types/int_uint.md)) — Metric's value. -- `description` ([String](../data_types/string.md)) — Description of the metric. +- `metric` ([String](../data_types/string.md)) — Metric name. +- `value` ([Int64](../data_types/int_uint.md)) — Metric value. +- `description` ([String](../data_types/string.md)) — Metric description. **Example** @@ -216,19 +216,19 @@ SELECT * FROM system.metrics LIMIT 10 │ Query │ 1 │ Number of executing queries │ │ Merge │ 0 │ Number of executing background merges │ │ PartMutation │ 0 │ Number of mutations (ALTER DELETE/UPDATE) │ -│ ReplicatedFetch │ 0 │ Number of data parts fetching from replica │ -│ ReplicatedSend │ 0 │ Number of data parts sending to replicas │ +│ ReplicatedFetch │ 0 │ Number of data parts being fetched from replicas │ +│ ReplicatedSend │ 0 │ Number of data parts being sent to replicas │ │ ReplicatedChecks │ 0 │ Number of data parts checking for consistency │ -│ BackgroundPoolTask │ 0 │ Number of active tasks in BackgroundProcessingPool (merges, mutations, fetches or replication queue bookkeeping) │ -│ BackgroundSchedulePoolTask │ 0 │ Number of active tasks in BackgroundSchedulePool. This pool is used for periodic tasks of ReplicatedMergeTree like cleaning old data parts, altering data parts, replica re-initialization, etc. │ -│ DiskSpaceReservedForMerge │ 0 │ Disk space reserved for currently running background merges. It is slightly more than total size of currently merging parts. │ -│ DistributedSend │ 0 │ Number of connections sending data, that was INSERTed to Distributed tables, to remote servers. Both synchronous and asynchronous mode. │ +│ BackgroundPoolTask │ 0 │ Number of active tasks in BackgroundProcessingPool (merges, mutations, fetches, or replication queue bookkeeping) │ +│ BackgroundSchedulePoolTask │ 0 │ Number of active tasks in BackgroundSchedulePool. This pool is used for periodic ReplicatedMergeTree tasks, like cleaning old data parts, altering data parts, replica re-initialization, etc. │ +│ DiskSpaceReservedForMerge │ 0 │ Disk space reserved for currently running background merges. It is slightly more than the total size of currently merging parts. │ +│ DistributedSend │ 0 │ Number of connections to remote servers sending data that was INSERTed into Distributed tables. Both synchronous and asynchronous mode. │ └────────────────────────────┴───────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ``` **See Also** - [system.asynchronous_metrics](#system_tables-asynchronous_metrics) — Contains periodically calculated metrics. -- [system.events](#system_tables-events) — Contains a umber of happened events. +- [system.events](#system_tables-events) — Contains a number of events that occurred. - [Monitoring](monitoring.md) — Base concepts of ClickHouse monitoring. ## system.numbers @@ -368,7 +368,7 @@ To enable query logging, set the parameter [log_queries](settings/settings.md#se The `system.query_log` table registers two kinds of queries: 1. Initial queries, that were run directly by the client. -2. Child queries that were initiated by other queries (for distributed query execution). For such a kind of queries, information about the parent queries is shown in the `initial_*` columns. +2. Child queries that were initiated by other queries (for distributed query execution). For such queries, information about parent queries is shown in the `initial_*` columns. Columns: @@ -391,9 +391,7 @@ Columns: - `query` (String) — Query string. - `exception` (String) — Exception message. - `stack_trace` (String) — Stack trace (a list of methods called before the error occurred). An empty string, if the query is completed successfully. -- `is_initial_query` (UInt8) — Kind of query. Possible values: - - 1 — Query was initiated by the client. - - 0 — Query was initiated by another query for distributed query execution. +- `is_initial_query` (UInt8) — Flag that indicates whether the query is initiated by the client (1), or by another query for distributed query execution (0). - `user` (String) — Name of the user initiated the current query. - `query_id` (String) — ID of the query. - `address` (FixedString(16)) — IP address the query was initiated from. diff --git a/docs/ru/operations/system_tables.md b/docs/ru/operations/system_tables.md index eb452c8de4e..da58fbe9ca1 100644 --- a/docs/ru/operations/system_tables.md +++ b/docs/ru/operations/system_tables.md @@ -8,10 +8,39 @@ ## system.asynchronous_metrics {#system_tables-asynchronous_metrics} -Содержат метрики, используемые для профилирования и мониторинга. -Обычно отражают количество событий, происходящих в данный момент в системе, или ресурсов, суммарно потребляемых системой. -Пример: количество запросов типа SELECT, исполняемых в текущий момент; количество потребляемой памяти. -`system.asynchronous_metrics` и `system.metrics` отличаются набором и способом вычисления метрик. +Содержит метрики, которые периодически вычисляются в фоновом режиме. Например, объем используемой оперативной памяти. + +Столбцы: + +- `metric` ([String](../data_types/string.md)) — название метрики. +- `value` ([Float64](../data_types/float.md)) — значение метрики. + +**Пример** + +```sql +SELECT * FROM system.asynchronous_metrics LIMIT 10 +``` + +```text +┌─metric──────────────────────────────────┬──────value─┐ +│ jemalloc.background_thread.run_interval │ 0 │ +│ jemalloc.background_thread.num_runs │ 0 │ +│ jemalloc.background_thread.num_threads │ 0 │ +│ jemalloc.retained │ 422551552 │ +│ jemalloc.mapped │ 1682989056 │ +│ jemalloc.resident │ 1656446976 │ +│ jemalloc.metadata_thp │ 0 │ +│ jemalloc.metadata │ 10226856 │ +│ UncompressedCacheCells │ 0 │ +│ MarkCacheFiles │ 0 │ +└─────────────────────────────────────────┴────────────┘ +``` + +**Смотрите также** + +- [Мониторинг](monitoring.md) — основы мониторинга в ClickHouse. +- [system.metrics](#system_tables-metrics) — таблица с мгновенно вычисляемыми метриками. +- [system.events](#system_tables-events) — таблица с количеством произошедших событий. ## system.clusters @@ -19,15 +48,16 @@ Столбцы: ``` -cluster String - имя кластера -shard_num UInt32 - номер шарда в кластере, начиная с 1 -shard_weight UInt32 - относительный вес шарда при записи данных -replica_num UInt32 - номер реплики в шарде, начиная с 1 -host_name String - имя хоста, как прописано в конфиге -host_address String - IP-адрес хоста, полученный из DNS -port UInt16 - порт, на который обращаться для соединения с сервером -user String - имя пользователя, которого использовать для соединения с сервером +cluster String — имя кластера. +shard_num UInt32 — номер шарда в кластере, начиная с 1. +shard_weight UInt32 — относительный вес шарда при записи данных +replica_num UInt32 — номер реплики в шарде, начиная с 1. +host_name String — хост, указанный в конфигурации. +host_address String — IP-адрес хоста, полученный из DNS. +port UInt16 — порт, на который обращаться для соединения с сервером. +user String — имя пользователя, которого использовать для соединения с сервером. ``` + ## system.columns Содержит информацию о столбцах всех таблиц. @@ -72,9 +102,35 @@ default_expression String - выражение для значения по ум ## system.events {#system_tables-events} -Содержит информацию о количестве произошедших в системе событий, для профилирования и мониторинга. -Пример: количество обработанных запросов типа SELECT. -Столбцы: event String - имя события, value UInt64 - количество. +Содержит информацию о количестве событий, произошедших в системе. Например, в таблице можно найти, сколько запросов `SELECT` обработано с момента запуска сервера ClickHouse. + +Столбцы: + +- `event` ([String](../data_types/string.md)) — имя события. +- `value` ([UInt64](../data_types/int_uint.md)) — количество произошедших событий. +- `description` ([String](../data_types/string.md)) — описание события. + +**Пример** + +```sql +SELECT * FROM system.events LIMIT 5 +``` + +```text +┌─event─────────────────────────────────┬─value─┬─description────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Query │ 12 │ Number of queries to be interpreted and potentially executed. Does not include queries that failed to parse or were rejected due to AST size limits, quota limits or limits on the number of simultaneously running queries. May include internal queries initiated by ClickHouse itself. Does not count subqueries. │ +│ SelectQuery │ 8 │ Same as Query, but only for SELECT queries. │ +│ FileOpen │ 73 │ Number of files opened. │ +│ ReadBufferFromFileDescriptorRead │ 155 │ Number of reads (read/pread) from a file descriptor. Does not include sockets. │ +│ ReadBufferFromFileDescriptorReadBytes │ 9931 │ Number of bytes read from file descriptors. If the file is compressed, this will show the compressed data size. │ +└───────────────────────────────────────┴───────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +``` + +**Смотрите также** + +- [system.asynchronous_metrics](#system_tables-asynchronous_metrics) — таблица с периодически вычисляемыми метриками. +- [system.metrics](#system_tables-metrics) — таблица с мгновенно вычисляемыми метриками. +- [Мониторинг](monitoring.md) — основы мониторинга в ClickHouse. ## system.functions @@ -123,11 +179,47 @@ default_expression String - выражение для значения по ум ## system.metrics {#system_tables-metrics} +Содержит метрики, которые могут быть рассчитаны мгновенно или имеют текущее значение. Например, число одновременно обрабатываемых запросов или текущее значение задержки реплики. Эта таблица всегда актуальна. + +Столбцы: + +- `metric` ([String](../data_types/string.md)) — название метрики. +- `value` ([Int64](../data_types/int_uint.md)) — значение метрики. +- `description` ([String](../data_types/string.md)) — описание метрики. + +**Пример** + +```sql +SELECT * FROM system.metrics LIMIT 10 +``` + +```text +┌─metric─────────────────────┬─value─┬─description──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ Query │ 1 │ Number of executing queries │ +│ Merge │ 0 │ Number of executing background merges │ +│ PartMutation │ 0 │ Number of mutations (ALTER DELETE/UPDATE) │ +│ ReplicatedFetch │ 0 │ Number of data parts being fetched from replicas │ +│ ReplicatedSend │ 0 │ Number of data parts being sent to replicas │ +│ ReplicatedChecks │ 0 │ Number of data parts checking for consistency │ +│ BackgroundPoolTask │ 0 │ Number of active tasks in BackgroundProcessingPool (merges, mutations, fetches, or replication queue bookkeeping) │ +│ BackgroundSchedulePoolTask │ 0 │ Number of active tasks in BackgroundSchedulePool. This pool is used for periodic ReplicatedMergeTree tasks, like cleaning old data parts, altering data parts, replica re-initialization, etc. │ +│ DiskSpaceReservedForMerge │ 0 │ Disk space reserved for currently running background merges. It is slightly more than the total size of currently merging parts. │ +│ DistributedSend │ 0 │ Number of connections to remote servers sending data that was INSERTed into Distributed tables. Both synchronous and asynchronous mode. │ +└────────────────────────────┴───────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +``` + +**Смотрите также** + +- [system.asynchronous_metrics](#system_tables-asynchronous_metrics) — таблица с периодически вычисляемыми метриками. +- [system.events](#system_tables-events) — таблица с количеством произошедших событий. +- [Мониторинг](monitoring.md) — основы мониторинга в ClickHouse. + ## system.numbers Таблица содержит один столбец с именем number типа UInt64, содержащим почти все натуральные числа, начиная с нуля. Эту таблицу можно использовать для тестов, а также если вам нужно сделать перебор. Чтения из этой таблицы не распараллеливаются. + ## system.numbers_mt То же самое, что и system.numbers, но чтение распараллеливается. Числа могут возвращаться в произвольном порядке. From bd493727b655d95bcadcce9bff7a3a4aad8cf304 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Wed, 31 Jul 2019 08:55:10 +0300 Subject: [PATCH 0509/1165] DOCAPI-7460: Added link to algorithm. --- docs/en/query_language/agg_functions/parametric_functions.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/en/query_language/agg_functions/parametric_functions.md b/docs/en/query_language/agg_functions/parametric_functions.md index da6052545dc..d27cb5d9431 100644 --- a/docs/en/query_language/agg_functions/parametric_functions.md +++ b/docs/en/query_language/agg_functions/parametric_functions.md @@ -10,6 +10,8 @@ Calculates a histogram. histogram(number_of_bins)(values) ``` +The functions uses [A Streaming Parallel Decision Tree Algorithm](http://jmlr.org/papers/volume11/ben-haim10a/ben-haim10a.pdf). It calculates the borders of histogram bins automatically, and in common case the widths of bins are not equal. + **Parameters** `number_of_bins` — Number of bins for the histogram. From 5bdb6aa9f3edb307f5511aa24573cdf5be82747e Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 31 Jul 2019 12:43:08 +0300 Subject: [PATCH 0510/1165] Update TSKVRowInputFormat. --- dbms/src/Processors/Formats/Impl/TSKVRowInputFormat.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dbms/src/Processors/Formats/Impl/TSKVRowInputFormat.cpp b/dbms/src/Processors/Formats/Impl/TSKVRowInputFormat.cpp index 7750962beec..b03480834c5 100644 --- a/dbms/src/Processors/Formats/Impl/TSKVRowInputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/TSKVRowInputFormat.cpp @@ -16,15 +16,16 @@ namespace ErrorCodes TSKVRowInputFormat::TSKVRowInputFormat(ReadBuffer & in_, Block header, Params params, const FormatSettings & format_settings) - : IRowInputFormat(std::move(header), in_, params), format_settings(format_settings), name_map(header.columns()) + : IRowInputFormat(std::move(header), in_, std::move(params)), format_settings(format_settings), name_map(header.columns()) { /// In this format, we assume that column name cannot contain BOM, /// so BOM at beginning of stream cannot be confused with name of field, and it is safe to skip it. skipBOMIfExists(in); - size_t num_columns = header.columns(); + const auto & sample_block = getPort().getHeader(); + size_t num_columns = sample_block.columns(); for (size_t i = 0; i < num_columns; ++i) - name_map[header.safeGetByPosition(i).name] = i; /// NOTE You could place names more cache-locally. + name_map[sample_block.getByPosition(i).name] = i; /// NOTE You could place names more cache-locally. } @@ -200,7 +201,7 @@ void registerInputFormatProcessorTSKV(FormatFactory & factory) IRowInputFormat::Params params, const FormatSettings & settings) { - return std::make_shared(buf, sample, params, settings); + return std::make_shared(buf, sample, std::move(params), settings); }); } From 8bfd909f5b9b15f5cc59f9f0cb95f4644556d7e6 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 31 Jul 2019 13:06:46 +0300 Subject: [PATCH 0511/1165] Update JSONEachRowRowOutputFormat. --- .../Processors/Formats/Impl/JSONEachRowRowInputFormat.cpp | 4 ++-- .../src/Processors/Formats/Impl/JSONEachRowRowOutputFormat.h | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/dbms/src/Processors/Formats/Impl/JSONEachRowRowInputFormat.cpp b/dbms/src/Processors/Formats/Impl/JSONEachRowRowInputFormat.cpp index b1dde6d2275..100edb20f37 100644 --- a/dbms/src/Processors/Formats/Impl/JSONEachRowRowInputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/JSONEachRowRowInputFormat.cpp @@ -28,7 +28,7 @@ enum JSONEachRowRowInputFormat::JSONEachRowRowInputFormat( ReadBuffer & in_, const Block & header, Params params, const FormatSettings & format_settings) - : IRowInputFormat(header, in_, params), format_settings(format_settings), name_map(header.columns()) + : IRowInputFormat(header, in_, std::move(params)), format_settings(format_settings), name_map(header.columns()) { /// In this format, BOM at beginning of stream cannot be confused with value, so it is safe to skip it. skipBOMIfExists(in); @@ -263,7 +263,7 @@ void registerInputFormatProcessorJSONEachRow(FormatFactory & factory) IRowInputFormat::Params params, const FormatSettings & settings) { - return std::make_shared(buf, sample, params, settings); + return std::make_shared(buf, sample, std::move(params), settings); }); } diff --git a/dbms/src/Processors/Formats/Impl/JSONEachRowRowOutputFormat.h b/dbms/src/Processors/Formats/Impl/JSONEachRowRowOutputFormat.h index 0ceeb5352c7..a45f193ea39 100644 --- a/dbms/src/Processors/Formats/Impl/JSONEachRowRowOutputFormat.h +++ b/dbms/src/Processors/Formats/Impl/JSONEachRowRowOutputFormat.h @@ -24,6 +24,11 @@ public: void writeRowStartDelimiter() override; void writeRowEndDelimiter() override; +protected: + /// No totals and extremes. + void consumeTotals(Chunk) override {} + void consumeExtremes(Chunk) override {} + private: size_t field_number = 0; Names fields; From e6052ec1173ebbf7e46068f34761db967cc16058 Mon Sep 17 00:00:00 2001 From: alesapin Date: Wed, 31 Jul 2019 13:22:56 +0300 Subject: [PATCH 0512/1165] Fix bug in prewhere + distributed --- dbms/src/Interpreters/ExpressionActions.cpp | 40 +++++++++++++++++-- dbms/src/Interpreters/ExpressionActions.h | 4 ++ .../test_remote_prewhere/__init__.py | 0 .../test_remote_prewhere/configs/log_conf.xml | 12 ++++++ .../integration/test_remote_prewhere/test.py | 35 ++++++++++++++++ 5 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 dbms/tests/integration/test_remote_prewhere/__init__.py create mode 100644 dbms/tests/integration/test_remote_prewhere/configs/log_conf.xml create mode 100644 dbms/tests/integration/test_remote_prewhere/test.py diff --git a/dbms/src/Interpreters/ExpressionActions.cpp b/dbms/src/Interpreters/ExpressionActions.cpp index 43592c2616a..837ec9c2b79 100644 --- a/dbms/src/Interpreters/ExpressionActions.cpp +++ b/dbms/src/Interpreters/ExpressionActions.cpp @@ -35,6 +35,8 @@ namespace ErrorCodes extern const int TYPE_MISMATCH; } +/// Read comment near usage +static constexpr auto DUMMY_COLUMN_NAME = "_dummy"; Names ExpressionAction::getNeededColumns() const { @@ -927,13 +929,43 @@ void ExpressionActions::finalize(const Names & output_columns) } } + + /// 1) Sometimes we don't need any columns to perform actions and sometimes actions doesn't produce any columns as result. + /// But Block class doesn't store any information about structure itself, it uses information from column. + /// If we remove all columns from input or output block we will lose information about amount of rows in it. + /// To avoid this situation we always leaving one of the columns in required columns (input) + /// and output column. We choose that "redundant" column by size with help of getSmallestColumn. + /// + /// 2) Sometimes we have to read data from different Storages to execute query. + /// For example in 'remote' function which requires to read data from local table (for example MergeTree) and + /// remote table (doesn't know anything about it). + /// + /// If we have combination of two previous cases, our heuristic from (1) can choose absolutely different columns, + /// so generated streams with these actions will have different headers. To avoid this we addionaly rename our "redundant" column + /// to DUMMY_COLUMN_NAME with help of PROJECTION action. It doesn't affect any logic, but all streams will have same "redundant" column + /// in header called "_dummy". + /// Also, it seems like we will always have same type (UInt8) of "redundant" column, but it's not obvious. + + bool dummy_projection_added = false; + + /// We will not throw out all the input columns, so as not to lose the number of rows in the block. if (needed_columns.empty() && !input_columns.empty()) - needed_columns.insert(getSmallestColumn(input_columns)); + { + auto colname = getSmallestColumn(input_columns); + needed_columns.insert(colname); + actions.insert(actions.begin(), ExpressionAction::project(NamesWithAliases{{colname, DUMMY_COLUMN_NAME}})); + dummy_projection_added = true; + } /// We will not leave the block empty so as not to lose the number of rows in it. if (final_columns.empty() && !input_columns.empty()) - final_columns.insert(getSmallestColumn(input_columns)); + { + auto colname = getSmallestColumn(input_columns); + final_columns.insert(DUMMY_COLUMN_NAME); + if (!dummy_projection_added) /// otherwise we already have this projection + actions.insert(actions.begin(), ExpressionAction::project(NamesWithAliases{{colname, DUMMY_COLUMN_NAME}})); + } for (NamesAndTypesList::iterator it = input_columns.begin(); it != input_columns.end();) { @@ -947,9 +979,9 @@ void ExpressionActions::finalize(const Names & output_columns) } } -/* std::cerr << "\n"; +/* std::cerr << "\n"; for (const auto & action : actions) - std::cerr << action.toString() << "\n"; + std::cerr << action.toString() << "\n"; std::cerr << "\n";*/ /// Deletes unnecessary temporary columns. diff --git a/dbms/src/Interpreters/ExpressionActions.h b/dbms/src/Interpreters/ExpressionActions.h index 68cc3e73b17..f280e723dd5 100644 --- a/dbms/src/Interpreters/ExpressionActions.h +++ b/dbms/src/Interpreters/ExpressionActions.h @@ -257,9 +257,13 @@ public: }; private: + /// These columns have to be in input blocks (arguments of execute* methods) NamesAndTypesList input_columns; + /// These actions will be executed on input blocks Actions actions; + /// The example of result (output) block. Block sample_block; + Settings settings; #if USE_EMBEDDED_COMPILER std::shared_ptr compilation_cache; diff --git a/dbms/tests/integration/test_remote_prewhere/__init__.py b/dbms/tests/integration/test_remote_prewhere/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dbms/tests/integration/test_remote_prewhere/configs/log_conf.xml b/dbms/tests/integration/test_remote_prewhere/configs/log_conf.xml new file mode 100644 index 00000000000..a4d05c1a598 --- /dev/null +++ b/dbms/tests/integration/test_remote_prewhere/configs/log_conf.xml @@ -0,0 +1,12 @@ + +3 + + trace + /var/log/clickhouse-server/log.log + /var/log/clickhouse-server/log.err.log + 1000M + 10 + /var/log/clickhouse-server/stderr.log + /var/log/clickhouse-server/stdout.log + + diff --git a/dbms/tests/integration/test_remote_prewhere/test.py b/dbms/tests/integration/test_remote_prewhere/test.py new file mode 100644 index 00000000000..5cf3836213e --- /dev/null +++ b/dbms/tests/integration/test_remote_prewhere/test.py @@ -0,0 +1,35 @@ +import time +import pytest + +from helpers.cluster import ClickHouseCluster +from helpers.client import QueryRuntimeException, QueryTimeoutExceedException + + +cluster = ClickHouseCluster(__file__) +node1 = cluster.add_instance('node1', main_configs=['configs/log_conf.xml']) +node2 = cluster.add_instance('node2', main_configs=['configs/log_conf.xml']) + +@pytest.fixture(scope="module") +def start_cluster(): + try: + cluster.start() + + for node in [node1, node2]: + node.query(""" + CREATE TABLE test_table( + APIKey UInt32, + CustomAttributeId UInt64, + ProfileIDHash UInt64, + DeviceIDHash UInt64, + Data String) + ENGINE = SummingMergeTree() + ORDER BY (APIKey, CustomAttributeId, ProfileIDHash, DeviceIDHash, intHash32(DeviceIDHash)) + """) + yield cluster + + finally: + cluster.shutdown() + + +def test_remote(start_cluster): + assert node1.query("SELECT 1 FROM remote('node{1,2}', default.test_table) WHERE (APIKey = 137715) AND (CustomAttributeId IN (45, 66)) AND (ProfileIDHash != 0) LIMIT 1") == "" From 4bea8541d1d48497f406a1fa01d88b325f174300 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 31 Jul 2019 13:28:54 +0300 Subject: [PATCH 0513/1165] Update FormatFactory. --- dbms/src/Formats/FormatFactory.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 9e5645492a8..e812eda944a 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace DB @@ -90,6 +91,16 @@ BlockInputStreamPtr FormatFactory::getInput( BlockOutputStreamPtr FormatFactory::getOutput(const String & name, WriteBuffer & buf, const Block & sample, const Context & context) const { + if (name == "PrettyCompactMonoBlock") + { + /// TODO: rewrite + auto format = getOutputFormat(name, buf, sample, context); + return std::make_shared( + std::make_shared( + std::make_shared(format), sample), + sample, context.getSettingsRef().output_format_pretty_max_rows, 0); + } + auto format = getOutputFormat(name, buf, sample, context); /** Materialization is needed, because formats can use the functions `IDataType`, From cc74c5ec78036e55a8c03630c6e9051da4cb3012 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 31 Jul 2019 13:31:14 +0300 Subject: [PATCH 0514/1165] Update FormatFactory. --- dbms/src/Formats/FormatFactory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index e812eda944a..0c28d1ec8e7 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -97,8 +97,8 @@ BlockOutputStreamPtr FormatFactory::getOutput(const String & name, WriteBuffer & auto format = getOutputFormat(name, buf, sample, context); return std::make_shared( std::make_shared( - std::make_shared(format), sample), - sample, context.getSettingsRef().output_format_pretty_max_rows, 0); + std::make_shared(format), + sample, context.getSettingsRef().output_format_pretty_max_rows, 0), sample); } auto format = getOutputFormat(name, buf, sample, context); From 0e61ca79d01ae415dcd3f40f1679d573222eace3 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 31 Jul 2019 13:34:31 +0300 Subject: [PATCH 0515/1165] Update FormatFactory. --- dbms/src/DataStreams/SquashingBlockOutputStream.cpp | 4 ++-- dbms/src/DataStreams/SquashingBlockOutputStream.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dbms/src/DataStreams/SquashingBlockOutputStream.cpp b/dbms/src/DataStreams/SquashingBlockOutputStream.cpp index 5698ee99f64..48156ed090f 100644 --- a/dbms/src/DataStreams/SquashingBlockOutputStream.cpp +++ b/dbms/src/DataStreams/SquashingBlockOutputStream.cpp @@ -4,8 +4,8 @@ namespace DB { -SquashingBlockOutputStream::SquashingBlockOutputStream(BlockOutputStreamPtr & dst, const Block & header, size_t min_block_size_rows, size_t min_block_size_bytes) - : output(dst), header(header), transform(min_block_size_rows, min_block_size_bytes) +SquashingBlockOutputStream::SquashingBlockOutputStream(BlockOutputStreamPtr dst, Block header, size_t min_block_size_rows, size_t min_block_size_bytes) + : output(std::move(dst)), header(std::move(header)), transform(min_block_size_rows, min_block_size_bytes) { } diff --git a/dbms/src/DataStreams/SquashingBlockOutputStream.h b/dbms/src/DataStreams/SquashingBlockOutputStream.h index 153f671a600..f255d18e331 100644 --- a/dbms/src/DataStreams/SquashingBlockOutputStream.h +++ b/dbms/src/DataStreams/SquashingBlockOutputStream.h @@ -12,7 +12,7 @@ namespace DB class SquashingBlockOutputStream : public IBlockOutputStream { public: - SquashingBlockOutputStream(BlockOutputStreamPtr & dst, const Block & header, size_t min_block_size_rows, size_t min_block_size_bytes); + SquashingBlockOutputStream(BlockOutputStreamPtr dst, Block header, size_t min_block_size_rows, size_t min_block_size_bytes); Block getHeader() const override { return header; } void write(const Block & block) override; From 2d5b282a31369db34d4f07e66da246a281ecc6f7 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 31 Jul 2019 13:37:28 +0300 Subject: [PATCH 0516/1165] Update FormatFactory. --- dbms/src/Formats/FormatFactory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 0c28d1ec8e7..3dfdc07b71d 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -94,7 +94,7 @@ BlockOutputStreamPtr FormatFactory::getOutput(const String & name, WriteBuffer & if (name == "PrettyCompactMonoBlock") { /// TODO: rewrite - auto format = getOutputFormat(name, buf, sample, context); + auto format = getOutputFormat("PrettyCompact", buf, sample, context); return std::make_shared( std::make_shared( std::make_shared(format), From 77d81687b3f4813af2be3d393d9cb37e0c190884 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 31 Jul 2019 13:54:50 +0300 Subject: [PATCH 0517/1165] Update FormatFactory. --- dbms/src/Formats/FormatFactory.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 3dfdc07b71d..c4315528e4b 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -95,10 +95,13 @@ BlockOutputStreamPtr FormatFactory::getOutput(const String & name, WriteBuffer & { /// TODO: rewrite auto format = getOutputFormat("PrettyCompact", buf, sample, context); - return std::make_shared( - std::make_shared( - std::make_shared(format), - sample, context.getSettingsRef().output_format_pretty_max_rows, 0), sample); + auto res = std::make_shared( + std::make_shared(format), + sample, context.getSettingsRef().output_format_pretty_max_rows, 0); + + res->disableFlush(); + + return std::make_shared(res, sample); } auto format = getOutputFormat(name, buf, sample, context); From 3ff143c60f39cad3c54cdee4b32a3be38fbf197a Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov Date: Tue, 30 Jul 2019 20:38:22 +0300 Subject: [PATCH 0518/1165] Lock the TinyLog storage when reading. Unlike StripeLog, we only have one set of files per column, so we can't read concurrently with writing. We didn't use any locking before, and that lead to user-visible error messages and tsan failures. --- dbms/src/Storages/StorageTinyLog.cpp | 14 ++++++++++++-- dbms/src/Storages/StorageTinyLog.h | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/dbms/src/Storages/StorageTinyLog.cpp b/dbms/src/Storages/StorageTinyLog.cpp index 24a75496a24..214964c32b4 100644 --- a/dbms/src/Storages/StorageTinyLog.cpp +++ b/dbms/src/Storages/StorageTinyLog.cpp @@ -59,7 +59,8 @@ class TinyLogBlockInputStream final : public IBlockInputStream public: TinyLogBlockInputStream(size_t block_size_, const NamesAndTypesList & columns_, StorageTinyLog & storage_, size_t max_read_buffer_size_) : block_size(block_size_), columns(columns_), - storage(storage_), max_read_buffer_size(max_read_buffer_size_) {} + storage(storage_), lock(storage_.rwlock), + max_read_buffer_size(max_read_buffer_size_) {} String getName() const override { return "TinyLog"; } @@ -79,6 +80,7 @@ private: size_t block_size; NamesAndTypesList columns; StorageTinyLog & storage; + std::shared_lock lock; bool finished = false; size_t max_read_buffer_size; @@ -109,7 +111,7 @@ class TinyLogBlockOutputStream final : public IBlockOutputStream { public: explicit TinyLogBlockOutputStream(StorageTinyLog & storage_) - : storage(storage_) + : storage(storage_), lock(storage_.rwlock) { } @@ -132,6 +134,7 @@ public: private: StorageTinyLog & storage; + std::unique_lock lock; bool done = false; struct Stream @@ -373,6 +376,8 @@ void StorageTinyLog::addFiles(const String & column_name, const IDataType & type void StorageTinyLog::rename(const String & new_path_to_db, const String & new_database_name, const String & new_table_name) { + std::unique_lock lock(rwlock); + /// Rename directory with data. Poco::File(path + escapeForFileName(table_name)).renameTo(new_path_to_db + escapeForFileName(new_table_name)); @@ -395,6 +400,8 @@ BlockInputStreams StorageTinyLog::read( const unsigned /*num_streams*/) { check(column_names); + // When reading, we lock the entire storage, because we only have one file + // per column and can't modify it concurrently. return BlockInputStreams(1, std::make_shared( max_block_size, Nested::collect(getColumns().getAllPhysical().addTypes(column_names)), *this, context.getSettingsRef().max_read_buffer_size)); } @@ -409,6 +416,7 @@ BlockOutputStreamPtr StorageTinyLog::write( CheckResults StorageTinyLog::checkData(const ASTPtr & /* query */, const Context & /* context */) { + std::shared_lock lock(rwlock); return file_checker.check(); } @@ -417,6 +425,8 @@ void StorageTinyLog::truncate(const ASTPtr &, const Context &) if (table_name.empty()) throw Exception("Logical error: table name is empty", ErrorCodes::LOGICAL_ERROR); + std::unique_lock lock(rwlock); + auto file = Poco::File(path + escapeForFileName(table_name)); file.remove(true); file.createDirectories(); diff --git a/dbms/src/Storages/StorageTinyLog.h b/dbms/src/Storages/StorageTinyLog.h index 7a360af632e..9ed53f12962 100644 --- a/dbms/src/Storages/StorageTinyLog.h +++ b/dbms/src/Storages/StorageTinyLog.h @@ -65,6 +65,7 @@ private: Files_t files; FileChecker file_checker; + mutable std::shared_mutex rwlock; Logger * log; From 2c638d577d8c5257eeba6924c9664e5fe5cb2fef Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 31 Jul 2019 14:51:00 +0300 Subject: [PATCH 0519/1165] Update VerticalRowOutputFormat. --- dbms/src/Processors/Formats/Impl/VerticalRowOutputFormat.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dbms/src/Processors/Formats/Impl/VerticalRowOutputFormat.cpp b/dbms/src/Processors/Formats/Impl/VerticalRowOutputFormat.cpp index 8e9d0cd37c5..55f04584c19 100644 --- a/dbms/src/Processors/Formats/Impl/VerticalRowOutputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/VerticalRowOutputFormat.cpp @@ -110,12 +110,15 @@ void VerticalRowOutputFormat::writeSuffix() void VerticalRowOutputFormat::writeBeforeTotals() { writeCString("\n", out); + writeCString("\n", out); } void VerticalRowOutputFormat::writeBeforeExtremes() { if (!was_totals_written) writeCString("\n", out); + + writeCString("\n", out); } void VerticalRowOutputFormat::writeMinExtreme(const Columns & columns, size_t row_num) @@ -136,8 +139,6 @@ void VerticalRowOutputFormat::writeTotals(const Columns & columns, size_t row_nu void VerticalRowOutputFormat::writeSpecialRow(const Columns & columns, size_t row_num, PortKind port_kind, const char * title) { - writeCString("\n", out); - row_number = 0; field_number = 0; From 46c1e9d1a20e01c05db9b9c852b4577d7b386f77 Mon Sep 17 00:00:00 2001 From: alesapin Date: Wed, 31 Jul 2019 15:33:58 +0300 Subject: [PATCH 0520/1165] Use COPY_COLUMN instead of PROJECT --- dbms/src/Interpreters/ExpressionActions.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/dbms/src/Interpreters/ExpressionActions.cpp b/dbms/src/Interpreters/ExpressionActions.cpp index 837ec9c2b79..9d0ce691aa3 100644 --- a/dbms/src/Interpreters/ExpressionActions.cpp +++ b/dbms/src/Interpreters/ExpressionActions.cpp @@ -514,7 +514,10 @@ void ExpressionAction::execute(Block & block, bool dry_run) const result.column = block.getByName(source_name).column; } else - block.insert({ block.getByName(source_name).column, result_type, result_name }); + { + const auto & source_column = block.getByName(source_name); + block.insert({source_column.column, source_column.type, result_name}); + } break; } @@ -942,8 +945,9 @@ void ExpressionActions::finalize(const Names & output_columns) /// /// If we have combination of two previous cases, our heuristic from (1) can choose absolutely different columns, /// so generated streams with these actions will have different headers. To avoid this we addionaly rename our "redundant" column - /// to DUMMY_COLUMN_NAME with help of PROJECTION action. It doesn't affect any logic, but all streams will have same "redundant" column - /// in header called "_dummy". + /// to DUMMY_COLUMN_NAME with help of COPY_COLUMN action and consequent remove of original column. + /// It doesn't affect any logic, but all streams will have same "redundant" column in header called "_dummy". + /// Also, it seems like we will always have same type (UInt8) of "redundant" column, but it's not obvious. bool dummy_projection_added = false; @@ -954,7 +958,7 @@ void ExpressionActions::finalize(const Names & output_columns) { auto colname = getSmallestColumn(input_columns); needed_columns.insert(colname); - actions.insert(actions.begin(), ExpressionAction::project(NamesWithAliases{{colname, DUMMY_COLUMN_NAME}})); + actions.insert(actions.begin(), ExpressionAction::copyColumn(colname, DUMMY_COLUMN_NAME, true)); dummy_projection_added = true; } @@ -964,7 +968,7 @@ void ExpressionActions::finalize(const Names & output_columns) auto colname = getSmallestColumn(input_columns); final_columns.insert(DUMMY_COLUMN_NAME); if (!dummy_projection_added) /// otherwise we already have this projection - actions.insert(actions.begin(), ExpressionAction::project(NamesWithAliases{{colname, DUMMY_COLUMN_NAME}})); + actions.insert(actions.begin(), ExpressionAction::copyColumn(colname, DUMMY_COLUMN_NAME, true)); } for (NamesAndTypesList::iterator it = input_columns.begin(); it != input_columns.end();) @@ -979,10 +983,10 @@ void ExpressionActions::finalize(const Names & output_columns) } } -/* std::cerr << "\n"; - for (const auto & action : actions) +/* std::cerr << "\n"; + for (const auto & action : actions) std::cerr << action.toString() << "\n"; - std::cerr << "\n";*/ + std::cerr << "\n";*/ /// Deletes unnecessary temporary columns. From 2254e6fd32b506f3ab8c8a1e356e9421bcd1eb67 Mon Sep 17 00:00:00 2001 From: alesapin Date: Wed, 31 Jul 2019 15:35:23 +0300 Subject: [PATCH 0521/1165] Fix comment --- dbms/src/Interpreters/ExpressionActions.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dbms/src/Interpreters/ExpressionActions.cpp b/dbms/src/Interpreters/ExpressionActions.cpp index 9d0ce691aa3..11d544613fa 100644 --- a/dbms/src/Interpreters/ExpressionActions.cpp +++ b/dbms/src/Interpreters/ExpressionActions.cpp @@ -950,7 +950,7 @@ void ExpressionActions::finalize(const Names & output_columns) /// Also, it seems like we will always have same type (UInt8) of "redundant" column, but it's not obvious. - bool dummy_projection_added = false; + bool dummy_column_copied = false; /// We will not throw out all the input columns, so as not to lose the number of rows in the block. @@ -959,7 +959,7 @@ void ExpressionActions::finalize(const Names & output_columns) auto colname = getSmallestColumn(input_columns); needed_columns.insert(colname); actions.insert(actions.begin(), ExpressionAction::copyColumn(colname, DUMMY_COLUMN_NAME, true)); - dummy_projection_added = true; + dummy_column_copied = true; } /// We will not leave the block empty so as not to lose the number of rows in it. @@ -967,7 +967,7 @@ void ExpressionActions::finalize(const Names & output_columns) { auto colname = getSmallestColumn(input_columns); final_columns.insert(DUMMY_COLUMN_NAME); - if (!dummy_projection_added) /// otherwise we already have this projection + if (!dummy_column_copied) /// otherwise we already have this column actions.insert(actions.begin(), ExpressionAction::copyColumn(colname, DUMMY_COLUMN_NAME, true)); } From cc8ce23215b3e72126ef08aad9cfb10f1447e638 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Wed, 31 Jul 2019 16:16:29 +0300 Subject: [PATCH 0522/1165] DOCAPI-6889: Fixes. --- docs/en/query_language/functions/ext_dict_functions.md | 2 +- docs/ru/query_language/functions/ext_dict_functions.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/en/query_language/functions/ext_dict_functions.md b/docs/en/query_language/functions/ext_dict_functions.md index 9c41bf24e56..95ddb0eaef6 100644 --- a/docs/en/query_language/functions/ext_dict_functions.md +++ b/docs/en/query_language/functions/ext_dict_functions.md @@ -132,7 +132,7 @@ Type: Array(UInt64). ## dictIsIn -Checks the ancestor of a key through the whole hierarchical chain in the hierarchical dictionary. +Checks the ancestor of a key through the whole hierarchical chain in the dictionary. ``` dictIsIn('dict_name', child_id_expr, ancestor_id_expr) diff --git a/docs/ru/query_language/functions/ext_dict_functions.md b/docs/ru/query_language/functions/ext_dict_functions.md index 6a8776556d7..e7f23a64664 100644 --- a/docs/ru/query_language/functions/ext_dict_functions.md +++ b/docs/ru/query_language/functions/ext_dict_functions.md @@ -93,7 +93,7 @@ LIMIT 3 ## dictHas -Проверяет, присутствует ли ключ в словаре. +Проверяет, присутствует ли запись с указанным ключом в словаре. ``` dictHas('dict_name', id) @@ -132,7 +132,7 @@ dictGetHierarchy('dict_name', id) ## dictIsIn -Проверяет предка ключа по всей цепочке иерархии в иерархическом словаре. +Проверяет предка ключа по всей иерархической цепочке словаря. `dictIsIn ('dict_name', child_id_expr, ancestor_id_expr)` @@ -140,7 +140,7 @@ dictGetHierarchy('dict_name', id) - `dict_name` — имя словаря. [Строковый литерал](../syntax.md#syntax-string-literal). - `child_id_expr` — ключ для проверки. [Выражение](../syntax.md#syntax-expressions), возвращающее значение типа [UInt64](../../data_types/int_uint.md). -- `ancestor_id_expr` — предполагаемый предок ключа `child_id_expr`. [выражение](../syntax.md#syntax-expressions), возвращающее значение типа [UInt64](../../data_types/int_uint.md). +- `ancestor_id_expr` — предполагаемый предок ключа `child_id_expr`. [Выражение](../syntax.md#syntax-expressions), возвращающее значение типа [UInt64](../../data_types/int_uint.md). **Возвращаемое значение** @@ -151,7 +151,7 @@ dictGetHierarchy('dict_name', id) ## Прочие функции {#ext_dict_functions-other} -ClickHouse поддерживает специализированные функции, которые приводят значения атрибутов справочника к определенному типу данных независимо от конфигурации справочника. +ClickHouse поддерживает специализированные функции, которые приводят значения атрибутов словаря к определённому типу данных независимо от конфигурации словаря. Функции: From 4e38a4592290537953585e9cd065fd58705b6f0e Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 31 Jul 2019 16:26:08 +0300 Subject: [PATCH 0523/1165] Update FormatFactory. --- dbms/src/Formats/FormatFactory.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index c4315528e4b..c5280e45b48 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace DB @@ -84,6 +85,9 @@ BlockInputStreamPtr FormatFactory::getInput( UInt64 rows_portion_size, ReadCallback callback) const { + if (name == "Native") + return std::make_shared(buf, sample, 0); + auto format = getInputFormat(name, buf, sample, context, max_block_size, rows_portion_size, std::move(callback)); return std::make_shared(std::move(format)); } From fffa1ec387f416adb5a43dddd62af15e48898d96 Mon Sep 17 00:00:00 2001 From: proller Date: Wed, 31 Jul 2019 17:00:45 +0300 Subject: [PATCH 0524/1165] fix glibc-compatibility --- CMakeLists.txt | 6 ++++++ contrib/brotli-cmake/CMakeLists.txt | 2 +- contrib/h3-cmake/CMakeLists.txt | 2 +- contrib/libxml2-cmake/CMakeLists.txt | 2 +- contrib/mariadb-connector-c-cmake/CMakeLists.txt | 2 +- 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e9a433d80b4..3223130632f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -342,6 +342,7 @@ if (OS_LINUX AND NOT UNBUNDLED AND (GLIBC_COMPATIBILITY OR USE_INTERNAL_UNWIND_L # FIXME: glibc-compatibility may be non-static in some builds! set (DEFAULT_LIBS "${DEFAULT_LIBS} ${ClickHouse_BINARY_DIR}/libs/libglibc-compatibility/libglibc-compatibility${${CMAKE_POSTFIX_VARIABLE}}.a") + set (M_OR_GLIBC_LIBRARY glibc-compatibility) endif () # Add Libc. GLIBC is actually a collection of interdependent libraries. @@ -352,6 +353,11 @@ if (OS_LINUX AND NOT UNBUNDLED AND (GLIBC_COMPATIBILITY OR USE_INTERNAL_UNWIND_L message(STATUS "Default libraries: ${DEFAULT_LIBS}") endif () +if (NOT M_OR_GLIBC_LIBRARY) + set (M_OR_GLIBC_LIBRARY m) +endif () +message(STATUS "Using m library=${M_OR_GLIBC_LIBRARY}") + if (DEFAULT_LIBS) # Add default libs to all targets as the last dependency. set(CMAKE_CXX_STANDARD_LIBRARIES ${DEFAULT_LIBS}) diff --git a/contrib/brotli-cmake/CMakeLists.txt b/contrib/brotli-cmake/CMakeLists.txt index 9bc6d3d89e7..3c995467c9d 100644 --- a/contrib/brotli-cmake/CMakeLists.txt +++ b/contrib/brotli-cmake/CMakeLists.txt @@ -31,4 +31,4 @@ set(SRCS add_library(brotli ${SRCS}) target_include_directories(brotli PUBLIC ${BROTLI_SOURCE_DIR}/include) -target_link_libraries(brotli PRIVATE m) +target_link_libraries(brotli PRIVATE ${M_OR_GLIBC_LIBRARY}) diff --git a/contrib/h3-cmake/CMakeLists.txt b/contrib/h3-cmake/CMakeLists.txt index 951e5e83bdc..5ad5f3fdb8d 100644 --- a/contrib/h3-cmake/CMakeLists.txt +++ b/contrib/h3-cmake/CMakeLists.txt @@ -25,4 +25,4 @@ add_library(h3 ${SRCS}) target_include_directories(h3 SYSTEM PUBLIC ${H3_SOURCE_DIR}/include) target_include_directories(h3 SYSTEM PUBLIC ${H3_BINARY_DIR}/include) target_compile_definitions(h3 PRIVATE H3_HAVE_VLA) -target_link_libraries(h3 PRIVATE m) +target_link_libraries(h3 PRIVATE ${M_OR_GLIBC_LIBRARY}) diff --git a/contrib/libxml2-cmake/CMakeLists.txt b/contrib/libxml2-cmake/CMakeLists.txt index 827ed8fefd8..ef362875e08 100644 --- a/contrib/libxml2-cmake/CMakeLists.txt +++ b/contrib/libxml2-cmake/CMakeLists.txt @@ -52,7 +52,7 @@ set(SRCS ) add_library(libxml2 ${SRCS}) -target_link_libraries(libxml2 PRIVATE ${ZLIB_LIBRARIES} m ${CMAKE_DL_LIBS}) +target_link_libraries(libxml2 PRIVATE ${ZLIB_LIBRARIES} ${M_OR_GLIBC_LIBRARY} ${CMAKE_DL_LIBS}) target_include_directories(libxml2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/linux_x86_64/include) target_include_directories(libxml2 PUBLIC ${LIBXML2_SOURCE_DIR}/include) diff --git a/contrib/mariadb-connector-c-cmake/CMakeLists.txt b/contrib/mariadb-connector-c-cmake/CMakeLists.txt index f9bd2490fba..d7ea148cf40 100644 --- a/contrib/mariadb-connector-c-cmake/CMakeLists.txt +++ b/contrib/mariadb-connector-c-cmake/CMakeLists.txt @@ -60,7 +60,7 @@ endif() add_library(mysqlclient ${SRCS}) -target_link_libraries(mysqlclient PRIVATE ${CMAKE_DL_LIBS} m Threads::Threads) +target_link_libraries(mysqlclient PRIVATE ${CMAKE_DL_LIBS} ${M_OR_GLIBC_LIBRARY} Threads::Threads) if(OPENSSL_LIBRARIES) target_link_libraries(mysqlclient PRIVATE ${OPENSSL_LIBRARIES}) From ad4459c4a28b80fbc6a0ea63b4458d15f9dd4b7a Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Wed, 31 Jul 2019 17:03:23 +0300 Subject: [PATCH 0525/1165] fixed flush_logs + added pretty function --- dbms/programs/server/Server.cpp | 8 ++--- dbms/src/Interpreters/Context.cpp | 15 +++++++++- dbms/src/Interpreters/Context.h | 3 +- .../Interpreters/InterpreterSystemQuery.cpp | 4 ++- dbms/src/Interpreters/SystemLog.h | 2 ++ .../00974_text_log_table_not_empty.sh | 1 + libs/libcommon/include/common/logger_useful.h | 30 +++++++++++-------- libs/libloggers/loggers/Loggers.cpp | 7 +++-- libs/libloggers/loggers/OwnSplitChannel.cpp | 2 +- libs/libloggers/loggers/OwnSplitChannel.h | 2 +- 10 files changed, 51 insertions(+), 23 deletions(-) diff --git a/dbms/programs/server/Server.cpp b/dbms/programs/server/Server.cpp index eac295fd660..f1d5d5aeac8 100644 --- a/dbms/programs/server/Server.cpp +++ b/dbms/programs/server/Server.cpp @@ -407,9 +407,6 @@ int Server::main(const std::vector & /*args*/) if (config().has("macros")) global_context->setMacros(std::make_unique(config(), "macros")); - /// Create text_log instance - text_log = createSystemLog(*global_context, "system", "text_log", global_context->getConfigRef(), "text_log"); - /// Initialize main config reloader. std::string include_from_path = config().getString("include_from", "/etc/metrika.xml"); auto main_config_reloader = std::make_unique(config_path, @@ -506,11 +503,14 @@ int Server::main(const std::vector & /*args*/) LOG_INFO(log, "Loading metadata from " + path); + /// Create text_log instance + text_log = createSystemLog(*global_context, "system", "text_log", global_context->getConfigRef(), "text_log"); + try { loadMetadataSystem(*global_context); /// After attaching system databases we can initialize system log. - global_context->initializeSystemLogs(); + global_context->initializeSystemLogs(text_log); /// After the system database is created, attach virtual system tables (in addition to query_log and part_log) attachSystemTablesServer(*global_context->getDatabase("system"), has_zookeeper); /// Then, load remaining databases diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index dd3e5ef578a..db32c29434f 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -1636,10 +1636,11 @@ Compiler & Context::getCompiler() } -void Context::initializeSystemLogs() +void Context::initializeSystemLogs(std::shared_ptr text_log) { auto lock = getLock(); shared->system_logs.emplace(*global_context, getConfigRef()); + shared->system_logs->text_log = text_log; } bool Context::hasTraceCollector() @@ -1702,6 +1703,18 @@ std::shared_ptr Context::getTraceLog() return shared->system_logs->trace_log; } +std::shared_ptr Context::getTextLog() +{ + auto lock = getLock(); + + if (!shared->system_logs) { + if (auto log = shared->system_logs->text_log.lock()) { + return log; + } + } + return {}; +} + CompressionCodecPtr Context::chooseCompressionCodec(size_t part_size, double part_size_ratio) const { diff --git a/dbms/src/Interpreters/Context.h b/dbms/src/Interpreters/Context.h index 31229a26a75..f37b126b8f4 100644 --- a/dbms/src/Interpreters/Context.h +++ b/dbms/src/Interpreters/Context.h @@ -420,7 +420,7 @@ public: Compiler & getCompiler(); /// Call after initialization before using system logs. Call for global context. - void initializeSystemLogs(); + void initializeSystemLogs(std::shared_ptr text_log); void initializeTraceCollector(); bool hasTraceCollector(); @@ -429,6 +429,7 @@ public: std::shared_ptr getQueryLog(); std::shared_ptr getQueryThreadLog(); std::shared_ptr getTraceLog(); + std::shared_ptr getTextLog(); /// Returns an object used to log opertaions with parts if it possible. /// Provide table name to make required cheks. diff --git a/dbms/src/Interpreters/InterpreterSystemQuery.cpp b/dbms/src/Interpreters/InterpreterSystemQuery.cpp index 16d6fe5ff93..54c10e9f31e 100644 --- a/dbms/src/Interpreters/InterpreterSystemQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSystemQuery.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -223,7 +224,8 @@ BlockIO InterpreterSystemQuery::execute() [&] () { if (auto query_log = context.getQueryLog()) query_log->flush(); }, [&] () { if (auto part_log = context.getPartLog("")) part_log->flush(); }, [&] () { if (auto query_thread_log = context.getQueryThreadLog()) query_thread_log->flush(); }, - [&] () { if (auto trace_log = context.getTraceLog()) trace_log->flush(); } + [&] () { if (auto trace_log = context.getTraceLog()) trace_log->flush(); }, + [&] () { if (auto text_log = context.getTextLog()) text_log->flush(); } ); break; case Type::STOP_LISTEN_QUERIES: diff --git a/dbms/src/Interpreters/SystemLog.h b/dbms/src/Interpreters/SystemLog.h index 026cac4495f..66b606891be 100644 --- a/dbms/src/Interpreters/SystemLog.h +++ b/dbms/src/Interpreters/SystemLog.h @@ -75,6 +75,8 @@ struct SystemLogs std::shared_ptr query_thread_log; /// Used to log query threads. std::shared_ptr part_log; /// Used to log operations with parts std::shared_ptr trace_log; /// Used to log traces from query profiler + std::weak_ptr text_log; /// Used to log all text. We use weak_ptr, because this log is + /// a server's field. String part_log_database; }; diff --git a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sh b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sh index 7eaf2c35674..869f7a54b6b 100755 --- a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sh +++ b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sh @@ -4,5 +4,6 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) . $CURDIR/../shell_config.sh ${CLICKHOUSE_CLIENT} --query="SELECT 6103" +sleep 0.1 ${CLICKHOUSE_CLIENT} --query="SYSTEM FLUSH LOGS" ${CLICKHOUSE_CLIENT} --query="SELECT count() > 0 FROM system.text_log WHERE position(system.text_log.message, 'SELECT 6103') > 0" diff --git a/libs/libcommon/include/common/logger_useful.h b/libs/libcommon/include/common/logger_useful.h index 53c83f127af..2e71312881a 100644 --- a/libs/libcommon/include/common/logger_useful.h +++ b/libs/libcommon/include/common/logger_useful.h @@ -9,6 +9,8 @@ #include #include +#include + #ifndef QUERY_PREVIEW_LENGTH #define QUERY_PREVIEW_LENGTH 160 #endif @@ -20,18 +22,22 @@ using DB::CurrentThread; /// Logs a message to a specified logger with that level. -#define LOG_SIMPLE(logger, message, priority, PRIORITY) do \ -{ \ - const bool is_clients_log = (CurrentThread::getGroup() != nullptr) && \ - (CurrentThread::getGroup()->client_logs_level >= (priority)); \ - if ((logger)->is((PRIORITY)) || is_clients_log) { \ - std::stringstream oss_internal_rare; \ - oss_internal_rare << message; \ - if (auto channel = (logger)->getChannel()) { \ - channel->log(Message((logger)->name(), oss_internal_rare.str(), \ - (PRIORITY), __FILE__, __LINE__)); \ - } \ - } \ +#define LOG_SIMPLE(logger, message, priority, PRIORITY) do \ +{ \ + const bool is_clients_log = (CurrentThread::getGroup() != nullptr) && \ + (CurrentThread::getGroup()->client_logs_level >= (priority)); \ + if ((logger)->is((PRIORITY)) || is_clients_log) { \ + std::stringstream oss_internal_rare; \ + oss_internal_rare << message; \ + if (auto channel = (logger)->getChannel()) { \ + std::string file_function; \ + file_function += __FILE__; \ + file_function += __PRETTY_FUNCTION__; \ + Message poco_message((logger)->name(), oss_internal_rare.str(), \ + (PRIORITY), file_function.c_str(), __LINE__); \ + channel->log(poco_message); \ + } \ + } \ } while (false) diff --git a/libs/libloggers/loggers/Loggers.cpp b/libs/libloggers/loggers/Loggers.cpp index d7b46d9a195..5e78bed2760 100644 --- a/libs/libloggers/loggers/Loggers.cpp +++ b/libs/libloggers/loggers/Loggers.cpp @@ -28,9 +28,12 @@ void Loggers::setTextLog(std::shared_ptr log) { void Loggers::buildLoggers(Poco::Util::AbstractConfiguration & config, Poco::Logger & logger /*_root*/, const std::string & cmd_name) { - if (split && !text_log.expired()) { - split->addTextLog(text_log); + if (split) { + if (auto log = text_log.lock()) { + split->addTextLog(log); + } } + auto current_logger = config.getString("logger", ""); if (config_logger == current_logger) { return; diff --git a/libs/libloggers/loggers/OwnSplitChannel.cpp b/libs/libloggers/loggers/OwnSplitChannel.cpp index b6bbc74ef4a..40361a2211f 100644 --- a/libs/libloggers/loggers/OwnSplitChannel.cpp +++ b/libs/libloggers/loggers/OwnSplitChannel.cpp @@ -86,7 +86,7 @@ void OwnSplitChannel::addChannel(Poco::AutoPtr channel) channels.emplace_back(std::move(channel), dynamic_cast(channel.get())); } -void OwnSplitChannel::addTextLog(std::weak_ptr log) +void OwnSplitChannel::addTextLog(std::shared_ptr log) { text_log = log; } diff --git a/libs/libloggers/loggers/OwnSplitChannel.h b/libs/libloggers/loggers/OwnSplitChannel.h index 52675fed317..8415cd79c6a 100644 --- a/libs/libloggers/loggers/OwnSplitChannel.h +++ b/libs/libloggers/loggers/OwnSplitChannel.h @@ -22,7 +22,7 @@ public: /// Adds a child channel void addChannel(Poco::AutoPtr channel); - void addTextLog(std::weak_ptr log); + void addTextLog(std::shared_ptr log); private: using ChannelPtr = Poco::AutoPtr; From f91c64bd286bcc96f6340da29f4c49b6edc83307 Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Wed, 31 Jul 2019 17:06:22 +0300 Subject: [PATCH 0526/1165] parser changed, test modified, comments added --- dbms/src/Parsers/ParserCreateQuery.h | 2 +- dbms/src/Storages/StorageValues.cpp | 4 ++- dbms/src/Storages/StorageValues.h | 4 ++- .../TableFunctions/TableFunctionValues.cpp | 35 ++++++++++++------- .../0_stateless/00975_values_list.reference | 1 + .../queries/0_stateless/00975_values_list.sql | 2 ++ 6 files changed, 32 insertions(+), 16 deletions(-) diff --git a/dbms/src/Parsers/ParserCreateQuery.h b/dbms/src/Parsers/ParserCreateQuery.h index bd3c8f671f0..98109ae9893 100644 --- a/dbms/src/Parsers/ParserCreateQuery.h +++ b/dbms/src/Parsers/ParserCreateQuery.h @@ -263,7 +263,7 @@ protected: class ParserColumnsOrIndicesDeclarationList : public IParserBase { - protected: +protected: const char * getName() const override { return "columns or indices declaration list"; } bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override; }; diff --git a/dbms/src/Storages/StorageValues.cpp b/dbms/src/Storages/StorageValues.cpp index bda44569cc6..c8b470307dc 100644 --- a/dbms/src/Storages/StorageValues.cpp +++ b/dbms/src/Storages/StorageValues.cpp @@ -5,7 +5,9 @@ namespace DB { - +/* One block storage used for values table function + * It's structure is similar to IStorageSystemOneBlock + */ StorageValues::StorageValues(const std::string & database_name_, const std::string & table_name_, const Block & res_block_) : database_name(database_name_), table_name(table_name_), res_block(res_block_) { diff --git a/dbms/src/Storages/StorageValues.h b/dbms/src/Storages/StorageValues.h index 640a198d97b..8ff52ed9df5 100644 --- a/dbms/src/Storages/StorageValues.h +++ b/dbms/src/Storages/StorageValues.h @@ -6,7 +6,9 @@ namespace DB { - +/* values(structure, values...) - creates a temporary storage filling columns with values + * values is case-insensitive table function + */ class StorageValues : public ext::shared_ptr_helper, public IStorage { public: diff --git a/dbms/src/TableFunctions/TableFunctionValues.cpp b/dbms/src/TableFunctions/TableFunctionValues.cpp index bf2e8679962..ebfd9fa5cba 100644 --- a/dbms/src/TableFunctions/TableFunctionValues.cpp +++ b/dbms/src/TableFunctions/TableFunctionValues.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -15,8 +16,7 @@ #include #include - -#include +#include namespace DB @@ -25,6 +25,7 @@ namespace DB namespace ErrorCodes { extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; + extern const int SYNTAX_ERROR; } static void parseAndInsertValues(MutableColumns & res_columns, const ASTs & args, const Block & sample_block, const Context & context) @@ -74,21 +75,30 @@ StoragePtr TableFunctionValues::executeImpl(const ASTPtr & ast_function, const C /// Parsing first argument as table structure std::string structure = args[0]->as().value.safeGet(); - std::vector structure_values; - boost::split(structure_values, structure, boost::algorithm::is_any_of(" ,"), boost::algorithm::token_compress_on); + Expected expected; - if (structure_values.size() % 2 != 0) - throw Exception("Odd number of elements in section structure: must be a list of name type pairs", ErrorCodes::LOGICAL_ERROR); + Tokens tokens(structure.c_str(), structure.c_str() + structure.size()); + TokenIterator token_iterator(tokens); + + ParserColumnDeclarationList parser; + ASTPtr columns_list_raw; + + if (!parser.parse(token_iterator, columns_list_raw, expected)) + throw Exception("Cannot parse columns declaration list.", ErrorCodes::SYNTAX_ERROR); + + auto * columns_list = dynamic_cast(columns_list_raw.get()); + if (!columns_list) + throw Exception("Could not cast AST to ASTExpressionList", ErrorCodes::LOGICAL_ERROR); + + ColumnsDescription columns_desc = InterpreterCreateQuery::getColumnsDescription(*columns_list, context); Block sample_block; - const DataTypeFactory & data_type_factory = DataTypeFactory::instance(); - - for (size_t i = 0, size = structure_values.size(); i < size; i += 2) + for (const auto & [name, type]: columns_desc.getAllPhysical()) { ColumnWithTypeAndName column; - column.name = structure_values[i]; - column.type = data_type_factory.get(structure_values[i + 1]); - column.column = column.type->createColumn(); + column.name = name; + column.type = type; + column.column = type->createColumn(); sample_block.insert(std::move(column)); } @@ -101,7 +111,6 @@ StoragePtr TableFunctionValues::executeImpl(const ASTPtr & ast_function, const C auto res = StorageValues::create(getDatabaseName(), table_name, res_block); res->startup(); return res; - } void registerTableFunctionValues(TableFunctionFactory & factory) diff --git a/dbms/tests/queries/0_stateless/00975_values_list.reference b/dbms/tests/queries/0_stateless/00975_values_list.reference index 0f719e42424..eee9e0a0ca5 100644 --- a/dbms/tests/queries/0_stateless/00975_values_list.reference +++ b/dbms/tests/queries/0_stateless/00975_values_list.reference @@ -10,3 +10,4 @@ cadabra abracadabra 23 23 23 24 24 24 +1.6660 a b diff --git a/dbms/tests/queries/0_stateless/00975_values_list.sql b/dbms/tests/queries/0_stateless/00975_values_list.sql index a71dd50860d..ad30cec21e9 100644 --- a/dbms/tests/queries/0_stateless/00975_values_list.sql +++ b/dbms/tests/queries/0_stateless/00975_values_list.sql @@ -9,4 +9,6 @@ SELECT subtractYears(date, 1), subtractYears(date_time, 1) FROM VALUES('date Dat SELECT * FROM VALUES('s String', ('abra'), ('cadabra'), ('abracadabra')); SELECT * FROM VALUES('n UInt64, s String, ss String', (1 + 22, '23', toString(23)), (toUInt64('24'), '24', concat('2', '4'))); + +SELECT * FROM VALUES('a Decimal(4, 4), b String, c String', (divide(toDecimal32(5, 3), 3), 'a', 'b')); DROP TABLE values_list; From a449a00e5843dcbf5d16421d3ec3635f17f67c1e Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Wed, 31 Jul 2019 17:12:05 +0300 Subject: [PATCH 0527/1165] Comments are now in right places --- dbms/src/Storages/StorageValues.cpp | 4 +--- dbms/src/Storages/StorageValues.h | 4 ++-- dbms/src/TableFunctions/TableFunctionValues.h | 4 +++- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dbms/src/Storages/StorageValues.cpp b/dbms/src/Storages/StorageValues.cpp index c8b470307dc..bda44569cc6 100644 --- a/dbms/src/Storages/StorageValues.cpp +++ b/dbms/src/Storages/StorageValues.cpp @@ -5,9 +5,7 @@ namespace DB { -/* One block storage used for values table function - * It's structure is similar to IStorageSystemOneBlock - */ + StorageValues::StorageValues(const std::string & database_name_, const std::string & table_name_, const Block & res_block_) : database_name(database_name_), table_name(table_name_), res_block(res_block_) { diff --git a/dbms/src/Storages/StorageValues.h b/dbms/src/Storages/StorageValues.h index 8ff52ed9df5..d26d1b27101 100644 --- a/dbms/src/Storages/StorageValues.h +++ b/dbms/src/Storages/StorageValues.h @@ -6,8 +6,8 @@ namespace DB { -/* values(structure, values...) - creates a temporary storage filling columns with values - * values is case-insensitive table function +/* One block storage used for values table function + * It's structure is similar to IStorageSystemOneBlock */ class StorageValues : public ext::shared_ptr_helper, public IStorage { diff --git a/dbms/src/TableFunctions/TableFunctionValues.h b/dbms/src/TableFunctions/TableFunctionValues.h index b6a4eb98b6b..f02dc69162f 100644 --- a/dbms/src/TableFunctions/TableFunctionValues.h +++ b/dbms/src/TableFunctions/TableFunctionValues.h @@ -4,7 +4,9 @@ namespace DB { - +/* values(structure, values...) - creates a temporary storage filling columns with values + * values is case-insensitive table function + */ class TableFunctionValues : public ITableFunction { public: From f0bf083efc92d3397bd646c300f24c3d13f74b4b Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 31 Jul 2019 17:16:28 +0300 Subject: [PATCH 0528/1165] Update CSVRowInputStream. --- dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp b/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp index bdcabc58042..5936ab0a369 100644 --- a/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/CSVRowInputFormat.cpp @@ -171,7 +171,7 @@ void CSVRowInputFormat::readPrefix() for (auto read_column : read_columns) { - if (read_column) + if (!read_column) { have_always_default_columns = true; break; From cac7972837193203d3d33b400fbb0e8d76f76c08 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Wed, 31 Jul 2019 17:18:59 +0300 Subject: [PATCH 0529/1165] better --- dbms/src/Interpreters/Context.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index db32c29434f..e06f1cddfaa 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -1707,11 +1707,10 @@ std::shared_ptr Context::getTextLog() { auto lock = getLock(); - if (!shared->system_logs) { - if (auto log = shared->system_logs->text_log.lock()) { + if (!shared->system_logs) + if (auto log = shared->system_logs->text_log.lock()) return log; - } - } + return {}; } From 4d2dee5aa7ec26230ddf303da8200aca645686bc Mon Sep 17 00:00:00 2001 From: proller Date: Wed, 31 Jul 2019 17:36:03 +0300 Subject: [PATCH 0530/1165] M_LIBRARY fix --- CMakeLists.txt | 6 ++---- contrib/brotli-cmake/CMakeLists.txt | 5 ++++- contrib/h3-cmake/CMakeLists.txt | 4 +++- contrib/libxml2-cmake/CMakeLists.txt | 5 ++++- contrib/mariadb-connector-c-cmake/CMakeLists.txt | 5 ++++- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3223130632f..a7ffdbc6a32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -342,7 +342,6 @@ if (OS_LINUX AND NOT UNBUNDLED AND (GLIBC_COMPATIBILITY OR USE_INTERNAL_UNWIND_L # FIXME: glibc-compatibility may be non-static in some builds! set (DEFAULT_LIBS "${DEFAULT_LIBS} ${ClickHouse_BINARY_DIR}/libs/libglibc-compatibility/libglibc-compatibility${${CMAKE_POSTFIX_VARIABLE}}.a") - set (M_OR_GLIBC_LIBRARY glibc-compatibility) endif () # Add Libc. GLIBC is actually a collection of interdependent libraries. @@ -353,10 +352,9 @@ if (OS_LINUX AND NOT UNBUNDLED AND (GLIBC_COMPATIBILITY OR USE_INTERNAL_UNWIND_L message(STATUS "Default libraries: ${DEFAULT_LIBS}") endif () -if (NOT M_OR_GLIBC_LIBRARY) - set (M_OR_GLIBC_LIBRARY m) +if (NOT GLIBC_COMPATIBILITY) + set (M_LIBRARY m) endif () -message(STATUS "Using m library=${M_OR_GLIBC_LIBRARY}") if (DEFAULT_LIBS) # Add default libs to all targets as the last dependency. diff --git a/contrib/brotli-cmake/CMakeLists.txt b/contrib/brotli-cmake/CMakeLists.txt index 3c995467c9d..e22f4593c02 100644 --- a/contrib/brotli-cmake/CMakeLists.txt +++ b/contrib/brotli-cmake/CMakeLists.txt @@ -31,4 +31,7 @@ set(SRCS add_library(brotli ${SRCS}) target_include_directories(brotli PUBLIC ${BROTLI_SOURCE_DIR}/include) -target_link_libraries(brotli PRIVATE ${M_OR_GLIBC_LIBRARY}) + +if(M_LIBRARY) + target_link_libraries(brotli PRIVATE ${M_LIBRARY}) +endif() diff --git a/contrib/h3-cmake/CMakeLists.txt b/contrib/h3-cmake/CMakeLists.txt index 5ad5f3fdb8d..ddd0b1e35ec 100644 --- a/contrib/h3-cmake/CMakeLists.txt +++ b/contrib/h3-cmake/CMakeLists.txt @@ -25,4 +25,6 @@ add_library(h3 ${SRCS}) target_include_directories(h3 SYSTEM PUBLIC ${H3_SOURCE_DIR}/include) target_include_directories(h3 SYSTEM PUBLIC ${H3_BINARY_DIR}/include) target_compile_definitions(h3 PRIVATE H3_HAVE_VLA) -target_link_libraries(h3 PRIVATE ${M_OR_GLIBC_LIBRARY}) +if(M_LIBRARY) + target_link_libraries(h3 PRIVATE ${M_LIBRARY}) +endif() \ No newline at end of file diff --git a/contrib/libxml2-cmake/CMakeLists.txt b/contrib/libxml2-cmake/CMakeLists.txt index ef362875e08..71127fb9e35 100644 --- a/contrib/libxml2-cmake/CMakeLists.txt +++ b/contrib/libxml2-cmake/CMakeLists.txt @@ -52,7 +52,10 @@ set(SRCS ) add_library(libxml2 ${SRCS}) -target_link_libraries(libxml2 PRIVATE ${ZLIB_LIBRARIES} ${M_OR_GLIBC_LIBRARY} ${CMAKE_DL_LIBS}) +target_link_libraries(libxml2 PRIVATE ${ZLIB_LIBRARIES} ${CMAKE_DL_LIBS}) +if(M_LIBRARY) + target_link_libraries(libxml2 PRIVATE ${M_LIBRARY}) +endif() target_include_directories(libxml2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/linux_x86_64/include) target_include_directories(libxml2 PUBLIC ${LIBXML2_SOURCE_DIR}/include) diff --git a/contrib/mariadb-connector-c-cmake/CMakeLists.txt b/contrib/mariadb-connector-c-cmake/CMakeLists.txt index d7ea148cf40..a0582d89685 100644 --- a/contrib/mariadb-connector-c-cmake/CMakeLists.txt +++ b/contrib/mariadb-connector-c-cmake/CMakeLists.txt @@ -60,7 +60,10 @@ endif() add_library(mysqlclient ${SRCS}) -target_link_libraries(mysqlclient PRIVATE ${CMAKE_DL_LIBS} ${M_OR_GLIBC_LIBRARY} Threads::Threads) +target_link_libraries(mysqlclient PRIVATE ${CMAKE_DL_LIBS} Threads::Threads) +if(M_LIBRARY) + target_link_libraries(mysqlclient PRIVATE ${M_LIBRARY}) +endif() if(OPENSSL_LIBRARIES) target_link_libraries(mysqlclient PRIVATE ${OPENSSL_LIBRARIES}) From 593194133ac3d01407ac89553d7119b58c56b76d Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Wed, 31 Jul 2019 17:42:23 +0300 Subject: [PATCH 0531/1165] lock to text_log added --- libs/libcommon/include/common/logger_useful.h | 1 + libs/libloggers/loggers/OwnSplitChannel.cpp | 2 ++ libs/libloggers/loggers/OwnSplitChannel.h | 1 + 3 files changed, 4 insertions(+) diff --git a/libs/libcommon/include/common/logger_useful.h b/libs/libcommon/include/common/logger_useful.h index 2e71312881a..86a8fccf374 100644 --- a/libs/libcommon/include/common/logger_useful.h +++ b/libs/libcommon/include/common/logger_useful.h @@ -32,6 +32,7 @@ using DB::CurrentThread; if (auto channel = (logger)->getChannel()) { \ std::string file_function; \ file_function += __FILE__; \ + file_function += ", " \ file_function += __PRETTY_FUNCTION__; \ Message poco_message((logger)->name(), oss_internal_rare.str(), \ (PRIORITY), file_function.c_str(), __LINE__); \ diff --git a/libs/libloggers/loggers/OwnSplitChannel.cpp b/libs/libloggers/loggers/OwnSplitChannel.cpp index 40361a2211f..a2f332a8cae 100644 --- a/libs/libloggers/loggers/OwnSplitChannel.cpp +++ b/libs/libloggers/loggers/OwnSplitChannel.cpp @@ -77,6 +77,7 @@ void OwnSplitChannel::log(const Poco::Message & msg) elem.source_line = msg.getSourceLine(); + std::lock_guard lock(text_log_mutex); if (auto log = text_log.lock()) log->add(elem); } @@ -88,6 +89,7 @@ void OwnSplitChannel::addChannel(Poco::AutoPtr channel) void OwnSplitChannel::addTextLog(std::shared_ptr log) { + std::lock_guard lock(text_log_mutex); text_log = log; } diff --git a/libs/libloggers/loggers/OwnSplitChannel.h b/libs/libloggers/loggers/OwnSplitChannel.h index 8415cd79c6a..1168a44acb0 100644 --- a/libs/libloggers/loggers/OwnSplitChannel.h +++ b/libs/libloggers/loggers/OwnSplitChannel.h @@ -30,6 +30,7 @@ private: using ExtendedChannelPtrPair = std::pair; std::vector channels; + std::mutex text_log_mutex; std::weak_ptr text_log; }; From 3a8fefdda8a0c752477d1c2b30f488a8d63bd0f3 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 31 Jul 2019 17:43:08 +0300 Subject: [PATCH 0532/1165] Update CSVRowInputStream. --- .../Impl/TabSeparatedRowInputFormat.cpp | 329 ++++++++++++------ .../Formats/Impl/TabSeparatedRowInputFormat.h | 13 + 2 files changed, 235 insertions(+), 107 deletions(-) diff --git a/dbms/src/Processors/Formats/Impl/TabSeparatedRowInputFormat.cpp b/dbms/src/Processors/Formats/Impl/TabSeparatedRowInputFormat.cpp index ab7562a0036..5834d46b322 100644 --- a/dbms/src/Processors/Formats/Impl/TabSeparatedRowInputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/TabSeparatedRowInputFormat.cpp @@ -16,24 +16,114 @@ namespace ErrorCodes } +static void skipTSVRow(ReadBuffer & istr, const size_t num_columns) +{ + NullSink null_sink; + + for (size_t i = 0; i < num_columns; ++i) + { + readEscapedStringInto(null_sink, istr); + assertChar(i == num_columns - 1 ? '\n' : '\t', istr); + } +} + + +/** Check for a common error case - usage of Windows line feed. + */ +static void checkForCarriageReturn(ReadBuffer & istr) +{ + if (istr.position()[0] == '\r' || (istr.position() != istr.buffer().begin() && istr.position()[-1] == '\r')) + throw Exception("\nYou have carriage return (\\r, 0x0D, ASCII 13) at end of first row." + "\nIt's like your input data has DOS/Windows style line separators, that are illegal in TabSeparated format." + " You must transform your file to Unix format." + "\nBut if you really need carriage return at end of string value of last column, you need to escape it as \\r.", + ErrorCodes::INCORRECT_DATA); +} + + TabSeparatedRowInputFormat::TabSeparatedRowInputFormat( ReadBuffer & in_, Block header, bool with_names, bool with_types, Params params, const FormatSettings & format_settings) - : IRowInputFormat(std::move(header), in_, params), with_names(with_names), with_types(with_types), format_settings(format_settings) + : IRowInputFormat(std::move(header), in_, std::move(params)), with_names(with_names), with_types(with_types), format_settings(format_settings) { auto & sample = getPort().getHeader(); size_t num_columns = sample.columns(); + data_types.resize(num_columns); + column_indexes_by_names.reserve(num_columns); + for (size_t i = 0; i < num_columns; ++i) - data_types[i] = sample.safeGetByPosition(i).type; + { + const auto & column_info = sample.getByPosition(i); + + data_types[i] = column_info.type; + column_indexes_by_names.emplace(column_info.name, i); + } + + column_indexes_for_input_fields.reserve(num_columns); + read_columns.assign(num_columns, false); +} + + +void TabSeparatedRowInputFormat::setupAllColumnsByTableSchema() +{ + auto & header = getPort().getHeader(); + read_columns.assign(header.columns(), true); + column_indexes_for_input_fields.resize(header.columns()); + + for (size_t i = 0; i < column_indexes_for_input_fields.size(); ++i) + column_indexes_for_input_fields[i] = i; +} + + +void TabSeparatedRowInputFormat::addInputColumn(const String & column_name) +{ + const auto column_it = column_indexes_by_names.find(column_name); + if (column_it == column_indexes_by_names.end()) + { + if (format_settings.skip_unknown_fields) + { + column_indexes_for_input_fields.push_back(std::nullopt); + return; + } + + throw Exception( + "Unknown field found in TSV header: '" + column_name + "' " + + "at position " + std::to_string(column_indexes_for_input_fields.size()) + + "\nSet the 'input_format_skip_unknown_fields' parameter explicitly to ignore and proceed", + ErrorCodes::INCORRECT_DATA + ); + } + + const auto column_index = column_it->second; + + if (read_columns[column_index]) + throw Exception("Duplicate field found while parsing TSV header: " + column_name, ErrorCodes::INCORRECT_DATA); + + read_columns[column_index] = true; + column_indexes_for_input_fields.emplace_back(column_index); +} + + +void TabSeparatedRowInputFormat::fillUnreadColumnsWithDefaults(MutableColumns & columns, RowReadExtension & row_read_extension) +{ + /// It is safe to memorize this on the first run - the format guarantees this does not change + if (unlikely(row_num == 1)) + { + columns_to_fill_with_default_values.clear(); + for (size_t index = 0; index < read_columns.size(); ++index) + if (read_columns[index] == 0) + columns_to_fill_with_default_values.push_back(index); + } + + for (const auto column_index : columns_to_fill_with_default_values) + data_types[column_index]->insertDefaultInto(*columns[column_index]); + + row_read_extension.read_columns = read_columns; } void TabSeparatedRowInputFormat::readPrefix() { - auto & header = getPort().getHeader(); - size_t num_columns = header.columns(); - String tmp; - if (with_names || with_types) { /// In this format, we assume that column name or type cannot contain BOM, @@ -44,65 +134,74 @@ void TabSeparatedRowInputFormat::readPrefix() if (with_names) { - for (size_t i = 0; i < num_columns; ++i) + if (format_settings.with_names_use_header) { - readEscapedString(tmp, in); - assertChar(i == num_columns - 1 ? '\n' : '\t', in); + String column_name; + do + { + readEscapedString(column_name, in); + addInputColumn(column_name); + } + while (checkChar('\t', in)); + + if (!in.eof()) + { + checkForCarriageReturn(in); + assertChar('\n', in); + } + } + else + { + setupAllColumnsByTableSchema(); + skipTSVRow(in, column_indexes_for_input_fields.size()); } } + else + setupAllColumnsByTableSchema(); if (with_types) { - for (size_t i = 0; i < num_columns; ++i) - { - readEscapedString(tmp, in); - assertChar(i == num_columns - 1 ? '\n' : '\t', in); - } + skipTSVRow(in, column_indexes_for_input_fields.size()); } } -/** Check for a common error case - usage of Windows line feed. - */ -static void checkForCarriageReturn(ReadBuffer & in) -{ - if (in.position()[0] == '\r' || (in.position() != in.buffer().begin() && in.position()[-1] == '\r')) - throw Exception("\nYou have carriage return (\\r, 0x0D, ASCII 13) at end of first row." - "\nIt's like your input data has DOS/Windows style line separators, that are illegal in TabSeparated format." - " You must transform your file to Unix format." - "\nBut if you really need carriage return at end of string value of last column, you need to escape it as \\r.", - ErrorCodes::INCORRECT_DATA); -} - - -bool TabSeparatedRowInputFormat::readRow(MutableColumns & columns, RowReadExtension &) +bool TabSeparatedRowInputFormat::readRow(MutableColumns & columns, RowReadExtension & ext) { if (in.eof()) return false; updateDiagnosticInfo(); - size_t size = data_types.size(); - - for (size_t i = 0; i < size; ++i) + for (size_t input_position = 0; input_position < column_indexes_for_input_fields.size(); ++input_position) { - data_types[i]->deserializeAsTextEscaped(*columns[i], in, format_settings); - - /// skip separators - if (i + 1 == size) + const auto & column_index = column_indexes_for_input_fields[input_position]; + if (column_index) { - if (!in.eof()) - { - if (unlikely(row_num == 1)) - checkForCarriageReturn(in); - - assertChar('\n', in); - } + data_types[*column_index]->deserializeAsTextEscaped(*columns[*column_index], in, format_settings); } else + { + NullSink null_sink; + readEscapedStringInto(null_sink, in); + } + + /// skip separators + if (input_position + 1 < column_indexes_for_input_fields.size()) + { assertChar('\t', in); + } + else if (!in.eof()) + { + if (unlikely(row_num == 1)) + checkForCarriageReturn(in); + + assertChar('\n', in); + } } + fillUnreadColumnsWithDefaults(columns, ext); + return true; } @@ -166,84 +265,100 @@ String TabSeparatedRowInputFormat::getDiagnosticInfo() bool TabSeparatedRowInputFormat::parseRowAndPrintDiagnosticInfo(MutableColumns & columns, WriteBuffer & out, size_t max_length_of_column_name, size_t max_length_of_data_type_name) { - auto & header = getPort().getHeader(); - size_t size = data_types.size(); - for (size_t i = 0; i < size; ++i) + for (size_t input_position = 0; input_position < column_indexes_for_input_fields.size(); ++input_position) { - if (i == 0 && in.eof()) + if (input_position == 0 && in.eof()) { out << "\n"; return false; } - out << "Column " << i << ", " << std::string((i < 10 ? 2 : i < 100 ? 1 : 0), ' ') - << "name: " << header.safeGetByPosition(i).name << ", " << std::string(max_length_of_column_name - header.safeGetByPosition(i).name.size(), ' ') - << "type: " << data_types[i]->getName() << ", " << std::string(max_length_of_data_type_name - data_types[i]->getName().size(), ' '); - - auto prev_position = in.position(); - std::exception_ptr exception; - - try + if (column_indexes_for_input_fields[input_position].has_value()) { - data_types[i]->deserializeAsTextEscaped(*columns[i], in, format_settings); - } - catch (...) - { - exception = std::current_exception(); - } + const auto & column_index = *column_indexes_for_input_fields[input_position]; + const auto & current_column_type = data_types[column_index]; - auto curr_position = in.position(); + const auto & header = getPort().getHeader(); - if (curr_position < prev_position) - throw Exception("Logical error: parsing is non-deterministic.", ErrorCodes::LOGICAL_ERROR); + out << "Column " << input_position << ", " << std::string((input_position < 10 ? 2 : input_position < 100 ? 1 : 0), ' ') + << "name: " << header.safeGetByPosition(column_index).name << ", " << std::string(max_length_of_column_name - header.safeGetByPosition(column_index).name.size(), ' ') + << "type: " << current_column_type->getName() << ", " << std::string(max_length_of_data_type_name - current_column_type->getName().size(), ' '); - if (isNumber(data_types[i]) || isDateOrDateTime(data_types[i])) - { - /// An empty string instead of a value. - if (curr_position == prev_position) + auto prev_position = in.position(); + std::exception_ptr exception; + + try { - out << "ERROR: text "; - verbosePrintString(prev_position, std::min(prev_position + 10, in.buffer().end()), out); - out << " is not like " << data_types[i]->getName() << "\n"; - return false; + current_column_type->deserializeAsTextEscaped(*columns[column_index], in, format_settings); } - } - - out << "parsed text: "; - verbosePrintString(prev_position, curr_position, out); - - if (exception) - { - if (data_types[i]->getName() == "DateTime") - out << "ERROR: DateTime must be in YYYY-MM-DD hh:mm:ss or NNNNNNNNNN (unix timestamp, exactly 10 digits) format.\n"; - else if (data_types[i]->getName() == "Date") - out << "ERROR: Date must be in YYYY-MM-DD format.\n"; - else - out << "ERROR\n"; - return false; - } - - out << "\n"; - - if (data_types[i]->haveMaximumSizeOfValue()) - { - if (*curr_position != '\n' && *curr_position != '\t') + catch (...) { - out << "ERROR: garbage after " << data_types[i]->getName() << ": "; - verbosePrintString(curr_position, std::min(curr_position + 10, in.buffer().end()), out); - out << "\n"; + exception = std::current_exception(); + } - if (data_types[i]->getName() == "DateTime") + auto curr_position = in.position(); + + if (curr_position < prev_position) + throw Exception("Logical error: parsing is non-deterministic.", ErrorCodes::LOGICAL_ERROR); + + if (isNativeNumber(current_column_type) || isDateOrDateTime(current_column_type)) + { + /// An empty string instead of a value. + if (curr_position == prev_position) + { + out << "ERROR: text "; + verbosePrintString(prev_position, std::min(prev_position + 10, in.buffer().end()), out); + out << " is not like " << current_column_type->getName() << "\n"; + return false; + } + } + + out << "parsed text: "; + verbosePrintString(prev_position, curr_position, out); + + if (exception) + { + if (current_column_type->getName() == "DateTime") out << "ERROR: DateTime must be in YYYY-MM-DD hh:mm:ss or NNNNNNNNNN (unix timestamp, exactly 10 digits) format.\n"; - else if (data_types[i]->getName() == "Date") + else if (current_column_type->getName() == "Date") out << "ERROR: Date must be in YYYY-MM-DD format.\n"; - + else + out << "ERROR\n"; return false; } + + out << "\n"; + + if (current_column_type->haveMaximumSizeOfValue()) + { + if (*curr_position != '\n' && *curr_position != '\t') + { + out << "ERROR: garbage after " << current_column_type->getName() << ": "; + verbosePrintString(curr_position, std::min(curr_position + 10, in.buffer().end()), out); + out << "\n"; + + if (current_column_type->getName() == "DateTime") + out << "ERROR: DateTime must be in YYYY-MM-DD hh:mm:ss or NNNNNNNNNN (unix timestamp, exactly 10 digits) format.\n"; + else if (current_column_type->getName() == "Date") + out << "ERROR: Date must be in YYYY-MM-DD format.\n"; + + return false; + } + } + } + else + { + static const String skipped_column_str = ""; + out << "Column " << input_position << ", " << std::string((input_position < 10 ? 2 : input_position < 100 ? 1 : 0), ' ') + << "name: " << skipped_column_str << ", " << std::string(max_length_of_column_name - skipped_column_str.length(), ' ') + << "type: " << skipped_column_str << ", " << std::string(max_length_of_data_type_name - skipped_column_str.length(), ' '); + + NullSink null_sink; + readEscapedStringInto(null_sink, in); } /// Delimiters - if (i + 1 == size) + if (input_position + 1 == column_indexes_for_input_fields.size()) { if (!in.eof()) { @@ -256,13 +371,13 @@ bool TabSeparatedRowInputFormat::parseRowAndPrintDiagnosticInfo(MutableColumns & if (*in.position() == '\t') { out << "ERROR: Tab found where line feed is expected." - " It's like your file has more columns than expected.\n" - "And if your file have right number of columns, maybe it have unescaped tab in value.\n"; + " It's like your file has more columns than expected.\n" + "And if your file have right number of columns, maybe it have unescaped tab in value.\n"; } else if (*in.position() == '\r') { out << "ERROR: Carriage return found where line feed is expected." - " It's like your file has DOS/Windows style line separators, that is illegal in TabSeparated format.\n"; + " It's like your file has DOS/Windows style line separators, that is illegal in TabSeparated format.\n"; } else { @@ -285,8 +400,8 @@ bool TabSeparatedRowInputFormat::parseRowAndPrintDiagnosticInfo(MutableColumns & if (*in.position() == '\n') { out << "ERROR: Line feed found where tab is expected." - " It's like your file has less columns than expected.\n" - "And if your file have right number of columns, maybe it have unescaped backslash in value before tab, which cause tab has escaped.\n"; + " It's like your file has less columns than expected.\n" + "And if your file have right number of columns, maybe it have unescaped backslash in value before tab, which cause tab has escaped.\n"; } else if (*in.position() == '\r') { @@ -336,7 +451,7 @@ void registerInputFormatProcessorTabSeparated(FormatFactory & factory) IRowInputFormat::Params params, const FormatSettings & settings) { - return std::make_shared(buf, sample, false, false, params, settings); + return std::make_shared(buf, sample, false, false, std::move(params), settings); }); } @@ -349,7 +464,7 @@ void registerInputFormatProcessorTabSeparated(FormatFactory & factory) IRowInputFormat::Params params, const FormatSettings & settings) { - return std::make_shared(buf, sample, true, false, params, settings); + return std::make_shared(buf, sample, true, false, std::move(params), settings); }); } @@ -362,7 +477,7 @@ void registerInputFormatProcessorTabSeparated(FormatFactory & factory) IRowInputFormat::Params params, const FormatSettings & settings) { - return std::make_shared(buf, sample, true, true, params, settings); + return std::make_shared(buf, sample, true, true, std::move(params), settings); }); } } diff --git a/dbms/src/Processors/Formats/Impl/TabSeparatedRowInputFormat.h b/dbms/src/Processors/Formats/Impl/TabSeparatedRowInputFormat.h index b91884d9db5..47256e0b9a7 100644 --- a/dbms/src/Processors/Formats/Impl/TabSeparatedRowInputFormat.h +++ b/dbms/src/Processors/Formats/Impl/TabSeparatedRowInputFormat.h @@ -37,6 +37,19 @@ private: const FormatSettings format_settings; DataTypes data_types; + using IndexesMap = std::unordered_map; + IndexesMap column_indexes_by_names; + + using OptionalIndexes = std::vector>; + OptionalIndexes column_indexes_for_input_fields; + + std::vector read_columns; + std::vector columns_to_fill_with_default_values; + + void addInputColumn(const String & column_name); + void setupAllColumnsByTableSchema(); + void fillUnreadColumnsWithDefaults(MutableColumns & columns, RowReadExtension& ext); + /// For convenient diagnostics in case of an error. size_t row_num = 0; From e3df5a79b334f8e4a8ca5ad545f5f1b1fe900962 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 31 Jul 2019 17:43:39 +0300 Subject: [PATCH 0533/1165] Updated test --- dbms/tests/queries/0_stateless/00900_parquet.reference | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/tests/queries/0_stateless/00900_parquet.reference b/dbms/tests/queries/0_stateless/00900_parquet.reference index 43c04bc70a6..0f4be2c74a0 100644 --- a/dbms/tests/queries/0_stateless/00900_parquet.reference +++ b/dbms/tests/queries/0_stateless/00900_parquet.reference @@ -32,7 +32,7 @@ 991 990 ContextLock Number of times the lock of Context was acquired or tried to acquire. This is global lock. -Query Number of queries started to be interpreted and maybe executed. Does not include queries that are failed to parse, that are rejected due to AST size limits; rejected due to quota limits or limits on number of simultaneously running queries. May include internal queries initiated by ClickHouse itself. Does not count subqueries. +Query Number of queries to be interpreted and potentially executed. Does not include queries that failed to parse or were rejected due to AST size limits, quota limits or limits on the number of simultaneously running queries. May include internal queries initiated by ClickHouse itself. Does not count subqueries. original: -128 0 -32768 0 -2147483648 0 -9223372036854775808 0 -1.032 -1.064 string-1 fixedstring-1\0\0 2003-04-05 2003-02-03 04:05:06 -108 108 -1016 1116 -1032 1132 -1064 1164 -1.032 -1.064 string-0 fixedstring\0\0\0\0 2001-02-03 2002-02-03 04:05:06 From 1e20c2bc27501f9bdc30e22ff334d8a80edd31a1 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Wed, 31 Jul 2019 17:49:16 +0300 Subject: [PATCH 0534/1165] DOCAPI-5760: Join engine docs. EN review. RU translation (#6234) --- docs/en/operations/table_engines/join.md | 30 +++--- .../functions/other_functions.md | 4 +- docs/ru/operations/table_engines/join.md | 96 +++++++++++++++++-- .../functions/other_functions.md | 6 ++ docs/ru/query_language/select.md | 2 +- 5 files changed, 115 insertions(+), 23 deletions(-) diff --git a/docs/en/operations/table_engines/join.md b/docs/en/operations/table_engines/join.md index af5f658d5b9..6a7236e2c5b 100644 --- a/docs/en/operations/table_engines/join.md +++ b/docs/en/operations/table_engines/join.md @@ -12,7 +12,7 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] ) ENGINE = Join(join_strictness, join_type, k1[, k2, ...]) ``` -See the detailed description of [CREATE TABLE](../../query_language/create.md#create-table-query) query. +See the detailed description of the [CREATE TABLE](../../query_language/create.md#create-table-query) query. **Engine Parameters** @@ -20,7 +20,7 @@ See the detailed description of [CREATE TABLE](../../query_language/create.md#cr - `join_type` – [JOIN type](../../query_language/select.md#select-join-types). - `k1[, k2, ...]` – Key columns from the `USING` clause that the `JOIN` operation is made with. -Set the parameters `join_strictness` and `join_type` without quotes, for example, `Join(ANY, LEFT, col1)`. They must match the `JOIN` operation that the table will be used for. If parameters don't match, ClickHouse doesn't throw an exception and may return incorrect data. +Enter `join_strictness` and `join_type` parameters without quotes, for example, `Join(ANY, LEFT, col1)`. They must match the `JOIN` operation that the table will be used for. If the parameters don't match, ClickHouse doesn't throw an exception and may return incorrect data. ## Table Usage @@ -29,14 +29,18 @@ Set the parameters `join_strictness` and `join_type` without quotes, for example Creating the left-side table: ```sql -CREATE TABLE id_val(`id` UInt32, `val` UInt32) ENGINE = TinyLog; -INSERT INTO id_val VALUES (1,11)(2,12)(3,13); +CREATE TABLE id_val(`id` UInt32, `val` UInt32) ENGINE = TinyLog +``` +```sql +INSERT INTO id_val VALUES (1,11)(2,12)(3,13) ``` Creating the right-side `Join` table: ```sql -CREATE TABLE id_val_join(`id` UInt32, `val` UInt8) ENGINE = Join(ANY, LEFT, id); +CREATE TABLE id_val_join(`id` UInt32, `val` UInt8) ENGINE = Join(ANY, LEFT, id) +``` +```sql INSERT INTO id_val_join VALUES (1,21)(1,22)(3,23) ``` @@ -53,7 +57,7 @@ SELECT * FROM id_val ANY LEFT JOIN id_val_join USING (id) SETTINGS join_use_null └────┴─────┴─────────────────┘ ``` -Retrieving the data from the `Join` table, specifying the join key value: +As an alternative, you can retrieve data from the `Join` table, specifying the join key value: ```sql SELECT joinGet('id_val_join', 'val', toUInt32(1)) @@ -66,12 +70,12 @@ SELECT joinGet('id_val_join', 'val', toUInt32(1)) ### Selecting and Inserting Data -You can use `INSERT` to add data to the table. For the `ANY` strictness, data for duplicated keys are ignored. For the `ALL` strictness, all rows are kept. +You can use `INSERT` queries to add data to the `Join`-engine tables. If the table was created with the `ANY` strictness, data for duplicate keys are ignored. With the `ALL` strictness, all rows are added. -You cannot perform the `SELECT` query directly from the table. Use one of the following ways: +You cannot perform a `SELECT` query directly from the table. Instead, use one of the following methods: -- Place the table at the right side in a `JOIN` clause. -- Call the [joinGet](../../query_language/functions/other_functions.md#other_functions-joinget) function, which allows to extract data from the table as from a dictionary. +- Place the table to the right side in a `JOIN` clause. +- Call the [joinGet](../../query_language/functions/other_functions.md#other_functions-joinget) function, which lets you extract data from the table the same way as from a dictionary. ### Limitations and Settings @@ -83,12 +87,12 @@ When creating a table, the following settings are applied: - [join_overflow_mode](../settings/query_complexity.md#settings-join_overflow_mode) - [join_any_take_last_row](../settings/settings.md#settings-join_any_take_last_row) -The table can't be used in `GLOBAL JOIN` operations. +The `Join`-engine tables can't be used in `GLOBAL JOIN` operations. ## Data Storage -Data for the `Join` tables is always located in RAM. When inserting rows into the table, ClickHouse writes the data blocks to the directory on disk to be able to restore them on server restart. +`Join` table data is always located in the RAM. When inserting rows into a table, ClickHouse writes data blocks to the directory on the disk so that they can be restored when the server restarts. -At the abnormal server restart, the block of data on the disk might be lost or damaged. In this case, you may need to manually delete the file with damaged data. +If the server restarts incorrectly, the data block on the disk might get lost or damaged. In this case, you may need to manually delete the file with damaged data. [Original article](https://clickhouse.yandex/docs/en/operations/table_engines/join/) diff --git a/docs/en/query_language/functions/other_functions.md b/docs/en/query_language/functions/other_functions.md index 007f1352775..57fa8acfee3 100644 --- a/docs/en/query_language/functions/other_functions.md +++ b/docs/en/query_language/functions/other_functions.md @@ -668,9 +668,9 @@ So, result of function depends on partition of data to blocks and on order of da ## joinGet('join_storage_table_name', 'get_column', join_key) {#other_functions-joinget} -Gets data from the [Join](../../operations/table_engines/join.md) table using the specified join key. +Gets data from [Join](../../operations/table_engines/join.md) tables using the specified join key. -Supports only tables created with `ENGINE = Join(ANY, LEFT, )` statement. +Only supports tables created with the `ENGINE = Join(ANY, LEFT, )` statement. ## modelEvaluate(model_name, ...) Evaluate external model. diff --git a/docs/ru/operations/table_engines/join.md b/docs/ru/operations/table_engines/join.md index d9ce49665e9..0de007b321d 100644 --- a/docs/ru/operations/table_engines/join.md +++ b/docs/ru/operations/table_engines/join.md @@ -1,18 +1,100 @@ # Join -Представляет собой подготовленную структуру данных для JOIN-а, постоянно находящуюся в оперативке. +Подготовленная структура данных для использования в операциях [JOIN](../../query_language/select.md#select-join). + +## Создание таблицы ``` -Join(ANY|ALL, LEFT|INNER, k1[, k2, ...]) +CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] +( + name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1], + name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2], +) ENGINE = Join(join_strictness, join_type, k1[, k2, ...]) ``` -Параметры движка: `ANY|ALL` - строгость, `LEFT|INNER` - тип. -Эти параметры (задаются без кавычек) должны соответствовать тому JOIN-у, для которого будет использоваться таблица. k1, k2, ... - ключевые столбцы из секции USING, по которым будет делаться соединение. +Смотрите подробное описание запроса [CREATE TABLE](../../query_language/create.md#create-table-query). -Таблица не может использоваться для GLOBAL JOIN-ов. +**Параметры движка** -В таблицу можно вставлять данные INSERT-ом, аналогично движку Set. В случае ANY, данные для дублирующихся ключей будут проигнорированы; в случае ALL - будут учитываться. Из таблицы нельзя, непосредственно, делать SELECT. Единственная возможность чтения - использование в качестве "правой" таблицы для JOIN. +- `join_strictness` – [строгость JOIN](../../query_language/select.md#select-join-strictness). +- `join_type` – [тип JOIN](../../query_language/select.md#select-join-types). +- `k1[, k2, ...]` – ключевые столбцы секции `USING` с которыми выполняется операция `JOIN`. -Хранение данных на диске аналогично движку Set. +Вводите параметры `join_strictness` и `join_type` без кавычек, например, `Join(ANY, LEFT, col1)`. Они должны быть такими же как и в той операции `JOIN`, в которой таблица будет использоваться. Если параметры не совпадают, ClickHouse не генерирует исключение и может возвращать неверные данные. + +## Использование таблицы + +### Пример + +Создание левой таблицы: + +```sql +CREATE TABLE id_val(`id` UInt32, `val` UInt32) ENGINE = TinyLog +``` +```sql +INSERT INTO id_val VALUES (1,11)(2,12)(3,13) +``` + +Создание правой таблицы с движком `Join`: + +```sql +CREATE TABLE id_val_join(`id` UInt32, `val` UInt8) ENGINE = Join(ANY, LEFT, id) +``` +```sql +INSERT INTO id_val_join VALUES (1,21)(1,22)(3,23) +``` + +Объединение таблиц: + +```sql +SELECT * FROM id_val ANY LEFT JOIN id_val_join USING (id) SETTINGS join_use_nulls = 1 +``` + +```text +┌─id─┬─val─┬─id_val_join.val─┐ +│ 1 │ 11 │ 21 │ +│ 2 │ 12 │ ᴺᵁᴸᴸ │ +│ 3 │ 13 │ 23 │ +└────┴─────┴─────────────────┘ +``` + +В качестве альтернативы, можно извлечь данные из таблицы `Join`, указав значение ключа объединения: + +```sql +SELECT joinGet('id_val_join', 'val', toUInt32(1)) +``` + +```text +┌─joinGet('id_val_join', 'val', toUInt32(1))─┐ +│ 21 │ +└────────────────────────────────────────────┘ +``` + +### Выборка и вставка данных + +Для добавления данных в таблицы с движком `Join` используйте запрос `INSERT`. Если таблица создавалась со строгостью `ANY`, то данные с повторяющимися ключами игнорируются. Если задавалась строгость `ALL`, то добавляются все строки. + +Из таблиц нельзя выбрать данные с помощью запроса `SELECT`. Вместо этого, используйте один из следующих методов: + +- Используйте таблицу как правую в секции `JOIN`. +- Используйте функцию [joinGet](../../query_language/functions/other_functions.md#other_functions-joinget), которая позволяет извлекать данные из таблицы таким же образом как из словаря. + +### Ограничения и настройки + +При создании таблицы, применяются следующие параметры : + +- [join_use_nulls](../settings/settings.md#settings-join_use_nulls) +- [max_rows_in_join](../settings/query_complexity.md#settings-max_rows_in_join) +- [max_bytes_in_join](../settings/query_complexity.md#settings-max_bytes_in_join) +- [join_overflow_mode](../settings/query_complexity.md#settings-join_overflow_mode) +- [join_any_take_last_row](../settings/settings.md#settings-join_any_take_last_row) + +Таблицы с движком `Join` нельзя использовать в операциях `GLOBAL JOIN`. + +## Хранение данных + +Данные таблиц `Join` всегда находятся в RAM. При вставке строк в таблицу ClickHouse записывает блоки данных в каталог на диске, чтобы их можно было восстановить при перезапуске сервера. + +При аварийном перезапуске сервера блок данных на диске может быть потерян или повреждён. В последнем случае, может потребоваться вручную удалить файл с повреждёнными данными. [Оригинальная статья](https://clickhouse.yandex/docs/ru/operations/table_engines/join/) diff --git a/docs/ru/query_language/functions/other_functions.md b/docs/ru/query_language/functions/other_functions.md index 6e4913638ee..1637c7bda93 100644 --- a/docs/ru/query_language/functions/other_functions.md +++ b/docs/ru/query_language/functions/other_functions.md @@ -637,4 +637,10 @@ SELECT filesystemAvailable() AS "Free space", toTypeName(filesystemAvailable()) Принимает на вход состояния агрегатной функции и возвращает столбец со значениями, которые представляют собой результат мёржа этих состояний для выборки строк из блока от первой до текущей строки. Например, принимает состояние агрегатной функции (например, `runningAccumulate(uniqState(UserID))`), и для каждой строки блока возвращает результат агрегатной функции после мёржа состояний функции для всех предыдущих строк и текущей. Таким образом, результат зависит от разбиения данных по блокам и от порядка данных в блоке. +## joinGet('join_storage_table_name', 'get_column', join_key) {#other_functions-joinget} + +Получает данные из таблиц [Join](../../operations/table_engines/join.md) по ключу. + +Поддержаны только таблицы, созданные запросом с `ENGINE = Join(ANY, LEFT, )`. + [Оригинальная статья](https://clickhouse.yandex/docs/ru/query_language/functions/other_functions/) diff --git a/docs/ru/query_language/select.md b/docs/ru/query_language/select.md index d85d706a81c..05ac81bf8be 100644 --- a/docs/ru/query_language/select.md +++ b/docs/ru/query_language/select.md @@ -506,7 +506,7 @@ FROM Вместо `` и `` можно указать имена таблиц. Это эквивалентно подзапросу `SELECT * FROM table`, за исключением особого случая таблицы с движком [Join](../operations/table_engines/join.md) – массива, подготовленного для присоединения. -**Поддерживаемые типы `JOIN`** +#### Поддерживаемые типы `JOIN` {#select-join-types} - `INNER JOIN` (or `JOIN`) - `LEFT JOIN` (or `LEFT OUTER JOIN`) From 4481bf429f1171ee7396626af3ed72f226ddb4e4 Mon Sep 17 00:00:00 2001 From: alesapin Date: Wed, 31 Jul 2019 17:54:58 +0300 Subject: [PATCH 0535/1165] Remove nulltype from assignment --- dbms/src/Interpreters/ExpressionActions.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/dbms/src/Interpreters/ExpressionActions.cpp b/dbms/src/Interpreters/ExpressionActions.cpp index 11d544613fa..b55ce6077be 100644 --- a/dbms/src/Interpreters/ExpressionActions.cpp +++ b/dbms/src/Interpreters/ExpressionActions.cpp @@ -510,7 +510,6 @@ void ExpressionAction::execute(Block & block, bool dry_run) const if (can_replace && block.has(result_name)) { auto & result = block.getByName(result_name); - result.type = result_type; result.column = block.getByName(source_name).column; } else From aed4e5d1c4c986906e42d14988bc24495e674954 Mon Sep 17 00:00:00 2001 From: alesapin Date: Wed, 31 Jul 2019 17:57:14 +0300 Subject: [PATCH 0536/1165] Get type from source column --- dbms/src/Interpreters/ExpressionActions.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/dbms/src/Interpreters/ExpressionActions.cpp b/dbms/src/Interpreters/ExpressionActions.cpp index b55ce6077be..df666cede38 100644 --- a/dbms/src/Interpreters/ExpressionActions.cpp +++ b/dbms/src/Interpreters/ExpressionActions.cpp @@ -510,6 +510,7 @@ void ExpressionAction::execute(Block & block, bool dry_run) const if (can_replace && block.has(result_name)) { auto & result = block.getByName(result_name); + result.type = block.getByName(source_name).type; result.column = block.getByName(source_name).column; } else From 1347cf13594d3682ae13df7c6c7af5c8cd68a35a Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 31 Jul 2019 17:58:56 +0300 Subject: [PATCH 0537/1165] Update ODBCDriver2BlockOutputFormat. --- .../Formats/Impl/ODBCDriver2BlockOutputFormat.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/dbms/src/Processors/Formats/Impl/ODBCDriver2BlockOutputFormat.cpp b/dbms/src/Processors/Formats/Impl/ODBCDriver2BlockOutputFormat.cpp index 543edade0e8..29effe47d5d 100644 --- a/dbms/src/Processors/Formats/Impl/ODBCDriver2BlockOutputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/ODBCDriver2BlockOutputFormat.cpp @@ -6,6 +6,7 @@ #include +#include namespace DB @@ -95,8 +96,10 @@ void ODBCDriver2BlockOutputFormat::writePrefix() writeODBCString(out, "type"); for (size_t i = 0; i < columns; ++i) { - const ColumnWithTypeAndName & col = header.getByPosition(i); - writeODBCString(out, col.type->getName()); + auto type = header.getByPosition(i).type; + if (type->lowCardinality()) + type = recursiveRemoveLowCardinality(type); + writeODBCString(out, type->getName()); } } From f70b0ed91052e6709783a5f22fbaded9deb77811 Mon Sep 17 00:00:00 2001 From: alesapin Date: Wed, 31 Jul 2019 18:05:21 +0300 Subject: [PATCH 0538/1165] Slightly better --- dbms/src/Interpreters/ExpressionActions.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dbms/src/Interpreters/ExpressionActions.cpp b/dbms/src/Interpreters/ExpressionActions.cpp index df666cede38..0bb59713868 100644 --- a/dbms/src/Interpreters/ExpressionActions.cpp +++ b/dbms/src/Interpreters/ExpressionActions.cpp @@ -510,8 +510,9 @@ void ExpressionAction::execute(Block & block, bool dry_run) const if (can_replace && block.has(result_name)) { auto & result = block.getByName(result_name); - result.type = block.getByName(source_name).type; - result.column = block.getByName(source_name).column; + const auto & source = block.getByName(source_name); + result.type = source.type; + result.column = source.column; } else { From 9c4aefe2ae380a49f8360871684f9972cd74959a Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 31 Jul 2019 18:10:51 +0300 Subject: [PATCH 0539/1165] Update ODBCDriver2BlockOutputFormat. --- .../Processors/Formats/Impl/ODBCDriver2BlockOutputFormat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Processors/Formats/Impl/ODBCDriver2BlockOutputFormat.cpp b/dbms/src/Processors/Formats/Impl/ODBCDriver2BlockOutputFormat.cpp index 29effe47d5d..d2a4842fa24 100644 --- a/dbms/src/Processors/Formats/Impl/ODBCDriver2BlockOutputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/ODBCDriver2BlockOutputFormat.cpp @@ -39,7 +39,7 @@ void ODBCDriver2BlockOutputFormat::writeRow(const Block & header, const Columns { { WriteBufferFromString text_out(buffer); - header.getByPosition(row_idx).type->serializeAsText(*column, row_idx, text_out, format_settings); + header.getByPosition(column_idx).type->serializeAsText(*column, row_idx, text_out, format_settings); } writeODBCString(out, buffer); } From 1ec249755eb95ca692059c05149d3aa241e8edfb Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Wed, 31 Jul 2019 18:36:10 +0300 Subject: [PATCH 0540/1165] Parser is now used for ITableFunctionFileLike --- .../TableFunctions/ITableFunctionFileLike.cpp | 29 ++++-------- .../TableFunctions/TableFunctionValues.cpp | 34 +++----------- .../parseColumnsListForTableFunction.cpp | 44 +++++++++++++++++++ .../parseColumnsListForTableFunction.h | 12 +++++ 4 files changed, 70 insertions(+), 49 deletions(-) create mode 100644 dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp create mode 100644 dbms/src/TableFunctions/parseColumnsListForTableFunction.h diff --git a/dbms/src/TableFunctions/ITableFunctionFileLike.cpp b/dbms/src/TableFunctions/ITableFunctionFileLike.cpp index 7201af6ca06..5fe5da5c47d 100644 --- a/dbms/src/TableFunctions/ITableFunctionFileLike.cpp +++ b/dbms/src/TableFunctions/ITableFunctionFileLike.cpp @@ -1,14 +1,17 @@ #include #include +#include + #include #include + #include #include + #include -#include + #include #include -#include namespace DB @@ -21,7 +24,7 @@ namespace ErrorCodes StoragePtr ITableFunctionFileLike::executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const { - // Parse args + /// Parse args ASTs & args_func = ast_function->children; if (args_func.size() != 1) @@ -40,26 +43,12 @@ StoragePtr ITableFunctionFileLike::executeImpl(const ASTPtr & ast_function, cons std::string format = args[1]->as().value.safeGet(); std::string structure = args[2]->as().value.safeGet(); - // Create sample block - std::vector structure_vals; - boost::split(structure_vals, structure, boost::algorithm::is_any_of(" ,"), boost::algorithm::token_compress_on); - - if (structure_vals.size() % 2 != 0) - throw Exception("Odd number of elements in section structure: must be a list of name type pairs", ErrorCodes::LOGICAL_ERROR); + /// Create sample block Block sample_block; - const DataTypeFactory & data_type_factory = DataTypeFactory::instance(); + parseColumnsList(structure, sample_block, context); - for (size_t i = 0, size = structure_vals.size(); i < size; i += 2) - { - ColumnWithTypeAndName column; - column.name = structure_vals[i]; - column.type = data_type_factory.get(structure_vals[i + 1]); - column.column = column.type->createColumn(); - sample_block.insert(std::move(column)); - } - - // Create table + /// Create table StoragePtr storage = getStorage(filename, format, sample_block, const_cast(context), table_name); storage->startup(); diff --git a/dbms/src/TableFunctions/TableFunctionValues.cpp b/dbms/src/TableFunctions/TableFunctionValues.cpp index ebfd9fa5cba..90cfbce7682 100644 --- a/dbms/src/TableFunctions/TableFunctionValues.cpp +++ b/dbms/src/TableFunctions/TableFunctionValues.cpp @@ -3,20 +3,19 @@ #include #include -#include #include #include #include -#include #include #include #include +#include #include #include -#include + namespace DB @@ -72,38 +71,15 @@ StoragePtr TableFunctionValues::executeImpl(const ASTPtr & ast_function, const C throw Exception("Table function '" + getName() + "' requires 2 or more arguments: structure and values.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); - /// Parsing first argument as table structure + /// Parsing first argument as table structure and creating a sample block std::string structure = args[0]->as().value.safeGet(); - Expected expected; - - Tokens tokens(structure.c_str(), structure.c_str() + structure.size()); - TokenIterator token_iterator(tokens); - - ParserColumnDeclarationList parser; - ASTPtr columns_list_raw; - - if (!parser.parse(token_iterator, columns_list_raw, expected)) - throw Exception("Cannot parse columns declaration list.", ErrorCodes::SYNTAX_ERROR); - - auto * columns_list = dynamic_cast(columns_list_raw.get()); - if (!columns_list) - throw Exception("Could not cast AST to ASTExpressionList", ErrorCodes::LOGICAL_ERROR); - - ColumnsDescription columns_desc = InterpreterCreateQuery::getColumnsDescription(*columns_list, context); - Block sample_block; - for (const auto & [name, type]: columns_desc.getAllPhysical()) - { - ColumnWithTypeAndName column; - column.name = name; - column.type = type; - column.column = type->createColumn(); - sample_block.insert(std::move(column)); - } + parseColumnsList(structure, sample_block, context); MutableColumns res_columns = sample_block.cloneEmptyColumns(); + /// Parsing other arguments as values and inserting them into columns parseAndInsertValues(res_columns, args, sample_block, context); Block res_block = sample_block.cloneWithColumns(std::move(res_columns)); diff --git a/dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp b/dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp new file mode 100644 index 00000000000..d2d7906ede8 --- /dev/null +++ b/dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp @@ -0,0 +1,44 @@ +#include +#include +#include +#include + + +namespace DB +{ + +namespace ErrorCodes +{ + extern const int SYNTAX_ERROR; +} + +void parseColumnsList(const std::string & structure, Block & sample_block, const Context & context) +{ + Expected expected; + + Tokens tokens(structure.c_str(), structure.c_str() + structure.size()); + TokenIterator token_iterator(tokens); + + ParserColumnDeclarationList parser; + ASTPtr columns_list_raw; + + if (!parser.parse(token_iterator, columns_list_raw, expected)) + throw Exception("Cannot parse columns declaration list.", ErrorCodes::SYNTAX_ERROR); + + auto * columns_list = dynamic_cast(columns_list_raw.get()); + if (!columns_list) + throw Exception("Could not cast AST to ASTExpressionList", ErrorCodes::LOGICAL_ERROR); + + ColumnsDescription columns_desc = InterpreterCreateQuery::getColumnsDescription(*columns_list, context); + + for (const auto & [name, type]: columns_desc.getAllPhysical()) + { + ColumnWithTypeAndName column; + column.name = name; + column.type = type; + column.column = type->createColumn(); + sample_block.insert(std::move(column)); + } +} + +} \ No newline at end of file diff --git a/dbms/src/TableFunctions/parseColumnsListForTableFunction.h b/dbms/src/TableFunctions/parseColumnsListForTableFunction.h new file mode 100644 index 00000000000..d5efa792dee --- /dev/null +++ b/dbms/src/TableFunctions/parseColumnsListForTableFunction.h @@ -0,0 +1,12 @@ +#pragma once + +#include + + +namespace DB +{ + +void parseColumnsList(const std::string & structure, Block & sample_block, const Context & context); + +} + From fbe7e56e93003005d9de47641e14545618a754e8 Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Wed, 31 Jul 2019 18:43:01 +0300 Subject: [PATCH 0541/1165] Changed name and added comments --- dbms/src/TableFunctions/ITableFunctionFileLike.cpp | 2 +- dbms/src/TableFunctions/TableFunctionValues.cpp | 2 +- dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp | 2 +- dbms/src/TableFunctions/parseColumnsListForTableFunction.h | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dbms/src/TableFunctions/ITableFunctionFileLike.cpp b/dbms/src/TableFunctions/ITableFunctionFileLike.cpp index 5fe5da5c47d..0413839e819 100644 --- a/dbms/src/TableFunctions/ITableFunctionFileLike.cpp +++ b/dbms/src/TableFunctions/ITableFunctionFileLike.cpp @@ -46,7 +46,7 @@ StoragePtr ITableFunctionFileLike::executeImpl(const ASTPtr & ast_function, cons /// Create sample block Block sample_block; - parseColumnsList(structure, sample_block, context); + parseColumnsListFromString(structure, sample_block, context); /// Create table StoragePtr storage = getStorage(filename, format, sample_block, const_cast(context), table_name); diff --git a/dbms/src/TableFunctions/TableFunctionValues.cpp b/dbms/src/TableFunctions/TableFunctionValues.cpp index 90cfbce7682..a38eaf20ee8 100644 --- a/dbms/src/TableFunctions/TableFunctionValues.cpp +++ b/dbms/src/TableFunctions/TableFunctionValues.cpp @@ -75,7 +75,7 @@ StoragePtr TableFunctionValues::executeImpl(const ASTPtr & ast_function, const C std::string structure = args[0]->as().value.safeGet(); Block sample_block; - parseColumnsList(structure, sample_block, context); + parseColumnsListFromString(structure, sample_block, context); MutableColumns res_columns = sample_block.cloneEmptyColumns(); diff --git a/dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp b/dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp index d2d7906ede8..c55a5db9476 100644 --- a/dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp +++ b/dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp @@ -12,7 +12,7 @@ namespace ErrorCodes extern const int SYNTAX_ERROR; } -void parseColumnsList(const std::string & structure, Block & sample_block, const Context & context) +void parseColumnsListFromString(const std::string & structure, Block & sample_block, const Context & context) { Expected expected; diff --git a/dbms/src/TableFunctions/parseColumnsListForTableFunction.h b/dbms/src/TableFunctions/parseColumnsListForTableFunction.h index d5efa792dee..7a67633968c 100644 --- a/dbms/src/TableFunctions/parseColumnsListForTableFunction.h +++ b/dbms/src/TableFunctions/parseColumnsListForTableFunction.h @@ -5,8 +5,8 @@ namespace DB { - -void parseColumnsList(const std::string & structure, Block & sample_block, const Context & context); +/*Parses a common argument for table functions such as table structure given in string*/ +void parseColumnsListFromString(const std::string & structure, Block & sample_block, const Context & context); } From 42641a5b56efef8054477e4edb48272e9e8c9d24 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Wed, 31 Jul 2019 18:43:55 +0300 Subject: [PATCH 0542/1165] update flappy test --- .../0_stateless/00974_text_log_table_not_empty.sh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sh b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sh index 869f7a54b6b..10f095b53f6 100755 --- a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sh +++ b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sh @@ -4,6 +4,16 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) . $CURDIR/../shell_config.sh ${CLICKHOUSE_CLIENT} --query="SELECT 6103" -sleep 0.1 + +>00974_text_log_table_not_empty.tmp + +for (( i=1; i <= 50; i++ )) +do + ${CLICKHOUSE_CLIENT} --query="SYSTEM FLUSH LOGS" -${CLICKHOUSE_CLIENT} --query="SELECT count() > 0 FROM system.text_log WHERE position(system.text_log.message, 'SELECT 6103') > 0" +sleep 0.1; +if [[ $($CLICKHOUSE_CURL -sS "$CLICKHOUSE_URL" -d "SELECT count() > 0 FROM system.text_log WHERE position(system.text_log.message, 'SELECT 6103') > 0") == 1 ]]; then echo 1; exit; fi; + +done; + + From 96e5a88a429db0dda9965875cc7c5c4e47ab8f34 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Wed, 31 Jul 2019 18:48:56 +0300 Subject: [PATCH 0543/1165] ; --- libs/libcommon/include/common/logger_useful.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/libcommon/include/common/logger_useful.h b/libs/libcommon/include/common/logger_useful.h index 86a8fccf374..eaf4154b59e 100644 --- a/libs/libcommon/include/common/logger_useful.h +++ b/libs/libcommon/include/common/logger_useful.h @@ -32,7 +32,7 @@ using DB::CurrentThread; if (auto channel = (logger)->getChannel()) { \ std::string file_function; \ file_function += __FILE__; \ - file_function += ", " \ + file_function += ", "; \ file_function += __PRETTY_FUNCTION__; \ Message poco_message((logger)->name(), oss_internal_rare.str(), \ (PRIORITY), file_function.c_str(), __LINE__); \ From fab6e89a9dcf295c2f6521b597ff515998247718 Mon Sep 17 00:00:00 2001 From: Dmitry Rubashkin Date: Wed, 31 Jul 2019 18:58:28 +0300 Subject: [PATCH 0544/1165] Minor style fixes --- dbms/src/TableFunctions/TableFunctionValues.cpp | 2 -- dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp | 2 +- dbms/src/TableFunctions/parseColumnsListForTableFunction.h | 3 +-- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/dbms/src/TableFunctions/TableFunctionValues.cpp b/dbms/src/TableFunctions/TableFunctionValues.cpp index a38eaf20ee8..326e6eaace7 100644 --- a/dbms/src/TableFunctions/TableFunctionValues.cpp +++ b/dbms/src/TableFunctions/TableFunctionValues.cpp @@ -17,14 +17,12 @@ #include - namespace DB { namespace ErrorCodes { extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; - extern const int SYNTAX_ERROR; } static void parseAndInsertValues(MutableColumns & res_columns, const ASTs & args, const Block & sample_block, const Context & context) diff --git a/dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp b/dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp index c55a5db9476..05d8aa7cddc 100644 --- a/dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp +++ b/dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp @@ -41,4 +41,4 @@ void parseColumnsListFromString(const std::string & structure, Block & sample_bl } } -} \ No newline at end of file +} diff --git a/dbms/src/TableFunctions/parseColumnsListForTableFunction.h b/dbms/src/TableFunctions/parseColumnsListForTableFunction.h index 7a67633968c..3e942afa358 100644 --- a/dbms/src/TableFunctions/parseColumnsListForTableFunction.h +++ b/dbms/src/TableFunctions/parseColumnsListForTableFunction.h @@ -5,8 +5,7 @@ namespace DB { -/*Parses a common argument for table functions such as table structure given in string*/ +/// Parses a common argument for table functions such as table structure given in string void parseColumnsListFromString(const std::string & structure, Block & sample_block, const Context & context); } - From 5cedc24e51687a0de826d40312f025c1998b63e3 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 31 Jul 2019 21:04:24 +0300 Subject: [PATCH 0545/1165] Fixed error --- dbms/src/Functions/intDiv.h | 16 +++++----------- dbms/src/Functions/intDivOrZero.cpp | 10 +--------- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/dbms/src/Functions/intDiv.h b/dbms/src/Functions/intDiv.h index 9c33d27a219..0cbe612c6e1 100644 --- a/dbms/src/Functions/intDiv.h +++ b/dbms/src/Functions/intDiv.h @@ -13,7 +13,6 @@ namespace DB namespace ErrorCodes { extern const int ILLEGAL_DIVISION; - extern const int LOGICAL_ERROR; } #pragma GCC diagnostic push @@ -57,17 +56,12 @@ struct DivideIntegralImpl { throwIfDivisionLeadsToFPE(a, b); - if constexpr (!std::is_same_v) - { - /// Otherwise overflow may occur due to integer promotion. Example: int8_t(-1) / uint64_t(2). - /// NOTE: overflow is still possible when dividing large signed number to large unsigned number or vice-versa. But it's less harmful. - if constexpr (std::is_integral_v && std::is_integral_v && (std::is_signed_v || std::is_signed_v)) - return std::make_signed_t(a) / std::make_signed_t(b); - else - return a / b; - } + /// Otherwise overflow may occur due to integer promotion. Example: int8_t(-1) / uint64_t(2). + /// NOTE: overflow is still possible when dividing large signed number to large unsigned number or vice-versa. But it's less harmful. + if constexpr (std::is_integral_v && std::is_integral_v && (std::is_signed_v || std::is_signed_v)) + return std::make_signed_t(a) / std::make_signed_t(b); else - throw Exception("Logical error: the types are not divisable", ErrorCodes::LOGICAL_ERROR); + return a / b; } #if USE_EMBEDDED_COMPILER diff --git a/dbms/src/Functions/intDivOrZero.cpp b/dbms/src/Functions/intDivOrZero.cpp index 2d1ca2a704d..01c8b9fedfb 100644 --- a/dbms/src/Functions/intDivOrZero.cpp +++ b/dbms/src/Functions/intDivOrZero.cpp @@ -7,11 +7,6 @@ namespace DB { -namespace ErrorCodes -{ - extern const int LOGICAL_ERROR; -} - template struct DivideIntegralOrZeroImpl { @@ -23,10 +18,7 @@ struct DivideIntegralOrZeroImpl if (unlikely(divisionLeadsToFPE(a, b))) return 0; - if constexpr (!std::is_same_v) - return DivideIntegralImpl::apply(a, b); - else - throw Exception("Logical error: the types are not divisable", ErrorCodes::LOGICAL_ERROR); + return DivideIntegralImpl::template apply(a, b); } #if USE_EMBEDDED_COMPILER From bc9d620155fca38b2a495fe3080ef085e9179f41 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 31 Jul 2019 21:21:13 +0300 Subject: [PATCH 0546/1165] Fixed the case when malicious ClickHouse replica can force clickhouse-server to write to arbitrary path --- dbms/src/Common/ErrorCodes.cpp | 1 + dbms/src/Storages/MergeTree/DataPartsExchange.cpp | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/dbms/src/Common/ErrorCodes.cpp b/dbms/src/Common/ErrorCodes.cpp index 5cb6b7e0a37..bb1636b7871 100644 --- a/dbms/src/Common/ErrorCodes.cpp +++ b/dbms/src/Common/ErrorCodes.cpp @@ -440,6 +440,7 @@ namespace ErrorCodes extern const int CANNOT_FCNTL = 463; extern const int CANNOT_PARSE_ELF = 464; extern const int CANNOT_PARSE_DWARF = 465; + extern const int INSECURE_PATH = 466; extern const int KEEPER_EXCEPTION = 999; extern const int POCO_EXCEPTION = 1000; diff --git a/dbms/src/Storages/MergeTree/DataPartsExchange.cpp b/dbms/src/Storages/MergeTree/DataPartsExchange.cpp index 42c668c9fcb..ee7de070776 100644 --- a/dbms/src/Storages/MergeTree/DataPartsExchange.cpp +++ b/dbms/src/Storages/MergeTree/DataPartsExchange.cpp @@ -27,6 +27,7 @@ namespace ErrorCodes extern const int CANNOT_WRITE_TO_OSTREAM; extern const int CHECKSUM_DOESNT_MATCH; extern const int UNKNOWN_TABLE; + extern const int INSECURE_PATH; } namespace DataPartsExchange @@ -225,7 +226,15 @@ MergeTreeData::MutableDataPartPtr Fetcher::fetchPart( readStringBinary(file_name, in); readBinary(file_size, in); - WriteBufferFromFile file_out(absolute_part_path + file_name); + /// File must be inside "absolute_part_path" directory. + /// Otherwise malicious ClickHouse replica may force us to write to arbitrary path. + String file_absolute_path = Poco::Path(absolute_part_path + file_name).absolute().toString(); + if (!startsWith(file_absolute_path, absolute_part_path)) + throw Exception("File path doesn't appear to be inside part path." + " This may happen if we are trying to download part from malicious replica or logical error.", + ErrorCodes::INSECURE_PATH); + + WriteBufferFromFile file_out(file_absolute_path); HashingWriteBuffer hashing_out(file_out); copyData(in, hashing_out, file_size, blocker.getCounter()); From 10edd76fe4c2545acae168e27ded76755a4a8c91 Mon Sep 17 00:00:00 2001 From: chertus Date: Wed, 31 Jul 2019 23:19:52 +0300 Subject: [PATCH 0547/1165] fix join_use_nulls results for key columns --- dbms/src/Interpreters/Join.cpp | 164 ++++++++---------- .../0_stateless/00702_join_on_dups.reference | 22 +-- .../00848_join_use_nulls_segfault.reference | 24 +-- .../00853_join_with_nulls_crash.reference | 2 +- .../00878_join_unexpected_results.reference | 13 ++ .../00878_join_unexpected_results.sql | 16 +- ...00977_join_use_nulls_denny_crane.reference | 20 +++ .../00977_join_use_nulls_denny_crane.sql | 72 ++++++++ 8 files changed, 211 insertions(+), 122 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00977_join_use_nulls_denny_crane.reference create mode 100644 dbms/tests/queries/0_stateless/00977_join_use_nulls_denny_crane.sql diff --git a/dbms/src/Interpreters/Join.cpp b/dbms/src/Interpreters/Join.cpp index cf23aef5b67..f482aa5fdbd 100644 --- a/dbms/src/Interpreters/Join.cpp +++ b/dbms/src/Interpreters/Join.cpp @@ -334,13 +334,11 @@ void Join::setSampleBlock(const Block & block) prepareBlockListStructure(blocklist_sample); /// Move from `sample_block_with_columns_to_add` key columns to `sample_block_with_keys`, keeping the order. - size_t pos = 0; - while (pos < sample_block_with_columns_to_add.columns()) + for (size_t pos = 0; pos < sample_block_with_columns_to_add.columns();) { - const auto & name = sample_block_with_columns_to_add.getByPosition(pos).name; - if (key_names_right.end() != std::find(key_names_right.begin(), key_names_right.end(), name)) + auto & col = sample_block_with_columns_to_add.getByPosition(pos); + if (key_names_right.end() != std::find(key_names_right.begin(), key_names_right.end(), col.name)) { - auto & col = sample_block_with_columns_to_add.getByPosition(pos); col.column = recursiveRemoveLowCardinality(col.column); col.type = recursiveRemoveLowCardinality(col.type); sample_block_with_keys.insert(col); @@ -824,13 +822,8 @@ void Join::joinBlockImpl( for (size_t i = 0; i < existing_columns; ++i) { block.getByPosition(i).column = block.getByPosition(i).column->convertToFullColumnIfConst(); - - /// If use_nulls, convert left columns (except keys) to Nullable. if (use_nulls) - { - if (std::end(key_names_left) == std::find(key_names_left.begin(), key_names_left.end(), block.getByPosition(i).name)) - convertColumnToNullable(block.getByPosition(i)); - } + convertColumnToNullable(block.getByPosition(i)); } } @@ -855,7 +848,34 @@ void Join::joinBlockImpl( /// Filter & insert missing rows auto right_keys = requiredRightKeys(key_names_right, columns_added_by_join); - if constexpr (STRICTNESS == ASTTableJoin::Strictness::Any || STRICTNESS == ASTTableJoin::Strictness::Asof) + constexpr bool is_all_join = STRICTNESS == ASTTableJoin::Strictness::All; + constexpr bool inner_or_right = static_in_v; + constexpr bool left_or_full = static_in_v; + + std::vector right_keys_to_replicate [[maybe_unused]]; + + if constexpr (!is_all_join && inner_or_right) + { + /// If ANY INNER | RIGHT JOIN - filter all the columns except the new ones. + for (size_t i = 0; i < existing_columns; ++i) + block.safeGetByPosition(i).column = block.safeGetByPosition(i).column->filter(row_filter, -1); + + /// Add join key columns from right block if they has different name. + for (size_t i = 0; i < key_names_right.size(); ++i) + { + auto & right_name = key_names_right[i]; + auto & left_name = key_names_left[i]; + + auto it = right_keys.find(right_name); + if (it != right_keys.end() && !block.has(right_name)) + { + const auto & col = block.getByName(left_name); + bool is_nullable = it->second->isNullable(); + block.insert(correctNullability({col.column, col.type, right_name}, is_nullable)); + } + } + } + else { /// Some trash to represent IColumn::Filter as ColumnUInt8 needed for ColumnNullable::applyNullMap() auto null_map_filter_ptr = ColumnUInt8::create(); @@ -863,63 +883,6 @@ void Join::joinBlockImpl( null_map_filter.getData().swap(row_filter); const IColumn::Filter & filter = null_map_filter.getData(); - constexpr bool inner_or_right = static_in_v; - if constexpr (inner_or_right) - { - /// If ANY INNER | RIGHT JOIN - filter all the columns except the new ones. - for (size_t i = 0; i < existing_columns; ++i) - block.safeGetByPosition(i).column = block.safeGetByPosition(i).column->filter(filter, -1); - - /// Add join key columns from right block if they has different name. - for (size_t i = 0; i < key_names_right.size(); ++i) - { - auto & right_name = key_names_right[i]; - auto & left_name = key_names_left[i]; - - auto it = right_keys.find(right_name); - if (it != right_keys.end() && !block.has(right_name)) - { - const auto & col = block.getByName(left_name); - bool is_nullable = it->second->isNullable(); - block.insert(correctNullability({col.column, col.type, right_name}, is_nullable)); - } - } - } - else - { - /// Add join key columns from right block if they has different name. - for (size_t i = 0; i < key_names_right.size(); ++i) - { - auto & right_name = key_names_right[i]; - auto & left_name = key_names_left[i]; - - auto it = right_keys.find(right_name); - if (it != right_keys.end() && !block.has(right_name)) - { - const auto & col = block.getByName(left_name); - ColumnPtr column = col.column->convertToFullColumnIfConst(); - MutableColumnPtr mut_column = column->cloneEmpty(); - - for (size_t row = 0; row < filter.size(); ++row) - { - if (filter[row]) - mut_column->insertFrom(*column, row); - else - mut_column->insertDefault(); - } - - bool is_nullable = use_nulls || it->second->isNullable(); - block.insert(correctNullability({std::move(mut_column), col.type, right_name}, is_nullable, null_map_filter)); - } - } - } - } - else - { - constexpr bool left_or_full = static_in_v; - if (!offsets_to_replicate) - throw Exception("No data to filter columns", ErrorCodes::LOGICAL_ERROR); - /// Add join key columns from right block if they has different name. for (size_t i = 0; i < key_names_right.size(); ++i) { @@ -932,31 +895,37 @@ void Join::joinBlockImpl( const auto & col = block.getByName(left_name); ColumnPtr column = col.column->convertToFullColumnIfConst(); MutableColumnPtr mut_column = column->cloneEmpty(); + mut_column->reserve(column->size()); - size_t last_offset = 0; - for (size_t row = 0; row < column->size(); ++row) + for (size_t row = 0; row < filter.size(); ++row) { - if (size_t to_insert = (*offsets_to_replicate)[row] - last_offset) - { - if (!row_filter[row]) - mut_column->insertDefault(); - else - for (size_t dup = 0; dup < to_insert; ++dup) - mut_column->insertFrom(*column, row); - } - - last_offset = (*offsets_to_replicate)[row]; + if (filter[row]) + mut_column->insertFrom(*column, row); + else + mut_column->insertDefault(); } - /// TODO: null_map_filter bool is_nullable = (use_nulls && left_or_full) || it->second->isNullable(); - block.insert(correctNullability({std::move(mut_column), col.type, right_name}, is_nullable)); + block.insert(correctNullability({std::move(mut_column), col.type, right_name}, is_nullable, null_map_filter)); + + if constexpr (is_all_join) + right_keys_to_replicate.push_back(block.getPositionByName(right_name)); } } + } + + if constexpr (is_all_join) + { + if (!offsets_to_replicate) + throw Exception("No data to filter columns", ErrorCodes::LOGICAL_ERROR); /// If ALL ... JOIN - we replicate all the columns except the new ones. for (size_t i = 0; i < existing_columns; ++i) block.safeGetByPosition(i).column = block.safeGetByPosition(i).column->replicate(*offsets_to_replicate); + + /// Replicate additional right keys + for (size_t pos : right_keys_to_replicate) + block.safeGetByPosition(pos).column = block.safeGetByPosition(pos).column->replicate(*offsets_to_replicate); } } @@ -1142,7 +1111,14 @@ struct AdderNonJoined static void add(const Mapped & mapped, size_t & rows_added, MutableColumns & columns_right) { for (size_t j = 0; j < columns_right.size(); ++j) - columns_right[j]->insertFrom(*mapped.block->getByPosition(j).column.get(), mapped.row_num); + { + const auto & mapped_column = mapped.block->getByPosition(j).column; +#ifndef NDEBUG + if (columns_right[j]->isNullable() != mapped_column->isNullable()) + throw Exception("Wrong columns nullability", ErrorCodes::LOGICAL_ERROR); +#endif + columns_right[j]->insertFrom(*mapped_column, mapped.row_num); + } ++rows_added; } @@ -1156,7 +1132,14 @@ struct AdderNonJoined for (auto it = mapped.begin(); it.ok(); ++it) { for (size_t j = 0; j < columns_right.size(); ++j) - columns_right[j]->insertFrom(*it->block->getByPosition(j).column.get(), it->row_num); + { + const auto & mapped_column = it->block->getByPosition(j).column; +#ifndef NDEBUG + if (columns_right[j]->isNullable() != mapped_column->isNullable()) + throw Exception("Wrong columns nullability", ErrorCodes::LOGICAL_ERROR); +#endif + columns_right[j]->insertFrom(*mapped_column, it->row_num); + } ++rows_added; } @@ -1200,7 +1183,7 @@ public: std::unordered_map left_to_right_key_map; makeResultSampleBlock(left_sample_block, right_sample_block, columns_added_by_join, - key_positions_left, is_left_key, left_to_right_key_map); + key_positions_left, left_to_right_key_map); auto nullability_changes = getNullabilityChanges(parent.sample_block_with_keys, result_sample_block, key_positions_left, left_to_right_key_map); @@ -1269,18 +1252,15 @@ private: void makeResultSampleBlock(const Block & left_sample_block, const Block & right_sample_block, const NamesAndTypesList & columns_added_by_join, - const std::vector & key_positions_left, const std::vector & is_left_key, + const std::vector & key_positions_left, std::unordered_map & left_to_right_key_map) { result_sample_block = materializeBlock(left_sample_block); /// Convert left columns to Nullable if allowed if (parent.use_nulls) - { for (size_t i = 0; i < result_sample_block.columns(); ++i) - if (!is_left_key[i]) - convertColumnToNullable(result_sample_block.getByPosition(i)); - } + convertColumnToNullable(result_sample_block.getByPosition(i)); /// Add columns from the right-side table to the block. for (size_t i = 0; i < right_sample_block.columns(); ++i) @@ -1455,7 +1435,7 @@ private: const auto & dst = out_block.getByPosition(key_pos).column; const auto & src = sample_block_with_keys.getByPosition(i).column; - if (isColumnNullable(*dst) != isColumnNullable(*src)) + if (dst->isNullable() != src->isNullable()) nullability_changes.insert(key_pos); } diff --git a/dbms/tests/queries/0_stateless/00702_join_on_dups.reference b/dbms/tests/queries/0_stateless/00702_join_on_dups.reference index d874ac1f0cf..58602bafb5d 100644 --- a/dbms/tests/queries/0_stateless/00702_join_on_dups.reference +++ b/dbms/tests/queries/0_stateless/00702_join_on_dups.reference @@ -178,15 +178,15 @@ self left nullable vs not nullable 3 l4 4 2 l3 3 4 l5 \N 3 l4 4 4 l6 \N 3 l4 4 -5 l7 \N 0 0 -8 l8 \N 0 0 -9 l9 \N 0 0 +5 l7 \N 0 \N +8 l8 \N 0 \N +9 l9 \N 0 \N self left nullable vs not nullable 2 -1 r1 \N 0 -1 r2 \N 0 -2 r3 \N 0 -3 r4 \N 0 -3 r5 \N 0 +1 r1 \N 0 \N +1 r2 \N 0 \N +2 r3 \N 0 \N +3 r4 \N 0 \N +3 r5 \N 0 \N 4 r6 nr6 4 r6 nr6 6 r7 nr7 6 r7 nr7 7 r8 nr8 7 r8 nr8 @@ -268,6 +268,6 @@ self full nullable vs not nullable 3 l4 4 2 l3 3 4 l5 \N 3 l4 4 4 l6 \N 3 l4 4 -5 l7 \N 0 0 -8 l8 \N 0 0 -9 l9 \N 0 0 +5 l7 \N 0 \N +8 l8 \N 0 \N +9 l9 \N 0 \N diff --git a/dbms/tests/queries/0_stateless/00848_join_use_nulls_segfault.reference b/dbms/tests/queries/0_stateless/00848_join_use_nulls_segfault.reference index c2b37fba363..ce03c844969 100644 --- a/dbms/tests/queries/0_stateless/00848_join_use_nulls_segfault.reference +++ b/dbms/tests/queries/0_stateless/00848_join_use_nulls_segfault.reference @@ -3,12 +3,12 @@ l \N \N String Nullable(String) l \N \N String Nullable(String) r \N String Nullable(String) \N r \N Nullable(String) Nullable(String) -l \N String Nullable(String) -l \N String Nullable(String) +l \N \N String Nullable(String) +l \N \N String Nullable(String) r \N String Nullable(String) \N r \N Nullable(String) Nullable(String) \N \N -0 \N +\N \N using l \N String Nullable(String) l \N String Nullable(String) @@ -19,26 +19,26 @@ l \N String Nullable(String) \N String Nullable(String) \N \N Nullable(String) Nullable(String) \N \N -0 \N +\N \N on + join_use_nulls l \N \N TODO Nullable(String) l \N \N TODO Nullable(String) - r \N TODO Nullable(String) +\N r \N TODO Nullable(String) \N r \N Nullable(String) Nullable(String) -l \N TODO Nullable(String) -l \N TODO Nullable(String) - r \N TODO Nullable(String) +l \N \N TODO Nullable(String) +l \N \N TODO Nullable(String) +\N r \N TODO Nullable(String) \N r \N Nullable(String) Nullable(String) \N \N -0 \N +\N \N using + join_use_nulls l \N TODO Nullable(String) l \N TODO Nullable(String) - \N TODO Nullable(String) +\N \N TODO Nullable(String) \N \N Nullable(String) Nullable(String) l \N TODO Nullable(String) l \N TODO Nullable(String) - \N TODO Nullable(String) +\N \N TODO Nullable(String) \N \N Nullable(String) Nullable(String) \N \N -0 \N +\N \N diff --git a/dbms/tests/queries/0_stateless/00853_join_with_nulls_crash.reference b/dbms/tests/queries/0_stateless/00853_join_with_nulls_crash.reference index c23c6409aa2..4eafec8a6c9 100644 --- a/dbms/tests/queries/0_stateless/00853_join_with_nulls_crash.reference +++ b/dbms/tests/queries/0_stateless/00853_join_with_nulls_crash.reference @@ -6,7 +6,7 @@ foo \N 2 0 Nullable(String) Nullable(String) bar bar 1 2 Nullable(String) Nullable(String) \N 0 1 Nullable(String) Nullable(String) foo \N 2 0 Nullable(String) Nullable(String) -foo 2 0 String Nullable(String) +foo \N 2 0 String Nullable(String) bar bar 1 2 String Nullable(String) test 0 1 String Nullable(String) \N 0 1 String Nullable(String) diff --git a/dbms/tests/queries/0_stateless/00878_join_unexpected_results.reference b/dbms/tests/queries/0_stateless/00878_join_unexpected_results.reference index c91ce9d853b..65fcbc257ca 100644 --- a/dbms/tests/queries/0_stateless/00878_join_unexpected_results.reference +++ b/dbms/tests/queries/0_stateless/00878_join_unexpected_results.reference @@ -9,13 +9,25 @@ join_use_nulls = 1 1 1 2 2 - +1 1 1 1 +2 2 \N \N - +1 1 1 1 +2 2 \N \N - 1 1 1 1 - +2 2 - +2 2 \N \N - +\N \N - +1 1 \N \N +2 2 \N \N +- +1 1 1 1 +2 2 \N \N - join_use_nulls = 0 1 1 @@ -38,6 +50,7 @@ join_use_nulls = 0 - - - +- 1 1 0 0 2 2 0 0 - diff --git a/dbms/tests/queries/0_stateless/00878_join_unexpected_results.sql b/dbms/tests/queries/0_stateless/00878_join_unexpected_results.sql index cac68d6e13b..6f6cd6e6479 100644 --- a/dbms/tests/queries/0_stateless/00878_join_unexpected_results.sql +++ b/dbms/tests/queries/0_stateless/00878_join_unexpected_results.sql @@ -18,19 +18,21 @@ select * from t join s on (t.a=s.a and t.b=s.b); select '-'; select t.* from t left join s on (t.a=s.a and t.b=s.b) order by t.a; select '-'; --- select t.*, s.* from t left join s on (t.a=s.a and t.b=s.b); -- TODO +select t.*, s.* from t left join s on (t.a=s.a and t.b=s.b) order by t.a; select '-'; --- select t.*, s.* from t left join s on (s.a=t.a and t.b=s.b); -- TODO +select t.*, s.* from t left join s on (s.a=t.a and t.b=s.b) order by t.a; select '-'; select t.*, s.* from t right join s on (t.a=s.a and t.b=s.b); select '-'; --- select * from t left outer join s using (a,b) where s.a is null; -- TODO +select * from t left outer join s using (a,b) where s.a is null; select '-'; --- select * from t left outer join s on (t.a=s.a and t.b=s.b) where s.a is null; -- TODO +select * from t left outer join s on (t.a=s.a and t.b=s.b) where s.a is null; select '-'; --- select t.*, s.* from t left join s on (s.a=t.a and t.b=s.b and t.a=toInt64(2)) order by t.a; -- TODO +select s.* from t left outer join s on (t.a=s.a and t.b=s.b) where s.a is null; select '-'; --- select t.*, s.* from t left join s on (s.a=t.a); -- TODO +select t.*, s.* from t left join s on (s.a=t.a and t.b=s.b and t.a=toInt64(2)) order by t.a; +select '-'; +select t.*, s.* from t left join s on (s.a=t.a) order by t.a; select '-'; select t.*, s.* from t left join s on (t.b=toInt64(2) and s.a=t.a) where s.b=2; @@ -54,6 +56,8 @@ select '-'; select '-'; -- select * from t left outer join s on (t.a=s.a and t.b=s.b) where s.a is null; -- TODO select '-'; +-- select s.* from t left outer join s on (t.a=s.a and t.b=s.b) where s.a is null; -- TODO +select '-'; select t.*, s.* from t left join s on (s.a=t.a and t.b=s.b and t.a=toInt64(2)) order by t.a; select '-'; select t.*, s.* from t left join s on (s.a=t.a) order by t.a; diff --git a/dbms/tests/queries/0_stateless/00977_join_use_nulls_denny_crane.reference b/dbms/tests/queries/0_stateless/00977_join_use_nulls_denny_crane.reference new file mode 100644 index 00000000000..d4398eb0da6 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00977_join_use_nulls_denny_crane.reference @@ -0,0 +1,20 @@ +1 1 a 0 0 +0 0 2 2 a +1 1 a \N \N \N +\N \N \N 2 2 a +1 1 a 0 0 \N +0 0 \N 2 2 a +1 1 a \N \N \N +\N \N \N 2 2 a +1 1 a 0 \N +0 \N 2 2 a +1 1 a \N \N \N +\N \N \N 2 2 a +1 1 a 0 \N \N +0 \N \N 2 2 a +1 1 a \N \N \N +\N \N \N 2 2 a +1 1 a \N \N \N +\N \N \N 2 2 a +1 1 a \N \N \N +\N \N \N 2 2 a diff --git a/dbms/tests/queries/0_stateless/00977_join_use_nulls_denny_crane.sql b/dbms/tests/queries/0_stateless/00977_join_use_nulls_denny_crane.sql new file mode 100644 index 00000000000..ab1eb02e972 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00977_join_use_nulls_denny_crane.sql @@ -0,0 +1,72 @@ +drop table if exists t; +drop table if exists s; + +create table t(a Int64, b Int64, c String) engine = Memory; +create table s(a Int64, b Int64, c String) engine = Memory; + +insert into t values(1,1,'a'); +insert into s values(2,2,'a'); + +select t.*, s.a, s.b, s.c from t left join s on (s.a = t.a and s.b = t.b); +select t.*, s.a, s.b, s.c from t right join s on (s.a = t.a and s.b = t.b); +select t.*, s.a, s.b, s.c from t left join s on (s.a = t.a and s.b = t.b) SETTINGS join_use_nulls = 1; +select t.*, s.a, s.b, s.c from t right join s on (s.a = t.a and s.b = t.b) SETTINGS join_use_nulls = 1; + +drop table t; +drop table s; + +create table t(a Int64, b Int64, c Nullable(String)) engine = Memory; +create table s(a Int64, b Int64, c Nullable(String)) engine = Memory; + +insert into t values(1,1,'a'); +insert into s values(2,2,'a'); + +select * from t left join s on (s.a = t.a and s.b = t.b); +select * from t right join s on (s.a = t.a and s.b = t.b); +select t.*, s.* from t left join s on (s.a = t.a and s.b = t.b) SETTINGS join_use_nulls = 1; +select t.*, s.* from t right join s on (s.a = t.a and s.b = t.b) SETTINGS join_use_nulls = 1; + +drop table t; +drop table s; + +create table t(a Int64, b Nullable(Int64), c String) engine = Memory; +create table s(a Int64, b Nullable(Int64), c String) engine = Memory; + +insert into t values(1,1,'a'); +insert into s values(2,2,'a'); + +select t.*, s.* from t left join s on (s.a = t.a and s.b = t.b); +select t.*, s.* from t right join s on (s.a = t.a and s.b = t.b); +select * from t left join s on (s.a = t.a and s.b = t.b) SETTINGS join_use_nulls = 1; +select * from t right join s on (s.a = t.a and s.b = t.b) SETTINGS join_use_nulls = 1; + +drop table t; +drop table s; + +create table t(a Int64, b Nullable(Int64), c Nullable(String)) engine = Memory; +create table s(a Int64, b Nullable(Int64), c Nullable(String)) engine = Memory; + +insert into t values(1,1,'a'); +insert into s values(2,2,'a'); + +select t.*, s.a, s.b, s.c from t left join s on (s.a = t.a and s.b = t.b); +select t.*, s.a, s.b, s.c from t right join s on (s.a = t.a and s.b = t.b); +select * from t left join s on (s.a = t.a and s.b = t.b) SETTINGS join_use_nulls = 1; +select * from t right join s on (s.a = t.a and s.b = t.b) SETTINGS join_use_nulls = 1; + +drop table t; +drop table s; + +create table t(a Nullable(Int64), b Nullable(Int64), c Nullable(String)) engine = Memory; +create table s(a Nullable(Int64), b Nullable(Int64), c Nullable(String)) engine = Memory; + +insert into t values(1,1,'a'); +insert into s values(2,2,'a'); + +select * from t left join s on (s.a = t.a and s.b = t.b); +select * from t right join s on (s.a = t.a and s.b = t.b); +select t.*, s.a, s.b, s.c from t left join s on (s.a = t.a and s.b = t.b) SETTINGS join_use_nulls = 1; +select t.*, s.a, s.b, s.c from t right join s on (s.a = t.a and s.b = t.b) SETTINGS join_use_nulls = 1; + +drop table t; +drop table s; From e3c342d8938f9f4462c898782aff04fb60ec55b7 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 00:40:29 +0300 Subject: [PATCH 0548/1165] Better stack traces: start outside of signal handler --- dbms/src/Common/QueryProfiler.cpp | 11 +++++-- dbms/src/Common/StackTrace.cpp | 51 ++++++++++++++++++++---------- dbms/src/Common/StackTrace.h | 15 ++------- dbms/src/Common/TraceCollector.cpp | 25 ++++++++------- 4 files changed, 60 insertions(+), 42 deletions(-) diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index 38c223678d7..bcdfcb5ae24 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -85,7 +85,8 @@ namespace constexpr size_t buf_size = sizeof(char) + // TraceCollector stop flag 8 * sizeof(char) + // maximum VarUInt length for string size QUERY_ID_MAX_LEN * sizeof(char) + // maximum query_id length - sizeof(StackTrace) + // collected stack trace + sizeof(UInt8) + // number of stack frames + sizeof(StackTrace::Frames) + // collected stack trace, maximum capacity sizeof(TimerType) + // timer type sizeof(UInt32); // thread_number char buffer[buf_size]; @@ -101,7 +102,13 @@ namespace writeChar(false, out); writeStringBinary(query_id, out); - writePODBinary(stack_trace, out); + + size_t stack_trace_size = stack_trace.getSize(); + size_t stack_trace_offset = stack_trace.getOffset(); + writeIntBinary(UInt8(stack_trace_size - stack_trace_offset), out); + for (size_t i = stack_trace_offset; i < stack_trace_size; ++i) + writePODBinary(stack_trace.getFrames()[i], out); + writePODBinary(timer_type, out); writePODBinary(thread_number, out); out.next(); diff --git a/dbms/src/Common/StackTrace.cpp b/dbms/src/Common/StackTrace.cpp index 30fb66f218e..a39eaf484e4 100644 --- a/dbms/src/Common/StackTrace.cpp +++ b/dbms/src/Common/StackTrace.cpp @@ -155,7 +155,7 @@ std::string signalToErrorMessage(int sig, const siginfo_t & info, const ucontext return error.str(); } -void * getCallerAddress(const ucontext_t & context) +static void * getCallerAddress(const ucontext_t & context) { #if defined(__x86_64__) /// Get the address at the time the signal was raised from the RIP (x86-64) @@ -182,12 +182,25 @@ StackTrace::StackTrace(const ucontext_t & signal_context) { tryCapture(); - if (size == 0) + void * caller_address = getCallerAddress(signal_context); + + if (size == 0 && caller_address) { - /// No stack trace was captured. At least we can try parsing caller address - void * caller_address = getCallerAddress(signal_context); - if (caller_address) - frames[size++] = reinterpret_cast(caller_address); + frames[0] = caller_address; + size = 1; + } + else + { + /// Skip excessive stack frames that we have created while finding stack trace. + + for (size_t i = 0; i < size; ++i) + { + if (frames[i] == caller_address) + { + offset = i; + break; + } + } } } @@ -214,21 +227,18 @@ size_t StackTrace::getSize() const return size; } +size_t StackTrace::getOffset() const +{ + return offset; +} + const StackTrace::Frames & StackTrace::getFrames() const { return frames; } -std::string StackTrace::toString() const -{ - /// Calculation of stack trace text is extremely slow. - /// We use simple cache because otherwise the server could be overloaded by trash queries. - static SimpleCache func_cached; - return func_cached(frames, size); -} - -std::string StackTrace::toStringImpl(const Frames & frames, size_t size) +static std::string toStringImpl(const StackTrace::Frames & frames, size_t offset, size_t size) { if (size == 0) return ""; @@ -238,7 +248,7 @@ std::string StackTrace::toStringImpl(const Frames & frames, size_t size) std::stringstream out; - for (size_t i = 0; i < size; ++i) + for (size_t i = offset; i < size; ++i) { const void * addr = frames[i]; @@ -275,3 +285,12 @@ std::string StackTrace::toStringImpl(const Frames & frames, size_t size) return out.str(); } + +std::string StackTrace::toString() const +{ + /// Calculation of stack trace text is extremely slow. + /// We use simple cache because otherwise the server could be overloaded by trash queries. + + static SimpleCache func_cached; + return func_cached(frames, offset, size); +} diff --git a/dbms/src/Common/StackTrace.h b/dbms/src/Common/StackTrace.h index 997730eb440..40e1bbbe504 100644 --- a/dbms/src/Common/StackTrace.h +++ b/dbms/src/Common/StackTrace.h @@ -34,28 +34,17 @@ public: /// Creates empty object for deferred initialization StackTrace(NoCapture); - /// Fills stack trace frames with provided sequence - template - StackTrace(Iterator it, Iterator end) - { - while (size < capacity && it != end) - { - frames[size++] = *(it++); - } - } - size_t getSize() const; + size_t getOffset() const; const Frames & getFrames() const; std::string toString() const; protected: void tryCapture(); - static std::string toStringImpl(const Frames & frames, size_t size); size_t size = 0; + size_t offset = 0; /// How many frames to skip while displaying. Frames frames{}; }; std::string signalToErrorMessage(int sig, const siginfo_t & info, const ucontext_t & context); - -void * getCallerAddress(const ucontext_t & context); diff --git a/dbms/src/Common/TraceCollector.cpp b/dbms/src/Common/TraceCollector.cpp index 13d2061c810..aad69fa4d40 100644 --- a/dbms/src/Common/TraceCollector.cpp +++ b/dbms/src/Common/TraceCollector.cpp @@ -103,25 +103,28 @@ void TraceCollector::run() break; std::string query_id; - StackTrace stack_trace(NoCapture{}); - TimerType timer_type; - UInt32 thread_number; - readStringBinary(query_id, in); - readPODBinary(stack_trace, in); - readPODBinary(timer_type, in); - readPODBinary(thread_number, in); - const auto size = stack_trace.getSize(); - const auto & frames = stack_trace.getFrames(); + UInt8 size = 0; + readIntBinary(size, in); Array trace; trace.reserve(size); + for (size_t i = 0; i < size; i++) - trace.emplace_back(UInt64(reinterpret_cast(frames[i]))); + { + uintptr_t addr = 0; + readPODBinary(addr, in); + trace.emplace_back(UInt64(addr)); + } + + TimerType timer_type; + readPODBinary(timer_type, in); + + UInt32 thread_number; + readPODBinary(thread_number, in); TraceLogElement element{std::time(nullptr), timer_type, thread_number, query_id, trace}; - trace_log->add(element); } } From 576878c205ad290c20f3958ef09467098fb16d45 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 00:43:20 +0300 Subject: [PATCH 0549/1165] Added RPM packages to website --- website/index.html | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/website/index.html b/website/index.html index 169e1752d44..9372b095e25 100644 --- a/website/index.html +++ b/website/index.html @@ -399,10 +399,10 @@

    System requirements: Linux, x86_64 with SSE 4.2.

    -

    Install packages for Ubuntu/Debian:

    +

    Install packages for Ubuntu/Debian, RedHat/CentOS:

    -
    +
     sudo apt-get install dirmngr
     sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv E0C56BD4
     
    @@ -413,6 +413,14 @@ sudo apt-get install -y clickhouse-server clickhouse-client
     
     sudo service clickhouse-server start
     clickhouse-client
    +
    +
    @@ -483,7 +491,7 @@ clickhouse-client target="_blank" >
    Fork me on GitHub
    - + From b21c89b4ebad2e70cc848e1c82d0233fcde5784a Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Thu, 1 Aug 2019 00:59:26 +0300 Subject: [PATCH 0550/1165] redudant braces --- libs/libloggers/loggers/Loggers.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libs/libloggers/loggers/Loggers.cpp b/libs/libloggers/loggers/Loggers.cpp index 5e78bed2760..20d06b06e6d 100644 --- a/libs/libloggers/loggers/Loggers.cpp +++ b/libs/libloggers/loggers/Loggers.cpp @@ -28,16 +28,14 @@ void Loggers::setTextLog(std::shared_ptr log) { void Loggers::buildLoggers(Poco::Util::AbstractConfiguration & config, Poco::Logger & logger /*_root*/, const std::string & cmd_name) { - if (split) { - if (auto log = text_log.lock()) { + if (split) + if (auto log = text_log.lock()) split->addTextLog(log); - } - } auto current_logger = config.getString("logger", ""); - if (config_logger == current_logger) { + if (config_logger == current_logger) return; - } + config_logger = current_logger; bool is_daemon = config.getBool("application.runAsDaemon", false); From f3921ce3e0e4a141b7c27e7488698b19383fb397 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 01:37:41 +0300 Subject: [PATCH 0551/1165] Changed boost::filesystem to std::filesystem --- dbms/programs/performance-test/PerformanceTest.cpp | 5 +++-- .../performance-test/PerformanceTestInfo.cpp | 5 +++-- .../performance-test/PerformanceTestSuite.cpp | 4 ++-- dbms/src/Common/tests/compact_array.cpp | 4 ++-- dbms/src/Functions/filesystem.cpp | 14 +++++++------- dbms/src/IO/tests/read_buffer_aio.cpp | 4 ++-- dbms/src/IO/tests/write_buffer_aio.cpp | 5 ++--- dbms/src/Interpreters/tests/users.cpp | 4 ++-- dbms/src/Storages/StorageDistributed.cpp | 14 +++++++------- 9 files changed, 30 insertions(+), 29 deletions(-) diff --git a/dbms/programs/performance-test/PerformanceTest.cpp b/dbms/programs/performance-test/PerformanceTest.cpp index a005fcb5fbb..45e9dfa89a7 100644 --- a/dbms/programs/performance-test/PerformanceTest.cpp +++ b/dbms/programs/performance-test/PerformanceTest.cpp @@ -9,10 +9,11 @@ #include #include -#include +#include #include "executeQuery.h" + namespace DB { @@ -48,7 +49,7 @@ void waitQuery(Connection & connection) } } -namespace fs = boost::filesystem; +namespace fs = std::filesystem; PerformanceTest::PerformanceTest( const XMLConfigurationPtr & config_, diff --git a/dbms/programs/performance-test/PerformanceTestInfo.cpp b/dbms/programs/performance-test/PerformanceTestInfo.cpp index f016b257c5f..40a066aa0a7 100644 --- a/dbms/programs/performance-test/PerformanceTestInfo.cpp +++ b/dbms/programs/performance-test/PerformanceTestInfo.cpp @@ -3,10 +3,11 @@ #include #include #include -#include #include "applySubstitutions.h" +#include #include + namespace DB { namespace ErrorCodes @@ -39,7 +40,7 @@ void extractSettings( } -namespace fs = boost::filesystem; +namespace fs = std::filesystem; PerformanceTestInfo::PerformanceTestInfo( XMLConfigurationPtr config, diff --git a/dbms/programs/performance-test/PerformanceTestSuite.cpp b/dbms/programs/performance-test/PerformanceTestSuite.cpp index 91314a0fbff..6ddcc67f48a 100644 --- a/dbms/programs/performance-test/PerformanceTestSuite.cpp +++ b/dbms/programs/performance-test/PerformanceTestSuite.cpp @@ -4,11 +4,11 @@ #include #include #include +#include #include #include -#include #include #include @@ -36,7 +36,7 @@ #include "ReportBuilder.h" -namespace fs = boost::filesystem; +namespace fs = std::filesystem; namespace po = boost::program_options; namespace DB diff --git a/dbms/src/Common/tests/compact_array.cpp b/dbms/src/Common/tests/compact_array.cpp index 14c6b819c37..3714b6ef176 100644 --- a/dbms/src/Common/tests/compact_array.cpp +++ b/dbms/src/Common/tests/compact_array.cpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include @@ -15,7 +15,7 @@ #include #include -namespace fs = boost::filesystem; +namespace fs = std::filesystem; std::string createTmpPath(const std::string & filename) { diff --git a/dbms/src/Functions/filesystem.cpp b/dbms/src/Functions/filesystem.cpp index 9859b5ed2f2..3aa27a81559 100644 --- a/dbms/src/Functions/filesystem.cpp +++ b/dbms/src/Functions/filesystem.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include namespace DB @@ -11,19 +11,19 @@ namespace DB struct FilesystemAvailable { static constexpr auto name = "filesystemAvailable"; - static boost::uintmax_t get(boost::filesystem::space_info & spaceinfo) { return spaceinfo.available; } + static std::uintmax_t get(std::filesystem::space_info & spaceinfo) { return spaceinfo.available; } }; struct FilesystemFree { static constexpr auto name = "filesystemFree"; - static boost::uintmax_t get(boost::filesystem::space_info & spaceinfo) { return spaceinfo.free; } + static std::uintmax_t get(std::filesystem::space_info & spaceinfo) { return spaceinfo.free; } }; struct FilesystemCapacity { static constexpr auto name = "filesystemCapacity"; - static boost::uintmax_t get(boost::filesystem::space_info & spaceinfo) { return spaceinfo.capacity; } + static std::uintmax_t get(std::filesystem::space_info & spaceinfo) { return spaceinfo.capacity; } }; template @@ -34,10 +34,10 @@ public: static FunctionPtr create(const Context & context) { - return std::make_shared>(boost::filesystem::space(context.getConfigRef().getString("path"))); + return std::make_shared>(std::filesystem::space(context.getConfigRef().getString("path"))); } - explicit FilesystemImpl(boost::filesystem::space_info spaceinfo_) : spaceinfo(spaceinfo_) { } + explicit FilesystemImpl(std::filesystem::space_info spaceinfo_) : spaceinfo(spaceinfo_) { } String getName() const override { return name; } size_t getNumberOfArguments() const override { return 0; } @@ -54,7 +54,7 @@ public: } private: - boost::filesystem::space_info spaceinfo; + std::filesystem::space_info spaceinfo; }; diff --git a/dbms/src/IO/tests/read_buffer_aio.cpp b/dbms/src/IO/tests/read_buffer_aio.cpp index 81d04da79f2..adb2f7d5458 100644 --- a/dbms/src/IO/tests/read_buffer_aio.cpp +++ b/dbms/src/IO/tests/read_buffer_aio.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include @@ -44,7 +44,7 @@ bool test20(const std::string & filename, const std::string & buf); void run() { - namespace fs = boost::filesystem; + namespace fs = std::filesystem; std::string filename; std::string buf; diff --git a/dbms/src/IO/tests/write_buffer_aio.cpp b/dbms/src/IO/tests/write_buffer_aio.cpp index 4e76a91639c..5794e277848 100644 --- a/dbms/src/IO/tests/write_buffer_aio.cpp +++ b/dbms/src/IO/tests/write_buffer_aio.cpp @@ -1,8 +1,7 @@ #include #include -#include - +#include #include #include #include @@ -11,7 +10,7 @@ namespace { -namespace fs = boost::filesystem; +namespace fs = std::filesystem; void run(); [[noreturn]] void die(const std::string & msg); diff --git a/dbms/src/Interpreters/tests/users.cpp b/dbms/src/Interpreters/tests/users.cpp index 986d97ce43e..ae680ce5e5a 100644 --- a/dbms/src/Interpreters/tests/users.cpp +++ b/dbms/src/Interpreters/tests/users.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include @@ -14,7 +14,7 @@ namespace { -namespace fs = boost::filesystem; +namespace fs = std::filesystem; struct TestEntry { diff --git a/dbms/src/Storages/StorageDistributed.cpp b/dbms/src/Storages/StorageDistributed.cpp index 7b810484d1c..6155dabd028 100644 --- a/dbms/src/Storages/StorageDistributed.cpp +++ b/dbms/src/Storages/StorageDistributed.cpp @@ -47,7 +47,7 @@ #include #include -#include +#include namespace DB @@ -120,13 +120,13 @@ UInt64 getMaximumFileNumber(const std::string & dir_path) { UInt64 res = 0; - boost::filesystem::recursive_directory_iterator begin(dir_path); - boost::filesystem::recursive_directory_iterator end; + std::filesystem::recursive_directory_iterator begin(dir_path); + std::filesystem::recursive_directory_iterator end; for (auto it = begin; it != end; ++it) { const auto & file_path = it->path(); - if (it->status().type() != boost::filesystem::regular_file || !endsWith(file_path.filename().string(), ".bin")) + if (!std::filesystem::is_regular_file(*it) || !endsWith(file_path.filename().string(), ".bin")) continue; UInt64 num = 0; @@ -431,10 +431,10 @@ void StorageDistributed::createDirectoryMonitors() Poco::File{path}.createDirectory(); - boost::filesystem::directory_iterator begin(path); - boost::filesystem::directory_iterator end; + std::filesystem::directory_iterator begin(path); + std::filesystem::directory_iterator end; for (auto it = begin; it != end; ++it) - if (it->status().type() == boost::filesystem::directory_file) + if (std::filesystem::is_directory(*it)) requireDirectoryMonitor(it->path().filename().string()); } From 63c57a4c269d37bdf41edacf528d3be30361acf5 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 01:49:14 +0300 Subject: [PATCH 0552/1165] Fixed flappy test --- .../0_stateless/00704_drop_truncate_memory_table.reference | 2 +- .../0_stateless/00704_drop_truncate_memory_table.sh | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00704_drop_truncate_memory_table.reference b/dbms/tests/queries/0_stateless/00704_drop_truncate_memory_table.reference index 83b33d238da..d00491fd7e5 100644 --- a/dbms/tests/queries/0_stateless/00704_drop_truncate_memory_table.reference +++ b/dbms/tests/queries/0_stateless/00704_drop_truncate_memory_table.reference @@ -1 +1 @@ -1000 +1 diff --git a/dbms/tests/queries/0_stateless/00704_drop_truncate_memory_table.sh b/dbms/tests/queries/0_stateless/00704_drop_truncate_memory_table.sh index 4e3ad2327f7..9081580ddfc 100755 --- a/dbms/tests/queries/0_stateless/00704_drop_truncate_memory_table.sh +++ b/dbms/tests/queries/0_stateless/00704_drop_truncate_memory_table.sh @@ -13,9 +13,14 @@ SET max_block_size = 1, min_insert_block_size_rows = 0, min_insert_block_size_by INSERT INTO memory SELECT * FROM numbers(1000);" +# NOTE Most of the time this query can start before the table will be dropped. +# And TRUNCATE or DROP query will test for correct locking inside ClickHouse. +# But if the table will be dropped before query - just pass. +# It's Ok, because otherwise the test will depend on the race condition in the test itself. + ${CLICKHOUSE_CLIENT} --multiquery --query=" SET max_threads = 1; -SELECT count() FROM memory WHERE NOT ignore(sleep(0.0001));" & +SELECT count() FROM memory WHERE NOT ignore(sleep(0.0001));" 2>&1 | grep -c -P '^1000$|Table .+? doesn.t exist' & sleep 0.05; From 466242b8de001b700b5710016a3078c7ce1b3964 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 02:02:08 +0300 Subject: [PATCH 0553/1165] Switched back to upstream "fastops" submodule. --- .gitmodules | 2 +- contrib/fastops | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 847abf7d931..75d8420be83 100644 --- a/.gitmodules +++ b/.gitmodules @@ -102,4 +102,4 @@ url = https://github.com/ClickHouse-Extras/mimalloc [submodule "contrib/fastops"] path = contrib/fastops - url = https://github.com/ClickHouse-Extras/fastops + url = https://github.com/yandex/fastops diff --git a/contrib/fastops b/contrib/fastops index 30f16c1dcb7..3a7cd7a6271 160000 --- a/contrib/fastops +++ b/contrib/fastops @@ -1 +1 @@ -Subproject commit 30f16c1dcb799d483fabc0f45aaf44fa0fed097e +Subproject commit 3a7cd7a6271f011025441bea178e7729d155c36b From b1c9fc0233f1d389fbd1d32e6530846002ba5ea1 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 03:29:32 +0300 Subject: [PATCH 0554/1165] Using FastOps library --- cmake/find_fastops.cmake | 15 ++++ dbms/src/Functions/CMakeLists.txt | 9 +- ...MathUnaryFloat64.h => FunctionMathUnary.h} | 86 +++++++++++++------ dbms/src/Functions/acos.cpp | 4 +- dbms/src/Functions/asin.cpp | 4 +- dbms/src/Functions/atan.cpp | 4 +- dbms/src/Functions/cbrt.cpp | 4 +- dbms/src/Functions/cos.cpp | 4 +- dbms/src/Functions/erf.cpp | 4 +- dbms/src/Functions/erfc.cpp | 4 +- dbms/src/Functions/exp.cpp | 27 +++++- dbms/src/Functions/exp10.cpp | 4 +- dbms/src/Functions/exp2.cpp | 4 +- dbms/src/Functions/lgamma.cpp | 4 +- dbms/src/Functions/log.cpp | 27 +++++- dbms/src/Functions/log10.cpp | 4 +- dbms/src/Functions/log2.cpp | 4 +- dbms/src/Functions/registerFunctionsMath.cpp | 4 + dbms/src/Functions/sin.cpp | 4 +- dbms/src/Functions/sqrt.cpp | 4 +- dbms/src/Functions/tan.cpp | 4 +- dbms/src/Functions/tgamma.cpp | 4 +- 22 files changed, 168 insertions(+), 64 deletions(-) create mode 100644 cmake/find_fastops.cmake rename dbms/src/Functions/{FunctionMathUnaryFloat64.h => FunctionMathUnary.h} (62%) diff --git a/cmake/find_fastops.cmake b/cmake/find_fastops.cmake new file mode 100644 index 00000000000..418c4f2b329 --- /dev/null +++ b/cmake/find_fastops.cmake @@ -0,0 +1,15 @@ +option (ENABLE_FASTOPS "Enable fast vectorized mathematical functions library by Michael Parakhin" ${NOT_UNBUNDLED}) + +if (ENABLE_FASTOPS) + if(NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/fastops/fastops/fastops.h") + message(FATAL_ERROR "submodule contrib/${INTERNAL_ZLIB_NAME} is missing. to fix try run: \n git submodule update --init --recursive") + set(USE_FASTOPS 0) + endif() + set (USE_FASTOPS 1) + set (FASTOPS_INCLUDE_DIR ${ClickHouse_SOURCE_DIR}/contrib/fastops/) + set (FASTOPS_LIBRARY fastops) +else () + set(USE_FASTOPS 0) +endif () + +message (STATUS "Using fastops") diff --git a/dbms/src/Functions/CMakeLists.txt b/dbms/src/Functions/CMakeLists.txt index 13b294197cf..b6953f90d04 100644 --- a/dbms/src/Functions/CMakeLists.txt +++ b/dbms/src/Functions/CMakeLists.txt @@ -20,6 +20,7 @@ target_link_libraries(clickhouse_functions ${METROHASH_LIBRARIES} murmurhash ${BASE64_LIBRARY} + ${FASTOPS_LIBRARY} PRIVATE ${Boost_FILESYSTEM_LIBRARY} @@ -30,7 +31,7 @@ if (OPENSSL_CRYPTO_LIBRARY) endif() target_include_directories(clickhouse_functions PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/include) -target_include_directories(clickhouse_functions SYSTEM BEFORE PUBLIC ${DIVIDE_INCLUDE_DIR} ${METROHASH_INCLUDE_DIR}) +target_include_directories(clickhouse_functions SYSTEM PRIVATE ${DIVIDE_INCLUDE_DIR} ${METROHASH_INCLUDE_DIR}) if (CONSISTENT_HASHING_INCLUDE_DIR) target_include_directories (clickhouse_functions PRIVATE ${CONSISTENT_HASHING_INCLUDE_DIR}) @@ -47,7 +48,11 @@ if (USE_ICU) endif () if (USE_VECTORCLASS) - target_include_directories (clickhouse_functions SYSTEM BEFORE PUBLIC ${VECTORCLASS_INCLUDE_DIR}) + target_include_directories (clickhouse_functions SYSTEM PRIVATE ${VECTORCLASS_INCLUDE_DIR}) +endif () + +if (USE_FASTOPS) + target_include_directories (clickhouse_functions SYSTEM PRIVATE ${FASTOPS_INCLUDE_DIR}) endif () if (ENABLE_TESTS) diff --git a/dbms/src/Functions/FunctionMathUnaryFloat64.h b/dbms/src/Functions/FunctionMathUnary.h similarity index 62% rename from dbms/src/Functions/FunctionMathUnaryFloat64.h rename to dbms/src/Functions/FunctionMathUnary.h index 04452ab3477..363951510fe 100644 --- a/dbms/src/Functions/FunctionMathUnaryFloat64.h +++ b/dbms/src/Functions/FunctionMathUnary.h @@ -31,6 +31,14 @@ #endif +/** FastOps is a fast vector math library from Michael Parakhin (former Yandex CTO), + * Enabled by default. + */ +#if USE_FASTOPS +#include +#endif + + namespace DB { @@ -41,16 +49,14 @@ namespace ErrorCodes template -class FunctionMathUnaryFloat64 : public IFunction +class FunctionMathUnary : public IFunction { public: static constexpr auto name = Impl::name; - static FunctionPtr create(const Context &) { return std::make_shared(); } - static_assert(Impl::rows_per_iteration > 0, "Impl must process at least one row per iteration"); + static FunctionPtr create(const Context &) { return std::make_shared(); } private: String getName() const override { return name; } - size_t getNumberOfArguments() const override { return 1; } DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override @@ -60,38 +66,63 @@ private: throw Exception{"Illegal type " + arg->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT}; - return std::make_shared(); + /// Integers are converted to Float64. + if (Impl::always_returns_float64 || !isFloat(arg)) + return std::make_shared(); + else + return arg; } - template - static void executeInIterations(const T * src_data, Float64 * dst_data, size_t size) + template + static void executeInIterations(const T * src_data, ReturnType * dst_data, size_t size) { - const size_t rows_remaining = size % Impl::rows_per_iteration; - const size_t rows_size = size - rows_remaining; - - for (size_t i = 0; i < rows_size; i += Impl::rows_per_iteration) - Impl::execute(&src_data[i], &dst_data[i]); - - if (rows_remaining != 0) + if constexpr (Impl::rows_per_iteration == 0) { - T src_remaining[Impl::rows_per_iteration]; - memcpy(src_remaining, &src_data[rows_size], rows_remaining * sizeof(T)); - memset(src_remaining + rows_remaining, 0, (Impl::rows_per_iteration - rows_remaining) * sizeof(T)); - Float64 dst_remaining[Impl::rows_per_iteration]; + /// Process all data as a whole and use FastOps implementation - Impl::execute(src_remaining, dst_remaining); + /// If the argument is integer, convert to Float64 beforehand + if constexpr (!std::is_floating_point_v) + { + PODArray tmp_vec(size); + for (size_t i = 0; i < size; ++i) + tmp_vec[i] = src_data[i]; - memcpy(&dst_data[rows_size], dst_remaining, rows_remaining * sizeof(Float64)); + Impl::execute(tmp_vec.data(), size, dst_data); + } + else + { + Impl::execute(src_data, size, dst_data); + } + } + else + { + const size_t rows_remaining = size % Impl::rows_per_iteration; + const size_t rows_size = size - rows_remaining; + + for (size_t i = 0; i < rows_size; i += Impl::rows_per_iteration) + Impl::execute(&src_data[i], &dst_data[i]); + + if (rows_remaining != 0) + { + T src_remaining[Impl::rows_per_iteration]; + memcpy(src_remaining, &src_data[rows_size], rows_remaining * sizeof(T)); + memset(src_remaining + rows_remaining, 0, (Impl::rows_per_iteration - rows_remaining) * sizeof(T)); + ReturnType dst_remaining[Impl::rows_per_iteration]; + + Impl::execute(src_remaining, dst_remaining); + + memcpy(&dst_data[rows_size], dst_remaining, rows_remaining * sizeof(ReturnType)); + } } } - template + template static bool execute(Block & block, const ColumnVector * col, const size_t result) { const auto & src_data = col->getData(); const size_t size = src_data.size(); - auto dst = ColumnVector::create(); + auto dst = ColumnVector::create(); auto & dst_data = dst->getData(); dst_data.resize(size); @@ -101,19 +132,19 @@ private: return true; } - template + template static bool execute(Block & block, const ColumnDecimal * col, const size_t result) { const auto & src_data = col->getData(); const size_t size = src_data.size(); UInt32 scale = src_data.getScale(); - auto dst = ColumnVector::create(); + auto dst = ColumnVector::create(); auto & dst_data = dst->getData(); dst_data.resize(size); for (size_t i = 0; i < size; ++i) - dst_data[i] = convertFromDecimal, DataTypeNumber>(src_data[i], scale); + dst_data[i] = convertFromDecimal, DataTypeNumber>(src_data[i], scale); executeInIterations(dst_data.data(), dst_data.data(), size); @@ -131,10 +162,11 @@ private: { using Types = std::decay_t; using Type = typename Types::RightType; + using ReturnType = std::conditional_t, Float64, Type>; using ColVecType = std::conditional_t, ColumnDecimal, ColumnVector>; const auto col_vec = checkAndGetColumn(col.column.get()); - return execute(block, col_vec, result); + return execute(block, col_vec, result); }; if (!callOnBasicType(col.type->getTypeId(), call)) @@ -149,6 +181,7 @@ struct UnaryFunctionPlain { static constexpr auto name = Name::name; static constexpr auto rows_per_iteration = 1; + static constexpr bool always_returns_float64 = true; template static void execute(const T * src, Float64 * dst) @@ -164,6 +197,7 @@ struct UnaryFunctionVectorized { static constexpr auto name = Name::name; static constexpr auto rows_per_iteration = 2; + static constexpr bool always_returns_float64 = true; template static void execute(const T * src, Float64 * dst) diff --git a/dbms/src/Functions/acos.cpp b/dbms/src/Functions/acos.cpp index a380ba9e5d5..5d562743f3b 100644 --- a/dbms/src/Functions/acos.cpp +++ b/dbms/src/Functions/acos.cpp @@ -1,11 +1,11 @@ -#include +#include #include namespace DB { struct AcosName { static constexpr auto name = "acos"; }; -using FunctionAcos = FunctionMathUnaryFloat64>; +using FunctionAcos = FunctionMathUnary>; void registerFunctionAcos(FunctionFactory & factory) { diff --git a/dbms/src/Functions/asin.cpp b/dbms/src/Functions/asin.cpp index c6edd2d3925..147df233fe4 100644 --- a/dbms/src/Functions/asin.cpp +++ b/dbms/src/Functions/asin.cpp @@ -1,11 +1,11 @@ -#include +#include #include namespace DB { struct AsinName { static constexpr auto name = "asin"; }; -using FunctionAsin = FunctionMathUnaryFloat64>; +using FunctionAsin = FunctionMathUnary>; void registerFunctionAsin(FunctionFactory & factory) { diff --git a/dbms/src/Functions/atan.cpp b/dbms/src/Functions/atan.cpp index 9918a2f76f4..751b508c7cd 100644 --- a/dbms/src/Functions/atan.cpp +++ b/dbms/src/Functions/atan.cpp @@ -1,11 +1,11 @@ -#include +#include #include namespace DB { struct AtanName { static constexpr auto name = "atan"; }; -using FunctionAtan = FunctionMathUnaryFloat64>; +using FunctionAtan = FunctionMathUnary>; void registerFunctionAtan(FunctionFactory & factory) { diff --git a/dbms/src/Functions/cbrt.cpp b/dbms/src/Functions/cbrt.cpp index 3969063e0e4..f12ae0a6504 100644 --- a/dbms/src/Functions/cbrt.cpp +++ b/dbms/src/Functions/cbrt.cpp @@ -1,11 +1,11 @@ -#include +#include #include namespace DB { struct CbrtName { static constexpr auto name = "cbrt"; }; -using FunctionCbrt = FunctionMathUnaryFloat64>; +using FunctionCbrt = FunctionMathUnary>; void registerFunctionCbrt(FunctionFactory & factory) { diff --git a/dbms/src/Functions/cos.cpp b/dbms/src/Functions/cos.cpp index da5256c44cf..a047ea2c252 100644 --- a/dbms/src/Functions/cos.cpp +++ b/dbms/src/Functions/cos.cpp @@ -1,11 +1,11 @@ -#include +#include #include namespace DB { struct CosName { static constexpr auto name = "cos"; }; -using FunctionCos = FunctionMathUnaryFloat64>; +using FunctionCos = FunctionMathUnary>; void registerFunctionCos(FunctionFactory & factory) { diff --git a/dbms/src/Functions/erf.cpp b/dbms/src/Functions/erf.cpp index d8f9e7abb0c..8ce6732213f 100644 --- a/dbms/src/Functions/erf.cpp +++ b/dbms/src/Functions/erf.cpp @@ -1,11 +1,11 @@ -#include +#include #include namespace DB { struct ErfName { static constexpr auto name = "erf"; }; -using FunctionErf = FunctionMathUnaryFloat64>; +using FunctionErf = FunctionMathUnary>; void registerFunctionErf(FunctionFactory & factory) { diff --git a/dbms/src/Functions/erfc.cpp b/dbms/src/Functions/erfc.cpp index 34802dc245f..cd7a36b6865 100644 --- a/dbms/src/Functions/erfc.cpp +++ b/dbms/src/Functions/erfc.cpp @@ -1,11 +1,11 @@ -#include +#include #include namespace DB { struct ErfcName { static constexpr auto name = "erfc"; }; -using FunctionErfc = FunctionMathUnaryFloat64>; +using FunctionErfc = FunctionMathUnary>; void registerFunctionErfc(FunctionFactory & factory) { diff --git a/dbms/src/Functions/exp.cpp b/dbms/src/Functions/exp.cpp index 0a387ac4031..70aa14c5cb5 100644 --- a/dbms/src/Functions/exp.cpp +++ b/dbms/src/Functions/exp.cpp @@ -1,11 +1,34 @@ -#include +#include #include namespace DB { struct ExpName { static constexpr auto name = "exp"; }; -using FunctionExp = FunctionMathUnaryFloat64>; + +#if USE_FASTOPS + +namespace +{ + struct Impl + { + static constexpr auto name = ExpName::name; + static constexpr auto rows_per_iteration = 0; + static constexpr bool always_returns_float64 = false; + + template + static void execute(const T * src, size_t size, T * dst) + { + NFastOps::Exp<>(src, size, dst); + } + }; +} + +using FunctionExp = FunctionMathUnary; + +#else +using FunctionExp = FunctionMathUnary>; +#endif void registerFunctionExp(FunctionFactory & factory) { diff --git a/dbms/src/Functions/exp10.cpp b/dbms/src/Functions/exp10.cpp index 158fa0a88d1..4828f33b6e5 100644 --- a/dbms/src/Functions/exp10.cpp +++ b/dbms/src/Functions/exp10.cpp @@ -1,4 +1,4 @@ -#include +#include #include #if !USE_VECTORCLASS # include @@ -9,7 +9,7 @@ namespace DB struct Exp10Name { static constexpr auto name = "exp10"; }; -using FunctionExp10 = FunctionMathUnaryFloat64 +#include #include namespace DB { struct Exp2Name { static constexpr auto name = "exp2"; }; -using FunctionExp2 = FunctionMathUnaryFloat64>; +using FunctionExp2 = FunctionMathUnary>; void registerFunctionExp2(FunctionFactory & factory) { diff --git a/dbms/src/Functions/lgamma.cpp b/dbms/src/Functions/lgamma.cpp index 8f55fd75014..58309ee2a11 100644 --- a/dbms/src/Functions/lgamma.cpp +++ b/dbms/src/Functions/lgamma.cpp @@ -1,11 +1,11 @@ -#include +#include #include namespace DB { struct LGammaName { static constexpr auto name = "lgamma"; }; -using FunctionLGamma = FunctionMathUnaryFloat64>; +using FunctionLGamma = FunctionMathUnary>; void registerFunctionLGamma(FunctionFactory & factory) { diff --git a/dbms/src/Functions/log.cpp b/dbms/src/Functions/log.cpp index 643a20e7e28..234d3370e79 100644 --- a/dbms/src/Functions/log.cpp +++ b/dbms/src/Functions/log.cpp @@ -1,11 +1,34 @@ -#include +#include #include namespace DB { struct LogName { static constexpr auto name = "log"; }; -using FunctionLog = FunctionMathUnaryFloat64>; + +#if USE_FASTOPS + +namespace +{ + struct Impl + { + static constexpr auto name = LogName::name; + static constexpr auto rows_per_iteration = 0; + static constexpr bool always_returns_float64 = false; + + template + static void execute(const T * src, size_t size, T * dst) + { + NFastOps::Log<>(src, size, dst); + } + }; +} + +using FunctionLog = FunctionMathUnary; + +#else +using FunctionLog = FunctionMathUnary>; +#endif void registerFunctionLog(FunctionFactory & factory) { diff --git a/dbms/src/Functions/log10.cpp b/dbms/src/Functions/log10.cpp index 718a377e2f3..53301a313df 100644 --- a/dbms/src/Functions/log10.cpp +++ b/dbms/src/Functions/log10.cpp @@ -1,11 +1,11 @@ -#include +#include #include namespace DB { struct Log10Name { static constexpr auto name = "log10"; }; -using FunctionLog10 = FunctionMathUnaryFloat64>; +using FunctionLog10 = FunctionMathUnary>; void registerFunctionLog10(FunctionFactory & factory) { diff --git a/dbms/src/Functions/log2.cpp b/dbms/src/Functions/log2.cpp index ef8281ecb0a..903c9176622 100644 --- a/dbms/src/Functions/log2.cpp +++ b/dbms/src/Functions/log2.cpp @@ -1,11 +1,11 @@ -#include +#include #include namespace DB { struct Log2Name { static constexpr auto name = "log2"; }; -using FunctionLog2 = FunctionMathUnaryFloat64>; +using FunctionLog2 = FunctionMathUnary>; void registerFunctionLog2(FunctionFactory & factory) { diff --git a/dbms/src/Functions/registerFunctionsMath.cpp b/dbms/src/Functions/registerFunctionsMath.cpp index 3f7bba95922..2a963d1ee79 100644 --- a/dbms/src/Functions/registerFunctionsMath.cpp +++ b/dbms/src/Functions/registerFunctionsMath.cpp @@ -23,6 +23,8 @@ void registerFunctionTan(FunctionFactory & factory); void registerFunctionAsin(FunctionFactory & factory); void registerFunctionAcos(FunctionFactory & factory); void registerFunctionAtan(FunctionFactory & factory); +void registerFunctionSigmoid(FunctionFactory & factory); +void registerFunctionTanh(FunctionFactory & factory); void registerFunctionPow(FunctionFactory & factory); void registerFunctionsMath(FunctionFactory & factory) @@ -47,6 +49,8 @@ void registerFunctionsMath(FunctionFactory & factory) registerFunctionAsin(factory); registerFunctionAcos(factory); registerFunctionAtan(factory); + registerFunctionSigmoid(factory); + registerFunctionTanh(factory); registerFunctionPow(factory); } diff --git a/dbms/src/Functions/sin.cpp b/dbms/src/Functions/sin.cpp index 2d1375c9a74..cd66b19c553 100644 --- a/dbms/src/Functions/sin.cpp +++ b/dbms/src/Functions/sin.cpp @@ -1,11 +1,11 @@ -#include +#include #include namespace DB { struct SinName { static constexpr auto name = "sin"; }; -using FunctionSin = FunctionMathUnaryFloat64>; +using FunctionSin = FunctionMathUnary>; void registerFunctionSin(FunctionFactory & factory) { diff --git a/dbms/src/Functions/sqrt.cpp b/dbms/src/Functions/sqrt.cpp index 817f6277f27..db861cde32e 100644 --- a/dbms/src/Functions/sqrt.cpp +++ b/dbms/src/Functions/sqrt.cpp @@ -1,11 +1,11 @@ -#include +#include #include namespace DB { struct SqrtName { static constexpr auto name = "sqrt"; }; -using FunctionSqrt = FunctionMathUnaryFloat64>; +using FunctionSqrt = FunctionMathUnary>; void registerFunctionSqrt(FunctionFactory & factory) { diff --git a/dbms/src/Functions/tan.cpp b/dbms/src/Functions/tan.cpp index ec83e83baf1..e18d81f1e01 100644 --- a/dbms/src/Functions/tan.cpp +++ b/dbms/src/Functions/tan.cpp @@ -1,11 +1,11 @@ -#include +#include #include namespace DB { struct TanName { static constexpr auto name = "tan"; }; -using FunctionTan = FunctionMathUnaryFloat64>; +using FunctionTan = FunctionMathUnary>; void registerFunctionTan(FunctionFactory & factory) { diff --git a/dbms/src/Functions/tgamma.cpp b/dbms/src/Functions/tgamma.cpp index d58732d3e84..e5e68963856 100644 --- a/dbms/src/Functions/tgamma.cpp +++ b/dbms/src/Functions/tgamma.cpp @@ -1,11 +1,11 @@ -#include +#include #include namespace DB { struct TGammaName { static constexpr auto name = "tgamma"; }; -using FunctionTGamma = FunctionMathUnaryFloat64>; +using FunctionTGamma = FunctionMathUnary>; void registerFunctionTGamma(FunctionFactory & factory) { From ab8dd7edd633291a6e1f73ccca1056758c0bffe2 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 03:37:47 +0300 Subject: [PATCH 0555/1165] Added performance test --- dbms/tests/performance/math.xml | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 dbms/tests/performance/math.xml diff --git a/dbms/tests/performance/math.xml b/dbms/tests/performance/math.xml new file mode 100644 index 00000000000..ea6d79b696d --- /dev/null +++ b/dbms/tests/performance/math.xml @@ -0,0 +1,46 @@ + + once + + + + 1000 + 10000 + + + + + + + + + + func + + exp + log + exp2 + log2 + exp10 + log10 + sqrt + cbrt + erf + erfc + lgamma + tgamma + sin + cos + tan + asin + acos + atan + sigmoid + tanh + + + + + SELECT count() FROM system.numbers WHERE NOT ignore({func}(toFloat64(number))) + SELECT count() FROM system.numbers WHERE NOT ignore({func}(toFloat32(number))) + SELECT count() FROM system.numbers WHERE NOT ignore({func}(number)) + From 74d4fb3ce11b5364e443977d397404daca59f696 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 03:43:50 +0300 Subject: [PATCH 0556/1165] Added a test for new functions --- dbms/tests/queries/0_stateless/00978_ml_math.reference | 3 +++ dbms/tests/queries/0_stateless/00978_ml_math.sql | 4 ++++ 2 files changed, 7 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00978_ml_math.reference create mode 100644 dbms/tests/queries/0_stateless/00978_ml_math.sql diff --git a/dbms/tests/queries/0_stateless/00978_ml_math.reference b/dbms/tests/queries/0_stateless/00978_ml_math.reference new file mode 100644 index 00000000000..1d1b5df35cf --- /dev/null +++ b/dbms/tests/queries/0_stateless/00978_ml_math.reference @@ -0,0 +1,3 @@ +0.268941 0.268941 0.268941 -0.761595 -0.761595 -0.761595 +0.5 0.5 0.5 0 0 0 +0.731059 0.731059 0.731059 0.761595 0.761595 0.761595 diff --git a/dbms/tests/queries/0_stateless/00978_ml_math.sql b/dbms/tests/queries/0_stateless/00978_ml_math.sql new file mode 100644 index 00000000000..dfad34e12ca --- /dev/null +++ b/dbms/tests/queries/0_stateless/00978_ml_math.sql @@ -0,0 +1,4 @@ +SELECT + round(sigmoid(x), 6), round(sigmoid(toFloat32(x)), 6), round(sigmoid(toFloat64(x)), 6), + round(tanh(x), 6), round(TANH(toFloat32(x)), 6), round(TANh(toFloat64(x)), 6) +FROM (SELECT arrayJoin([-1, 0, 1]) AS x); From 36906a78b5b0279cf776493068e2526981c7e336 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 03:45:36 +0300 Subject: [PATCH 0557/1165] Fixed typo --- cmake/find_fastops.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/find_fastops.cmake b/cmake/find_fastops.cmake index 418c4f2b329..c8ddbaf80a7 100644 --- a/cmake/find_fastops.cmake +++ b/cmake/find_fastops.cmake @@ -2,7 +2,7 @@ option (ENABLE_FASTOPS "Enable fast vectorized mathematical functions library by if (ENABLE_FASTOPS) if(NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/fastops/fastops/fastops.h") - message(FATAL_ERROR "submodule contrib/${INTERNAL_ZLIB_NAME} is missing. to fix try run: \n git submodule update --init --recursive") + message(FATAL_ERROR "submodule contrib/fastops is missing. to fix try run: \n git submodule update --init --recursive") set(USE_FASTOPS 0) endif() set (USE_FASTOPS 1) From ec2fd3e29dd45316efbb05d29ce98c8658eef6f1 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 04:17:44 +0300 Subject: [PATCH 0558/1165] Added missing files --- dbms/src/Functions/sigmoid.cpp | 46 ++++++++++++++++++++++++++++++++++ dbms/src/Functions/tanh.cpp | 46 ++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 dbms/src/Functions/sigmoid.cpp create mode 100644 dbms/src/Functions/tanh.cpp diff --git a/dbms/src/Functions/sigmoid.cpp b/dbms/src/Functions/sigmoid.cpp new file mode 100644 index 00000000000..ef63d4b5494 --- /dev/null +++ b/dbms/src/Functions/sigmoid.cpp @@ -0,0 +1,46 @@ +#include +#include + +namespace DB +{ + +struct SigmoidName { static constexpr auto name = "sigmoid"; }; + +#if USE_FASTOPS + +namespace +{ + struct Impl + { + static constexpr auto name = SigmoidName::name; + static constexpr auto rows_per_iteration = 0; + static constexpr bool always_returns_float64 = false; + + template + static void execute(const T * src, size_t size, T * dst) + { + NFastOps::Sigmoid<>(src, size, dst); + } + }; +} + +using FunctionSigmoid = FunctionMathUnary; + +#else + +static double sigmoid(double x) +{ + return 1.0 / (1.0 + exp(x)); +} + +using FunctionSigmoid = FunctionMathUnary>; + +#endif + +void registerFunctionSigmoid(FunctionFactory & factory) +{ + factory.registerFunction(); +} + +} + diff --git a/dbms/src/Functions/tanh.cpp b/dbms/src/Functions/tanh.cpp new file mode 100644 index 00000000000..919b5e29263 --- /dev/null +++ b/dbms/src/Functions/tanh.cpp @@ -0,0 +1,46 @@ +#include +#include + +namespace DB +{ + +struct TanhName { static constexpr auto name = "tanh"; }; + +#if USE_FASTOPS + +namespace +{ + struct Impl + { + static constexpr auto name = TanhName::name; + static constexpr auto rows_per_iteration = 0; + static constexpr bool always_returns_float64 = false; + + template + static void execute(const T * src, size_t size, T * dst) + { + NFastOps::Tanh<>(src, size, dst); + } + }; +} + +using FunctionTanh = FunctionMathUnary; + +#else + +static double tanh(double x) +{ + return 2 / (1.0 + exp(-2 * x)) - 1; +} + +using FunctionTanh = FunctionMathUnary>; +#endif + +void registerFunctionTanh(FunctionFactory & factory) +{ + factory.registerFunction(FunctionFactory::CaseInsensitive); +} + +} + + From 50303a8520efbed06153608b4b90ac2aac90c135 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 04:29:53 +0300 Subject: [PATCH 0559/1165] Fixed build with gcc-8 --- .gitmodules | 2 +- contrib/fastops | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 75d8420be83..847abf7d931 100644 --- a/.gitmodules +++ b/.gitmodules @@ -102,4 +102,4 @@ url = https://github.com/ClickHouse-Extras/mimalloc [submodule "contrib/fastops"] path = contrib/fastops - url = https://github.com/yandex/fastops + url = https://github.com/ClickHouse-Extras/fastops diff --git a/contrib/fastops b/contrib/fastops index 3a7cd7a6271..b969b7aee07 160000 --- a/contrib/fastops +++ b/contrib/fastops @@ -1 +1 @@ -Subproject commit 3a7cd7a6271f011025441bea178e7729d155c36b +Subproject commit b969b7aee07651248da8b7367b8e4338be8bca2a From 26bb14da4ed0705eef3ff9bdc0c60131c188a756 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 04:53:38 +0300 Subject: [PATCH 0560/1165] Simplified table function "values" --- dbms/src/Storages/StorageValues.cpp | 5 +++-- dbms/src/Storages/StorageValues.h | 2 +- dbms/src/TableFunctions/ITableFunctionFileLike.cpp | 7 ++----- dbms/src/TableFunctions/ITableFunctionFileLike.h | 6 ++++-- dbms/src/TableFunctions/TableFunctionFile.cpp | 5 +++-- dbms/src/TableFunctions/TableFunctionFile.h | 3 +-- dbms/src/TableFunctions/TableFunctionHDFS.cpp | 5 +++-- dbms/src/TableFunctions/TableFunctionHDFS.h | 3 +-- dbms/src/TableFunctions/TableFunctionURL.cpp | 5 +++-- dbms/src/TableFunctions/TableFunctionURL.h | 3 +-- dbms/src/TableFunctions/TableFunctionValues.cpp | 7 +++++-- .../parseColumnsListForTableFunction.cpp | 13 ++----------- .../parseColumnsListForTableFunction.h | 8 ++++++-- 13 files changed, 35 insertions(+), 37 deletions(-) diff --git a/dbms/src/Storages/StorageValues.cpp b/dbms/src/Storages/StorageValues.cpp index bda44569cc6..d289a4d6579 100644 --- a/dbms/src/Storages/StorageValues.cpp +++ b/dbms/src/Storages/StorageValues.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -6,10 +7,10 @@ namespace DB { -StorageValues::StorageValues(const std::string & database_name_, const std::string & table_name_, const Block & res_block_) +StorageValues::StorageValues(const std::string & database_name_, const std::string & table_name_, const ColumnsDescription & columns, const Block & res_block_) : database_name(database_name_), table_name(table_name_), res_block(res_block_) { - setColumns(ColumnsDescription(res_block.getNamesAndTypesList())); + setColumns(columns); } BlockInputStreams StorageValues::read( diff --git a/dbms/src/Storages/StorageValues.h b/dbms/src/Storages/StorageValues.h index d26d1b27101..f5c6881ae36 100644 --- a/dbms/src/Storages/StorageValues.h +++ b/dbms/src/Storages/StorageValues.h @@ -30,7 +30,7 @@ private: Block res_block; protected: - StorageValues(const std::string & database_name_, const std::string & table_name_, const Block & res_block_); + StorageValues(const std::string & database_name_, const std::string & table_name_, const ColumnsDescription & columns, const Block & res_block_); }; } diff --git a/dbms/src/TableFunctions/ITableFunctionFileLike.cpp b/dbms/src/TableFunctions/ITableFunctionFileLike.cpp index 0413839e819..51c95d3a1be 100644 --- a/dbms/src/TableFunctions/ITableFunctionFileLike.cpp +++ b/dbms/src/TableFunctions/ITableFunctionFileLike.cpp @@ -43,13 +43,10 @@ StoragePtr ITableFunctionFileLike::executeImpl(const ASTPtr & ast_function, cons std::string format = args[1]->as().value.safeGet(); std::string structure = args[2]->as().value.safeGet(); - /// Create sample block - - Block sample_block; - parseColumnsListFromString(structure, sample_block, context); + ColumnsDescription columns = parseColumnsListFromString(structure, context); /// Create table - StoragePtr storage = getStorage(filename, format, sample_block, const_cast(context), table_name); + StoragePtr storage = getStorage(filename, format, columns, const_cast(context), table_name); storage->startup(); diff --git a/dbms/src/TableFunctions/ITableFunctionFileLike.h b/dbms/src/TableFunctions/ITableFunctionFileLike.h index 26e046f0b41..1e4febc935b 100644 --- a/dbms/src/TableFunctions/ITableFunctionFileLike.h +++ b/dbms/src/TableFunctions/ITableFunctionFileLike.h @@ -2,10 +2,12 @@ #include #include -#include namespace DB { + +class ColumnsDescription; + /* * function(source, format, structure) - creates a temporary storage from formated source */ @@ -14,6 +16,6 @@ class ITableFunctionFileLike : public ITableFunction private: StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const override; virtual StoragePtr getStorage( - const String & source, const String & format, const Block & sample_block, Context & global_context, const std::string & table_name) const = 0; + const String & source, const String & format, const ColumnsDescription & columns, Context & global_context, const std::string & table_name) const = 0; }; } diff --git a/dbms/src/TableFunctions/TableFunctionFile.cpp b/dbms/src/TableFunctions/TableFunctionFile.cpp index 8b2c3313cb8..9bd85a5bbb5 100644 --- a/dbms/src/TableFunctions/TableFunctionFile.cpp +++ b/dbms/src/TableFunctions/TableFunctionFile.cpp @@ -1,11 +1,12 @@ #include +#include #include #include namespace DB { StoragePtr TableFunctionFile::getStorage( - const String & source, const String & format, const Block & sample_block, Context & global_context, const std::string & table_name) const + const String & source, const String & format, const ColumnsDescription & columns, Context & global_context, const std::string & table_name) const { return StorageFile::create(source, -1, @@ -13,7 +14,7 @@ StoragePtr TableFunctionFile::getStorage( getDatabaseName(), table_name, format, - ColumnsDescription{sample_block.getNamesAndTypesList()}, + columns, global_context); } diff --git a/dbms/src/TableFunctions/TableFunctionFile.h b/dbms/src/TableFunctions/TableFunctionFile.h index 2a508d06339..d5e54c1113f 100644 --- a/dbms/src/TableFunctions/TableFunctionFile.h +++ b/dbms/src/TableFunctions/TableFunctionFile.h @@ -2,7 +2,6 @@ #include #include -#include namespace DB @@ -24,6 +23,6 @@ public: private: StoragePtr getStorage( - const String & source, const String & format, const Block & sample_block, Context & global_context, const std::string & table_name) const override; + const String & source, const String & format, const ColumnsDescription & columns, Context & global_context, const std::string & table_name) const override; }; } diff --git a/dbms/src/TableFunctions/TableFunctionHDFS.cpp b/dbms/src/TableFunctions/TableFunctionHDFS.cpp index 0cdf0a08b26..c4b61e178d6 100644 --- a/dbms/src/TableFunctions/TableFunctionHDFS.cpp +++ b/dbms/src/TableFunctions/TableFunctionHDFS.cpp @@ -2,19 +2,20 @@ #if USE_HDFS #include +#include #include #include namespace DB { StoragePtr TableFunctionHDFS::getStorage( - const String & source, const String & format, const Block & sample_block, Context & global_context, const std::string & table_name) const + const String & source, const String & format, const ColumnsDescription & columns, Context & global_context, const std::string & table_name) const { return StorageHDFS::create(source, getDatabaseName(), table_name, format, - ColumnsDescription{sample_block.getNamesAndTypesList()}, + columns, global_context); } diff --git a/dbms/src/TableFunctions/TableFunctionHDFS.h b/dbms/src/TableFunctions/TableFunctionHDFS.h index 9dafadc8df8..ffe7eb58a10 100644 --- a/dbms/src/TableFunctions/TableFunctionHDFS.h +++ b/dbms/src/TableFunctions/TableFunctionHDFS.h @@ -6,7 +6,6 @@ #include #include -#include namespace DB @@ -25,7 +24,7 @@ public: private: StoragePtr getStorage( - const String & source, const String & format, const Block & sample_block, Context & global_context, const std::string & table_name) const override; + const String & source, const String & format, const ColumnsDescription & columns, Context & global_context, const std::string & table_name) const override; }; } diff --git a/dbms/src/TableFunctions/TableFunctionURL.cpp b/dbms/src/TableFunctions/TableFunctionURL.cpp index 58a4c7c2b2a..9991bc2f527 100644 --- a/dbms/src/TableFunctions/TableFunctionURL.cpp +++ b/dbms/src/TableFunctions/TableFunctionURL.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -6,10 +7,10 @@ namespace DB { StoragePtr TableFunctionURL::getStorage( - const String & source, const String & format, const Block & sample_block, Context & global_context, const std::string & table_name) const + const String & source, const String & format, const ColumnsDescription & columns, Context & global_context, const std::string & table_name) const { Poco::URI uri(source); - return StorageURL::create(uri, getDatabaseName(), table_name, format, ColumnsDescription{sample_block.getNamesAndTypesList()}, global_context); + return StorageURL::create(uri, getDatabaseName(), table_name, format, columns, global_context); } void registerTableFunctionURL(TableFunctionFactory & factory) diff --git a/dbms/src/TableFunctions/TableFunctionURL.h b/dbms/src/TableFunctions/TableFunctionURL.h index f7b723a422c..fefd3ec072c 100644 --- a/dbms/src/TableFunctions/TableFunctionURL.h +++ b/dbms/src/TableFunctions/TableFunctionURL.h @@ -2,7 +2,6 @@ #include #include -#include namespace DB @@ -20,6 +19,6 @@ public: private: StoragePtr getStorage( - const String & source, const String & format, const Block & sample_block, Context & global_context, const std::string & table_name) const override; + const String & source, const String & format, const ColumnsDescription & columns, Context & global_context, const std::string & table_name) const override; }; } diff --git a/dbms/src/TableFunctions/TableFunctionValues.cpp b/dbms/src/TableFunctions/TableFunctionValues.cpp index 326e6eaace7..ecbe386c382 100644 --- a/dbms/src/TableFunctions/TableFunctionValues.cpp +++ b/dbms/src/TableFunctions/TableFunctionValues.cpp @@ -72,8 +72,11 @@ StoragePtr TableFunctionValues::executeImpl(const ASTPtr & ast_function, const C /// Parsing first argument as table structure and creating a sample block std::string structure = args[0]->as().value.safeGet(); + ColumnsDescription columns = parseColumnsListFromString(structure, context); + Block sample_block; - parseColumnsListFromString(structure, sample_block, context); + for (const auto & name_type : columns.getOrdinary()) + sample_block.insert({ name_type.type->createColumn(), name_type.type, name_type.name }); MutableColumns res_columns = sample_block.cloneEmptyColumns(); @@ -82,7 +85,7 @@ StoragePtr TableFunctionValues::executeImpl(const ASTPtr & ast_function, const C Block res_block = sample_block.cloneWithColumns(std::move(res_columns)); - auto res = StorageValues::create(getDatabaseName(), table_name, res_block); + auto res = StorageValues::create(getDatabaseName(), table_name, columns, res_block); res->startup(); return res; } diff --git a/dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp b/dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp index 05d8aa7cddc..be7f2efb7ac 100644 --- a/dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp +++ b/dbms/src/TableFunctions/parseColumnsListForTableFunction.cpp @@ -12,7 +12,7 @@ namespace ErrorCodes extern const int SYNTAX_ERROR; } -void parseColumnsListFromString(const std::string & structure, Block & sample_block, const Context & context) +ColumnsDescription parseColumnsListFromString(const std::string & structure, const Context & context) { Expected expected; @@ -29,16 +29,7 @@ void parseColumnsListFromString(const std::string & structure, Block & sample_bl if (!columns_list) throw Exception("Could not cast AST to ASTExpressionList", ErrorCodes::LOGICAL_ERROR); - ColumnsDescription columns_desc = InterpreterCreateQuery::getColumnsDescription(*columns_list, context); - - for (const auto & [name, type]: columns_desc.getAllPhysical()) - { - ColumnWithTypeAndName column; - column.name = name; - column.type = type; - column.column = type->createColumn(); - sample_block.insert(std::move(column)); - } + return InterpreterCreateQuery::getColumnsDescription(*columns_list, context); } } diff --git a/dbms/src/TableFunctions/parseColumnsListForTableFunction.h b/dbms/src/TableFunctions/parseColumnsListForTableFunction.h index 3e942afa358..d077d308e37 100644 --- a/dbms/src/TableFunctions/parseColumnsListForTableFunction.h +++ b/dbms/src/TableFunctions/parseColumnsListForTableFunction.h @@ -1,11 +1,15 @@ #pragma once -#include +#include +#include namespace DB { + +class Context; + /// Parses a common argument for table functions such as table structure given in string -void parseColumnsListFromString(const std::string & structure, Block & sample_block, const Context & context); +ColumnsDescription parseColumnsListFromString(const std::string & structure, const Context & context); } From 6de3939a3d505d65deadfd23ac7f0409f3b7d9a9 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 05:08:44 +0300 Subject: [PATCH 0561/1165] Added a test --- .../0_stateless/00978_table_function_values_alias.reference | 2 ++ .../queries/0_stateless/00978_table_function_values_alias.sql | 1 + 2 files changed, 3 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00978_table_function_values_alias.reference create mode 100644 dbms/tests/queries/0_stateless/00978_table_function_values_alias.sql diff --git a/dbms/tests/queries/0_stateless/00978_table_function_values_alias.reference b/dbms/tests/queries/0_stateless/00978_table_function_values_alias.reference new file mode 100644 index 00000000000..756765f7ea5 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00978_table_function_values_alias.reference @@ -0,0 +1,2 @@ +1 hello 1: hello +2 world 2: world diff --git a/dbms/tests/queries/0_stateless/00978_table_function_values_alias.sql b/dbms/tests/queries/0_stateless/00978_table_function_values_alias.sql new file mode 100644 index 00000000000..93da57ae2d3 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00978_table_function_values_alias.sql @@ -0,0 +1 @@ +SELECT x, s, z FROM VALUES('x UInt64, s String, z ALIAS concat(toString(x), \': \', s)', (1, 'hello'), (2, 'world')); From 12f6b75284d4dd8b786671852dad915f9bdc5dee Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 05:34:58 +0300 Subject: [PATCH 0562/1165] Fixed error --- dbms/src/Storages/MergeTree/DataPartsExchange.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dbms/src/Storages/MergeTree/DataPartsExchange.cpp b/dbms/src/Storages/MergeTree/DataPartsExchange.cpp index ee7de070776..80e521b32c1 100644 --- a/dbms/src/Storages/MergeTree/DataPartsExchange.cpp +++ b/dbms/src/Storages/MergeTree/DataPartsExchange.cpp @@ -201,7 +201,7 @@ MergeTreeData::MutableDataPartPtr Fetcher::fetchPart( String tmp_prefix = tmp_prefix_.empty() ? TMP_PREFIX : tmp_prefix_; String relative_part_path = String(to_detached ? "detached/" : "") + tmp_prefix + part_name; - String absolute_part_path = data.getFullPath() + relative_part_path + "/"; + String absolute_part_path = Poco::Path(data.getFullPath() + relative_part_path + "/").absolute().toString(); Poco::File part_file(absolute_part_path); if (part_file.exists()) @@ -228,13 +228,13 @@ MergeTreeData::MutableDataPartPtr Fetcher::fetchPart( /// File must be inside "absolute_part_path" directory. /// Otherwise malicious ClickHouse replica may force us to write to arbitrary path. - String file_absolute_path = Poco::Path(absolute_part_path + file_name).absolute().toString(); - if (!startsWith(file_absolute_path, absolute_part_path)) - throw Exception("File path doesn't appear to be inside part path." + String absolute_file_path = Poco::Path(absolute_part_path + file_name).absolute().toString(); + if (!startsWith(absolute_file_path, absolute_part_path)) + throw Exception("File path (" + absolute_file_path + ") doesn't appear to be inside part path (" + absolute_part_path + ")." " This may happen if we are trying to download part from malicious replica or logical error.", ErrorCodes::INSECURE_PATH); - WriteBufferFromFile file_out(file_absolute_path); + WriteBufferFromFile file_out(absolute_file_path); HashingWriteBuffer hashing_out(file_out); copyData(in, hashing_out, file_size, blocker.getCounter()); From c3f54f85c1323b2ed82968d7fbd0e2112f63748a Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 06:06:15 +0300 Subject: [PATCH 0563/1165] Fixed error with "unbundled" build --- dbms/src/Functions/tanh.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Functions/tanh.cpp b/dbms/src/Functions/tanh.cpp index 919b5e29263..4fe3d616d25 100644 --- a/dbms/src/Functions/tanh.cpp +++ b/dbms/src/Functions/tanh.cpp @@ -33,7 +33,7 @@ static double tanh(double x) return 2 / (1.0 + exp(-2 * x)) - 1; } -using FunctionTanh = FunctionMathUnary>; +using FunctionTanh = FunctionMathUnary>; #endif void registerFunctionTanh(FunctionFactory & factory) From 99b9d354f7d96deace4e772aeb22c5561438002c Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 06:20:54 +0300 Subject: [PATCH 0564/1165] Fixed glibc compatibility --- .../musl/__math_divzerof.c | 17 ++++ .../musl/__math_invalidf.c | 4 + libs/libglibc-compatibility/musl/logf.c | 88 +++++++++++++++++++ libs/libglibc-compatibility/musl/logf_data.c | 33 +++++++ libs/libglibc-compatibility/musl/logf_data.h | 18 ++++ 5 files changed, 160 insertions(+) create mode 100644 libs/libglibc-compatibility/musl/__math_divzerof.c create mode 100644 libs/libglibc-compatibility/musl/__math_invalidf.c create mode 100644 libs/libglibc-compatibility/musl/logf.c create mode 100644 libs/libglibc-compatibility/musl/logf_data.c create mode 100644 libs/libglibc-compatibility/musl/logf_data.h diff --git a/libs/libglibc-compatibility/musl/__math_divzerof.c b/libs/libglibc-compatibility/musl/__math_divzerof.c new file mode 100644 index 00000000000..cd1263fde2a --- /dev/null +++ b/libs/libglibc-compatibility/musl/__math_divzerof.c @@ -0,0 +1,17 @@ +#include + +/* fp_barrier returns its input, but limits code transformations + as if it had a side-effect (e.g. observable io) and returned + an arbitrary value. */ + +static inline float fp_barrierf(float x) +{ + volatile float y = x; + return y; +} + + +float __math_divzerof(uint32_t sign) +{ + return fp_barrierf(sign ? -1.0f : 1.0f) / 0.0f; +} diff --git a/libs/libglibc-compatibility/musl/__math_invalidf.c b/libs/libglibc-compatibility/musl/__math_invalidf.c new file mode 100644 index 00000000000..ee41c32378e --- /dev/null +++ b/libs/libglibc-compatibility/musl/__math_invalidf.c @@ -0,0 +1,4 @@ +float __math_invalidf(float x) +{ + return (x - x) / (x - x); +} diff --git a/libs/libglibc-compatibility/musl/logf.c b/libs/libglibc-compatibility/musl/logf.c new file mode 100644 index 00000000000..bb2cf39405b --- /dev/null +++ b/libs/libglibc-compatibility/musl/logf.c @@ -0,0 +1,88 @@ +/* + * Single-precision log function. + * + * Copyright (c) 2017-2018, Arm Limited. + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include "logf_data.h" + +float __math_invalidf(float); +float __math_divzerof(uint32_t); + +/* +LOGF_TABLE_BITS = 4 +LOGF_POLY_ORDER = 4 + +ULP error: 0.818 (nearest rounding.) +Relative error: 1.957 * 2^-26 (before rounding.) +*/ + +#define T __logf_data.tab +#define A __logf_data.poly +#define Ln2 __logf_data.ln2 +#define N (1 << LOGF_TABLE_BITS) +#define OFF 0x3f330000 +#define WANT_ROUNDING 1 + +#define asuint(f) ((union{float _f; uint32_t _i;}){f})._i +#define asfloat(i) ((union{uint32_t _i; float _f;}){i})._f + +/* Evaluate an expression as the specified type. With standard excess + precision handling a type cast or assignment is enough (with + -ffloat-store an assignment is required, in old compilers argument + passing and return statement may not drop excess precision). */ + +static inline float eval_as_float(float x) +{ + float y = x; + return y; +} + +float logf(float x) +{ + double_t z, r, r2, y, y0, invc, logc; + uint32_t ix, iz, tmp; + int k, i; + + ix = asuint(x); + /* Fix sign of zero with downward rounding when x==1. */ + if (WANT_ROUNDING && __builtin_expect(ix == 0x3f800000, 0)) + return 0; + if (__builtin_expect(ix - 0x00800000 >= 0x7f800000 - 0x00800000, 0)) { + /* x < 0x1p-126 or inf or nan. */ + if (ix * 2 == 0) + return __math_divzerof(1); + if (ix == 0x7f800000) /* log(inf) == inf. */ + return x; + if ((ix & 0x80000000) || ix * 2 >= 0xff000000) + return __math_invalidf(x); + /* x is subnormal, normalize it. */ + ix = asuint(x * 0x1p23f); + ix -= 23 << 23; + } + + /* x = 2^k z; where z is in range [OFF,2*OFF] and exact. + The range is split into N subintervals. + The ith subinterval contains z and c is near its center. */ + tmp = ix - OFF; + i = (tmp >> (23 - LOGF_TABLE_BITS)) % N; + k = (int32_t)tmp >> 23; /* arithmetic shift */ + iz = ix - (tmp & 0x1ff << 23); + invc = T[i].invc; + logc = T[i].logc; + z = (double_t)asfloat(iz); + + /* log(x) = log1p(z/c-1) + log(c) + k*Ln2 */ + r = z * invc - 1; + y0 = logc + (double_t)k * Ln2; + + /* Pipelined polynomial evaluation to approximate log1p(r). */ + r2 = r * r; + y = A[1] * r + A[2]; + y = A[0] * r2 + y; + y = y * r2 + (y0 + r); + return eval_as_float(y); +} diff --git a/libs/libglibc-compatibility/musl/logf_data.c b/libs/libglibc-compatibility/musl/logf_data.c new file mode 100644 index 00000000000..857221f7901 --- /dev/null +++ b/libs/libglibc-compatibility/musl/logf_data.c @@ -0,0 +1,33 @@ +/* + * Data definition for logf. + * + * Copyright (c) 2017-2018, Arm Limited. + * SPDX-License-Identifier: MIT + */ + +#include "logf_data.h" + +const struct logf_data __logf_data = { + .tab = { + { 0x1.661ec79f8f3bep+0, -0x1.57bf7808caadep-2 }, + { 0x1.571ed4aaf883dp+0, -0x1.2bef0a7c06ddbp-2 }, + { 0x1.49539f0f010bp+0, -0x1.01eae7f513a67p-2 }, + { 0x1.3c995b0b80385p+0, -0x1.b31d8a68224e9p-3 }, + { 0x1.30d190c8864a5p+0, -0x1.6574f0ac07758p-3 }, + { 0x1.25e227b0b8eap+0, -0x1.1aa2bc79c81p-3 }, + { 0x1.1bb4a4a1a343fp+0, -0x1.a4e76ce8c0e5ep-4 }, + { 0x1.12358f08ae5bap+0, -0x1.1973c5a611cccp-4 }, + { 0x1.0953f419900a7p+0, -0x1.252f438e10c1ep-5 }, + { 0x1p+0, 0x0p+0 }, + { 0x1.e608cfd9a47acp-1, 0x1.aa5aa5df25984p-5 }, + { 0x1.ca4b31f026aap-1, 0x1.c5e53aa362eb4p-4 }, + { 0x1.b2036576afce6p-1, 0x1.526e57720db08p-3 }, + { 0x1.9c2d163a1aa2dp-1, 0x1.bc2860d22477p-3 }, + { 0x1.886e6037841edp-1, 0x1.1058bc8a07ee1p-2 }, + { 0x1.767dcf5534862p-1, 0x1.4043057b6ee09p-2 }, + }, + .ln2 = 0x1.62e42fefa39efp-1, + .poly = { + -0x1.00ea348b88334p-2, 0x1.5575b0be00b6ap-2, -0x1.ffffef20a4123p-2, + } +}; diff --git a/libs/libglibc-compatibility/musl/logf_data.h b/libs/libglibc-compatibility/musl/logf_data.h new file mode 100644 index 00000000000..a11a8984cc1 --- /dev/null +++ b/libs/libglibc-compatibility/musl/logf_data.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2017-2018, Arm Limited. + * SPDX-License-Identifier: MIT + */ +#ifndef _LOGF_DATA_H +#define _LOGF_DATA_H + +#define LOGF_TABLE_BITS 4 +#define LOGF_POLY_ORDER 4 +extern __attribute__((__visibility__("hidden"))) const struct logf_data { + struct { + double invc, logc; + } tab[1 << LOGF_TABLE_BITS]; + double ln2; + double poly[LOGF_POLY_ORDER - 1]; /* First order coefficient is 1. */ +} __logf_data; + +#endif From 591af05e5739d3ccd87ce2cd19d2651f3c14c5e5 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 06:45:33 +0300 Subject: [PATCH 0565/1165] Fixed error with searching debug info --- dbms/src/Common/SymbolIndex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Common/SymbolIndex.cpp b/dbms/src/Common/SymbolIndex.cpp index 25edb2350f9..d4cf41342a0 100644 --- a/dbms/src/Common/SymbolIndex.cpp +++ b/dbms/src/Common/SymbolIndex.cpp @@ -235,7 +235,7 @@ void collectSymbolsFromELF(dl_phdr_info * info, return; /// Debug info and symbol table sections may be splitted to separate binary. - std::filesystem::path debug_info_path = std::filesystem::path("/usr/lib/debug") / canonical_path; + std::filesystem::path debug_info_path = std::filesystem::path("/usr/lib/debug") / canonical_path.relative_path(); object_name = std::filesystem::exists(debug_info_path) ? debug_info_path : canonical_path; From 9116c08959ede5acc43b7bde690706688d68b101 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Thu, 1 Aug 2019 10:38:04 +0300 Subject: [PATCH 0566/1165] DOCAPI-7414: groupArrayMovingSum, groupArrayMovingAvg docs. (#5949) * DOCAPI-7414: groupArrayMovingSum, groupArrayMovingAvg docs. --- .../query_language/agg_functions/reference.md | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) diff --git a/docs/en/query_language/agg_functions/reference.md b/docs/en/query_language/agg_functions/reference.md index ce9f2b6cdbb..f9cb88c0113 100644 --- a/docs/en/query_language/agg_functions/reference.md +++ b/docs/en/query_language/agg_functions/reference.md @@ -672,6 +672,146 @@ Optional parameters: - The default value for substituting in empty positions. - The length of the resulting array. This allows you to receive arrays of the same size for all the aggregate keys. When using this parameter, the default value must be specified. +## groupArrayMovingSum {#agg_function-grouparraymovingsum} + +Calculates the moving sum of input values. + +``` +groupArrayMovingSum(numbers_for_summing) +groupArrayMovingSum(window_size)(numbers_for_summing) +``` + +The function can take the window size as a parameter. If it not specified, the function takes the window size equal to the number of rows in the column. + +**Parameters** + +- `numbers_for_summing` — [Expression](../syntax.md#syntax-expressions) resulting with a value in a numeric data type. +- `window_size` — Size of the calculation window. + +**Returned values** + +- Array of the same size and type as the input data. + +**Example** + +The sample table: + +```sql +CREATE TABLE t +( + `int` UInt8, + `float` Float32, + `dec` Decimal32(2) +) +ENGINE = TinyLog +``` +```text +┌─int─┬─float─┬──dec─┐ +│ 1 │ 1.1 │ 1.10 │ +│ 2 │ 2.2 │ 2.20 │ +│ 4 │ 4.4 │ 4.40 │ +│ 7 │ 7.77 │ 7.77 │ +└─────┴───────┴──────┘ +``` + +The queries: + +```sql +SELECT + groupArrayMovingSum(int) AS I, + groupArrayMovingSum(float) AS F, + groupArrayMovingSum(dec) AS D +FROM t +``` +```text +┌─I──────────┬─F───────────────────────────────┬─D──────────────────────┐ +│ [1,3,7,14] │ [1.1,3.3000002,7.7000003,15.47] │ [1.10,3.30,7.70,15.47] │ +└────────────┴─────────────────────────────────┴────────────────────────┘ +``` +```sql +SELECT + groupArrayMovingSum(2)(int) AS I, + groupArrayMovingSum(2)(float) AS F, + groupArrayMovingSum(2)(dec) AS D +FROM t +``` +```text +┌─I──────────┬─F───────────────────────────────┬─D──────────────────────┐ +│ [1,3,6,11] │ [1.1,3.3000002,6.6000004,12.17] │ [1.10,3.30,6.60,12.17] │ +└────────────┴─────────────────────────────────┴────────────────────────┘ +``` + +## groupArrayMovingAvg {#agg_function-grouparraymovingavg} + +Calculates the moving average of input values. + +``` +groupArrayMovingAvg(numbers_for_summing) +groupArrayMovingAvg(window_size)(numbers_for_summing) +``` + +The function can take the window size as a parameter. If it not specified, the function takes the window size equal to the number of rows in the column. + +**Parameters** + +- `numbers_for_summing` — [Expression](../syntax.md#syntax-expressions) resulting with a value in a numeric data type. +- `window_size` — Size of the calculation window. + +**Returned values** + +- Array of the same size and type as the input data. + +The function uses [rounding towards zero](https://en.wikipedia.org/wiki/Rounding#Rounding_towards_zero). It truncates the decimal places insignificant for the resulting data type. + +**Example** + +The sample table `b`: + +```sql +CREATE TABLE t +( + `int` UInt8, + `float` Float32, + `dec` Decimal32(2) +) +ENGINE = TinyLog +``` +```text +┌─int─┬─float─┬──dec─┐ +│ 1 │ 1.1 │ 1.10 │ +│ 2 │ 2.2 │ 2.20 │ +│ 4 │ 4.4 │ 4.40 │ +│ 7 │ 7.77 │ 7.77 │ +└─────┴───────┴──────┘ +``` + +The queries: + +```sql +SELECT + groupArrayMovingAvg(int) AS I, + groupArrayMovingAvg(float) AS F, + groupArrayMovingAvg(dec) AS D +FROM t +``` +```text +┌─I─────────┬─F───────────────────────────────────┬─D─────────────────────┐ +│ [0,0,1,3] │ [0.275,0.82500005,1.9250001,3.8675] │ [0.27,0.82,1.92,3.86] │ +└───────────┴─────────────────────────────────────┴───────────────────────┘ +``` +```sql +SELECT + groupArrayMovingAvg(2)(int) AS I, + groupArrayMovingAvg(2)(float) AS F, + groupArrayMovingAvg(2)(dec) AS D +FROM t +``` +```text +┌─I─────────┬─F────────────────────────────────┬─D─────────────────────┐ +│ [0,1,3,5] │ [0.55,1.6500001,3.3000002,6.085] │ [0.55,1.65,3.30,6.08] │ +└───────────┴──────────────────────────────────┴───────────────────────┘ +``` + ## groupUniqArray(x), groupUniqArray(max_size)(x) Creates an array from different argument values. Memory consumption is the same as for the `uniqExact` function. From 9811fdcdc7ff96590d6ffdd56266feae78b99482 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 1 Aug 2019 11:31:08 +0300 Subject: [PATCH 0567/1165] Update CapnProtoRowInputFormat. --- .../Formats/Impl/CapnProtoRowInputFormat.cpp | 55 +++++++++++-------- .../Formats/Impl/CapnProtoRowInputFormat.h | 2 + 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/dbms/src/Processors/Formats/Impl/CapnProtoRowInputFormat.cpp b/dbms/src/Processors/Formats/Impl/CapnProtoRowInputFormat.cpp index 9ed84e89780..a6bead68bc5 100644 --- a/dbms/src/Processors/Formats/Impl/CapnProtoRowInputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/CapnProtoRowInputFormat.cpp @@ -206,28 +206,42 @@ CapnProtoRowInputFormat::CapnProtoRowInputFormat(ReadBuffer & in_, Block header, createActions(list, root); } +kj::Array CapnProtoRowInputFormat::readMessage() +{ + uint32_t segment_count; + in.readStrict(reinterpret_cast(&segment_count), sizeof(uint32_t)); + + // one for segmentCount and one because segmentCount starts from 0 + const auto prefix_size = (2 + segment_count) * sizeof(uint32_t); + const auto words_prefix_size = (segment_count + 1) / 2 + 1; + auto prefix = kj::heapArray(words_prefix_size); + auto prefix_chars = prefix.asChars(); + ::memcpy(prefix_chars.begin(), &segment_count, sizeof(uint32_t)); + + // read size of each segment + for (size_t i = 0; i <= segment_count; ++i) + in.readStrict(prefix_chars.begin() + ((i + 1) * sizeof(uint32_t)), sizeof(uint32_t)); + + // calculate size of message + const auto expected_words = capnp::expectedSizeInWordsFromPrefix(prefix); + const auto expected_bytes = expected_words * sizeof(capnp::word); + const auto data_size = expected_bytes - prefix_size; + auto msg = kj::heapArray(expected_words); + auto msg_chars = msg.asChars(); + + // read full message + ::memcpy(msg_chars.begin(), prefix_chars.begin(), prefix_size); + in.readStrict(msg_chars.begin() + prefix_size, data_size); + + return msg; +} bool CapnProtoRowInputFormat::readRow(MutableColumns & columns, RowReadExtension &) { if (in.eof()) return false; - // Read from underlying buffer directly - auto buf = in.buffer(); - auto base = reinterpret_cast(in.position()); - - // Check if there's enough bytes in the buffer to read the full message - kj::Array heap_array; - auto array = kj::arrayPtr(base, buf.size() - in.offset()); - auto expected_words = capnp::expectedSizeInWordsFromPrefix(array); - if (expected_words * sizeof(capnp::word) > array.size()) - { - // We'll need to reassemble the message in a contiguous buffer - heap_array = kj::heapArray(expected_words); - in.readStrict(heap_array.asChars().begin(), heap_array.asChars().size()); - array = heap_array.asPtr(); - } - + auto array = readMessage(); #if CAPNP_VERSION >= 8000 capnp::UnalignedFlatArrayMessageReader msg(array); @@ -281,13 +295,6 @@ bool CapnProtoRowInputFormat::readRow(MutableColumns & columns, RowReadExtension } } - // Advance buffer position if used directly - if (heap_array.size() == 0) - { - auto parsed = (msg.getEnd() - base) * sizeof(capnp::word); - in.position() += parsed; - } - return true; } @@ -297,7 +304,7 @@ void registerInputFormatProcessorCapnProto(FormatFactory & factory) "CapnProto", [](ReadBuffer & buf, const Block & sample, const Context & context, IRowInputFormat::Params params, const FormatSettings &) { - return std::make_shared(buf, sample, params, FormatSchemaInfo(context, "capnp")); + return std::make_shared(buf, sample, std::move(params), FormatSchemaInfo(context, "capnp")); }); } diff --git a/dbms/src/Processors/Formats/Impl/CapnProtoRowInputFormat.h b/dbms/src/Processors/Formats/Impl/CapnProtoRowInputFormat.h index 8d768538719..b941ceb514d 100644 --- a/dbms/src/Processors/Formats/Impl/CapnProtoRowInputFormat.h +++ b/dbms/src/Processors/Formats/Impl/CapnProtoRowInputFormat.h @@ -40,6 +40,8 @@ public: bool readRow(MutableColumns & columns, RowReadExtension &) override; private: + kj::Array readMessage(); + // Build a traversal plan from a sorted list of fields void createActions(const NestedFieldList & sortedFields, capnp::StructSchema reader); From a5bb2e2b3ff1d0f42282a1372cb4f232e8e23120 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 1 Aug 2019 12:56:30 +0300 Subject: [PATCH 0568/1165] Update Schema name in Protobuf and CapnProto formats. --- dbms/src/Processors/Formats/Impl/CapnProtoRowInputFormat.cpp | 4 ++-- dbms/src/Processors/Formats/Impl/ProtobufRowInputFormat.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dbms/src/Processors/Formats/Impl/CapnProtoRowInputFormat.cpp b/dbms/src/Processors/Formats/Impl/CapnProtoRowInputFormat.cpp index a6bead68bc5..87cad3022fb 100644 --- a/dbms/src/Processors/Formats/Impl/CapnProtoRowInputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/CapnProtoRowInputFormat.cpp @@ -179,7 +179,7 @@ void CapnProtoRowInputFormat::createActions(const NestedFieldList & sorted_field } CapnProtoRowInputFormat::CapnProtoRowInputFormat(ReadBuffer & in_, Block header, Params params, const FormatSchemaInfo & info) - : IRowInputFormat(std::move(header), in_, params), parser(std::make_shared()) + : IRowInputFormat(std::move(header), in_, std::move(params)), parser(std::make_shared()) { // Parse the schema and fetch the root object @@ -304,7 +304,7 @@ void registerInputFormatProcessorCapnProto(FormatFactory & factory) "CapnProto", [](ReadBuffer & buf, const Block & sample, const Context & context, IRowInputFormat::Params params, const FormatSettings &) { - return std::make_shared(buf, sample, std::move(params), FormatSchemaInfo(context, "capnp")); + return std::make_shared(buf, sample, std::move(params), FormatSchemaInfo(context, "CapnProto")); }); } diff --git a/dbms/src/Processors/Formats/Impl/ProtobufRowInputFormat.cpp b/dbms/src/Processors/Formats/Impl/ProtobufRowInputFormat.cpp index a2f3a47def3..771aa9ea42e 100644 --- a/dbms/src/Processors/Formats/Impl/ProtobufRowInputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/ProtobufRowInputFormat.cpp @@ -75,7 +75,7 @@ void registerInputFormatProcessorProtobuf(FormatFactory & factory) IRowInputFormat::Params params, const FormatSettings &) { - return std::make_shared(buf, sample, params, FormatSchemaInfo(context, "proto")); + return std::make_shared(buf, sample, params, FormatSchemaInfo(context, "Protobuf")); }); } From a9fea0314e519235264853c780777d5ce53af3bd Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Thu, 1 Aug 2019 13:31:29 +0300 Subject: [PATCH 0569/1165] better style --- dbms/programs/server/Server.cpp | 3 --- dbms/src/Interpreters/SystemLog.h | 4 ---- .../queries/0_stateless/00974_text_log_table_not_empty.sh | 2 -- libs/libcommon/include/common/logger_useful.h | 2 -- libs/libloggers/loggers/Loggers.cpp | 3 ++- libs/libloggers/loggers/OwnSplitChannel.h | 2 -- 6 files changed, 2 insertions(+), 14 deletions(-) diff --git a/dbms/programs/server/Server.cpp b/dbms/programs/server/Server.cpp index f1d5d5aeac8..a9bd41199de 100644 --- a/dbms/programs/server/Server.cpp +++ b/dbms/programs/server/Server.cpp @@ -171,8 +171,6 @@ void Server::defineOptions(Poco::Util::OptionSet & _options) BaseDaemon::defineOptions(_options); } - - int Server::main(const std::vector & /*args*/) { Logger * log = &logger(); @@ -180,7 +178,6 @@ int Server::main(const std::vector & /*args*/) ThreadStatus thread_status; - registerFunctions(); registerAggregateFunctions(); registerTableFunctions(); diff --git a/dbms/src/Interpreters/SystemLog.h b/dbms/src/Interpreters/SystemLog.h index 66b606891be..7b1192ac970 100644 --- a/dbms/src/Interpreters/SystemLog.h +++ b/dbms/src/Interpreters/SystemLog.h @@ -309,8 +309,6 @@ void SystemLog::threadFunction() } - - template void SystemLog::flushImpl(EntryType reason) { @@ -444,5 +442,3 @@ void SystemLog::prepareTable() } } - - diff --git a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sh b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sh index 10f095b53f6..149f0668bd1 100755 --- a/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sh +++ b/dbms/tests/queries/0_stateless/00974_text_log_table_not_empty.sh @@ -5,8 +5,6 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) ${CLICKHOUSE_CLIENT} --query="SELECT 6103" ->00974_text_log_table_not_empty.tmp - for (( i=1; i <= 50; i++ )) do diff --git a/libs/libcommon/include/common/logger_useful.h b/libs/libcommon/include/common/logger_useful.h index eaf4154b59e..e5f9ea2b996 100644 --- a/libs/libcommon/include/common/logger_useful.h +++ b/libs/libcommon/include/common/logger_useful.h @@ -9,8 +9,6 @@ #include #include -#include - #ifndef QUERY_PREVIEW_LENGTH #define QUERY_PREVIEW_LENGTH 160 #endif diff --git a/libs/libloggers/loggers/Loggers.cpp b/libs/libloggers/loggers/Loggers.cpp index 20d06b06e6d..ebdc3e37571 100644 --- a/libs/libloggers/loggers/Loggers.cpp +++ b/libs/libloggers/loggers/Loggers.cpp @@ -22,7 +22,8 @@ static std::string createDirectory(const std::string & file) return path.toString(); }; -void Loggers::setTextLog(std::shared_ptr log) { +void Loggers::setTextLog(std::shared_ptr log) +{ text_log = log; } diff --git a/libs/libloggers/loggers/OwnSplitChannel.h b/libs/libloggers/loggers/OwnSplitChannel.h index 1168a44acb0..ee190124c66 100644 --- a/libs/libloggers/loggers/OwnSplitChannel.h +++ b/libs/libloggers/loggers/OwnSplitChannel.h @@ -14,8 +14,6 @@ namespace DB class OwnSplitChannel : public Poco::Channel { public: - OwnSplitChannel() = default; - /// Makes an extended message from msg and passes it to the client logs queue and child (if possible) void log(const Poco::Message & msg) override; From e5d3f1722524a4a60a147f9d4f5d9e19996430ad Mon Sep 17 00:00:00 2001 From: chertus Date: Thu, 1 Aug 2019 14:02:32 +0300 Subject: [PATCH 0570/1165] fix test results --- .../queries/0_stateless/00875_join_right_nulls.reference | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00875_join_right_nulls.reference b/dbms/tests/queries/0_stateless/00875_join_right_nulls.reference index 01932c3f068..2751528db29 100644 --- a/dbms/tests/queries/0_stateless/00875_join_right_nulls.reference +++ b/dbms/tests/queries/0_stateless/00875_join_right_nulls.reference @@ -6,12 +6,12 @@ n fj n 1 1 n fj n id id n fj n \N \N n fj n \N \N -t rj n \N t rj n 1 1 t rj n id id -t fj n \N +t rj n \N \N t fj n 1 1 t fj n id id +t fj n \N \N n rj t 1 1 n rj t id id n fj t 1 1 @@ -25,12 +25,12 @@ n fj n 1 1 n fj n id id n fj n \N \N n fj n \N \N -t rj n \N t rj n 1 1 t rj n id id -t fj n \N +t rj n \N \N t fj n 1 1 t fj n id id +t fj n \N \N n rj t 1 1 n rj t id id n fj t 1 1 From f224269d4160dce93412fd658cb9276afca9becb Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Thu, 1 Aug 2019 14:10:42 +0300 Subject: [PATCH 0571/1165] filter by ttl parts created before 'alter ... modify ttl' query with 'optimize ... final' query --- dbms/src/DataStreams/TTLBlockInputStream.cpp | 35 +++++++++++-------- dbms/src/DataStreams/TTLBlockInputStream.h | 9 +++-- dbms/src/Storages/MergeTree/MergeTreeData.h | 1 + .../MergeTree/MergeTreeDataMergerMutator.cpp | 7 ++-- .../MergeTree/MergeTreeDataMergerMutator.h | 2 +- .../MergeTree/ReplicatedMergeTreeLogEntry.h | 2 ++ dbms/src/Storages/StorageMergeTree.cpp | 3 +- .../Storages/StorageReplicatedMergeTree.cpp | 11 ++++-- .../src/Storages/StorageReplicatedMergeTree.h | 1 + .../00976_ttl_with_old_parts.reference | 2 ++ .../0_stateless/00976_ttl_with_old_parts.sql | 16 +++++++++ 11 files changed, 62 insertions(+), 27 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00976_ttl_with_old_parts.reference create mode 100644 dbms/tests/queries/0_stateless/00976_ttl_with_old_parts.sql diff --git a/dbms/src/DataStreams/TTLBlockInputStream.cpp b/dbms/src/DataStreams/TTLBlockInputStream.cpp index 11999b894aa..33c111cb5bf 100644 --- a/dbms/src/DataStreams/TTLBlockInputStream.cpp +++ b/dbms/src/DataStreams/TTLBlockInputStream.cpp @@ -17,10 +17,12 @@ TTLBlockInputStream::TTLBlockInputStream( const BlockInputStreamPtr & input_, const MergeTreeData & storage_, const MergeTreeData::MutableDataPartPtr & data_part_, - time_t current_time_) + time_t current_time_, + bool force_) : storage(storage_) , data_part(data_part_) , current_time(current_time_) + , force(force_) , old_ttl_infos(data_part->ttl_infos) , log(&Logger::get(storage.getLogName() + " (TTLBlockInputStream)")) , date_lut(DateLUT::instance()) @@ -60,6 +62,10 @@ TTLBlockInputStream::TTLBlockInputStream( } } +bool TTLBlockInputStream::isTTLExpired(time_t ttl) +{ + return (ttl && (ttl <= current_time)); +} Block TTLBlockInputStream::readImpl() { @@ -70,13 +76,13 @@ Block TTLBlockInputStream::readImpl() if (storage.hasTableTTL()) { /// Skip all data if table ttl is expired for part - if (old_ttl_infos.table_ttl.max <= current_time) + if (isTTLExpired(old_ttl_infos.table_ttl.max)) { rows_removed = data_part->rows_count; return {}; } - if (old_ttl_infos.table_ttl.min <= current_time) + if (force || isTTLExpired(old_ttl_infos.table_ttl.min)) removeRowsWithExpiredTableTTL(block); } @@ -96,15 +102,15 @@ void TTLBlockInputStream::readSuffixImpl() data_part->empty_columns = std::move(empty_columns); if (rows_removed) - LOG_INFO(log, "Removed " << rows_removed << " rows with expired ttl from part " << data_part->name); + LOG_INFO(log, "Removed " << rows_removed << " rows with expired TTL from part " << data_part->name); } void TTLBlockInputStream::removeRowsWithExpiredTableTTL(Block & block) { storage.ttl_table_entry.expression->execute(block); - const auto & current = block.getByName(storage.ttl_table_entry.result_column); - const IColumn * ttl_column = current.column.get(); + const IColumn * ttl_column = + block.getByName(storage.ttl_table_entry.result_column).column.get(); const auto & column_names = header.getNames(); MutableColumns result_columns; @@ -112,15 +118,14 @@ void TTLBlockInputStream::removeRowsWithExpiredTableTTL(Block & block) for (auto it = column_names.begin(); it != column_names.end(); ++it) { - auto & column_with_type = block.getByName(*it); - const IColumn * values_column = column_with_type.column.get(); + const IColumn * values_column = block.getByName(*it).column.get(); MutableColumnPtr result_column = values_column->cloneEmpty(); result_column->reserve(block.rows()); for (size_t i = 0; i < block.rows(); ++i) { UInt32 cur_ttl = getTimestampByIndex(ttl_column, i); - if (cur_ttl > current_time) + if (!isTTLExpired(cur_ttl)) { new_ttl_infos.table_ttl.update(cur_ttl); result_column->insertFrom(*values_column, i); @@ -148,10 +153,12 @@ void TTLBlockInputStream::removeValuesWithExpiredColumnTTL(Block & block) const auto & old_ttl_info = old_ttl_infos.columns_ttl[name]; auto & new_ttl_info = new_ttl_infos.columns_ttl[name]; - if (old_ttl_info.min > current_time) + /// Nothing to do + if (!force && !isTTLExpired(old_ttl_info.min)) continue; - if (old_ttl_info.max <= current_time) + /// Later drop full column + if (isTTLExpired(old_ttl_info.max)) continue; if (!block.has(ttl_entry.result_column)) @@ -166,14 +173,12 @@ void TTLBlockInputStream::removeValuesWithExpiredColumnTTL(Block & block) MutableColumnPtr result_column = values_column->cloneEmpty(); result_column->reserve(block.rows()); - const auto & current = block.getByName(ttl_entry.result_column); - const IColumn * ttl_column = current.column.get(); + const IColumn * ttl_column = block.getByName(ttl_entry.result_column).column.get(); for (size_t i = 0; i < block.rows(); ++i) { UInt32 cur_ttl = getTimestampByIndex(ttl_column, i); - - if (cur_ttl <= current_time) + if (isTTLExpired(cur_ttl)) { if (default_column) result_column->insertFrom(*default_column, i); diff --git a/dbms/src/DataStreams/TTLBlockInputStream.h b/dbms/src/DataStreams/TTLBlockInputStream.h index de0d4f9156b..a57c6cf74bf 100644 --- a/dbms/src/DataStreams/TTLBlockInputStream.h +++ b/dbms/src/DataStreams/TTLBlockInputStream.h @@ -16,7 +16,8 @@ public: const BlockInputStreamPtr & input_, const MergeTreeData & storage_, const MergeTreeData::MutableDataPartPtr & data_part_, - time_t current_time + time_t current_time, + bool force_ ); String getName() const override { return "TTLBlockInputStream"; } @@ -36,6 +37,7 @@ private: const MergeTreeData::MutableDataPartPtr & data_part; time_t current_time; + bool force; MergeTreeDataPart::TTLInfos old_ttl_infos; MergeTreeDataPart::TTLInfos new_ttl_infos; @@ -50,13 +52,14 @@ private: Block header; private: - /// Removes values with expired ttl and computes new min_ttl and empty_columns for part + /// Removes values with expired ttl and computes new_ttl_infos and empty_columns for part void removeValuesWithExpiredColumnTTL(Block & block); - /// Remove rows with expired table ttl and computes new min_ttl for part + /// Removes rows with expired table ttl and computes new ttl_infos for part void removeRowsWithExpiredTableTTL(Block & block); UInt32 getTimestampByIndex(const IColumn * column, size_t ind); + bool isTTLExpired(time_t ttl); }; } diff --git a/dbms/src/Storages/MergeTree/MergeTreeData.h b/dbms/src/Storages/MergeTree/MergeTreeData.h index 271ad231f41..c6b85e6d98f 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeData.h +++ b/dbms/src/Storages/MergeTree/MergeTreeData.h @@ -531,6 +531,7 @@ public: bool hasPrimaryKey() const { return !primary_key_columns.empty(); } bool hasSkipIndices() const { return !skip_indices.empty(); } bool hasTableTTL() const { return ttl_table_ast != nullptr; } + bool hasAnyColumnTTL() const { return !ttl_entries_by_name.empty(); } /// Check that the part is not broken and calculate the checksums for it if they are not present. MutableDataPartPtr loadPartAndFixMetadata(const String & relative_path); diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp index e30bbdcda0b..2b17475801f 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp @@ -522,7 +522,7 @@ public: /// parts should be sorted. MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mergePartsToTemporaryPart( const FutureMergedMutatedPart & future_part, MergeList::Entry & merge_entry, - time_t time_of_merge, DiskSpaceMonitor::Reservation * disk_reservation, bool deduplicate) + time_t time_of_merge, DiskSpaceMonitor::Reservation * disk_reservation, bool deduplicate, bool force_ttl) { static const String TMP_PREFIX = "tmp_merge_"; @@ -560,7 +560,7 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mergePartsToTempor size_t sum_input_rows_upper_bound = merge_entry->total_rows_count; - bool need_remove_expired_values = false; + bool need_remove_expired_values = force_ttl; for (const MergeTreeData::DataPartPtr & part : parts) new_data_part->ttl_infos.update(part->ttl_infos); @@ -568,7 +568,6 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mergePartsToTempor if (part_min_ttl && part_min_ttl <= time_of_merge) need_remove_expired_values = true; - MergeAlgorithm merge_alg = chooseMergeAlgorithm(parts, sum_input_rows_upper_bound, gathering_columns, deduplicate, need_remove_expired_values); LOG_DEBUG(log, "Selected MergeAlgorithm: " << ((merge_alg == MergeAlgorithm::Vertical) ? "Vertical" : "Horizontal")); @@ -707,7 +706,7 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mergePartsToTempor merged_stream = std::make_shared(merged_stream, SizeLimits(), 0 /*limit_hint*/, Names()); if (need_remove_expired_values) - merged_stream = std::make_shared(merged_stream, data, new_data_part, time_of_merge); + merged_stream = std::make_shared(merged_stream, data, new_data_part, time_of_merge, force_ttl); MergedBlockOutputStream to{ data, diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.h b/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.h index 29fd615d39b..a380b5c2bc2 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.h +++ b/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.h @@ -95,7 +95,7 @@ public: MergeTreeData::MutableDataPartPtr mergePartsToTemporaryPart( const FutureMergedMutatedPart & future_part, MergeListEntry & merge_entry, time_t time_of_merge, - DiskSpaceMonitor::Reservation * disk_reservation, bool deduplication); + DiskSpaceMonitor::Reservation * disk_reservation, bool deduplication, bool force_ttl); /// Mutate a single data part with the specified commands. Will create and return a temporary part. MergeTreeData::MutableDataPartPtr mutatePartToTemporaryPart( diff --git a/dbms/src/Storages/MergeTree/ReplicatedMergeTreeLogEntry.h b/dbms/src/Storages/MergeTree/ReplicatedMergeTreeLogEntry.h index 602249c86ea..4797922d837 100644 --- a/dbms/src/Storages/MergeTree/ReplicatedMergeTreeLogEntry.h +++ b/dbms/src/Storages/MergeTree/ReplicatedMergeTreeLogEntry.h @@ -77,6 +77,8 @@ struct ReplicatedMergeTreeLogEntryData bool deduplicate = false; /// Do deduplicate on merge String column_name; + bool force_ttl = false; + /// For DROP_RANGE, true means that the parts need not be deleted, but moved to the `detached` directory. bool detach = false; diff --git a/dbms/src/Storages/StorageMergeTree.cpp b/dbms/src/Storages/StorageMergeTree.cpp index 0536423101d..589a5ad2af2 100644 --- a/dbms/src/Storages/StorageMergeTree.cpp +++ b/dbms/src/Storages/StorageMergeTree.cpp @@ -590,9 +590,10 @@ bool StorageMergeTree::merge( try { + bool force_ttl = (final && (hasTableTTL() || hasAnyColumnTTL())); new_part = merger_mutator.mergePartsToTemporaryPart( future_part, *merge_entry, time(nullptr), - merging_tagger->reserved_space.get(), deduplicate); + merging_tagger->reserved_space.get(), deduplicate, force_ttl); merger_mutator.renameMergedTemporaryPart(new_part, future_part.parts, nullptr); removeEmptyColumnsFromPart(new_part); diff --git a/dbms/src/Storages/StorageReplicatedMergeTree.cpp b/dbms/src/Storages/StorageReplicatedMergeTree.cpp index 934d651fead..8492dd2c007 100644 --- a/dbms/src/Storages/StorageReplicatedMergeTree.cpp +++ b/dbms/src/Storages/StorageReplicatedMergeTree.cpp @@ -1083,7 +1083,7 @@ bool StorageReplicatedMergeTree::tryExecuteMerge(const LogEntry & entry) try { part = merger_mutator.mergePartsToTemporaryPart( - future_merged_part, *merge_entry, entry.create_time, reserved_space.get(), entry.deduplicate); + future_merged_part, *merge_entry, entry.create_time, reserved_space.get(), entry.deduplicate, entry.force_ttl); merger_mutator.renameMergedTemporaryPart(part, parts, &transaction); removeEmptyColumnsFromPart(part); @@ -2157,6 +2157,7 @@ void StorageReplicatedMergeTree::mergeSelectingTask() return; const bool deduplicate = false; /// TODO: read deduplicate option from table config + const bool force_ttl = false; bool success = false; @@ -2190,7 +2191,7 @@ void StorageReplicatedMergeTree::mergeSelectingTask() if (max_source_parts_size_for_merge > 0 && merger_mutator.selectPartsToMerge(future_merged_part, false, max_source_parts_size_for_merge, merge_pred)) { - success = createLogEntryToMergeParts(zookeeper, future_merged_part.parts, future_merged_part.name, deduplicate); + success = createLogEntryToMergeParts(zookeeper, future_merged_part.parts, future_merged_part.name, deduplicate, force_ttl); } else if (max_source_part_size_for_mutation > 0 && queue.countMutations() > 0) { @@ -2254,6 +2255,7 @@ bool StorageReplicatedMergeTree::createLogEntryToMergeParts( const DataPartsVector & parts, const String & merged_name, bool deduplicate, + bool force_ttl, ReplicatedMergeTreeLogEntryData * out_log_entry) { std::vector> exists_futures; @@ -2289,6 +2291,7 @@ bool StorageReplicatedMergeTree::createLogEntryToMergeParts( entry.source_replica = replica_name; entry.new_part_name = merged_name; entry.deduplicate = deduplicate; + entry.force_ttl = force_ttl; entry.create_time = time(nullptr); for (const auto & part : parts) @@ -2999,6 +3002,8 @@ bool StorageReplicatedMergeTree::optimize(const ASTPtr & query, const ASTPtr & p return false; }; + bool force_ttl = (final && (hasTableTTL() || hasAnyColumnTTL())); + if (!partition && final) { DataPartsVector data_parts = getDataPartsVector(); @@ -3016,7 +3021,7 @@ bool StorageReplicatedMergeTree::optimize(const ASTPtr & query, const ASTPtr & p future_merged_part, disk_space, can_merge, partition_id, true, nullptr); ReplicatedMergeTreeLogEntryData merge_entry; if (selected && - !createLogEntryToMergeParts(zookeeper, future_merged_part.parts, future_merged_part.name, deduplicate, &merge_entry)) + !createLogEntryToMergeParts(zookeeper, future_merged_part.parts, future_merged_part.name, deduplicate, force_ttl, &merge_entry)) return handle_noop("Can't create merge queue node in ZooKeeper"); if (merge_entry.type != ReplicatedMergeTreeLogEntryData::Type::EMPTY) merge_entries.push_back(std::move(merge_entry)); diff --git a/dbms/src/Storages/StorageReplicatedMergeTree.h b/dbms/src/Storages/StorageReplicatedMergeTree.h index 59afb96a523..878c5ce0619 100644 --- a/dbms/src/Storages/StorageReplicatedMergeTree.h +++ b/dbms/src/Storages/StorageReplicatedMergeTree.h @@ -424,6 +424,7 @@ private: const DataPartsVector & parts, const String & merged_name, bool deduplicate, + bool force_ttl, ReplicatedMergeTreeLogEntryData * out_log_entry = nullptr); bool createLogEntryToMutatePart(const MergeTreeDataPart & part, Int64 mutation_version); diff --git a/dbms/tests/queries/0_stateless/00976_ttl_with_old_parts.reference b/dbms/tests/queries/0_stateless/00976_ttl_with_old_parts.reference new file mode 100644 index 00000000000..301c460aba8 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00976_ttl_with_old_parts.reference @@ -0,0 +1,2 @@ +2100-10-10 3 +2100-10-10 4 diff --git a/dbms/tests/queries/0_stateless/00976_ttl_with_old_parts.sql b/dbms/tests/queries/0_stateless/00976_ttl_with_old_parts.sql new file mode 100644 index 00000000000..0ed69850cf6 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00976_ttl_with_old_parts.sql @@ -0,0 +1,16 @@ +drop table if exists ttl; + +create table ttl (d Date, a Int) engine = MergeTree order by a partition by toDayOfMonth(d); +insert into ttl values (toDateTime('2000-10-10 00:00:00'), 1); +insert into ttl values (toDateTime('2000-10-10 00:00:00'), 2); +insert into ttl values (toDateTime('2100-10-10 00:00:00'), 3); +insert into ttl values (toDateTime('2100-10-10 00:00:00'), 4); + +alter table ttl modify ttl d + interval 1 day; + +select sleep(1) format Null; -- wait if very fast merge happen +optimize table ttl partition 10 final; + +select * from ttl order by d; + +drop table if exists ttl; From 406f7a2bfee32d6bd1bdf16fa107cccb1451a464 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Thu, 1 Aug 2019 14:11:08 +0300 Subject: [PATCH 0572/1165] done --- dbms/src/Interpreters/QueryLog.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/dbms/src/Interpreters/QueryLog.cpp b/dbms/src/Interpreters/QueryLog.cpp index 2bc49c42b4b..b04de2fe273 100644 --- a/dbms/src/Interpreters/QueryLog.cpp +++ b/dbms/src/Interpreters/QueryLog.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -20,11 +21,23 @@ namespace DB { +template <> struct NearestFieldTypeImpl { using Type = UInt64; }; + Block QueryLogElement::createBlock() { + + auto query_status_datatype = std::make_shared( + DataTypeEnum8::Values + { + {"QUERY_START", static_cast(QUERY_START)}, + {"QUERY_FINISH", static_cast(QUERY_FINISH)}, + {"EXCEPTION_BEFORE_START", static_cast(EXCEPTION_BEFORE_START)}, + {"EXCEPTION_WHILE_PROCESSING", static_cast(EXCEPTION_WHILE_PROCESSING)} + }); + return { - {std::make_shared(), "type"}, + {std::move(query_status_datatype), "type"}, {std::make_shared(), "event_date"}, {std::make_shared(), "event_time"}, {std::make_shared(), "query_start_time"}, @@ -80,7 +93,7 @@ void QueryLogElement::appendToBlock(Block & block) const size_t i = 0; - columns[i++]->insert(UInt64(type)); + columns[i++]->insert(type); columns[i++]->insert(DateLUT::instance().toDayNum(event_time)); columns[i++]->insert(event_time); columns[i++]->insert(query_start_time); From c30bdecf6d5a575548e4f4786194fb9117396729 Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Thu, 1 Aug 2019 15:00:35 +0300 Subject: [PATCH 0573/1165] add missing comments --- dbms/src/Storages/MergeTree/ReplicatedMergeTreeLogEntry.h | 2 ++ dbms/src/Storages/StorageMergeTree.cpp | 3 +++ 2 files changed, 5 insertions(+) diff --git a/dbms/src/Storages/MergeTree/ReplicatedMergeTreeLogEntry.h b/dbms/src/Storages/MergeTree/ReplicatedMergeTreeLogEntry.h index 4797922d837..1d7d39f1b9e 100644 --- a/dbms/src/Storages/MergeTree/ReplicatedMergeTreeLogEntry.h +++ b/dbms/src/Storages/MergeTree/ReplicatedMergeTreeLogEntry.h @@ -77,6 +77,8 @@ struct ReplicatedMergeTreeLogEntryData bool deduplicate = false; /// Do deduplicate on merge String column_name; + /// Force filter by TTL in 'OPTIMIZE ... FINAL' query to remove expired values from old parts + /// without TTL infos or with outdated TTL infos, e.g. after 'ALTER ... MODIFY TTL' query. bool force_ttl = false; /// For DROP_RANGE, true means that the parts need not be deleted, but moved to the `detached` directory. diff --git a/dbms/src/Storages/StorageMergeTree.cpp b/dbms/src/Storages/StorageMergeTree.cpp index 589a5ad2af2..69020023df5 100644 --- a/dbms/src/Storages/StorageMergeTree.cpp +++ b/dbms/src/Storages/StorageMergeTree.cpp @@ -590,7 +590,10 @@ bool StorageMergeTree::merge( try { + /// Force filter by TTL in 'OPTIMIZE ... FINAL' query to remove expired values from old parts + /// without TTL infos or with outdated TTL infos, e.g. after 'ALTER ... MODIFY TTL' query. bool force_ttl = (final && (hasTableTTL() || hasAnyColumnTTL())); + new_part = merger_mutator.mergePartsToTemporaryPart( future_part, *merge_entry, time(nullptr), merging_tagger->reserved_space.get(), deduplicate, force_ttl); From a47236b136eb77da4aa2eb5304311b5ad70e8429 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Thu, 1 Aug 2019 15:03:30 +0300 Subject: [PATCH 0574/1165] Update index.html --- website/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/website/index.html b/website/index.html index 9372b095e25..4dc4766c9d3 100644 --- a/website/index.html +++ b/website/index.html @@ -416,6 +416,7 @@ clickhouse-client
    - Upcoming Meetups: Mountain View on August 13, Shenzhen on October 20 and Shanghai on October 27 + Upcoming Meetups: Mountain View on August 13, Moscow on September 5, Shenzhen on October 20 and Shanghai on October 27
    From 44b3dbb23b92bd8325c797c8d319aa499c585200 Mon Sep 17 00:00:00 2001 From: Alexander Rodin Date: Thu, 1 Aug 2019 13:16:09 +0000 Subject: [PATCH 0581/1165] Return Bad Request for INCORRECT_DATA and TYPE_MISMATCH errors --- dbms/programs/server/HTTPHandler.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dbms/programs/server/HTTPHandler.cpp b/dbms/programs/server/HTTPHandler.cpp index 5db7ce1a3ae..b54d1110a63 100644 --- a/dbms/programs/server/HTTPHandler.cpp +++ b/dbms/programs/server/HTTPHandler.cpp @@ -61,6 +61,9 @@ namespace ErrorCodes extern const int SYNTAX_ERROR; + extern const int INCORRECT_DATA; + extern const int TYPE_MISMATCH; + extern const int UNKNOWN_TABLE; extern const int UNKNOWN_FUNCTION; extern const int UNKNOWN_IDENTIFIER; @@ -109,6 +112,9 @@ static Poco::Net::HTTPResponse::HTTPStatus exceptionCodeToHTTPStatus(int excepti return HTTPResponse::HTTP_BAD_REQUEST; else if (exception_code == ErrorCodes::SYNTAX_ERROR) return HTTPResponse::HTTP_BAD_REQUEST; + else if (exception_code == ErrorCodes::INCORRECT_DATA || + exception_code == ErrorCodes::TYPE_MISMATCH) + return HTTPResponse::HTTP_BAD_REQUEST; else if (exception_code == ErrorCodes::UNKNOWN_TABLE || exception_code == ErrorCodes::UNKNOWN_FUNCTION || exception_code == ErrorCodes::UNKNOWN_IDENTIFIER || From c228f1813046c206720db202fa108da21857af56 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 1 Aug 2019 17:25:41 +0300 Subject: [PATCH 0582/1165] Update IRowInputFormat and FormatFactory. --- dbms/src/Formats/FormatFactory.cpp | 2 + .../Processors/Executors/PipelineExecutor.cpp | 17 ++++++- .../Processors/Executors/PipelineExecutor.h | 11 ++--- .../Processors/Formats/IRowInputFormat.cpp | 46 ++++++++++++++++++- dbms/src/Processors/Formats/IRowInputFormat.h | 7 +++ .../Formats/InputStreamFromInputFormat.h | 6 +++ dbms/src/Processors/IProcessor.h | 13 +++++- 7 files changed, 90 insertions(+), 12 deletions(-) diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index c5280e45b48..022d6ae5915 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -139,6 +139,8 @@ InputFormatPtr FormatFactory::getInputFormat( params.allow_errors_ratio = format_settings.input_allow_errors_ratio; params.rows_portion_size = rows_portion_size; params.callback = std::move(callback); + params.max_execution_time = settings.max_execution_time; + params.timeout_overflow_mode = settings.timeout_overflow_mode; return input_getter(buf, sample, context, params, format_settings); } diff --git a/dbms/src/Processors/Executors/PipelineExecutor.cpp b/dbms/src/Processors/Executors/PipelineExecutor.cpp index 9da53793e81..e45bded427c 100644 --- a/dbms/src/Processors/Executors/PipelineExecutor.cpp +++ b/dbms/src/Processors/Executors/PipelineExecutor.cpp @@ -185,9 +185,12 @@ void PipelineExecutor::expandPipeline(Stack & stack, UInt64 pid) graph.emplace_back(processor.get(), graph.size()); } - processors.insert(processors.end(), new_processors.begin(), new_processors.end()); - UInt64 num_processors = processors.size(); + { + std::lock_guard guard(processors_mutex); + processors.insert(processors.end(), new_processors.begin(), new_processors.end()); + } + UInt64 num_processors = processors.size(); for (UInt64 node = 0; node < num_processors; ++node) { if (addEdges(node)) @@ -374,6 +377,16 @@ void PipelineExecutor::doExpandPipeline(ExpandPipelineTask * task, bool processi } } +void PipelineExecutor::cancel() +{ + cancelled = true; + finish(); + + std::lock_guard guard(processors_mutex); + for (auto & processor : processors) + processor->cancel(); +} + void PipelineExecutor::finish() { { diff --git a/dbms/src/Processors/Executors/PipelineExecutor.h b/dbms/src/Processors/Executors/PipelineExecutor.h index 0994532f953..02149cb042f 100644 --- a/dbms/src/Processors/Executors/PipelineExecutor.h +++ b/dbms/src/Processors/Executors/PipelineExecutor.h @@ -35,14 +35,11 @@ public: const Processors & getProcessors() const { return processors; } /// Cancel execution. May be called from another thread. - void cancel() - { - cancelled = true; - finish(); - } + void cancel(); private: Processors & processors; + std::mutex processors_mutex; struct Edge { @@ -75,8 +72,8 @@ private: std::exception_ptr exception; std::function job; - IProcessor * processor; - UInt64 processors_id; + IProcessor * processor = nullptr; + UInt64 processors_id = 0; /// Counters for profiling. size_t num_executed_jobs = 0; diff --git a/dbms/src/Processors/Formats/IRowInputFormat.cpp b/dbms/src/Processors/Formats/IRowInputFormat.cpp index 1565ec82e1d..2860587cbf2 100644 --- a/dbms/src/Processors/Formats/IRowInputFormat.cpp +++ b/dbms/src/Processors/Formats/IRowInputFormat.cpp @@ -1,5 +1,6 @@ #include #include // toString +#include namespace DB @@ -16,6 +17,7 @@ namespace ErrorCodes extern const int CANNOT_PARSE_UUID; extern const int TOO_LARGE_STRING_SIZE; extern const int INCORRECT_NUMBER_OF_COLUMNS; + extern const int TIMEOUT_EXCEEDED; } @@ -32,6 +34,33 @@ static bool isParseError(int code) } +static bool handleOverflowMode(OverflowMode mode, const String & message, int code) +{ + switch (mode) + { + case OverflowMode::THROW: + throw Exception(message, code); + case OverflowMode::BREAK: + return false; + default: + throw Exception("Logical error: unknown overflow mode", ErrorCodes::LOGICAL_ERROR); + } +} + + +static bool checkTimeLimit(const IRowInputFormat::Params & params, const Stopwatch & stopwatch) +{ + if (params.max_execution_time != 0 + && stopwatch.elapsed() > static_cast(params.max_execution_time.totalMicroseconds()) * 1000) + return handleOverflowMode(params.timeout_overflow_mode, + "Timeout exceeded: elapsed " + toString(stopwatch.elapsedSeconds()) + + " seconds, maximum: " + toString(params.max_execution_time.totalMicroseconds() / 1000000.0), + ErrorCodes::TIMEOUT_EXCEEDED); + + return true; +} + + Chunk IRowInputFormat::generate() { if (total_rows == 0) @@ -47,8 +76,15 @@ Chunk IRowInputFormat::generate() try { - for (size_t rows = 0; rows < params.max_block_size; ++rows) + for (size_t rows = 0, batch = 0; rows < params.max_block_size; ++rows, ++batch) { + if (params.rows_portion_size && batch == params.rows_portion_size) + { + batch = 0; + if (!checkTimeLimit(params, total_stopwatch) || isCancelled()) + break; + } + try { ++total_rows; @@ -56,6 +92,8 @@ Chunk IRowInputFormat::generate() RowReadExtension info; if (!readRow(columns, info)) break; + if (params.callback) + params.callback(); for (size_t column_idx = 0; column_idx < info.read_columns.size(); ++column_idx) { @@ -134,6 +172,12 @@ Chunk IRowInputFormat::generate() if (columns.empty() || columns[0]->empty()) { + if (params.allow_errors_num > 0 || params.allow_errors_ratio > 0) + { + Logger * log = &Logger::get("BlockInputStreamFromRowInputStream"); + LOG_TRACE(log, "Skipped " << num_errors << " rows with errors while reading the input stream"); + } + readSuffix(); return {}; } diff --git a/dbms/src/Processors/Formats/IRowInputFormat.h b/dbms/src/Processors/Formats/IRowInputFormat.h index b70edf47a64..26d1a11a657 100644 --- a/dbms/src/Processors/Formats/IRowInputFormat.h +++ b/dbms/src/Processors/Formats/IRowInputFormat.h @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include namespace DB @@ -28,6 +31,9 @@ struct RowInputFormatParams using ReadCallback = std::function; ReadCallback callback; + + Poco::Timespan max_execution_time = 0; + OverflowMode timeout_overflow_mode = OverflowMode::THROW; }; ///Row oriented input format: reads data row by row. @@ -70,6 +76,7 @@ protected: private: Params params; + Stopwatch total_stopwatch {CLOCK_MONOTONIC_COARSE}; size_t total_rows = 0; size_t num_errors = 0; diff --git a/dbms/src/Processors/Formats/InputStreamFromInputFormat.h b/dbms/src/Processors/Formats/InputStreamFromInputFormat.h index 4f94652fac7..963193940b8 100644 --- a/dbms/src/Processors/Formats/InputStreamFromInputFormat.h +++ b/dbms/src/Processors/Formats/InputStreamFromInputFormat.h @@ -22,6 +22,12 @@ public: String getName() const override { return input_format->getName(); } Block getHeader() const override { return input_format->getPort().getHeader(); } + void cancel(bool kill) override + { + input_format->cancel(); + IBlockInputStream::cancel(kill); + } + const BlockMissingValues & getMissingValues() const override { return input_format->getMissingValues(); } protected: diff --git a/dbms/src/Processors/IProcessor.h b/dbms/src/Processors/IProcessor.h index c5f9ef64b4a..18d34f29c99 100644 --- a/dbms/src/Processors/IProcessor.h +++ b/dbms/src/Processors/IProcessor.h @@ -211,6 +211,11 @@ public: throw Exception("Method 'expandPipeline' is not implemented for " + getName() + " processor", ErrorCodes::NOT_IMPLEMENTED); } + /// In case if query was cancelled executor will wait till all processors finish their jobs. + /// Generally, there is no reason to check this flag. However, it may be reasonable for long operations (e.g. i/o). + bool isCancelled() const { return is_cancelled; } + void cancel() { is_cancelled = true; } + virtual ~IProcessor() = default; auto & getInputs() { return inputs; } @@ -219,10 +224,14 @@ public: /// Debug output. void dump() const; - std::string processor_description; - + /// Used to print pipeline. void setDescription(const std::string & description_) { processor_description = description_; } const std::string & getDescription() const { return processor_description; } + +private: + std::atomic is_cancelled{false}; + + std::string processor_description; }; From 0c70f78fcb9edc0d1fd94fb896c3ecc2eb183064 Mon Sep 17 00:00:00 2001 From: Alexander Rodin Date: Thu, 1 Aug 2019 15:23:20 +0000 Subject: [PATCH 0583/1165] Replace ifs by cases --- dbms/programs/server/HTTPHandler.cpp | 91 ++++++++++++++-------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/dbms/programs/server/HTTPHandler.cpp b/dbms/programs/server/HTTPHandler.cpp index b54d1110a63..51df8a4ed39 100644 --- a/dbms/programs/server/HTTPHandler.cpp +++ b/dbms/programs/server/HTTPHandler.cpp @@ -95,51 +95,54 @@ static Poco::Net::HTTPResponse::HTTPStatus exceptionCodeToHTTPStatus(int excepti { using namespace Poco::Net; - if (exception_code == ErrorCodes::REQUIRED_PASSWORD) - return HTTPResponse::HTTP_UNAUTHORIZED; - else if (exception_code == ErrorCodes::CANNOT_PARSE_TEXT || - exception_code == ErrorCodes::CANNOT_PARSE_ESCAPE_SEQUENCE || - exception_code == ErrorCodes::CANNOT_PARSE_QUOTED_STRING || - exception_code == ErrorCodes::CANNOT_PARSE_DATE || - exception_code == ErrorCodes::CANNOT_PARSE_DATETIME || - exception_code == ErrorCodes::CANNOT_PARSE_NUMBER) - return HTTPResponse::HTTP_BAD_REQUEST; - else if (exception_code == ErrorCodes::UNKNOWN_ELEMENT_IN_AST || - exception_code == ErrorCodes::UNKNOWN_TYPE_OF_AST_NODE || - exception_code == ErrorCodes::TOO_DEEP_AST || - exception_code == ErrorCodes::TOO_BIG_AST || - exception_code == ErrorCodes::UNEXPECTED_AST_STRUCTURE) - return HTTPResponse::HTTP_BAD_REQUEST; - else if (exception_code == ErrorCodes::SYNTAX_ERROR) - return HTTPResponse::HTTP_BAD_REQUEST; - else if (exception_code == ErrorCodes::INCORRECT_DATA || - exception_code == ErrorCodes::TYPE_MISMATCH) - return HTTPResponse::HTTP_BAD_REQUEST; - else if (exception_code == ErrorCodes::UNKNOWN_TABLE || - exception_code == ErrorCodes::UNKNOWN_FUNCTION || - exception_code == ErrorCodes::UNKNOWN_IDENTIFIER || - exception_code == ErrorCodes::UNKNOWN_TYPE || - exception_code == ErrorCodes::UNKNOWN_STORAGE || - exception_code == ErrorCodes::UNKNOWN_DATABASE || - exception_code == ErrorCodes::UNKNOWN_SETTING || - exception_code == ErrorCodes::UNKNOWN_DIRECTION_OF_SORTING || - exception_code == ErrorCodes::UNKNOWN_AGGREGATE_FUNCTION || - exception_code == ErrorCodes::UNKNOWN_FORMAT || - exception_code == ErrorCodes::UNKNOWN_DATABASE_ENGINE) - return HTTPResponse::HTTP_NOT_FOUND; - else if (exception_code == ErrorCodes::UNKNOWN_TYPE_OF_QUERY) - return HTTPResponse::HTTP_NOT_FOUND; - else if (exception_code == ErrorCodes::QUERY_IS_TOO_LARGE) - return HTTPResponse::HTTP_REQUESTENTITYTOOLARGE; - else if (exception_code == ErrorCodes::NOT_IMPLEMENTED) - return HTTPResponse::HTTP_NOT_IMPLEMENTED; - else if (exception_code == ErrorCodes::SOCKET_TIMEOUT || - exception_code == ErrorCodes::CANNOT_OPEN_FILE) - return HTTPResponse::HTTP_SERVICE_UNAVAILABLE; - else if (exception_code == ErrorCodes::HTTP_LENGTH_REQUIRED) - return HTTPResponse::HTTP_LENGTH_REQUIRED; + switch (exception_code) + { + case ErrorCodes::REQUIRED_PASSWORD: + return HTTPResponse::HTTP_UNAUTHORIZED; + case ErrorCodes::CANNOT_PARSE_TEXT: + case ErrorCodes::CANNOT_PARSE_ESCAPE_SEQUENCE: + case ErrorCodes::CANNOT_PARSE_QUOTED_STRING: + case ErrorCodes::CANNOT_PARSE_DATE: + case ErrorCodes::CANNOT_PARSE_DATETIME: + case ErrorCodes::CANNOT_PARSE_NUMBER: - return HTTPResponse::HTTP_INTERNAL_SERVER_ERROR; + case ErrorCodes::CANNOT_PARSE_NUMBER: + case ErrorCodes::UNKNOWN_TYPE_OF_AST_NODE: + case ErrorCodes::TOO_DEEP_AST: + case ErrorCodes::TOO_BIG_AST: + case ErrorCodes::UNEXPECTED_AST_STRUCTURE: + + case ErrorCodes::SYNTAX_ERROR: + + case ErrorCodes::INCORRECT_DATA: + case ErrorCodes::TYPE_MISMATCH: + return HTTPResponse::HTTP_BAD_REQUEST; + case ErrorCodes::UNKNOWN_TABLE: + case ErrorCodes::UNKNOWN_FUNCTION: + case ErrorCodes::UNKNOWN_IDENTIFIER: + case ErrorCodes::UNKNOWN_TYPE: + case ErrorCodes::UNKNOWN_STORAGE: + case ErrorCodes::UNKNOWN_DATABASE: + case ErrorCodes::UNKNOWN_SETTING: + case ErrorCodes::UNKNOWN_DIRECTION_OF_SORTING: + case ErrorCodes::UNKNOWN_AGGREGATE_FUNCTION: + case ErrorCodes::UNKNOWN_FORMAT: + case ErrorCodes::UNKNOWN_DATABASE_ENGINE: + + case ErrorCodes::UNKNOWN_TYPE_OF_QUERY: + return HTTPResponse::HTTP_NOT_FOUND; + case ErrorCodes::QUERY_IS_TOO_LARGE: + return HTTPResponse::HTTP_REQUESTENTITYTOOLARGE; + case ErrorCodes::NOT_IMPLEMENTED: + return HTTPResponse::HTTP_NOT_IMPLEMENTED; + case ErrorCodes::SOCKET_TIMEOUT: + case ErrorCodes::CANNOT_OPEN_FILE: + return HTTPResponse::HTTP_SERVICE_UNAVAILABLE; + case ErrorCodes::HTTP_LENGTH_REQUIRED: + return HTTPResponse::HTTP_LENGTH_REQUIRED; + default: + return HTTPResponse::HTTP_INTERNAL_SERVER_ERROR; + } } From 82f304f81e491cbbba164762404a9d3e2a570588 Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Thu, 1 Aug 2019 18:36:12 +0300 Subject: [PATCH 0584/1165] add query 'SYSTEM STOP TTL MERGES' --- dbms/src/DataStreams/TTLBlockInputStream.h | 2 +- dbms/src/Interpreters/ActionLocksManager.cpp | 1 + .../Interpreters/InterpreterSystemQuery.cpp | 7 +++++ dbms/src/Parsers/ASTSystemQuery.cpp | 6 +++++ dbms/src/Parsers/ASTSystemQuery.h | 2 ++ dbms/src/Parsers/ParserSystemQuery.cpp | 2 ++ .../MergeTree/MergeTreeDataMergerMutator.cpp | 26 ++++++++++++++----- .../MergeTree/MergeTreeDataMergerMutator.h | 3 ++- .../ReplicatedMergeTreeAlterThread.cpp | 2 +- .../MergeTree/ReplicatedMergeTreeQueue.cpp | 2 +- dbms/src/Storages/StorageMergeTree.cpp | 17 +++++++----- .../Storages/StorageReplicatedMergeTree.cpp | 8 ++++-- .../00976_system_stop_ttl_merges.reference | 6 +++++ .../00976_system_stop_ttl_merges.sql | 18 +++++++++++++ 14 files changed, 82 insertions(+), 20 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00976_system_stop_ttl_merges.reference create mode 100644 dbms/tests/queries/0_stateless/00976_system_stop_ttl_merges.sql diff --git a/dbms/src/DataStreams/TTLBlockInputStream.h b/dbms/src/DataStreams/TTLBlockInputStream.h index a57c6cf74bf..5ed6aa9e520 100644 --- a/dbms/src/DataStreams/TTLBlockInputStream.h +++ b/dbms/src/DataStreams/TTLBlockInputStream.h @@ -20,7 +20,7 @@ public: bool force_ ); - String getName() const override { return "TTLBlockInputStream"; } + String getName() const override { return "TTL"; } Block getHeader() const override { return header; } diff --git a/dbms/src/Interpreters/ActionLocksManager.cpp b/dbms/src/Interpreters/ActionLocksManager.cpp index 1f9329f85a9..56e0e37c432 100644 --- a/dbms/src/Interpreters/ActionLocksManager.cpp +++ b/dbms/src/Interpreters/ActionLocksManager.cpp @@ -14,6 +14,7 @@ namespace ActionLocks extern const StorageActionBlockType PartsSend = 3; extern const StorageActionBlockType ReplicationQueue = 4; extern const StorageActionBlockType DistributedSend = 5; + extern const StorageActionBlockType PartsTTLMerge = 6; } diff --git a/dbms/src/Interpreters/InterpreterSystemQuery.cpp b/dbms/src/Interpreters/InterpreterSystemQuery.cpp index 16d6fe5ff93..b15479704f8 100644 --- a/dbms/src/Interpreters/InterpreterSystemQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSystemQuery.cpp @@ -46,6 +46,7 @@ namespace ActionLocks extern StorageActionBlockType PartsSend; extern StorageActionBlockType ReplicationQueue; extern StorageActionBlockType DistributedSend; + extern StorageActionBlockType PartsTTLMerge; } @@ -180,6 +181,12 @@ BlockIO InterpreterSystemQuery::execute() case Type::START_MERGES: startStopAction(context, query, ActionLocks::PartsMerge, true); break; + case Type::STOP_TTL_MERGES: + startStopAction(context, query, ActionLocks::PartsTTLMerge, false); + break; + case Type::START_TTL_MERGES: + startStopAction(context, query, ActionLocks::PartsTTLMerge, true); + break; case Type::STOP_FETCHES: startStopAction(context, query, ActionLocks::PartsFetch, false); break; diff --git a/dbms/src/Parsers/ASTSystemQuery.cpp b/dbms/src/Parsers/ASTSystemQuery.cpp index 699dd9d0f54..115a922dc99 100644 --- a/dbms/src/Parsers/ASTSystemQuery.cpp +++ b/dbms/src/Parsers/ASTSystemQuery.cpp @@ -55,6 +55,10 @@ const char * ASTSystemQuery::typeToString(Type type) return "STOP MERGES"; case Type::START_MERGES: return "START MERGES"; + case Type::STOP_TTL_MERGES: + return "STOP TTL MERGES"; + case Type::START_TTL_MERGES: + return "START TTL MERGES"; case Type::STOP_FETCHES: return "STOP FETCHES"; case Type::START_FETCHES: @@ -100,6 +104,8 @@ void ASTSystemQuery::formatImpl(const FormatSettings & settings, FormatState &, if ( type == Type::STOP_MERGES || type == Type::START_MERGES + || type == Type::STOP_TTL_MERGES + || type == Type::START_TTL_MERGES || type == Type::STOP_FETCHES || type == Type::START_FETCHES || type == Type::STOP_REPLICATED_SENDS diff --git a/dbms/src/Parsers/ASTSystemQuery.h b/dbms/src/Parsers/ASTSystemQuery.h index eef7a38425b..3418bccd350 100644 --- a/dbms/src/Parsers/ASTSystemQuery.h +++ b/dbms/src/Parsers/ASTSystemQuery.h @@ -33,6 +33,8 @@ public: RELOAD_CONFIG, STOP_MERGES, START_MERGES, + STOP_TTL_MERGES, + START_TTL_MERGES, STOP_FETCHES, START_FETCHES, STOP_REPLICATED_SENDS, diff --git a/dbms/src/Parsers/ParserSystemQuery.cpp b/dbms/src/Parsers/ParserSystemQuery.cpp index 333613e9512..57263c65601 100644 --- a/dbms/src/Parsers/ParserSystemQuery.cpp +++ b/dbms/src/Parsers/ParserSystemQuery.cpp @@ -56,6 +56,8 @@ bool ParserSystemQuery::parseImpl(IParser::Pos & pos, ASTPtr & node, Expected & case Type::STOP_MERGES: case Type::START_MERGES: + case Type::STOP_TTL_MERGES: + case Type::START_TTL_MERGES: case Type::STOP_FETCHES: case Type::START_FETCHES: case Type::STOP_REPLICATED_SENDS: diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp index 2b17475801f..3a4d4038317 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp @@ -226,7 +226,7 @@ bool MergeTreeDataMergerMutator::selectPartsToMerge( (current_time - last_merge_with_ttl > data.settings.merge_with_ttl_timeout); /// NOTE Could allow selection of different merge strategy. - if (can_merge_with_ttl && has_part_with_expired_ttl) + if (can_merge_with_ttl && has_part_with_expired_ttl && !ttl_merges_blocker.isCancelled()) { merge_selector = std::make_unique(current_time); last_merge_with_ttl = current_time; @@ -526,7 +526,7 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mergePartsToTempor { static const String TMP_PREFIX = "tmp_merge_"; - if (actions_blocker.isCancelled()) + if (merges_blocker.isCancelled()) throw Exception("Cancelled merging parts", ErrorCodes::ABORTED); const MergeTreeData::DataPartsVector & parts = future_part.parts; @@ -568,6 +568,12 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mergePartsToTempor if (part_min_ttl && part_min_ttl <= time_of_merge) need_remove_expired_values = true; + if (need_remove_expired_values && ttl_merges_blocker.isCancelled()) + { + LOG_INFO(log, "Part " << new_data_part->name << " has values with expired TTL, but merges with TTL are cancelled."); + need_remove_expired_values = false; + } + MergeAlgorithm merge_alg = chooseMergeAlgorithm(parts, sum_input_rows_upper_bound, gathering_columns, deduplicate, need_remove_expired_values); LOG_DEBUG(log, "Selected MergeAlgorithm: " << ((merge_alg == MergeAlgorithm::Vertical) ? "Vertical" : "Horizontal")); @@ -723,8 +729,11 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mergePartsToTempor size_t rows_written = 0; const size_t initial_reservation = disk_reservation ? disk_reservation->getSize() : 0; + auto is_cancelled = [&]() { return merges_blocker.isCancelled() + || (need_remove_expired_values && ttl_merges_blocker.isCancelled()); }; + Block block; - while (!actions_blocker.isCancelled() && (block = merged_stream->read())) + while (!is_cancelled() && (block = merged_stream->read())) { rows_written += block.rows(); @@ -748,9 +757,12 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mergePartsToTempor merged_stream->readSuffix(); merged_stream.reset(); - if (actions_blocker.isCancelled()) + if (merges_blocker.isCancelled()) throw Exception("Cancelled merging parts", ErrorCodes::ABORTED); + if (need_remove_expired_values && ttl_merges_blocker.isCancelled()) + throw Exception("Cancelled merging parts with expired TTL", ErrorCodes::ABORTED); + MergeTreeData::DataPart::Checksums checksums_gathered_columns; /// Gather ordinary columns @@ -814,13 +826,13 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mergePartsToTempor size_t column_elems_written = 0; column_to.writePrefix(); - while (!actions_blocker.isCancelled() && (block = column_gathered_stream.read())) + while (!merges_blocker.isCancelled() && (block = column_gathered_stream.read())) { column_elems_written += block.rows(); column_to.write(block); } - if (actions_blocker.isCancelled()) + if (merges_blocker.isCancelled()) throw Exception("Cancelled merging parts", ErrorCodes::ABORTED); column_gathered_stream.readSuffix(); @@ -874,7 +886,7 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mutatePartToTempor { auto check_not_cancelled = [&]() { - if (actions_blocker.isCancelled() || merge_entry->is_cancelled) + if (merges_blocker.isCancelled() || merge_entry->is_cancelled) throw Exception("Cancelled mutating parts", ErrorCodes::ABORTED); return true; diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.h b/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.h index a380b5c2bc2..43e3cd15910 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.h +++ b/dbms/src/Storages/MergeTree/MergeTreeDataMergerMutator.h @@ -120,7 +120,8 @@ public: /** Is used to cancel all merges and mutations. On cancel() call all currently running actions will throw exception soon. * All new attempts to start a merge or mutation will throw an exception until all 'LockHolder' objects will be destroyed. */ - ActionBlocker actions_blocker; + ActionBlocker merges_blocker; + ActionBlocker ttl_merges_blocker; enum class MergeAlgorithm { diff --git a/dbms/src/Storages/MergeTree/ReplicatedMergeTreeAlterThread.cpp b/dbms/src/Storages/MergeTree/ReplicatedMergeTreeAlterThread.cpp index 07d3122f29e..fd0c3ace0ab 100644 --- a/dbms/src/Storages/MergeTree/ReplicatedMergeTreeAlterThread.cpp +++ b/dbms/src/Storages/MergeTree/ReplicatedMergeTreeAlterThread.cpp @@ -86,7 +86,7 @@ void ReplicatedMergeTreeAlterThread::run() auto metadata_diff = ReplicatedMergeTreeTableMetadata(storage).checkAndFindDiff(metadata_in_zk, /* allow_alter = */ true); /// If you need to lock table structure, then suspend merges. - ActionLock merge_blocker = storage.merger_mutator.actions_blocker.cancel(); + ActionLock merge_blocker = storage.merger_mutator.merges_blocker.cancel(); MergeTreeData::DataParts parts; diff --git a/dbms/src/Storages/MergeTree/ReplicatedMergeTreeQueue.cpp b/dbms/src/Storages/MergeTree/ReplicatedMergeTreeQueue.cpp index 6ce01f7b500..a6be0c3b9a9 100644 --- a/dbms/src/Storages/MergeTree/ReplicatedMergeTreeQueue.cpp +++ b/dbms/src/Storages/MergeTree/ReplicatedMergeTreeQueue.cpp @@ -948,7 +948,7 @@ bool ReplicatedMergeTreeQueue::shouldExecuteLogEntry( sum_parts_size_in_bytes += part->bytes_on_disk; } - if (merger_mutator.actions_blocker.isCancelled()) + if (merger_mutator.merges_blocker.isCancelled()) { String reason = "Not executing log entry for part " + entry.new_part_name + " because merges and mutations are cancelled now."; LOG_DEBUG(log, reason); diff --git a/dbms/src/Storages/StorageMergeTree.cpp b/dbms/src/Storages/StorageMergeTree.cpp index 69020023df5..9c4b6559f39 100644 --- a/dbms/src/Storages/StorageMergeTree.cpp +++ b/dbms/src/Storages/StorageMergeTree.cpp @@ -41,6 +41,7 @@ namespace ErrorCodes namespace ActionLocks { extern const StorageActionBlockType PartsMerge; + extern const StorageActionBlockType PartsTTLMerge; } @@ -104,7 +105,7 @@ void StorageMergeTree::shutdown() if (shutdown_called) return; shutdown_called = true; - merger_mutator.actions_blocker.cancelForever(); + merger_mutator.merges_blocker.cancelForever(); if (background_task_handle) background_pool.removeTask(background_task_handle); } @@ -164,7 +165,7 @@ void StorageMergeTree::truncate(const ASTPtr &, const Context &) { /// Asks to complete merges and does not allow them to start. /// This protects against "revival" of data for a removed partition after completion of merge. - auto merge_blocker = merger_mutator.actions_blocker.cancel(); + auto merge_blocker = merger_mutator.merges_blocker.cancel(); /// NOTE: It's assumed that this method is called under lockForAlter. @@ -252,7 +253,7 @@ void StorageMergeTree::alter( } /// NOTE: Here, as in ReplicatedMergeTree, you can do ALTER which does not block the writing of data for a long time. - auto merge_blocker = merger_mutator.actions_blocker.cancel(); + auto merge_blocker = merger_mutator.merges_blocker.cancel(); lockNewDataStructureExclusively(table_lock_holder, context.getCurrentQueryId()); @@ -734,7 +735,7 @@ BackgroundProcessingPoolTaskResult StorageMergeTree::backgroundTask() if (shutdown_called) return BackgroundProcessingPoolTaskResult::ERROR; - if (merger_mutator.actions_blocker.isCancelled()) + if (merger_mutator.merges_blocker.isCancelled()) return BackgroundProcessingPoolTaskResult::ERROR; try @@ -829,7 +830,7 @@ void StorageMergeTree::clearColumnInPartition(const ASTPtr & partition, const Fi { /// Asks to complete merges and does not allow them to start. /// This protects against "revival" of data for a removed partition after completion of merge. - auto merge_blocker = merger_mutator.actions_blocker.cancel(); + auto merge_blocker = merger_mutator.merges_blocker.cancel(); /// We don't change table structure, only data in some parts, parts are locked inside alterDataPart() function auto lock_read_structure = lockStructureForShare(false, context.getCurrentQueryId()); @@ -986,7 +987,7 @@ void StorageMergeTree::dropPartition(const ASTPtr & partition, bool detach, cons { /// Asks to complete merges and does not allow them to start. /// This protects against "revival" of data for a removed partition after completion of merge. - auto merge_blocker = merger_mutator.actions_blocker.cancel(); + auto merge_blocker = merger_mutator.merges_blocker.cancel(); /// Waits for completion of merge and does not start new ones. auto lock = lockExclusively(context.getCurrentQueryId()); @@ -1144,7 +1145,9 @@ void StorageMergeTree::replacePartitionFrom(const StoragePtr & source_table, con ActionLock StorageMergeTree::getActionLock(StorageActionBlockType action_type) { if (action_type == ActionLocks::PartsMerge) - return merger_mutator.actions_blocker.cancel(); + return merger_mutator.merges_blocker.cancel(); + else if (action_type == ActionLocks::PartsTTLMerge) + return merger_mutator.ttl_merges_blocker.cancel(); return {}; } diff --git a/dbms/src/Storages/StorageReplicatedMergeTree.cpp b/dbms/src/Storages/StorageReplicatedMergeTree.cpp index 8492dd2c007..302e6743db1 100644 --- a/dbms/src/Storages/StorageReplicatedMergeTree.cpp +++ b/dbms/src/Storages/StorageReplicatedMergeTree.cpp @@ -118,6 +118,7 @@ namespace ActionLocks extern const StorageActionBlockType PartsFetch; extern const StorageActionBlockType PartsSend; extern const StorageActionBlockType ReplicationQueue; + extern const StorageActionBlockType PartsTTLMerge; } @@ -2860,7 +2861,7 @@ void StorageReplicatedMergeTree::shutdown() { /// Cancel fetches, merges and mutations to force the queue_task to finish ASAP. fetcher.blocker.cancelForever(); - merger_mutator.actions_blocker.cancelForever(); + merger_mutator.merges_blocker.cancelForever(); restarting_thread.shutdown(); @@ -5029,7 +5030,10 @@ ReplicatedMergeTreeAddress StorageReplicatedMergeTree::getReplicatedMergeTreeAdd ActionLock StorageReplicatedMergeTree::getActionLock(StorageActionBlockType action_type) { if (action_type == ActionLocks::PartsMerge) - return merger_mutator.actions_blocker.cancel(); + return merger_mutator.merges_blocker.cancel(); + + if (action_type == ActionLocks::PartsTTLMerge) + return merger_mutator.ttl_merges_blocker.cancel(); if (action_type == ActionLocks::PartsFetch) return fetcher.blocker.cancel(); diff --git a/dbms/tests/queries/0_stateless/00976_system_stop_ttl_merges.reference b/dbms/tests/queries/0_stateless/00976_system_stop_ttl_merges.reference new file mode 100644 index 00000000000..07c0a1ee521 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00976_system_stop_ttl_merges.reference @@ -0,0 +1,6 @@ +2000-10-10 1 +2000-10-10 2 +2100-10-10 3 +2100-10-10 4 +2100-10-10 3 +2100-10-10 4 diff --git a/dbms/tests/queries/0_stateless/00976_system_stop_ttl_merges.sql b/dbms/tests/queries/0_stateless/00976_system_stop_ttl_merges.sql new file mode 100644 index 00000000000..41f2428d9e6 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00976_system_stop_ttl_merges.sql @@ -0,0 +1,18 @@ +drop table if exists ttl; + +create table ttl (d Date, a Int) engine = MergeTree order by a partition by toDayOfMonth(d) ttl d + interval 1 day; + +system stop ttl merges; + +insert into ttl values (toDateTime('2000-10-10 00:00:00'), 1), (toDateTime('2000-10-10 00:00:00'), 2) +insert into ttl values (toDateTime('2100-10-10 00:00:00'), 3), (toDateTime('2100-10-10 00:00:00'), 4); + +select sleep(1) format Null; -- wait if very fast merge happen +optimize table ttl partition 10 final; +select * from ttl order by d, a; + +system start ttl merges; +optimize table ttl partition 10 final; +select * from ttl order by d, a; + +drop table if exists ttl; From 241751542e58bc5658eb89b721795f057d87ee5b Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Thu, 1 Aug 2019 19:37:50 +0300 Subject: [PATCH 0585/1165] CamelCase --- dbms/src/Interpreters/PartLog.cpp | 10 +++++----- dbms/src/Interpreters/QueryLog.cpp | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dbms/src/Interpreters/PartLog.cpp b/dbms/src/Interpreters/PartLog.cpp index 1b3c6a0224e..a10f6a5cadc 100644 --- a/dbms/src/Interpreters/PartLog.cpp +++ b/dbms/src/Interpreters/PartLog.cpp @@ -22,11 +22,11 @@ Block PartLogElement::createBlock() auto event_type_datatype = std::make_shared( DataTypeEnum8::Values { - {"New part", static_cast(NEW_PART)}, - {"Merge parts", static_cast(MERGE_PARTS)}, - {"Download part", static_cast(DOWNLOAD_PART)}, - {"Remove part", static_cast(REMOVE_PART)}, - {"Mutate part", static_cast(MUTATE_PART)}, + {"NewPart", static_cast(NEW_PART)}, + {"MergeParts", static_cast(MERGE_PARTS)}, + {"DownloadPart", static_cast(DOWNLOAD_PART)}, + {"RemovePart", static_cast(REMOVE_PART)}, + {"MutatePart", static_cast(MUTATE_PART)}, }); return diff --git a/dbms/src/Interpreters/QueryLog.cpp b/dbms/src/Interpreters/QueryLog.cpp index 27e0c5a602c..52e552d833f 100644 --- a/dbms/src/Interpreters/QueryLog.cpp +++ b/dbms/src/Interpreters/QueryLog.cpp @@ -28,10 +28,10 @@ Block QueryLogElement::createBlock() auto query_status_datatype = std::make_shared( DataTypeEnum8::Values { - {"Query start", static_cast(QUERY_START)}, - {"Query finish", static_cast(QUERY_FINISH)}, - {"Exception before start", static_cast(EXCEPTION_BEFORE_START)}, - {"Exception while processing", static_cast(EXCEPTION_WHILE_PROCESSING)} + {"QueryStart", static_cast(QUERY_START)}, + {"QueryFinish", static_cast(QUERY_FINISH)}, + {"ExceptionBeforeStart", static_cast(EXCEPTION_BEFORE_START)}, + {"ExceptionWhileProcessing", static_cast(EXCEPTION_WHILE_PROCESSING)} }); return From 011150fa8a62fc6e1f22b43527dc82107d71f0eb Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov Date: Thu, 1 Aug 2019 18:57:02 +0300 Subject: [PATCH 0586/1165] Make PairNoInit a simple struct. --- .../AggregateFunctionEntropy.h | 2 +- .../QuantileExactWeighted.h | 16 +++++------ dbms/src/Common/ColumnsHashing.h | 6 ++-- dbms/src/Common/ColumnsHashingImpl.h | 14 +++++----- dbms/src/Common/HashTable/HashMap.h | 28 ++++++++----------- dbms/src/Interpreters/Aggregator.h | 12 ++++---- dbms/src/Interpreters/tests/hash_map3.cpp | 2 +- 7 files changed, 38 insertions(+), 42 deletions(-) diff --git a/dbms/src/AggregateFunctions/AggregateFunctionEntropy.h b/dbms/src/AggregateFunctions/AggregateFunctionEntropy.h index 720dd12d2da..97433a8de02 100644 --- a/dbms/src/AggregateFunctions/AggregateFunctionEntropy.h +++ b/dbms/src/AggregateFunctions/AggregateFunctionEntropy.h @@ -68,7 +68,7 @@ struct EntropyData while (reader.next()) { const auto & pair = reader.get(); - map[pair.getFirst()] = pair.getSecond(); + map[pair.first] = pair.second; } } diff --git a/dbms/src/AggregateFunctions/QuantileExactWeighted.h b/dbms/src/AggregateFunctions/QuantileExactWeighted.h index a3a4c972931..31a485ef695 100644 --- a/dbms/src/AggregateFunctions/QuantileExactWeighted.h +++ b/dbms/src/AggregateFunctions/QuantileExactWeighted.h @@ -72,7 +72,7 @@ struct QuantileExactWeighted while (reader.next()) { const auto & pair = reader.get(); - map[pair.getFirst()] = pair.getSecond(); + map[pair.first] = pair.second; } } @@ -98,7 +98,7 @@ struct QuantileExactWeighted ++i; } - std::sort(array, array + size, [](const Pair & a, const Pair & b) { return a.getFirst() < b.getFirst(); }); + std::sort(array, array + size, [](const Pair & a, const Pair & b) { return a.first < b.first; }); UInt64 threshold = std::ceil(sum_weight * level); UInt64 accumulated = 0; @@ -107,7 +107,7 @@ struct QuantileExactWeighted const Pair * end = array + size; while (it < end) { - accumulated += it->getSecond(); + accumulated += it->second; if (accumulated >= threshold) break; @@ -118,7 +118,7 @@ struct QuantileExactWeighted if (it == end) --it; - return it->getFirst(); + return it->first; } /// Get the `size` values of `levels` quantiles. Write `size` results starting with `result` address. @@ -148,7 +148,7 @@ struct QuantileExactWeighted ++i; } - std::sort(array, array + size, [](const Pair & a, const Pair & b) { return a.getFirst() < b.getFirst(); }); + std::sort(array, array + size, [](const Pair & a, const Pair & b) { return a.first < b.first; }); UInt64 accumulated = 0; @@ -160,11 +160,11 @@ struct QuantileExactWeighted while (it < end) { - accumulated += it->getSecond(); + accumulated += it->second; while (accumulated >= threshold) { - result[indices[level_index]] = it->getFirst(); + result[indices[level_index]] = it->first; ++level_index; if (level_index == num_levels) @@ -178,7 +178,7 @@ struct QuantileExactWeighted while (level_index < num_levels) { - result[indices[level_index]] = array[size - 1].getFirst(); + result[indices[level_index]] = array[size - 1].first; ++level_index; } } diff --git a/dbms/src/Common/ColumnsHashing.h b/dbms/src/Common/ColumnsHashing.h index d3cdc62aa47..661f6527d8e 100644 --- a/dbms/src/Common/ColumnsHashing.h +++ b/dbms/src/Common/ColumnsHashing.h @@ -61,7 +61,7 @@ struct HashMethodOneNumber /// Get StringRef from value which can be inserted into column. static StringRef getValueRef(const Value & value) { - return StringRef(reinterpret_cast(&value.getFirst()), sizeof(value.getFirst())); + return StringRef(reinterpret_cast(&value.first), sizeof(value.first)); } }; @@ -90,7 +90,7 @@ struct HashMethodString return StringRef(chars + offsets[row - 1], offsets[row] - offsets[row - 1] - 1); } - static StringRef getValueRef(const Value & value) { return StringRef(value.getFirst().data, value.getFirst().size); } + static StringRef getValueRef(const Value & value) { return value.first; } protected: friend class columns_hashing_impl::HashMethodBase; @@ -127,7 +127,7 @@ struct HashMethodFixedString StringRef getKey(size_t row, Arena &) const { return StringRef(&(*chars)[row * n], n); } - static StringRef getValueRef(const Value & value) { return StringRef(value.getFirst().data, value.getFirst().size); } + static StringRef getValueRef(const Value & value) { return value.first; } protected: friend class columns_hashing_impl::HashMethodBase; diff --git a/dbms/src/Common/ColumnsHashingImpl.h b/dbms/src/Common/ColumnsHashingImpl.h index d7e9010862e..2a6cdb6cd69 100644 --- a/dbms/src/Common/ColumnsHashingImpl.h +++ b/dbms/src/Common/ColumnsHashingImpl.h @@ -39,7 +39,7 @@ struct LastElementCache bool check(const Value & value_) { return !empty && value == value_; } template - bool check(const Key & key) { return !empty && value.getFirst() == key; } + bool check(const Key & key) { return !empty && value.first == key; } }; template @@ -147,8 +147,8 @@ protected: if constexpr (has_mapped) { /// Init PairNoInit elements. - cache.value.getSecond() = Mapped(); - cache.value.getFirstMutable() = {}; + cache.value.second = Mapped(); + cache.value.first = {}; } else cache.value = Value(); @@ -170,7 +170,7 @@ protected: static_cast(*this).onExistingKey(key, pool); if constexpr (has_mapped) - return EmplaceResult(cache.value.getSecond(), cache.value.getSecond(), false); + return EmplaceResult(cache.value.second, cache.value.second, false); else return EmplaceResult(false); } @@ -204,7 +204,7 @@ protected: cache.empty = false; if constexpr (has_mapped) - cached = &cache.value.getSecond(); + cached = &cache.value.second; } if constexpr (has_mapped) @@ -221,7 +221,7 @@ protected: if (cache.check(key)) { if constexpr (has_mapped) - return FindResult(&cache.value.getSecond(), cache.found); + return FindResult(&cache.value.second, cache.found); else return FindResult(cache.found); } @@ -240,7 +240,7 @@ protected: else { if constexpr (has_mapped) - cache.value.getFirstMutable() = key; + cache.value.first = key; else cache.value = key; } diff --git a/dbms/src/Common/HashTable/HashMap.h b/dbms/src/Common/HashTable/HashMap.h index 445b2a9887c..f82563c4449 100644 --- a/dbms/src/Common/HashTable/HashMap.h +++ b/dbms/src/Common/HashTable/HashMap.h @@ -11,32 +11,28 @@ */ -struct NoInitTag {}; +struct NoInitTag +{ +}; /// A pair that does not initialize the elements, if not needed. template -class PairNoInit +struct PairNoInit { First first; Second second; - template - friend class HashMapCell; -public: PairNoInit() {} template - PairNoInit(First_ && first_, NoInitTag) - : first(std::forward(first_)) {} + PairNoInit(First_ && first_, NoInitTag) : first(std::forward(first_)) + { + } template - PairNoInit(First_ && first_, Second_ && second_) - : first(std::forward(first_)), second(std::forward(second_)) {} - - First & getFirstMutable() { return first; } - const First & getFirst() const { return first; } - Second & getSecond() { return second; } - const Second & getSecond() const { return second; } + PairNoInit(First_ && first_, Second_ && second_) : first(std::forward(first_)), second(std::forward(second_)) + { + } }; @@ -123,8 +119,8 @@ struct HashMapCellWithSavedHash : public HashMapCell using Base::Base; - bool keyEquals(const Key & key_) const { return this->value.getFirst() == key_; } - bool keyEquals(const Key & key_, size_t hash_) const { return saved_hash == hash_ && this->value.getFirst() == key_; } + bool keyEquals(const Key & key_) const { return this->value.first == key_; } + bool keyEquals(const Key & key_, size_t hash_) const { return saved_hash == hash_ && this->value.first == key_; } bool keyEquals(const Key & key_, size_t hash_, const typename Base::State &) const { return keyEquals(key_, hash_); } void setHash(size_t hash_value) { saved_hash = hash_value; } diff --git a/dbms/src/Interpreters/Aggregator.h b/dbms/src/Interpreters/Aggregator.h index 8c67271b1d5..e47bd622016 100644 --- a/dbms/src/Interpreters/Aggregator.h +++ b/dbms/src/Interpreters/Aggregator.h @@ -180,7 +180,7 @@ struct AggregationMethodOneNumber // Insert the key from the hash table into columns. static void insertKeyIntoColumns(const typename Data::value_type & value, MutableColumns & key_columns, const Sizes & /*key_sizes*/) { - static_cast(key_columns[0].get())->insertRawData(reinterpret_cast(&value.getFirst())); + static_cast(key_columns[0].get())->insertRawData(reinterpret_cast(&value.first)); } }; @@ -208,7 +208,7 @@ struct AggregationMethodString static void insertKeyIntoColumns(const typename Data::value_type & value, MutableColumns & key_columns, const Sizes &) { - key_columns[0]->insertData(value.getFirst().data, value.getFirst().size); + key_columns[0]->insertData(value.first.data, value.first.size); } }; @@ -236,7 +236,7 @@ struct AggregationMethodFixedString static void insertKeyIntoColumns(const typename Data::value_type & value, MutableColumns & key_columns, const Sizes &) { - key_columns[0]->insertData(value.getFirst().data, value.getFirst().size); + key_columns[0]->insertData(value.first.data, value.first.size); } }; @@ -332,7 +332,7 @@ struct AggregationMethodKeysFixed /// corresponding key is nullable. Update the null map accordingly. size_t bucket = i / 8; size_t offset = i % 8; - UInt8 val = (reinterpret_cast(&value.getFirst())[bucket] >> offset) & 1; + UInt8 val = (reinterpret_cast(&value.first)[bucket] >> offset) & 1; null_map->insertValue(val); is_null = val == 1; } @@ -342,7 +342,7 @@ struct AggregationMethodKeysFixed else { size_t size = key_sizes[i]; - observed_column->insertData(reinterpret_cast(&value.getFirst()) + pos, size); + observed_column->insertData(reinterpret_cast(&value.first) + pos, size); pos += size; } } @@ -377,7 +377,7 @@ struct AggregationMethodSerialized static void insertKeyIntoColumns(const typename Data::value_type & value, MutableColumns & key_columns, const Sizes &) { - auto pos = value.getFirst().data; + auto pos = value.first.data; for (auto & column : key_columns) pos = column->deserializeAndInsertFromArena(pos); } diff --git a/dbms/src/Interpreters/tests/hash_map3.cpp b/dbms/src/Interpreters/tests/hash_map3.cpp index 8b32db85e70..4b076152b07 100644 --- a/dbms/src/Interpreters/tests/hash_map3.cpp +++ b/dbms/src/Interpreters/tests/hash_map3.cpp @@ -38,7 +38,7 @@ public: if (this->buf[i].isZero(*this)) std::cerr << "[ ]"; else - std::cerr << '[' << this->buf[i].getValue().getFirst().data << ", " << this->buf[i].getValue().getSecond() << ']'; + std::cerr << '[' << this->buf[i].getValue().first.data << ", " << this->buf[i].getValue().second << ']'; } std::cerr << std::endl; } From 5b4b875497a20e5a19ef8bb836b19459186fe382 Mon Sep 17 00:00:00 2001 From: alesapin Date: Thu, 1 Aug 2019 20:03:34 +0300 Subject: [PATCH 0587/1165] Fix bool settings parsing in config --- dbms/src/Core/SettingsCommon.cpp | 11 +++++++ .../__init__.py | 0 .../configs/notleader.xml | 5 +++ .../test_replica_can_become_leader/test.py | 33 +++++++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 dbms/tests/integration/test_replica_can_become_leader/__init__.py create mode 100644 dbms/tests/integration/test_replica_can_become_leader/configs/notleader.xml create mode 100644 dbms/tests/integration/test_replica_can_become_leader/test.py diff --git a/dbms/src/Core/SettingsCommon.cpp b/dbms/src/Core/SettingsCommon.cpp index 8f56a6d1454..f1e6d6016ea 100644 --- a/dbms/src/Core/SettingsCommon.cpp +++ b/dbms/src/Core/SettingsCommon.cpp @@ -63,6 +63,17 @@ void SettingNumber::set(const String & x) set(parse(x)); } +template <> +void SettingNumber::set(const String & x) +{ + if (x == "false") + set(false); + else if (x == "true") + set(true); + else + set(parse(x)); +} + template void SettingNumber::serialize(WriteBuffer & buf) const { diff --git a/dbms/tests/integration/test_replica_can_become_leader/__init__.py b/dbms/tests/integration/test_replica_can_become_leader/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dbms/tests/integration/test_replica_can_become_leader/configs/notleader.xml b/dbms/tests/integration/test_replica_can_become_leader/configs/notleader.xml new file mode 100644 index 00000000000..9905191d955 --- /dev/null +++ b/dbms/tests/integration/test_replica_can_become_leader/configs/notleader.xml @@ -0,0 +1,5 @@ + + + false + + diff --git a/dbms/tests/integration/test_replica_can_become_leader/test.py b/dbms/tests/integration/test_replica_can_become_leader/test.py new file mode 100644 index 00000000000..b4c1d8f309c --- /dev/null +++ b/dbms/tests/integration/test_replica_can_become_leader/test.py @@ -0,0 +1,33 @@ +import pytest + +from helpers.cluster import ClickHouseCluster + +cluster = ClickHouseCluster(__file__) +node1 = cluster.add_instance('node1', main_configs=['configs/notleader.xml'], with_zookeeper=True) +node2 = cluster.add_instance('node2', with_zookeeper=True) +node3 = cluster.add_instance('node3', with_zookeeper=True) + +@pytest.fixture(scope="module") +def start_cluster(): + try: + cluster.start() + + for i, node in enumerate((node1, node2, node3)): + node.query( + ''' + CREATE TABLE test_table(date Date, id UInt32, dummy UInt32) + ENGINE = ReplicatedMergeTree('/clickhouse/tables/test_table', '{}') + PARTITION BY date ORDER BY id + '''.format(i) + ) + + yield cluster + + finally: + cluster.shutdown() + + +def test_can_become_leader(start_cluster): + assert node1.query("select can_become_leader from system.replicas where table = 'test_table'") == '0\n' + assert node2.query("select can_become_leader from system.replicas where table = 'test_table'") == '1\n' + assert node3.query("select can_become_leader from system.replicas where table = 'test_table'") == '1\n' From 4072214b5d7cb659ed4f3472a6894a62a03cb048 Mon Sep 17 00:00:00 2001 From: chertus Date: Thu, 1 Aug 2019 20:27:51 +0300 Subject: [PATCH 0588/1165] fix UB in join keys order --- dbms/src/Interpreters/AnalyzedJoin.cpp | 6 +-- dbms/src/Interpreters/AnalyzedJoin.h | 2 +- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 17 +++------ dbms/src/Interpreters/Join.cpp | 39 ++++++-------------- dbms/src/Interpreters/SubqueryForSet.cpp | 6 +-- dbms/src/Interpreters/SubqueryForSet.h | 4 +- 6 files changed, 27 insertions(+), 47 deletions(-) diff --git a/dbms/src/Interpreters/AnalyzedJoin.cpp b/dbms/src/Interpreters/AnalyzedJoin.cpp index 8357ab80aba..265f3404b80 100644 --- a/dbms/src/Interpreters/AnalyzedJoin.cpp +++ b/dbms/src/Interpreters/AnalyzedJoin.cpp @@ -126,14 +126,14 @@ NameSet AnalyzedJoin::getOriginalColumnsSet() const return out; } -std::unordered_map AnalyzedJoin::getOriginalColumnsMap(const NameSet & required_columns) const +Names AnalyzedJoin::getOriginalColumnNames(const Names & required_columns) const { - std::unordered_map out; + Names out; for (const auto & column : required_columns) { auto it = original_names.find(column); if (it != original_names.end()) - out.insert(*it); + out.push_back(it->second); } return out; } diff --git a/dbms/src/Interpreters/AnalyzedJoin.h b/dbms/src/Interpreters/AnalyzedJoin.h index d820cb0da7b..5fe47ada2e4 100644 --- a/dbms/src/Interpreters/AnalyzedJoin.h +++ b/dbms/src/Interpreters/AnalyzedJoin.h @@ -61,7 +61,7 @@ public: NameSet getQualifiedColumnsSet() const; NameSet getOriginalColumnsSet() const; - std::unordered_map getOriginalColumnsMap(const NameSet & required_columns) const; + Names getOriginalColumnNames(const Names & required_columns) const; void deduplicateAndQualifyColumnNames(const NameSet & left_table_columns, const String & right_table_prefix); void calculateAvailableJoinedColumns(bool make_nullable); diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index 79ff40956b5..a62a1ddbf9d 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -516,15 +516,15 @@ void ExpressionAnalyzer::addJoinAction(ExpressionActionsPtr & actions, bool only } static void appendRequiredColumns( - NameSet & required_columns, const Block & sample, const Names & key_names_right, const NamesAndTypesList & columns_added_by_join) + Names & required_columns, const Block & sample, const Names & key_names_right, const NamesAndTypesList & columns_added_by_join) { for (auto & column : key_names_right) if (!sample.has(column)) - required_columns.insert(column); + required_columns.push_back(column); for (auto & column : columns_added_by_join) if (!sample.has(column.name)) - required_columns.insert(column.name); + required_columns.push_back(column.name); } bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_types) @@ -606,20 +606,15 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty else if (table_to_join.database_and_table_name) table = table_to_join.database_and_table_name; - Names action_columns = joined_block_actions->getRequiredColumns(); - NameSet required_columns(action_columns.begin(), action_columns.end()); + Names required_columns = joined_block_actions->getRequiredColumns(); appendRequiredColumns( required_columns, joined_block_actions->getSampleBlock(), analyzed_join.key_names_right, columns_added_by_join); - auto original_map = analyzed_join.getOriginalColumnsMap(required_columns); - Names original_columns; - for (auto & pr : original_map) - original_columns.push_back(pr.second); - + Names original_columns = analyzed_join.getOriginalColumnNames(required_columns); auto interpreter = interpretSubquery(table, context, subquery_depth, original_columns); - subquery_for_set.makeSource(interpreter, original_map); + subquery_for_set.makeSource(interpreter, original_columns, required_columns); } Block sample_block = subquery_for_set.renamedSampleBlock(); diff --git a/dbms/src/Interpreters/Join.cpp b/dbms/src/Interpreters/Join.cpp index f482aa5fdbd..2f9044cf519 100644 --- a/dbms/src/Interpreters/Join.cpp +++ b/dbms/src/Interpreters/Join.cpp @@ -275,18 +275,21 @@ void Join::setSampleBlock(const Block & block) size_t keys_size = key_names_right.size(); ColumnRawPtrs key_columns(keys_size); - Columns materialized_columns; + + sample_block_with_columns_to_add = materializeBlock(block); for (size_t i = 0; i < keys_size; ++i) { - auto & column = block.getByName(key_names_right[i]).column; - key_columns[i] = column.get(); - auto column_no_lc = recursiveRemoveLowCardinality(column); - if (column.get() != column_no_lc.get()) - { - materialized_columns.emplace_back(std::move(column_no_lc)); - key_columns[i] = materialized_columns.back().get(); - } + const String & column_name = key_names_right[i]; + auto & col = sample_block_with_columns_to_add.getByName(column_name); + col.column = recursiveRemoveLowCardinality(col.column); + col.type = recursiveRemoveLowCardinality(col.type); + + /// Extract right keys with correct keys order. + sample_block_with_keys.insert(col); + sample_block_with_columns_to_add.erase(column_name); + + key_columns[i] = sample_block_with_keys.getColumns().back().get(); /// We will join only keys, where all components are not NULL. if (auto * nullable = checkAndGetColumn(*key_columns[i])) @@ -327,27 +330,9 @@ void Join::setSampleBlock(const Block & block) init(chooseMethod(key_columns, key_sizes)); } - - sample_block_with_columns_to_add = materializeBlock(block); - blocklist_sample = Block(block.getColumnsWithTypeAndName()); prepareBlockListStructure(blocklist_sample); - /// Move from `sample_block_with_columns_to_add` key columns to `sample_block_with_keys`, keeping the order. - for (size_t pos = 0; pos < sample_block_with_columns_to_add.columns();) - { - auto & col = sample_block_with_columns_to_add.getByPosition(pos); - if (key_names_right.end() != std::find(key_names_right.begin(), key_names_right.end(), col.name)) - { - col.column = recursiveRemoveLowCardinality(col.column); - col.type = recursiveRemoveLowCardinality(col.type); - sample_block_with_keys.insert(col); - sample_block_with_columns_to_add.erase(pos); - } - else - ++pos; - } - size_t num_columns_to_add = sample_block_with_columns_to_add.columns(); for (size_t i = 0; i < num_columns_to_add; ++i) diff --git a/dbms/src/Interpreters/SubqueryForSet.cpp b/dbms/src/Interpreters/SubqueryForSet.cpp index f6528bf110c..4bad82c4b91 100644 --- a/dbms/src/Interpreters/SubqueryForSet.cpp +++ b/dbms/src/Interpreters/SubqueryForSet.cpp @@ -7,13 +7,13 @@ namespace DB { void SubqueryForSet::makeSource(std::shared_ptr & interpreter, - const std::unordered_map & name_to_origin) + const Names & original_names, const Names & required_names) { source = std::make_shared(interpreter->getSampleBlock(), [interpreter]() mutable { return interpreter->execute().in; }); - for (const auto & names : name_to_origin) - joined_block_aliases.emplace_back(names.second, names.first); + for (size_t i = 0; i < original_names.size(); ++i) + joined_block_aliases.emplace_back(original_names[i], required_names[i]); sample_block = source->getHeader(); for (const auto & name_with_alias : joined_block_aliases) diff --git a/dbms/src/Interpreters/SubqueryForSet.h b/dbms/src/Interpreters/SubqueryForSet.h index 1844f686f0a..932b9f160da 100644 --- a/dbms/src/Interpreters/SubqueryForSet.h +++ b/dbms/src/Interpreters/SubqueryForSet.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -12,7 +13,6 @@ class Join; using JoinPtr = std::shared_ptr; class InterpreterSelectWithUnionQuery; -struct AnalyzedJoin; /// Information on what to do when executing a subquery in the [GLOBAL] IN/JOIN section. @@ -32,7 +32,7 @@ struct SubqueryForSet StoragePtr table; void makeSource(std::shared_ptr & interpreter, - const std::unordered_map & name_to_origin); + const Names & original_names, const Names & required_names); Block renamedSampleBlock() const { return sample_block; } void renameColumns(Block & block); From 7c37450c3d6eda4da4119064e0242168ae7cf16d Mon Sep 17 00:00:00 2001 From: alesapin Date: Thu, 1 Aug 2019 20:43:10 +0300 Subject: [PATCH 0589/1165] Better code and tests --- dbms/src/Common/ErrorCodes.cpp | 1 + dbms/src/Core/SettingsCommon.cpp | 25 +++++++++++++++---- .../configs/notleader.xml | 2 +- .../configs/notleaderignorecase.xml | 5 ++++ .../test_replica_can_become_leader/test.py | 17 ++++++++++--- 5 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 dbms/tests/integration/test_replica_can_become_leader/configs/notleaderignorecase.xml diff --git a/dbms/src/Common/ErrorCodes.cpp b/dbms/src/Common/ErrorCodes.cpp index bb1636b7871..56598aa2e89 100644 --- a/dbms/src/Common/ErrorCodes.cpp +++ b/dbms/src/Common/ErrorCodes.cpp @@ -441,6 +441,7 @@ namespace ErrorCodes extern const int CANNOT_PARSE_ELF = 464; extern const int CANNOT_PARSE_DWARF = 465; extern const int INSECURE_PATH = 466; + extern const int CANNOT_PARSE_BOOL = 467; extern const int KEEPER_EXCEPTION = 999; extern const int POCO_EXCEPTION = 1000; diff --git a/dbms/src/Core/SettingsCommon.cpp b/dbms/src/Core/SettingsCommon.cpp index f1e6d6016ea..988a4b2d736 100644 --- a/dbms/src/Core/SettingsCommon.cpp +++ b/dbms/src/Core/SettingsCommon.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -26,6 +27,7 @@ namespace ErrorCodes extern const int SIZE_OF_FIXED_STRING_DOESNT_MATCH; extern const int BAD_ARGUMENTS; extern const int UNKNOWN_SETTING; + extern const int CANNOT_PARSE_BOOL; } @@ -66,12 +68,25 @@ void SettingNumber::set(const String & x) template <> void SettingNumber::set(const String & x) { - if (x == "false") - set(false); - else if (x == "true") - set(true); + if (x.size() == 1) + { + if (x[0] == '0') + set(false); + else if (x[0] == '1') + set(true); + else + throw Exception("Cannot parse bool from string '" + x + "'", ErrorCodes::CANNOT_PARSE_BOOL); + } else - set(parse(x)); + { + ReadBufferFromString buf(x); + if (checkStringCaseInsensitive("true", buf)) + set(true); + else if (checkStringCaseInsensitive("false", buf)) + set(false); + else + throw Exception("Cannot parse bool from string '" + x + "'", ErrorCodes::CANNOT_PARSE_BOOL); + } } template diff --git a/dbms/tests/integration/test_replica_can_become_leader/configs/notleader.xml b/dbms/tests/integration/test_replica_can_become_leader/configs/notleader.xml index 9905191d955..2a19ffcc52c 100644 --- a/dbms/tests/integration/test_replica_can_become_leader/configs/notleader.xml +++ b/dbms/tests/integration/test_replica_can_become_leader/configs/notleader.xml @@ -1,5 +1,5 @@ - false + 0 diff --git a/dbms/tests/integration/test_replica_can_become_leader/configs/notleaderignorecase.xml b/dbms/tests/integration/test_replica_can_become_leader/configs/notleaderignorecase.xml new file mode 100644 index 00000000000..6cb2f9530ec --- /dev/null +++ b/dbms/tests/integration/test_replica_can_become_leader/configs/notleaderignorecase.xml @@ -0,0 +1,5 @@ + + + FAlse + + diff --git a/dbms/tests/integration/test_replica_can_become_leader/test.py b/dbms/tests/integration/test_replica_can_become_leader/test.py index b4c1d8f309c..2ef518d5570 100644 --- a/dbms/tests/integration/test_replica_can_become_leader/test.py +++ b/dbms/tests/integration/test_replica_can_become_leader/test.py @@ -1,10 +1,11 @@ import pytest from helpers.cluster import ClickHouseCluster +from helpers.client import QueryRuntimeException cluster = ClickHouseCluster(__file__) node1 = cluster.add_instance('node1', main_configs=['configs/notleader.xml'], with_zookeeper=True) -node2 = cluster.add_instance('node2', with_zookeeper=True) +node2 = cluster.add_instance('node2', main_configs=['configs/notleaderignorecase.xml'], with_zookeeper=True) node3 = cluster.add_instance('node3', with_zookeeper=True) @pytest.fixture(scope="module") @@ -12,7 +13,7 @@ def start_cluster(): try: cluster.start() - for i, node in enumerate((node1, node2, node3)): + for i, node in enumerate((node1, node2)): node.query( ''' CREATE TABLE test_table(date Date, id UInt32, dummy UInt32) @@ -21,6 +22,15 @@ def start_cluster(): '''.format(i) ) + with pytest.raises(QueryRuntimeException): + node3.query( + ''' + CREATE TABLE test_table(date Date, id UInt32, dummy UInt32) + ENGINE = ReplicatedMergeTree('/clickhouse/tables/test_table', '{}') + PARTITION BY date ORDER BY id SETTINGS replicated_can_become_leader=0sad + '''.format(3) + ) + yield cluster finally: @@ -29,5 +39,4 @@ def start_cluster(): def test_can_become_leader(start_cluster): assert node1.query("select can_become_leader from system.replicas where table = 'test_table'") == '0\n' - assert node2.query("select can_become_leader from system.replicas where table = 'test_table'") == '1\n' - assert node3.query("select can_become_leader from system.replicas where table = 'test_table'") == '1\n' + assert node2.query("select can_become_leader from system.replicas where table = 'test_table'") == '0\n' From ca3796f0a3a1e495940b44a8d7e5c2ae0fb3633e Mon Sep 17 00:00:00 2001 From: alesapin Date: Thu, 1 Aug 2019 20:46:37 +0300 Subject: [PATCH 0590/1165] Less branches --- dbms/src/Core/SettingsCommon.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dbms/src/Core/SettingsCommon.cpp b/dbms/src/Core/SettingsCommon.cpp index 988a4b2d736..55736a38dd3 100644 --- a/dbms/src/Core/SettingsCommon.cpp +++ b/dbms/src/Core/SettingsCommon.cpp @@ -74,8 +74,6 @@ void SettingNumber::set(const String & x) set(false); else if (x[0] == '1') set(true); - else - throw Exception("Cannot parse bool from string '" + x + "'", ErrorCodes::CANNOT_PARSE_BOOL); } else { @@ -84,9 +82,9 @@ void SettingNumber::set(const String & x) set(true); else if (checkStringCaseInsensitive("false", buf)) set(false); - else - throw Exception("Cannot parse bool from string '" + x + "'", ErrorCodes::CANNOT_PARSE_BOOL); } + if (!changed) + throw Exception("Cannot parse bool from string '" + x + "'", ErrorCodes::CANNOT_PARSE_BOOL); } template From a8378e8ef09506521eb46e8dbc40ee5dd8e9f804 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 1 Aug 2019 21:22:38 +0300 Subject: [PATCH 0591/1165] Fix LowCardinality arguments conversion for AggregateFunctionFactory. --- .../AggregateFunctions/AggregateFunctionFactory.cpp | 13 ++++--------- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/dbms/src/AggregateFunctions/AggregateFunctionFactory.cpp b/dbms/src/AggregateFunctions/AggregateFunctionFactory.cpp index ce7adf5b96d..83fb9f48abe 100644 --- a/dbms/src/AggregateFunctions/AggregateFunctionFactory.cpp +++ b/dbms/src/AggregateFunctions/AggregateFunctionFactory.cpp @@ -49,12 +49,7 @@ static DataTypes convertLowCardinalityTypesToNested(const DataTypes & types) DataTypes res_types; res_types.reserve(types.size()); for (const auto & type : types) - { - if (auto * low_cardinality_type = typeid_cast(type.get())) - res_types.push_back(low_cardinality_type->getDictionaryType()); - else - res_types.push_back(type); - } + res_types.emplace_back(recursiveRemoveLowCardinality(type)); return res_types; } @@ -69,7 +64,7 @@ AggregateFunctionPtr AggregateFunctionFactory::get( /// If one of types is Nullable, we apply aggregate function combinator "Null". - if (std::any_of(argument_types.begin(), argument_types.end(), + if (std::any_of(type_without_low_cardinality.begin(), type_without_low_cardinality.end(), [](const auto & type) { return type->isNullable(); })) { AggregateFunctionCombinatorPtr combinator = AggregateFunctionCombinatorFactory::instance().tryFindSuffix("Null"); @@ -83,11 +78,11 @@ AggregateFunctionPtr AggregateFunctionFactory::get( /// A little hack - if we have NULL arguments, don't even create nested function. /// Combinator will check if nested_function was created. - if (name == "count" || std::none_of(argument_types.begin(), argument_types.end(), + if (name == "count" || std::none_of(type_without_low_cardinality.begin(), type_without_low_cardinality.end(), [](const auto & type) { return type->onlyNull(); })) nested_function = getImpl(name, nested_types, nested_parameters, recursion_level); - return combinator->transformAggregateFunction(nested_function, argument_types, parameters); + return combinator->transformAggregateFunction(nested_function, type_without_low_cardinality, parameters); } auto res = getImpl(name, type_without_low_cardinality, parameters, recursion_level); diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index 055f5c8f3ec..04b41e1bfe2 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -412,7 +412,7 @@ void ExpressionAnalyzer::getAggregates(const ASTPtr & ast, ExpressionActionsPtr getRootActions(arguments[i], true, actions); const std::string & name = arguments[i]->getColumnName(); - types[i] = recursiveRemoveLowCardinality(actions->getSampleBlock().getByName(name).type); + types[i] = actions->getSampleBlock().getByName(name).type; aggregate.argument_names[i] = name; } From c11e04f9d959a29b385e40542fea1d30f54f3eea Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 1 Aug 2019 21:44:23 +0300 Subject: [PATCH 0592/1165] Added test. --- .../00976_shard_low_cardinality_achimbab.reference | 1 + .../0_stateless/00976_shard_low_cardinality_achimbab.sql | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00976_shard_low_cardinality_achimbab.reference create mode 100644 dbms/tests/queries/0_stateless/00976_shard_low_cardinality_achimbab.sql diff --git a/dbms/tests/queries/0_stateless/00976_shard_low_cardinality_achimbab.reference b/dbms/tests/queries/0_stateless/00976_shard_low_cardinality_achimbab.reference new file mode 100644 index 00000000000..9972842f982 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00976_shard_low_cardinality_achimbab.reference @@ -0,0 +1 @@ +1 1 diff --git a/dbms/tests/queries/0_stateless/00976_shard_low_cardinality_achimbab.sql b/dbms/tests/queries/0_stateless/00976_shard_low_cardinality_achimbab.sql new file mode 100644 index 00000000000..3736be891cd --- /dev/null +++ b/dbms/tests/queries/0_stateless/00976_shard_low_cardinality_achimbab.sql @@ -0,0 +1,6 @@ +DROP TABLE IF EXISTS han_1; +CREATE TABLE han_1 (k Int32, date_dt LowCardinality(Nullable(String))) +ENGINE = MergeTree() PARTITION BY k ORDER BY k; +INSERT INTO han_1 values (1, '2019-07-31'); +SELECT k, uniq(date_dt) FROM remote('127.0.0.{1,2}', currentDatabase(), han_1) GROUP BY k; +DROP TABLE IF EXISTS han_1; From b8dff6ebb1b26f8818c78dfcee193163421d68fb Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Thu, 1 Aug 2019 22:03:39 +0300 Subject: [PATCH 0593/1165] more optimal ranges selection at reading in order --- .../MergeTree/MergeTreeDataSelectExecutor.cpp | 70 +++++++++++-------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index ccbcd04857d..d528755005b 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -831,39 +831,11 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsWithO size_t adaptive_parts = 0; std::vector sum_marks_in_parts(parts.size()); - /// In case of reverse order let's split ranges to avoid reading much data. - auto split_ranges = [max_block_size](const auto & ranges, size_t rows_granularity, size_t num_marks_in_part) - { - /// Constants is just a guess. - const size_t min_rows_in_range = max_block_size; - const size_t max_num_ranges = 64; - - size_t min_marks_in_range = std::max( - (min_rows_in_range + rows_granularity - 1) / rows_granularity, - (num_marks_in_part + max_num_ranges - 1) / max_num_ranges); - - MarkRanges new_ranges; - for (auto range : ranges) - { - while (range.begin + min_marks_in_range < range.end) - { - new_ranges.emplace_back(range.begin, range.begin + min_marks_in_range); - range.begin += min_marks_in_range; - } - new_ranges.emplace_back(range.begin, range.end); - } - - return new_ranges; - }; - for (size_t i = 0; i < parts.size(); ++i) { sum_marks_in_parts[i] = parts[i].getMarksCount(); sum_marks += sum_marks_in_parts[i]; - if (sorting_info->direction == -1) - parts[i].ranges = split_ranges(parts[i].ranges, data.settings.index_granularity, sum_marks_in_parts[i]); - /// Let the ranges be listed from right to left so that the leftmost range can be dropped using `pop_back()`. std::reverse(parts[i].ranges.begin(), parts[i].ranges.end()); @@ -895,6 +867,46 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsWithO if (sum_marks == 0) return streams; + /// In case of reverse order let's split ranges to avoid reading much data. + auto split_ranges = [rows_granularity = data.settings.index_granularity, max_block_size](const auto & ranges, int direction) + { + if (direction == 1) + return ranges; + + MarkRanges new_ranges; + + /// Probably it useful to make it larger. + const size_t max_marks_in_range = (max_block_size + rows_granularity - 1) / rows_granularity; + size_t marks_in_range = 1; + + for (auto range : ranges) + { + while (range.begin + marks_in_range < range.end) + { + if (direction == 1) + { + /// Comment + new_ranges.emplace_back(range.begin, range.begin + marks_in_range); + range.begin += marks_in_range; + marks_in_range *= 2; + + if (marks_in_range > max_block_size) + break; + } + else + { + /// Comment + new_ranges.emplace_back(range.end - marks_in_range, range.end); + range.end -= marks_in_range; + marks_in_range = std::min(marks_in_range * 2, max_marks_in_range); + } + } + new_ranges.emplace_back(range.begin, range.end); + } + + return new_ranges; + }; + const size_t min_marks_per_stream = (sum_marks - 1) / num_streams + 1; for (size_t i = 0; i < num_streams && !parts.empty(); ++i) @@ -959,6 +971,8 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsWithO parts.emplace_back(part); } + ranges_to_get_from_part = split_ranges(ranges_to_get_from_part, sorting_info->direction); + BlockInputStreamPtr source_stream; if (sorting_info->direction == 1) { From d169f42b365b32e357e86a7950b3756139b2e84c Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Thu, 1 Aug 2019 22:07:31 +0300 Subject: [PATCH 0594/1165] fix build --- dbms/src/Storages/StorageReplicatedMergeTree.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dbms/src/Storages/StorageReplicatedMergeTree.cpp b/dbms/src/Storages/StorageReplicatedMergeTree.cpp index 302e6743db1..deb01614430 100644 --- a/dbms/src/Storages/StorageReplicatedMergeTree.cpp +++ b/dbms/src/Storages/StorageReplicatedMergeTree.cpp @@ -2192,7 +2192,8 @@ void StorageReplicatedMergeTree::mergeSelectingTask() if (max_source_parts_size_for_merge > 0 && merger_mutator.selectPartsToMerge(future_merged_part, false, max_source_parts_size_for_merge, merge_pred)) { - success = createLogEntryToMergeParts(zookeeper, future_merged_part.parts, future_merged_part.name, deduplicate, force_ttl); + success = createLogEntryToMergeParts(zookeeper, future_merged_part.parts, + future_merged_part.name, deduplicate, force_ttl); } else if (max_source_part_size_for_mutation > 0 && queue.countMutations() > 0) { @@ -3021,8 +3022,8 @@ bool StorageReplicatedMergeTree::optimize(const ASTPtr & query, const ASTPtr & p bool selected = merger_mutator.selectAllPartsToMergeWithinPartition( future_merged_part, disk_space, can_merge, partition_id, true, nullptr); ReplicatedMergeTreeLogEntryData merge_entry; - if (selected && - !createLogEntryToMergeParts(zookeeper, future_merged_part.parts, future_merged_part.name, deduplicate, force_ttl, &merge_entry)) + if (selected && !createLogEntryToMergeParts(zookeeper, future_merged_part.parts, + future_merged_part.name, deduplicate, force_ttl, &merge_entry)) return handle_noop("Can't create merge queue node in ZooKeeper"); if (merge_entry.type != ReplicatedMergeTreeLogEntryData::Type::EMPTY) merge_entries.push_back(std::move(merge_entry)); @@ -3057,7 +3058,8 @@ bool StorageReplicatedMergeTree::optimize(const ASTPtr & query, const ASTPtr & p } ReplicatedMergeTreeLogEntryData merge_entry; - if (!createLogEntryToMergeParts(zookeeper, future_merged_part.parts, future_merged_part.name, deduplicate, &merge_entry)) + if (!createLogEntryToMergeParts(zookeeper, future_merged_part.parts, + future_merged_part.name, deduplicate, force_ttl, &merge_entry)) return handle_noop("Can't create merge queue node in ZooKeeper"); if (merge_entry.type != ReplicatedMergeTreeLogEntryData::Type::EMPTY) merge_entries.push_back(std::move(merge_entry)); From 5c361c327b18a49e20aa7f4a6668b7049bca9847 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 22:17:49 +0300 Subject: [PATCH 0595/1165] Enabled "precise" mode; updated tests --- dbms/src/Functions/exp.cpp | 2 +- dbms/src/Functions/log.cpp | 2 +- .../0_stateless/00087_math_functions.sql | 10 +- .../00232_format_readable_size.reference | 140 +++++++++--------- .../00232_format_readable_size.sql | 5 +- .../00332_quantile_timing_memory_leak.sql | 2 +- .../0_stateless/00700_decimal_math.reference | 18 +-- .../0_stateless/00700_decimal_math.sql | 18 +-- .../00712_nan_comparison.reference | 2 +- .../0_stateless/00712_nan_comparison.sql | 2 +- .../0_stateless/00715_bounding_ratio.sql | 2 +- .../00760_insert_json_with_defaults.reference | 16 +- .../00760_insert_json_with_defaults.sql | 2 +- .../00851_http_insert_json_defaults.reference | 8 +- .../00851_http_insert_json_defaults.sh | 2 +- 15 files changed, 117 insertions(+), 114 deletions(-) diff --git a/dbms/src/Functions/exp.cpp b/dbms/src/Functions/exp.cpp index 70aa14c5cb5..550b3b9d3ab 100644 --- a/dbms/src/Functions/exp.cpp +++ b/dbms/src/Functions/exp.cpp @@ -19,7 +19,7 @@ namespace template static void execute(const T * src, size_t size, T * dst) { - NFastOps::Exp<>(src, size, dst); + NFastOps::Exp(src, size, dst); } }; } diff --git a/dbms/src/Functions/log.cpp b/dbms/src/Functions/log.cpp index 234d3370e79..c12300d7be4 100644 --- a/dbms/src/Functions/log.cpp +++ b/dbms/src/Functions/log.cpp @@ -19,7 +19,7 @@ namespace template static void execute(const T * src, size_t size, T * dst) { - NFastOps::Log<>(src, size, dst); + NFastOps::Log(src, size, dst); } }; } diff --git a/dbms/tests/queries/0_stateless/00087_math_functions.sql b/dbms/tests/queries/0_stateless/00087_math_functions.sql index 4070035802f..8de8a774ff8 100644 --- a/dbms/tests/queries/0_stateless/00087_math_functions.sql +++ b/dbms/tests/queries/0_stateless/00087_math_functions.sql @@ -32,16 +32,16 @@ select tgamma(2) = 1; select tgamma(3) = 2; select tgamma(4) = 6; -select sum(abs(lgamma(x + 1) - log(tgamma(x + 1))) < 1.0e-9) / count() from system.one array join range(10) as x; +select sum(abs(lgamma(x + 1) - log(tgamma(x + 1))) < 1.0e-8) / count() from system.one array join range(10) as x; select abs(e() - arraySum(arrayMap(x -> 1 / tgamma(x + 1), range(13)))) < 1.0e-9; select log(0) = -inf; select log(1) = 0; -select log(e()) = 1; -select log(exp(1)) = 1; -select log(exp(2)) = 2; -select sum(abs(log(exp(x)) - x) < 1.0e-9) / count() from system.one array join range(100) as x; +select abs(log(e()) - 1) < 1e-8; +select abs(log(exp(1)) - 1) < 1e-8; +select abs(log(exp(2)) - 2) < 1e-8; +select sum(abs(log(exp(x)) - x) < 1e-8) / count() from system.one array join range(100) as x; select exp2(-1) = 1/2; select exp2(0) = 1; diff --git a/dbms/tests/queries/0_stateless/00232_format_readable_size.reference b/dbms/tests/queries/0_stateless/00232_format_readable_size.reference index 92c078dcfcb..51fdbd330f5 100644 --- a/dbms/tests/queries/0_stateless/00232_format_readable_size.reference +++ b/dbms/tests/queries/0_stateless/00232_format_readable_size.reference @@ -1,70 +1,70 @@ -1 1.00 B 1 1.00 B 1 1.00 B -2.718282 2.72 B 2 2.00 B 2 2.00 B -7.389056 7.39 B 7 7.00 B 7 7.00 B -20.085537 20.09 B 20 20.00 B 20 20.00 B -54.59815 54.60 B 54 54.00 B 54 54.00 B -148.413159 148.41 B 148 148.00 B 148 148.00 B -403.428793 403.43 B 403 403.00 B 403 403.00 B -1096.633158 1.07 KiB 1096 1.07 KiB 1096 1.07 KiB -2980.957987 2.91 KiB 2980 2.91 KiB 2980 2.91 KiB -8103.083928 7.91 KiB 8103 7.91 KiB 8103 7.91 KiB -22026.465795 21.51 KiB 22026 21.51 KiB 22026 21.51 KiB -59874.141715 58.47 KiB 59874 58.47 KiB 59874 58.47 KiB -162754.791419 158.94 KiB 162754 158.94 KiB 162754 158.94 KiB -442413.392009 432.04 KiB 442413 432.04 KiB 442413 432.04 KiB -1202604.284165 1.15 MiB 1202604 1.15 MiB 1202604 1.15 MiB -3269017.372472 3.12 MiB 3269017 3.12 MiB 3269017 3.12 MiB -8886110.520508 8.47 MiB 8886110 8.47 MiB 8886110 8.47 MiB -24154952.753575 23.04 MiB 24154952 23.04 MiB 24154952 23.04 MiB -65659969.137331 62.62 MiB 65659969 62.62 MiB 65659969 62.62 MiB -178482300.963187 170.21 MiB 178482300 170.21 MiB 178482300 170.21 MiB -485165195.40979 462.69 MiB 485165195 462.69 MiB 485165195 462.69 MiB -1318815734.483214 1.23 GiB 1318815734 1.23 GiB 1318815734 1.23 GiB -3584912846.131592 3.34 GiB 3584912846 3.34 GiB -710054450 -677.16 MiB -9744803446.248903 9.08 GiB 9744803446 9.08 GiB 1154868854 1.08 GiB -26489122129.84347 24.67 GiB 26489122129 24.67 GiB 719318353 686.00 MiB -72004899337.38588 67.06 GiB 72004899337 67.06 GiB -1009544695 -962.78 MiB -195729609428.83878 182.29 GiB 195729609428 182.29 GiB -1838886188 -1.71 GiB -532048240601.79865 495.51 GiB 532048240601 495.51 GiB -527704103 -503.26 MiB -1446257064291.475 1.32 TiB 1446257064291 1.32 TiB -1146914461 -1.07 GiB -3931334297144.042 3.58 TiB 3931334297144 3.58 TiB 1439221304 1.34 GiB -10686474581524.463 9.72 TiB 10686474581524 9.72 TiB 595949076 568.34 MiB -29048849665247.426 26.42 TiB 29048849665247 26.42 TiB 1985842399 1.85 GiB -78962960182680.69 71.82 TiB 78962960182680 71.82 TiB -13554280 -12.93 MiB -214643579785916.06 195.22 TiB 214643579785916 195.22 TiB -1705798980 -1.59 GiB -583461742527454.9 530.66 TiB 583461742527454 530.66 TiB -974699554 -929.55 MiB -1586013452313430.8 1.41 PiB 1586013452313430 1.41 PiB -2005982378 -1.87 GiB -4311231547115195 3.83 PiB 4311231547115195 3.83 PiB -790034757 -753.44 MiB -11719142372802612 10.41 PiB 11719142372802612 10.41 PiB 1983119412 1.85 GiB -31855931757113756 28.29 PiB 31855931757113756 28.29 PiB 408891804 389.95 MiB -86593400423993740 76.91 PiB 86593400423993744 76.91 PiB 673862032 642.64 MiB -235385266837020000 209.06 PiB 235385266837020000 209.06 PiB 791567712 754.90 MiB -639843493530054900 568.30 PiB 639843493530054912 568.30 PiB 1874080000 1.75 GiB -1739274941520501000 1.51 EiB 1739274941520500992 1.51 EiB 538007808 513.08 MiB -4727839468229346000 4.10 EiB 4727839468229346304 4.10 EiB 2061616128 1.92 GiB -12851600114359308000 11.15 EiB 12851600114359308288 11.15 EiB -1681813504 -1.57 GiB -34934271057485095000 30.30 EiB 0 0.00 B 0 0.00 B -94961194206024480000 82.37 EiB 0 0.00 B 0 0.00 B -258131288619006750000 223.89 EiB 0 0.00 B 0 0.00 B -701673591209763100000 608.60 EiB 0 0.00 B 0 0.00 B -1.9073465724950998e21 1.62 ZiB 0 0.00 B 0 0.00 B -5.184705528587072e21 4.39 ZiB 0 0.00 B 0 0.00 B -1.4093490824269389e22 11.94 ZiB 0 0.00 B 0 0.00 B -3.831008000716577e22 32.45 ZiB 0 0.00 B 0 0.00 B -1.0413759433029089e23 88.21 ZiB 0 0.00 B 0 0.00 B -2.830753303274694e23 239.77 ZiB 0 0.00 B 0 0.00 B -7.694785265142018e23 651.77 ZiB 0 0.00 B 0 0.00 B -2.091659496012996e24 1.73 YiB 0 0.00 B 0 0.00 B -5.685719999335932e24 4.70 YiB 0 0.00 B 0 0.00 B -1.545538935590104e25 12.78 YiB 0 0.00 B 0 0.00 B -4.2012104037905144e25 34.75 YiB 0 0.00 B 0 0.00 B -1.1420073898156842e26 94.46 YiB 0 0.00 B 0 0.00 B -3.10429793570192e26 256.78 YiB 0 0.00 B 0 0.00 B -8.438356668741454e26 698.00 YiB 0 0.00 B 0 0.00 B -2.29378315946961e27 1897.37 YiB 0 0.00 B 0 0.00 B -6.235149080811617e27 5157.59 YiB 0 0.00 B 0 0.00 B -1.6948892444103338e28 14019.80 YiB 0 0.00 B 0 0.00 B -4.607186634331292e28 38109.75 YiB 0 0.00 B 0 0.00 B -1.2523631708422137e29 103593.05 YiB 0 0.00 B 0 0.00 B -3.404276049931741e29 281595.11 YiB 0 0.00 B 0 0.00 B -9.253781725587787e29 765454.88 YiB 0 0.00 B 0 0.00 B +1.00 B 1.00 B 1.00 B +2.72 B 2.00 B 2.00 B +7.39 B 7.00 B 7.00 B +20.09 B 20.00 B 20.00 B +54.60 B 54.00 B 54.00 B +148.41 B 148.00 B 148.00 B +403.43 B 403.00 B 403.00 B +1.07 KiB 1.07 KiB 1.07 KiB +2.91 KiB 2.91 KiB 2.91 KiB +7.91 KiB 7.91 KiB 7.91 KiB +21.51 KiB 21.51 KiB 21.51 KiB +58.47 KiB 58.47 KiB 58.47 KiB +158.94 KiB 158.94 KiB 158.94 KiB +432.04 KiB 432.04 KiB 432.04 KiB +1.15 MiB 1.15 MiB 1.15 MiB +3.12 MiB 3.12 MiB 3.12 MiB +8.47 MiB 8.47 MiB 8.47 MiB +23.04 MiB 23.04 MiB 23.04 MiB +62.62 MiB 62.62 MiB 62.62 MiB +170.21 MiB 170.21 MiB 170.21 MiB +462.69 MiB 462.69 MiB 462.69 MiB +1.23 GiB 1.23 GiB 1.23 GiB +3.34 GiB 3.34 GiB -677.16 MiB +9.08 GiB 9.08 GiB 1.08 GiB +24.67 GiB 24.67 GiB 686.00 MiB +67.06 GiB 67.06 GiB -962.78 MiB +182.29 GiB 182.29 GiB -1.71 GiB +495.51 GiB 495.51 GiB -503.26 MiB +1.32 TiB 1.32 TiB -1.07 GiB +3.58 TiB 3.58 TiB 1.34 GiB +9.72 TiB 9.72 TiB 568.34 MiB +26.42 TiB 26.42 TiB 1.85 GiB +71.82 TiB 71.82 TiB -12.93 MiB +195.22 TiB 195.22 TiB -1.59 GiB +530.66 TiB 530.66 TiB -929.55 MiB +1.41 PiB 1.41 PiB -1.87 GiB +3.83 PiB 3.83 PiB -753.44 MiB +10.41 PiB 10.41 PiB 1.85 GiB +28.29 PiB 28.29 PiB 389.95 MiB +76.91 PiB 76.91 PiB 642.59 MiB +209.06 PiB 209.06 PiB 755.06 MiB +568.30 PiB 568.30 PiB 1.75 GiB +1.51 EiB 1.51 EiB 511.72 MiB +4.10 EiB 4.10 EiB 1.92 GiB +11.15 EiB 11.15 EiB -1.57 GiB +30.30 EiB 0.00 B 0.00 B +82.37 EiB 0.00 B 0.00 B +223.89 EiB 0.00 B 0.00 B +608.60 EiB 0.00 B 0.00 B +1.62 ZiB 0.00 B 0.00 B +4.39 ZiB 0.00 B 0.00 B +11.94 ZiB 0.00 B 0.00 B +32.45 ZiB 0.00 B 0.00 B +88.21 ZiB 0.00 B 0.00 B +239.77 ZiB 0.00 B 0.00 B +651.77 ZiB 0.00 B 0.00 B +1.73 YiB 0.00 B 0.00 B +4.70 YiB 0.00 B 0.00 B +12.78 YiB 0.00 B 0.00 B +34.75 YiB 0.00 B 0.00 B +94.46 YiB 0.00 B 0.00 B +256.78 YiB 0.00 B 0.00 B +698.00 YiB 0.00 B 0.00 B +1897.37 YiB 0.00 B 0.00 B +5157.59 YiB 0.00 B 0.00 B +14019.80 YiB 0.00 B 0.00 B +38109.75 YiB 0.00 B 0.00 B +103593.05 YiB 0.00 B 0.00 B +281595.11 YiB 0.00 B 0.00 B +765454.88 YiB 0.00 B 0.00 B diff --git a/dbms/tests/queries/0_stateless/00232_format_readable_size.sql b/dbms/tests/queries/0_stateless/00232_format_readable_size.sql index e2639e8fe1d..c3891c63c6f 100644 --- a/dbms/tests/queries/0_stateless/00232_format_readable_size.sql +++ b/dbms/tests/queries/0_stateless/00232_format_readable_size.sql @@ -1 +1,4 @@ -SELECT round(exp(number), 6) AS x, formatReadableSize(x), toUInt64(x) AS y, formatReadableSize(y), toInt32(y) AS z, formatReadableSize(z) FROM system.numbers LIMIT 70; +WITH round(exp(number), 6) AS x, toUInt64(x) AS y, toInt32(y) AS z +SELECT formatReadableSize(x), formatReadableSize(y), formatReadableSize(z) +FROM system.numbers +LIMIT 70; diff --git a/dbms/tests/queries/0_stateless/00332_quantile_timing_memory_leak.sql b/dbms/tests/queries/0_stateless/00332_quantile_timing_memory_leak.sql index f9137132e1d..17400eb6b7a 100644 --- a/dbms/tests/queries/0_stateless/00332_quantile_timing_memory_leak.sql +++ b/dbms/tests/queries/0_stateless/00332_quantile_timing_memory_leak.sql @@ -1,2 +1,2 @@ SELECT quantileTiming(number) FROM (SELECT * FROM system.numbers LIMIT 10000); -SELECT floor(log(1 + number) / log(1.5)) AS k, count() AS c, quantileTiming(number % 10000) AS q FROM (SELECT * FROM system.numbers LIMIT 1000000) GROUP BY k ORDER BY k; +SELECT floor(log2(1 + number) / log2(1.5)) AS k, count() AS c, quantileTiming(number % 10000) AS q FROM (SELECT * FROM system.numbers LIMIT 1000000) GROUP BY k ORDER BY k; diff --git a/dbms/tests/queries/0_stateless/00700_decimal_math.reference b/dbms/tests/queries/0_stateless/00700_decimal_math.reference index e40ed048f5b..88917004702 100644 --- a/dbms/tests/queries/0_stateless/00700_decimal_math.reference +++ b/dbms/tests/queries/0_stateless/00700_decimal_math.reference @@ -1,6 +1,6 @@ -42.4200 3.7476 42.419153766068966 -42.4200 5.4066 42.41786197045111 -42.4200 1.6275 42.413098391048806 +42.4200 3.7476 42.419154 +42.4200 5.4066 42.417862 +42.4200 1.6275 42.413098 42.4200 6.513 42.419169 42.4200 3.4875 42.417263671875 1.00000 0.8427007929497149 0.15729920705028513 @@ -8,9 +8,9 @@ 0.00 0 1 0 3.14159265 0 -1 -0 1.00 1.5707963267948966 0 0.7853981633974483 -42.4200 3.7476 42.419153766068966 -42.4200 5.4066 42.41786197045111 -42.4200 1.6275 42.413098391048806 +42.4200 3.7476 42.419154 +42.4200 5.4066 42.417862 +42.4200 1.6275 42.413098 42.4200 6.513 42.419169 42.4200 3.4875 42.417263671875 1.00000 0.8427007929497149 0.15729920705028513 @@ -18,9 +18,9 @@ 0.00 0 1 0 3.14159265358979328 0 -1 -0 1.00 1.5707963267948966 0 0.7853981633974483 -42.4200 3.7476 42.419153766068966 -42.4200 5.4066 42.41786197045111 -42.4200 1.6275 42.413098391048806 +42.4200 3.7476 42.419154 +42.4200 5.4066 42.417862 +42.4200 1.6275 42.413098 42.4200 6.513 42.419169 42.4200 3.4875 42.417263671875 1.00000 0.8427007929497149 0.15729920705028513 diff --git a/dbms/tests/queries/0_stateless/00700_decimal_math.sql b/dbms/tests/queries/0_stateless/00700_decimal_math.sql index a3a175777ed..a6c1ab2f393 100644 --- a/dbms/tests/queries/0_stateless/00700_decimal_math.sql +++ b/dbms/tests/queries/0_stateless/00700_decimal_math.sql @@ -1,6 +1,6 @@ -SELECT toDecimal32('42.42', 4) AS x, toDecimal32(log(x), 4) AS y, exp(y); -SELECT toDecimal32('42.42', 4) AS x, toDecimal32(log2(x), 4) AS y, exp2(y); -SELECT toDecimal32('42.42', 4) AS x, toDecimal32(log10(x), 4) AS y, exp10(y); +SELECT toDecimal32('42.42', 4) AS x, toDecimal32(log(x), 4) AS y, round(exp(y), 6); +SELECT toDecimal32('42.42', 4) AS x, toDecimal32(log2(x), 4) AS y, round(exp2(y), 6); +SELECT toDecimal32('42.42', 4) AS x, toDecimal32(log10(x), 4) AS y, round(exp10(y), 6); SELECT toDecimal32('42.42', 4) AS x, toDecimal32(sqrt(x), 3) AS y, y * y; SELECT toDecimal32('42.42', 4) AS x, toDecimal32(cbrt(x), 4) AS y, toDecimal64(y, 4) * y * y; @@ -12,9 +12,9 @@ SELECT toDecimal32(pi(), 8) AS x, round(sin(x), 8), round(cos(x), 8), round(tan( SELECT toDecimal32('1.0', 2) AS x, asin(x), acos(x), atan(x); -SELECT toDecimal64('42.42', 4) AS x, toDecimal32(log(x), 4) AS y, exp(y); -SELECT toDecimal64('42.42', 4) AS x, toDecimal32(log2(x), 4) AS y, exp2(y); -SELECT toDecimal64('42.42', 4) AS x, toDecimal32(log10(x), 4) AS y, exp10(y); +SELECT toDecimal64('42.42', 4) AS x, toDecimal32(log(x), 4) AS y, round(exp(y), 6); +SELECT toDecimal64('42.42', 4) AS x, toDecimal32(log2(x), 4) AS y, round(exp2(y), 6); +SELECT toDecimal64('42.42', 4) AS x, toDecimal32(log10(x), 4) AS y, round(exp10(y), 6); SELECT toDecimal64('42.42', 4) AS x, toDecimal32(sqrt(x), 3) AS y, y * y; SELECT toDecimal64('42.42', 4) AS x, toDecimal32(cbrt(x), 4) AS y, toDecimal64(y, 4) * y * y; @@ -26,9 +26,9 @@ SELECT toDecimal64(pi(), 17) AS x, round(sin(x), 8), round(cos(x), 8), round(tan SELECT toDecimal64('1.0', 2) AS x, asin(x), acos(x), atan(x); -SELECT toDecimal128('42.42', 4) AS x, toDecimal32(log(x), 4) AS y, exp(y); -SELECT toDecimal128('42.42', 4) AS x, toDecimal32(log2(x), 4) AS y, exp2(y); -SELECT toDecimal128('42.42', 4) AS x, toDecimal32(log10(x), 4) AS y, exp10(y); +SELECT toDecimal128('42.42', 4) AS x, toDecimal32(log(x), 4) AS y, round(exp(y), 6); +SELECT toDecimal128('42.42', 4) AS x, toDecimal32(log2(x), 4) AS y, round(exp2(y), 6); +SELECT toDecimal128('42.42', 4) AS x, toDecimal32(log10(x), 4) AS y, round(exp10(y), 6); SELECT toDecimal128('42.42', 4) AS x, toDecimal32(sqrt(x), 3) AS y, y * y; SELECT toDecimal128('42.42', 4) AS x, toDecimal32(cbrt(x), 4) AS y, toDecimal64(y, 4) * y * y; diff --git a/dbms/tests/queries/0_stateless/00712_nan_comparison.reference b/dbms/tests/queries/0_stateless/00712_nan_comparison.reference index 1631046f6dc..fe3ec276083 100644 --- a/dbms/tests/queries/0_stateless/00712_nan_comparison.reference +++ b/dbms/tests/queries/0_stateless/00712_nan_comparison.reference @@ -19,7 +19,7 @@ 0 1 0 0 0 0 0 1 0 0 0 0 nan nan nan nan nan nan -nan nan nan nan nan nan nan nan nan +nan 0 nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan -1 1 diff --git a/dbms/tests/queries/0_stateless/00712_nan_comparison.sql b/dbms/tests/queries/0_stateless/00712_nan_comparison.sql index a1eee82ae29..c0e1f692d55 100644 --- a/dbms/tests/queries/0_stateless/00712_nan_comparison.sql +++ b/dbms/tests/queries/0_stateless/00712_nan_comparison.sql @@ -22,7 +22,7 @@ SELECT -nan = toFloat64(0.0), -nan != toFloat64(0.0), -nan < toFloat64(0.0), -na --SELECT 1 % nan, nan % 1, pow(x, 1), pow(1, x); -- TODO SELECT 1 + nan, 1 - nan, nan - 1, 1 * nan, 1 / nan, nan / 1; -SELECT nan AS x, exp(x), exp2(x), exp10(x), log(x), log2(x), log10(x), sqrt(x), cbrt(x); +SELECT nan AS x, isFinite(exp(x)) /* exp(nan) is allowed to return inf */, exp2(x), exp10(x), log(x), log2(x), log10(x), sqrt(x), cbrt(x); SELECT nan AS x, erf(x), erfc(x), lgamma(x), tgamma(x); SELECT nan AS x, sin(x), cos(x), tan(x), asin(x), acos(x), atan(x); diff --git a/dbms/tests/queries/0_stateless/00715_bounding_ratio.sql b/dbms/tests/queries/0_stateless/00715_bounding_ratio.sql index ff3cd4c606b..b790aedf741 100644 --- a/dbms/tests/queries/0_stateless/00715_bounding_ratio.sql +++ b/dbms/tests/queries/0_stateless/00715_bounding_ratio.sql @@ -23,4 +23,4 @@ SELECT number % 10 AS k, boundingRatio(1000 + number, number * 1.5 - 111) FROM n SELECT boundingRatio(1000 + number, number * 1.5 - 111) FROM numbers(2); SELECT boundingRatio(1000 + number, number * 1.5 - 111) FROM numbers(1); SELECT boundingRatio(1000 + number, number * 1.5 - 111) FROM numbers(1) WHERE 0; -SELECT boundingRatio(number, exp(number)) = e() - 1 FROM numbers(2); +SELECT boundingRatio(number, exp(number)) = exp(1) - 1 FROM numbers(2); diff --git a/dbms/tests/queries/0_stateless/00760_insert_json_with_defaults.reference b/dbms/tests/queries/0_stateless/00760_insert_json_with_defaults.reference index a1634da50cf..4e07a79e8bc 100644 --- a/dbms/tests/queries/0_stateless/00760_insert_json_with_defaults.reference +++ b/dbms/tests/queries/0_stateless/00760_insert_json_with_defaults.reference @@ -1,10 +1,10 @@ 0 0 6 6 6 -0 5 5 1.7917595 5 -1 1 2 1.0986123 42 -1 1 2 1.0986123 42 -2 2 4 1.609438 2 +0 5 5 1.79176 5 +1 1 2 1.09861 42 +1 1 2 1.09861 42 +2 2 4 1.60944 2 3 3 3 3 3 -4 0 4 1.609438 42 -{"x":7,"y":7,"a":"14","b":2.7080503,"c":42,"n.a":["1","2"],"n.b":["a","b"]} -{"x":8,"y":8,"a":"16","b":2.8332133,"c":42,"n.a":["3","4"],"n.c":[0,0],"n.b":["c","d"]} -{"x":9,"y":9,"a":"18","b":2.944439,"c":42,"n.a":[],"n.c":[],"n.b":[]} +4 0 4 1.60944 42 +{"x":7,"y":7,"a":"14","b":2.70805,"c":42,"n.a":["1","2"],"n.b":["a","b"]} +{"x":8,"y":8,"a":"16","b":2.83321,"c":42,"n.a":["3","4"],"n.c":[0,0],"n.b":["c","d"]} +{"x":9,"y":9,"a":"18","b":2.94444,"c":42,"n.a":[],"n.c":[],"n.b":[]} diff --git a/dbms/tests/queries/0_stateless/00760_insert_json_with_defaults.sql b/dbms/tests/queries/0_stateless/00760_insert_json_with_defaults.sql index 1c269aa6423..6a1b367abba 100644 --- a/dbms/tests/queries/0_stateless/00760_insert_json_with_defaults.sql +++ b/dbms/tests/queries/0_stateless/00760_insert_json_with_defaults.sql @@ -6,7 +6,7 @@ CREATE TABLE defaults x UInt32, y UInt32, a DEFAULT x + y, - b Float32 DEFAULT log(1 + x + y), + b Float32 DEFAULT round(log(1 + x + y), 5), c UInt32 DEFAULT 42, e MATERIALIZED x + y, f ALIAS x + y diff --git a/dbms/tests/queries/0_stateless/00851_http_insert_json_defaults.reference b/dbms/tests/queries/0_stateless/00851_http_insert_json_defaults.reference index 3c1e6b22e57..0211325dab5 100644 --- a/dbms/tests/queries/0_stateless/00851_http_insert_json_defaults.reference +++ b/dbms/tests/queries/0_stateless/00851_http_insert_json_defaults.reference @@ -1,6 +1,6 @@ {"x":0,"y":0,"a":"6","b":6,"c":6} -{"x":0,"y":5,"a":"5","b":1.7917595,"c":5} -{"x":1,"y":1,"a":"2","b":1.0986123,"c":42} -{"x":2,"y":2,"a":"4","b":1.609438,"c":2} +{"x":0,"y":5,"a":"5","b":1.79176,"c":5} +{"x":1,"y":1,"a":"2","b":1.09861,"c":42} +{"x":2,"y":2,"a":"4","b":1.60944,"c":2} {"x":3,"y":3,"a":"3","b":3,"c":3} -{"x":4,"y":0,"a":"4","b":1.609438,"c":42} +{"x":4,"y":0,"a":"4","b":1.60944,"c":42} diff --git a/dbms/tests/queries/0_stateless/00851_http_insert_json_defaults.sh b/dbms/tests/queries/0_stateless/00851_http_insert_json_defaults.sh index a78d716985f..a1b71e97b0b 100755 --- a/dbms/tests/queries/0_stateless/00851_http_insert_json_defaults.sh +++ b/dbms/tests/queries/0_stateless/00851_http_insert_json_defaults.sh @@ -4,7 +4,7 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) . $CURDIR/../shell_config.sh $CLICKHOUSE_CLIENT --query="DROP TABLE IF EXISTS defaults" -$CLICKHOUSE_CLIENT --query="CREATE TABLE defaults (x UInt32, y UInt32, a DEFAULT x + y, b Float32 DEFAULT log(1 + x + y), c UInt32 DEFAULT 42, e MATERIALIZED x + y, f ALIAS x + y) ENGINE = Memory" +$CLICKHOUSE_CLIENT --query="CREATE TABLE defaults (x UInt32, y UInt32, a DEFAULT x + y, b Float32 DEFAULT round(log(1 + x + y), 5), c UInt32 DEFAULT 42, e MATERIALIZED x + y, f ALIAS x + y) ENGINE = Memory" echo -ne '{"x":1, "y":1}\n' | ${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL_PARAMS}&query=INSERT%20INTO%20defaults%20FORMAT%20JSONEachRow%20SETTINGS%20input_format_defaults_for_omitted_fields=1" --data-binary @- echo -ne '{"x":2, "y":2, "c":2}\n' | ${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL_PARAMS}&query=INSERT+INTO+defaults+FORMAT+JSONEachRow+SETTINGS+input_format_defaults_for_omitted_fields=1" --data-binary @- From 7aacbbdc5a0e30d2e50cda6ac6a8edf6bc554ae9 Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Thu, 1 Aug 2019 22:18:36 +0300 Subject: [PATCH 0596/1165] fix bug --- dbms/src/Functions/bitNotFunc.cpp | 41 +++++++++++++++++++ .../Functions/registerFunctionsArithmetic.cpp | 2 + .../Storages/MergeTree/MergeTreeIndexSet.cpp | 4 +- .../0_stateless/00979_set_index_not.reference | 2 + .../0_stateless/00979_set_index_not.sql | 12 ++++++ 5 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 dbms/src/Functions/bitNotFunc.cpp create mode 100644 dbms/tests/queries/0_stateless/00979_set_index_not.reference create mode 100644 dbms/tests/queries/0_stateless/00979_set_index_not.sql diff --git a/dbms/src/Functions/bitNotFunc.cpp b/dbms/src/Functions/bitNotFunc.cpp new file mode 100644 index 00000000000..b5057e72801 --- /dev/null +++ b/dbms/src/Functions/bitNotFunc.cpp @@ -0,0 +1,41 @@ +#include +#include +#include + +namespace DB +{ + + template + struct BitNotFuncImpl + { + using ResultType = UInt8; + + static inline ResultType NO_SANITIZE_UNDEFINED apply(A a) + { + return a == 0 ? static_cast(0b10) : static_cast(0b1); + } + +#if USE_EMBEDDED_COMPILER + static constexpr bool compilable = false; + +#endif + }; + + struct NameBitNotFunc { static constexpr auto name = "__bitNotFunc"; }; + using FunctionBitNotFunc = FunctionUnaryArithmetic; + + template <> struct FunctionUnaryArithmeticMonotonicity + { + static bool has() { return false; } + static IFunction::Monotonicity get(const Field &, const Field &) + { + return {}; + } + }; + + void registerFunctionBitNotFunc(FunctionFactory & factory) + { + factory.registerFunction(); + } + +} diff --git a/dbms/src/Functions/registerFunctionsArithmetic.cpp b/dbms/src/Functions/registerFunctionsArithmetic.cpp index 77df48fc6b4..0ac0223a822 100644 --- a/dbms/src/Functions/registerFunctionsArithmetic.cpp +++ b/dbms/src/Functions/registerFunctionsArithmetic.cpp @@ -33,6 +33,7 @@ void registerFunctionRoundToExp2(FunctionFactory & factory); void registerFunctionRoundDuration(FunctionFactory & factory); void registerFunctionRoundAge(FunctionFactory & factory); +void registerFunctionBitNotFunc(FunctionFactory & factory); void registerFunctionBitSwapLastTwo(FunctionFactory & factory); void registerFunctionsArithmetic(FunctionFactory & factory) @@ -68,6 +69,7 @@ void registerFunctionsArithmetic(FunctionFactory & factory) registerFunctionRoundAge(factory); /// Not for external use. + registerFunctionBitNotFunc(factory); registerFunctionBitSwapLastTwo(factory); } diff --git a/dbms/src/Storages/MergeTree/MergeTreeIndexSet.cpp b/dbms/src/Storages/MergeTree/MergeTreeIndexSet.cpp index fc3b905d1eb..0371bd9e1a7 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeIndexSet.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeIndexSet.cpp @@ -305,7 +305,9 @@ void MergeTreeIndexConditionSet::traverseAST(ASTPtr & node) const return; } - if (!atomFromAST(node)) + if (atomFromAST(node)) + node = makeASTFunction("__bitNotFunc", node); + else node = std::make_shared(UNKNOWN_FIELD); } diff --git a/dbms/tests/queries/0_stateless/00979_set_index_not.reference b/dbms/tests/queries/0_stateless/00979_set_index_not.reference new file mode 100644 index 00000000000..455708dfe99 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00979_set_index_not.reference @@ -0,0 +1,2 @@ +Jon alive +Jon alive diff --git a/dbms/tests/queries/0_stateless/00979_set_index_not.sql b/dbms/tests/queries/0_stateless/00979_set_index_not.sql new file mode 100644 index 00000000000..86789819ad4 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00979_set_index_not.sql @@ -0,0 +1,12 @@ +SET allow_experimental_data_skipping_indices = 1; + +CREATE TABLE a +( name String, status Enum8('alive' = 0, 'rip' = 1), + INDEX idx_status status TYPE set(2) GRANULARITY 1 +) +ENGINE = MergeTree() ORDER BY name SETTINGS index_granularity = 8192; + +insert into a values ('Jon','alive'),('Ramsey','rip'); + +select * from a where status!='rip'; +select * from a where NOT (status ='rip'); From af5cabd74097a2d6dd108d8fda4e195cf65b289b Mon Sep 17 00:00:00 2001 From: alesapin Date: Thu, 1 Aug 2019 22:30:00 +0300 Subject: [PATCH 0597/1165] Fix changed logic --- dbms/src/Core/SettingsCommon.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dbms/src/Core/SettingsCommon.cpp b/dbms/src/Core/SettingsCommon.cpp index 55736a38dd3..988a4b2d736 100644 --- a/dbms/src/Core/SettingsCommon.cpp +++ b/dbms/src/Core/SettingsCommon.cpp @@ -74,6 +74,8 @@ void SettingNumber::set(const String & x) set(false); else if (x[0] == '1') set(true); + else + throw Exception("Cannot parse bool from string '" + x + "'", ErrorCodes::CANNOT_PARSE_BOOL); } else { @@ -82,9 +84,9 @@ void SettingNumber::set(const String & x) set(true); else if (checkStringCaseInsensitive("false", buf)) set(false); + else + throw Exception("Cannot parse bool from string '" + x + "'", ErrorCodes::CANNOT_PARSE_BOOL); } - if (!changed) - throw Exception("Cannot parse bool from string '" + x + "'", ErrorCodes::CANNOT_PARSE_BOOL); } template From 479a0a9c8e00615c44d2def2c24fc270e94f34ae Mon Sep 17 00:00:00 2001 From: chertus Date: Thu, 1 Aug 2019 22:39:39 +0300 Subject: [PATCH 0598/1165] fix case with several same keys in join --- dbms/src/Interpreters/Join.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dbms/src/Interpreters/Join.cpp b/dbms/src/Interpreters/Join.cpp index 2f9044cf519..ccd5e76161b 100644 --- a/dbms/src/Interpreters/Join.cpp +++ b/dbms/src/Interpreters/Join.cpp @@ -281,6 +281,14 @@ void Join::setSampleBlock(const Block & block) for (size_t i = 0; i < keys_size; ++i) { const String & column_name = key_names_right[i]; + + /// there could be the same key names + if (sample_block_with_keys.has(column_name)) + { + key_columns[i] = sample_block_with_keys.getByName(column_name).column.get(); + continue; + } + auto & col = sample_block_with_columns_to_add.getByName(column_name); col.column = recursiveRemoveLowCardinality(col.column); col.type = recursiveRemoveLowCardinality(col.type); From c1de1d445c55467dffa198f58b5aac0740a9946a Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 22:47:04 +0300 Subject: [PATCH 0599/1165] Enabled query profiler by default --- dbms/src/Core/Settings.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Core/Settings.h b/dbms/src/Core/Settings.h index 916ededa75c..ea437832749 100644 --- a/dbms/src/Core/Settings.h +++ b/dbms/src/Core/Settings.h @@ -222,8 +222,8 @@ struct Settings : public SettingsCollection M(SettingBool, empty_result_for_aggregation_by_empty_set, false, "Return empty result when aggregating without keys on empty set.") \ M(SettingBool, allow_distributed_ddl, true, "If it is set to true, then a user is allowed to executed distributed DDL queries.") \ M(SettingUInt64, odbc_max_field_size, 1024, "Max size of filed can be read from ODBC dictionary. Long strings are truncated.") \ - M(SettingUInt64, query_profiler_real_time_period_ns, 0, "Highly experimental. Period for real clock timer of query profiler (in nanoseconds). Set 0 value to turn off real clock query profiler. Recommended value is at least 10000000 (100 times a second) for single queries or 1000000000 (once a second) for cluster-wide profiling.") \ - M(SettingUInt64, query_profiler_cpu_time_period_ns, 0, "Highly experimental. Period for CPU clock timer of query profiler (in nanoseconds). Set 0 value to turn off CPU clock query profiler. Recommended value is at least 10000000 (100 times a second) for single queries or 1000000000 (once a second) for cluster-wide profiling.") \ + M(SettingUInt64, query_profiler_real_time_period_ns, 1000000000, "Highly experimental. Period for real clock timer of query profiler (in nanoseconds). Set 0 value to turn off real clock query profiler. Recommended value is at least 10000000 (100 times a second) for single queries or 1000000000 (once a second) for cluster-wide profiling.") \ + M(SettingUInt64, query_profiler_cpu_time_period_ns, 1000000000, "Highly experimental. Period for CPU clock timer of query profiler (in nanoseconds). Set 0 value to turn off CPU clock query profiler. Recommended value is at least 10000000 (100 times a second) for single queries or 1000000000 (once a second) for cluster-wide profiling.") \ \ \ /** Limits during query execution are part of the settings. \ From 94813b21ba43c2057b3f7084ccc017093605b40e Mon Sep 17 00:00:00 2001 From: chertus Date: Thu, 1 Aug 2019 22:48:21 +0300 Subject: [PATCH 0600/1165] restore names deduplication --- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index a62a1ddbf9d..f88b2ff721c 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -73,6 +73,18 @@ namespace ErrorCodes extern const int EXPECTED_ALL_OR_ANY; } +namespace +{ + +Names deduplicateNames(const Names & names) +{ + NameSet dedup(names.begin(), names.end()); + return Names(dedup.begin(), dedup.end()); +} + +} + + ExpressionAnalyzer::ExpressionAnalyzer( const ASTPtr & query_, const SyntaxAnalyzerResultPtr & syntax_analyzer_result_, @@ -606,7 +618,7 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty else if (table_to_join.database_and_table_name) table = table_to_join.database_and_table_name; - Names required_columns = joined_block_actions->getRequiredColumns(); + Names required_columns = deduplicateNames(joined_block_actions->getRequiredColumns()); appendRequiredColumns( required_columns, joined_block_actions->getSampleBlock(), analyzed_join.key_names_right, columns_added_by_join); From b242c6ec79548b0ac8eda0733d935b3bf8415e7a Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Thu, 1 Aug 2019 22:51:51 +0300 Subject: [PATCH 0601/1165] fix test --- .../queries/0_stateless/00979_set_index_not.sql | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00979_set_index_not.sql b/dbms/tests/queries/0_stateless/00979_set_index_not.sql index 86789819ad4..6b34457e575 100644 --- a/dbms/tests/queries/0_stateless/00979_set_index_not.sql +++ b/dbms/tests/queries/0_stateless/00979_set_index_not.sql @@ -1,12 +1,16 @@ SET allow_experimental_data_skipping_indices = 1; -CREATE TABLE a +DROP TABLE IF EXISTS test.set_index_not; + +CREATE TABLE test.set_index_not ( name String, status Enum8('alive' = 0, 'rip' = 1), INDEX idx_status status TYPE set(2) GRANULARITY 1 ) ENGINE = MergeTree() ORDER BY name SETTINGS index_granularity = 8192; -insert into a values ('Jon','alive'),('Ramsey','rip'); +insert into test.set_index_not values ('Jon','alive'),('Ramsey','rip'); -select * from a where status!='rip'; -select * from a where NOT (status ='rip'); +select * from test.set_index_not where status!='rip'; +select * from test.set_index_not where NOT (status ='rip'); + +DROP TABLE test.set_index_not; \ No newline at end of file From c5a661a05ce224a63fe63dd0ec7bd3496ed60891 Mon Sep 17 00:00:00 2001 From: chertus Date: Thu, 1 Aug 2019 22:56:29 +0300 Subject: [PATCH 0602/1165] undo wrong changes --- dbms/src/Interpreters/AnalyzedJoin.cpp | 6 ++-- dbms/src/Interpreters/AnalyzedJoin.h | 2 +- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 29 ++++++++------------ dbms/src/Interpreters/SubqueryForSet.cpp | 6 ++-- dbms/src/Interpreters/SubqueryForSet.h | 4 +-- 5 files changed, 20 insertions(+), 27 deletions(-) diff --git a/dbms/src/Interpreters/AnalyzedJoin.cpp b/dbms/src/Interpreters/AnalyzedJoin.cpp index 265f3404b80..8357ab80aba 100644 --- a/dbms/src/Interpreters/AnalyzedJoin.cpp +++ b/dbms/src/Interpreters/AnalyzedJoin.cpp @@ -126,14 +126,14 @@ NameSet AnalyzedJoin::getOriginalColumnsSet() const return out; } -Names AnalyzedJoin::getOriginalColumnNames(const Names & required_columns) const +std::unordered_map AnalyzedJoin::getOriginalColumnsMap(const NameSet & required_columns) const { - Names out; + std::unordered_map out; for (const auto & column : required_columns) { auto it = original_names.find(column); if (it != original_names.end()) - out.push_back(it->second); + out.insert(*it); } return out; } diff --git a/dbms/src/Interpreters/AnalyzedJoin.h b/dbms/src/Interpreters/AnalyzedJoin.h index 5fe47ada2e4..d820cb0da7b 100644 --- a/dbms/src/Interpreters/AnalyzedJoin.h +++ b/dbms/src/Interpreters/AnalyzedJoin.h @@ -61,7 +61,7 @@ public: NameSet getQualifiedColumnsSet() const; NameSet getOriginalColumnsSet() const; - Names getOriginalColumnNames(const Names & required_columns) const; + std::unordered_map getOriginalColumnsMap(const NameSet & required_columns) const; void deduplicateAndQualifyColumnNames(const NameSet & left_table_columns, const String & right_table_prefix); void calculateAvailableJoinedColumns(bool make_nullable); diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index f88b2ff721c..79ff40956b5 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -73,18 +73,6 @@ namespace ErrorCodes extern const int EXPECTED_ALL_OR_ANY; } -namespace -{ - -Names deduplicateNames(const Names & names) -{ - NameSet dedup(names.begin(), names.end()); - return Names(dedup.begin(), dedup.end()); -} - -} - - ExpressionAnalyzer::ExpressionAnalyzer( const ASTPtr & query_, const SyntaxAnalyzerResultPtr & syntax_analyzer_result_, @@ -528,15 +516,15 @@ void ExpressionAnalyzer::addJoinAction(ExpressionActionsPtr & actions, bool only } static void appendRequiredColumns( - Names & required_columns, const Block & sample, const Names & key_names_right, const NamesAndTypesList & columns_added_by_join) + NameSet & required_columns, const Block & sample, const Names & key_names_right, const NamesAndTypesList & columns_added_by_join) { for (auto & column : key_names_right) if (!sample.has(column)) - required_columns.push_back(column); + required_columns.insert(column); for (auto & column : columns_added_by_join) if (!sample.has(column.name)) - required_columns.push_back(column.name); + required_columns.insert(column.name); } bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_types) @@ -618,15 +606,20 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty else if (table_to_join.database_and_table_name) table = table_to_join.database_and_table_name; - Names required_columns = deduplicateNames(joined_block_actions->getRequiredColumns()); + Names action_columns = joined_block_actions->getRequiredColumns(); + NameSet required_columns(action_columns.begin(), action_columns.end()); appendRequiredColumns( required_columns, joined_block_actions->getSampleBlock(), analyzed_join.key_names_right, columns_added_by_join); - Names original_columns = analyzed_join.getOriginalColumnNames(required_columns); + auto original_map = analyzed_join.getOriginalColumnsMap(required_columns); + Names original_columns; + for (auto & pr : original_map) + original_columns.push_back(pr.second); + auto interpreter = interpretSubquery(table, context, subquery_depth, original_columns); - subquery_for_set.makeSource(interpreter, original_columns, required_columns); + subquery_for_set.makeSource(interpreter, original_map); } Block sample_block = subquery_for_set.renamedSampleBlock(); diff --git a/dbms/src/Interpreters/SubqueryForSet.cpp b/dbms/src/Interpreters/SubqueryForSet.cpp index 4bad82c4b91..f6528bf110c 100644 --- a/dbms/src/Interpreters/SubqueryForSet.cpp +++ b/dbms/src/Interpreters/SubqueryForSet.cpp @@ -7,13 +7,13 @@ namespace DB { void SubqueryForSet::makeSource(std::shared_ptr & interpreter, - const Names & original_names, const Names & required_names) + const std::unordered_map & name_to_origin) { source = std::make_shared(interpreter->getSampleBlock(), [interpreter]() mutable { return interpreter->execute().in; }); - for (size_t i = 0; i < original_names.size(); ++i) - joined_block_aliases.emplace_back(original_names[i], required_names[i]); + for (const auto & names : name_to_origin) + joined_block_aliases.emplace_back(names.second, names.first); sample_block = source->getHeader(); for (const auto & name_with_alias : joined_block_aliases) diff --git a/dbms/src/Interpreters/SubqueryForSet.h b/dbms/src/Interpreters/SubqueryForSet.h index 932b9f160da..1844f686f0a 100644 --- a/dbms/src/Interpreters/SubqueryForSet.h +++ b/dbms/src/Interpreters/SubqueryForSet.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include @@ -13,6 +12,7 @@ class Join; using JoinPtr = std::shared_ptr; class InterpreterSelectWithUnionQuery; +struct AnalyzedJoin; /// Information on what to do when executing a subquery in the [GLOBAL] IN/JOIN section. @@ -32,7 +32,7 @@ struct SubqueryForSet StoragePtr table; void makeSource(std::shared_ptr & interpreter, - const Names & original_names, const Names & required_names); + const std::unordered_map & name_to_origin); Block renamedSampleBlock() const { return sample_block; } void renameColumns(Block & block); From 07273c79141294461dcea6cf129f727d141bd7d5 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 23:09:38 +0300 Subject: [PATCH 0603/1165] Instrumented ThreadPool --- dbms/src/Common/CurrentMetrics.cpp | 4 ++++ dbms/src/Common/ThreadPool.cpp | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/dbms/src/Common/CurrentMetrics.cpp b/dbms/src/Common/CurrentMetrics.cpp index 070afd3b231..b8e30f3cccd 100644 --- a/dbms/src/Common/CurrentMetrics.cpp +++ b/dbms/src/Common/CurrentMetrics.cpp @@ -45,6 +45,10 @@ M(RWLockWaitingWriters, "Number of threads waiting for write on a table RWLock.") \ M(RWLockActiveReaders, "Number of threads holding read lock in a table RWLock.") \ M(RWLockActiveWriters, "Number of threads holding write lock in a table RWLock.") \ + M(GlobalThread, "Number of threads in global thread pool.") \ + M(GlobalThreadActive, "Number of threads in global thread pool running a task.") \ + M(LocalThread, "Number of threads in local thread pools. Should be similar to GlobalThreadActive.") \ + M(LocalThreadActive, "Number of threads in local thread pools running a task.") \ namespace CurrentMetrics diff --git a/dbms/src/Common/ThreadPool.cpp b/dbms/src/Common/ThreadPool.cpp index 91ec29dc188..cb08fa944a9 100644 --- a/dbms/src/Common/ThreadPool.cpp +++ b/dbms/src/Common/ThreadPool.cpp @@ -13,6 +13,14 @@ namespace DB } } +namespace CurrentMetrics +{ + extern const Metric GlobalThread; + extern const Metric GlobalThreadActive; + extern const Metric LocalThread; + extern const Metric LocalThreadActive; +} + template ThreadPoolImpl::ThreadPoolImpl(size_t max_threads) @@ -148,6 +156,9 @@ size_t ThreadPoolImpl::active() const template void ThreadPoolImpl::worker(typename std::list::iterator thread_it) { + CurrentMetrics::Increment metric_all_threads( + std::is_same_v ? CurrentMetrics::GlobalThread : CurrentMetrics::LocalThread); + while (true) { Job job; @@ -174,6 +185,9 @@ void ThreadPoolImpl::worker(typename std::list::iterator thread_ { try { + CurrentMetrics::Increment metric_active_threads( + std::is_same_v ? CurrentMetrics::GlobalThreadActive : CurrentMetrics::LocalThreadActive); + job(); } catch (...) From e3f7dbd7d43e6f6357082e76f379dbb8032d4b77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0imon=20Podlipsk=C3=BD?= Date: Thu, 1 Aug 2019 22:33:26 +0200 Subject: [PATCH 0604/1165] Update aggregatingmergetree.md (#6276) --- docs/en/operations/table_engines/aggregatingmergetree.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/operations/table_engines/aggregatingmergetree.md b/docs/en/operations/table_engines/aggregatingmergetree.md index 0a3b1dcf35d..bab352d5cb5 100644 --- a/docs/en/operations/table_engines/aggregatingmergetree.md +++ b/docs/en/operations/table_engines/aggregatingmergetree.md @@ -21,6 +21,7 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] [PARTITION BY expr] [ORDER BY expr] [SAMPLE BY expr] +[TTL expr] [SETTINGS name=value, ...] ``` From 5c5b4f4de2bdba45ce4dfd103824f56db593108c Mon Sep 17 00:00:00 2001 From: Alexander Rodin Date: Fri, 2 Aug 2019 05:07:10 +0000 Subject: [PATCH 0605/1165] Revert "Replace ifs by cases" This reverts commit 0c70f78fcb9edc0d1fd94fb896c3ecc2eb183064. --- dbms/programs/server/HTTPHandler.cpp | 91 ++++++++++++++-------------- 1 file changed, 44 insertions(+), 47 deletions(-) diff --git a/dbms/programs/server/HTTPHandler.cpp b/dbms/programs/server/HTTPHandler.cpp index 51df8a4ed39..b54d1110a63 100644 --- a/dbms/programs/server/HTTPHandler.cpp +++ b/dbms/programs/server/HTTPHandler.cpp @@ -95,54 +95,51 @@ static Poco::Net::HTTPResponse::HTTPStatus exceptionCodeToHTTPStatus(int excepti { using namespace Poco::Net; - switch (exception_code) - { - case ErrorCodes::REQUIRED_PASSWORD: - return HTTPResponse::HTTP_UNAUTHORIZED; - case ErrorCodes::CANNOT_PARSE_TEXT: - case ErrorCodes::CANNOT_PARSE_ESCAPE_SEQUENCE: - case ErrorCodes::CANNOT_PARSE_QUOTED_STRING: - case ErrorCodes::CANNOT_PARSE_DATE: - case ErrorCodes::CANNOT_PARSE_DATETIME: - case ErrorCodes::CANNOT_PARSE_NUMBER: + if (exception_code == ErrorCodes::REQUIRED_PASSWORD) + return HTTPResponse::HTTP_UNAUTHORIZED; + else if (exception_code == ErrorCodes::CANNOT_PARSE_TEXT || + exception_code == ErrorCodes::CANNOT_PARSE_ESCAPE_SEQUENCE || + exception_code == ErrorCodes::CANNOT_PARSE_QUOTED_STRING || + exception_code == ErrorCodes::CANNOT_PARSE_DATE || + exception_code == ErrorCodes::CANNOT_PARSE_DATETIME || + exception_code == ErrorCodes::CANNOT_PARSE_NUMBER) + return HTTPResponse::HTTP_BAD_REQUEST; + else if (exception_code == ErrorCodes::UNKNOWN_ELEMENT_IN_AST || + exception_code == ErrorCodes::UNKNOWN_TYPE_OF_AST_NODE || + exception_code == ErrorCodes::TOO_DEEP_AST || + exception_code == ErrorCodes::TOO_BIG_AST || + exception_code == ErrorCodes::UNEXPECTED_AST_STRUCTURE) + return HTTPResponse::HTTP_BAD_REQUEST; + else if (exception_code == ErrorCodes::SYNTAX_ERROR) + return HTTPResponse::HTTP_BAD_REQUEST; + else if (exception_code == ErrorCodes::INCORRECT_DATA || + exception_code == ErrorCodes::TYPE_MISMATCH) + return HTTPResponse::HTTP_BAD_REQUEST; + else if (exception_code == ErrorCodes::UNKNOWN_TABLE || + exception_code == ErrorCodes::UNKNOWN_FUNCTION || + exception_code == ErrorCodes::UNKNOWN_IDENTIFIER || + exception_code == ErrorCodes::UNKNOWN_TYPE || + exception_code == ErrorCodes::UNKNOWN_STORAGE || + exception_code == ErrorCodes::UNKNOWN_DATABASE || + exception_code == ErrorCodes::UNKNOWN_SETTING || + exception_code == ErrorCodes::UNKNOWN_DIRECTION_OF_SORTING || + exception_code == ErrorCodes::UNKNOWN_AGGREGATE_FUNCTION || + exception_code == ErrorCodes::UNKNOWN_FORMAT || + exception_code == ErrorCodes::UNKNOWN_DATABASE_ENGINE) + return HTTPResponse::HTTP_NOT_FOUND; + else if (exception_code == ErrorCodes::UNKNOWN_TYPE_OF_QUERY) + return HTTPResponse::HTTP_NOT_FOUND; + else if (exception_code == ErrorCodes::QUERY_IS_TOO_LARGE) + return HTTPResponse::HTTP_REQUESTENTITYTOOLARGE; + else if (exception_code == ErrorCodes::NOT_IMPLEMENTED) + return HTTPResponse::HTTP_NOT_IMPLEMENTED; + else if (exception_code == ErrorCodes::SOCKET_TIMEOUT || + exception_code == ErrorCodes::CANNOT_OPEN_FILE) + return HTTPResponse::HTTP_SERVICE_UNAVAILABLE; + else if (exception_code == ErrorCodes::HTTP_LENGTH_REQUIRED) + return HTTPResponse::HTTP_LENGTH_REQUIRED; - case ErrorCodes::CANNOT_PARSE_NUMBER: - case ErrorCodes::UNKNOWN_TYPE_OF_AST_NODE: - case ErrorCodes::TOO_DEEP_AST: - case ErrorCodes::TOO_BIG_AST: - case ErrorCodes::UNEXPECTED_AST_STRUCTURE: - - case ErrorCodes::SYNTAX_ERROR: - - case ErrorCodes::INCORRECT_DATA: - case ErrorCodes::TYPE_MISMATCH: - return HTTPResponse::HTTP_BAD_REQUEST; - case ErrorCodes::UNKNOWN_TABLE: - case ErrorCodes::UNKNOWN_FUNCTION: - case ErrorCodes::UNKNOWN_IDENTIFIER: - case ErrorCodes::UNKNOWN_TYPE: - case ErrorCodes::UNKNOWN_STORAGE: - case ErrorCodes::UNKNOWN_DATABASE: - case ErrorCodes::UNKNOWN_SETTING: - case ErrorCodes::UNKNOWN_DIRECTION_OF_SORTING: - case ErrorCodes::UNKNOWN_AGGREGATE_FUNCTION: - case ErrorCodes::UNKNOWN_FORMAT: - case ErrorCodes::UNKNOWN_DATABASE_ENGINE: - - case ErrorCodes::UNKNOWN_TYPE_OF_QUERY: - return HTTPResponse::HTTP_NOT_FOUND; - case ErrorCodes::QUERY_IS_TOO_LARGE: - return HTTPResponse::HTTP_REQUESTENTITYTOOLARGE; - case ErrorCodes::NOT_IMPLEMENTED: - return HTTPResponse::HTTP_NOT_IMPLEMENTED; - case ErrorCodes::SOCKET_TIMEOUT: - case ErrorCodes::CANNOT_OPEN_FILE: - return HTTPResponse::HTTP_SERVICE_UNAVAILABLE; - case ErrorCodes::HTTP_LENGTH_REQUIRED: - return HTTPResponse::HTTP_LENGTH_REQUIRED; - default: - return HTTPResponse::HTTP_INTERNAL_SERVER_ERROR; - } + return HTTPResponse::HTTP_INTERNAL_SERVER_ERROR; } From 68487d512a1a6d718847c4d80128d93ab8a11eb2 Mon Sep 17 00:00:00 2001 From: Alexander Rodin Date: Fri, 2 Aug 2019 05:11:02 +0000 Subject: [PATCH 0606/1165] Merge if branches with the same status code --- dbms/programs/server/HTTPHandler.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/dbms/programs/server/HTTPHandler.cpp b/dbms/programs/server/HTTPHandler.cpp index b54d1110a63..1289a7915b1 100644 --- a/dbms/programs/server/HTTPHandler.cpp +++ b/dbms/programs/server/HTTPHandler.cpp @@ -102,17 +102,17 @@ static Poco::Net::HTTPResponse::HTTPStatus exceptionCodeToHTTPStatus(int excepti exception_code == ErrorCodes::CANNOT_PARSE_QUOTED_STRING || exception_code == ErrorCodes::CANNOT_PARSE_DATE || exception_code == ErrorCodes::CANNOT_PARSE_DATETIME || - exception_code == ErrorCodes::CANNOT_PARSE_NUMBER) - return HTTPResponse::HTTP_BAD_REQUEST; - else if (exception_code == ErrorCodes::UNKNOWN_ELEMENT_IN_AST || + exception_code == ErrorCodes::CANNOT_PARSE_NUMBER || + + exception_code == ErrorCodes::UNKNOWN_ELEMENT_IN_AST || exception_code == ErrorCodes::UNKNOWN_TYPE_OF_AST_NODE || exception_code == ErrorCodes::TOO_DEEP_AST || exception_code == ErrorCodes::TOO_BIG_AST || - exception_code == ErrorCodes::UNEXPECTED_AST_STRUCTURE) - return HTTPResponse::HTTP_BAD_REQUEST; - else if (exception_code == ErrorCodes::SYNTAX_ERROR) - return HTTPResponse::HTTP_BAD_REQUEST; - else if (exception_code == ErrorCodes::INCORRECT_DATA || + exception_code == ErrorCodes::UNEXPECTED_AST_STRUCTURE || + + exception_code == ErrorCodes::SYNTAX_ERROR || + + exception_code == ErrorCodes::INCORRECT_DATA || exception_code == ErrorCodes::TYPE_MISMATCH) return HTTPResponse::HTTP_BAD_REQUEST; else if (exception_code == ErrorCodes::UNKNOWN_TABLE || @@ -125,9 +125,9 @@ static Poco::Net::HTTPResponse::HTTPStatus exceptionCodeToHTTPStatus(int excepti exception_code == ErrorCodes::UNKNOWN_DIRECTION_OF_SORTING || exception_code == ErrorCodes::UNKNOWN_AGGREGATE_FUNCTION || exception_code == ErrorCodes::UNKNOWN_FORMAT || - exception_code == ErrorCodes::UNKNOWN_DATABASE_ENGINE) - return HTTPResponse::HTTP_NOT_FOUND; - else if (exception_code == ErrorCodes::UNKNOWN_TYPE_OF_QUERY) + exception_code == ErrorCodes::UNKNOWN_DATABASE_ENGINE || + + exception_code == ErrorCodes::UNKNOWN_TYPE_OF_QUERY) return HTTPResponse::HTTP_NOT_FOUND; else if (exception_code == ErrorCodes::QUERY_IS_TOO_LARGE) return HTTPResponse::HTTP_REQUESTENTITYTOOLARGE; From 10e562cddd8668b2f564d387f9b82644990cb19d Mon Sep 17 00:00:00 2001 From: BayoNet Date: Fri, 2 Aug 2019 09:50:13 +0300 Subject: [PATCH 0607/1165] Link fix. --- docs/en/interfaces/formats.md | 2 +- docs/ru/interfaces/formats.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/interfaces/formats.md b/docs/en/interfaces/formats.md index 8c9badaa02f..46a553089d9 100644 --- a/docs/en/interfaces/formats.md +++ b/docs/en/interfaces/formats.md @@ -173,7 +173,7 @@ Empty unquoted input values are replaced with default values for the respective [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#session_settings-input_format_defaults_for_omitted_fields) is enabled. -`NULL` is formatted as `\N` or `NULL` or an empty unquoted string (see settings [input_format_csv_unquoted_null_literal_as_null](../operations/settings/settings.md#settings-input_format_csv_unquoted_null_literal_as_null) and [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#settings-input_format_defaults_for_omitted_fields)). +`NULL` is formatted as `\N` or `NULL` or an empty unquoted string (see settings [input_format_csv_unquoted_null_literal_as_null](../operations/settings/settings.md#settings-input_format_csv_unquoted_null_literal_as_null) and [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#session_settings-input_format_defaults_for_omitted_fields)). The CSV format supports the output of totals and extremes the same way as `TabSeparated`. diff --git a/docs/ru/interfaces/formats.md b/docs/ru/interfaces/formats.md index 14d6408b7e7..20aa78630b7 100644 --- a/docs/ru/interfaces/formats.md +++ b/docs/ru/interfaces/formats.md @@ -165,7 +165,7 @@ clickhouse-client --format_csv_delimiter="|" --query="INSERT INTO test.csv FORMA При парсинге, все значения могут парситься как в кавычках, так и без кавычек. Поддерживаются как двойные, так и одинарные кавычки. Строки также могут быть без кавычек. В этом случае они парсятся до символа-разделителя или перевода строки (CR или LF). В нарушение RFC, в случае парсинга строк не в кавычках, начальные и конечные пробелы и табы игнорируются. В качестве перевода строки, поддерживаются как Unix (LF), так и Windows (CR LF) и Mac OS Classic (LF CR) варианты. -`NULL` форматируется в виде `\N` или `NULL` или пустой неэкранированной строки (см. настройки [input_format_csv_unquoted_null_literal_as_null](../operations/settings/settings.md#settings-input_format_csv_unquoted_null_literal_as_null) и [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#settings-input_format_defaults_for_omitted_fields)). +`NULL` форматируется в виде `\N` или `NULL` или пустой неэкранированной строки (см. настройки [input_format_csv_unquoted_null_literal_as_null](../operations/settings/settings.md#settings-input_format_csv_unquoted_null_literal_as_null) и [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#session_settings-input_format_defaults_for_omitted_fields)). Если установлена настройка [input_format_defaults_for_omitted_fields = 1](../operations/settings/settings.md#session_settings-input_format_defaults_for_omitted_fields) и тип столбца не `Nullable(T)`, то пустые значения без кавычек заменяются значениями по умолчанию для типа данных столбца. From 7015e5ca7df1647a6189a0da4f33bb9f8edc99fa Mon Sep 17 00:00:00 2001 From: BayoNet Date: Fri, 2 Aug 2019 10:11:40 +0300 Subject: [PATCH 0608/1165] Link fix. (#6288) --- docs/en/interfaces/formats.md | 2 +- docs/ru/interfaces/formats.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/interfaces/formats.md b/docs/en/interfaces/formats.md index 8c9badaa02f..46a553089d9 100644 --- a/docs/en/interfaces/formats.md +++ b/docs/en/interfaces/formats.md @@ -173,7 +173,7 @@ Empty unquoted input values are replaced with default values for the respective [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#session_settings-input_format_defaults_for_omitted_fields) is enabled. -`NULL` is formatted as `\N` or `NULL` or an empty unquoted string (see settings [input_format_csv_unquoted_null_literal_as_null](../operations/settings/settings.md#settings-input_format_csv_unquoted_null_literal_as_null) and [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#settings-input_format_defaults_for_omitted_fields)). +`NULL` is formatted as `\N` or `NULL` or an empty unquoted string (see settings [input_format_csv_unquoted_null_literal_as_null](../operations/settings/settings.md#settings-input_format_csv_unquoted_null_literal_as_null) and [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#session_settings-input_format_defaults_for_omitted_fields)). The CSV format supports the output of totals and extremes the same way as `TabSeparated`. diff --git a/docs/ru/interfaces/formats.md b/docs/ru/interfaces/formats.md index 14d6408b7e7..20aa78630b7 100644 --- a/docs/ru/interfaces/formats.md +++ b/docs/ru/interfaces/formats.md @@ -165,7 +165,7 @@ clickhouse-client --format_csv_delimiter="|" --query="INSERT INTO test.csv FORMA При парсинге, все значения могут парситься как в кавычках, так и без кавычек. Поддерживаются как двойные, так и одинарные кавычки. Строки также могут быть без кавычек. В этом случае они парсятся до символа-разделителя или перевода строки (CR или LF). В нарушение RFC, в случае парсинга строк не в кавычках, начальные и конечные пробелы и табы игнорируются. В качестве перевода строки, поддерживаются как Unix (LF), так и Windows (CR LF) и Mac OS Classic (LF CR) варианты. -`NULL` форматируется в виде `\N` или `NULL` или пустой неэкранированной строки (см. настройки [input_format_csv_unquoted_null_literal_as_null](../operations/settings/settings.md#settings-input_format_csv_unquoted_null_literal_as_null) и [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#settings-input_format_defaults_for_omitted_fields)). +`NULL` форматируется в виде `\N` или `NULL` или пустой неэкранированной строки (см. настройки [input_format_csv_unquoted_null_literal_as_null](../operations/settings/settings.md#settings-input_format_csv_unquoted_null_literal_as_null) и [input_format_defaults_for_omitted_fields](../operations/settings/settings.md#session_settings-input_format_defaults_for_omitted_fields)). Если установлена настройка [input_format_defaults_for_omitted_fields = 1](../operations/settings/settings.md#session_settings-input_format_defaults_for_omitted_fields) и тип столбца не `Nullable(T)`, то пустые значения без кавычек заменяются значениями по умолчанию для типа данных столбца. From ac5daf964e573a4a74d1b0117a9cbfc5ba6b5258 Mon Sep 17 00:00:00 2001 From: alesapin Date: Fri, 2 Aug 2019 11:09:23 +0300 Subject: [PATCH 0609/1165] Fix buggy tests --- dbms/tests/queries/0_stateless/00301_csv.sh | 2 +- .../0_stateless/00416_pocopatch_progress_in_http_headers.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00301_csv.sh b/dbms/tests/queries/0_stateless/00301_csv.sh index 3ecc87e5bc1..c1bb6710c1f 100755 --- a/dbms/tests/queries/0_stateless/00301_csv.sh +++ b/dbms/tests/queries/0_stateless/00301_csv.sh @@ -12,7 +12,7 @@ Hello "world", 789 ,2016-01-03 "Hello world", 100, 2016-01-04, default,, - default-eof,,' | $CLICKHOUSE_CLIENT --input_format_defaults_for_omitted_fields --query="INSERT INTO csv FORMAT CSV"; + default-eof,,' | $CLICKHOUSE_CLIENT --input_format_defaults_for_omitted_fields=1 --query="INSERT INTO csv FORMAT CSV"; $CLICKHOUSE_CLIENT --query="SELECT * FROM csv ORDER BY d"; $CLICKHOUSE_CLIENT --query="DROP TABLE csv"; diff --git a/dbms/tests/queries/0_stateless/00416_pocopatch_progress_in_http_headers.sh b/dbms/tests/queries/0_stateless/00416_pocopatch_progress_in_http_headers.sh index 2ae5d905fbe..d95798bc95c 100755 --- a/dbms/tests/queries/0_stateless/00416_pocopatch_progress_in_http_headers.sh +++ b/dbms/tests/queries/0_stateless/00416_pocopatch_progress_in_http_headers.sh @@ -8,7 +8,7 @@ ${CLICKHOUSE_CURL} -vsS "${CLICKHOUSE_URL}?max_block_size=5&send_progress_in_htt # "grep -v 11" in order to skip extra progress header for 11-th row (for processors pipeline) ${CLICKHOUSE_CURL} -vsS "${CLICKHOUSE_URL}?max_block_size=1&send_progress_in_http_headers=1&http_headers_progress_interval_ms=0&experimental_use_processors=0" -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep -E 'Content-Encoding|X-ClickHouse-Progress|^[0-9]' | grep -v 11 -${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}?max_block_size=1&send_progress_in_http_headers=1&http_headers_progress_interval_ms=0&enable_http_compression=1experimental_use_processors=0" -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 10' | gzip -d +${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}?max_block_size=1&send_progress_in_http_headers=1&http_headers_progress_interval_ms=0&enable_http_compression=1&experimental_use_processors=0" -H 'Accept-Encoding: gzip' -d 'SELECT number FROM system.numbers LIMIT 10' | gzip -d # 'send_progress_in_http_headers' is false by default ${CLICKHOUSE_CURL} -vsS "${CLICKHOUSE_URL}?max_block_size=1&http_headers_progress_interval_ms=0" -d 'SELECT number FROM system.numbers LIMIT 10' 2>&1 | grep -q 'X-ClickHouse-Progress' && echo 'Fail' || true From f71ce27a702cc171682bb33e1b08ae00efa06a49 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 13:49:52 +0300 Subject: [PATCH 0610/1165] Remove LowCardinality in AggregatingSortedBlockInputStream. --- .../AggregatingSortedBlockInputStream.cpp | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/dbms/src/DataStreams/AggregatingSortedBlockInputStream.cpp b/dbms/src/DataStreams/AggregatingSortedBlockInputStream.cpp index d3d5bd5c908..ca00eacb61b 100644 --- a/dbms/src/DataStreams/AggregatingSortedBlockInputStream.cpp +++ b/dbms/src/DataStreams/AggregatingSortedBlockInputStream.cpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace DB @@ -15,17 +16,59 @@ namespace ErrorCodes } +class RemovingLowCardinalityBlockInputStream : public IBlockInputStream +{ +public: + RemovingLowCardinalityBlockInputStream(BlockInputStreamPtr input_, ColumnNumbers positions_) + : input(std::move(input_)), positions(std::move(positions_)) + { + header = transform(input_->getHeader()); + } + + Block transform(Block block) + { + if (block) + { + for (auto & pos : positions) + { + auto & col = block.safeGetByPosition(pos); + col.column = recursiveRemoveLowCardinality(col.column); + col.type = recursiveRemoveLowCardinality(col.type); + } + } + + return block; + } + + String getName() const override { return "RemovingLowCardinality"; } + Block getHeader() const override { return header; } + const BlockMissingValues & getMissingValues() const override { return input->getMissingValues(); } + bool isSortedOutput() const override { return input->isSortedOutput(); } + const SortDescription & getSortDescription() const override { return input->getSortDescription(); } + +protected: + Block readImpl() override { return transform(input->read()); } + +private: + Block header; + BlockInputStreamPtr input; + ColumnNumbers positions; +}; + + AggregatingSortedBlockInputStream::AggregatingSortedBlockInputStream( const BlockInputStreams & inputs_, const SortDescription & description_, size_t max_block_size_) : MergingSortedBlockInputStream(inputs_, description_, max_block_size_) { + ColumnNumbers positions; + /// Fill in the column numbers that need to be aggregated. for (size_t i = 0; i < num_columns; ++i) { ColumnWithTypeAndName & column = header.safeGetByPosition(i); /// We leave only states of aggregate functions. - if (!dynamic_cast(column.type.get()) && !dynamic_cast(column.type->getCustomName())) + if (!dynamic_cast(column.type.get()) && !dynamic_cast(column.type->getCustomName())) { column_numbers_not_to_aggregate.push_back(i); continue; @@ -51,6 +94,9 @@ AggregatingSortedBlockInputStream::AggregatingSortedBlockInputStream( allocatesMemoryInArena = true; columns_to_simple_aggregate.emplace_back(std::move(desc)); + + if (recursiveRemoveLowCardinality(column.type).get() != column.type.get()) + positions.emplace_back(i); } else { @@ -58,6 +104,14 @@ AggregatingSortedBlockInputStream::AggregatingSortedBlockInputStream( column_numbers_to_aggregate.push_back(i); } } + + if (!positions.empty()) + { + for (auto & input : children) + input = std::make_shared(input, positions); + + header = children.at(0)->getHeader(); + } } From 5a9a4b23c3295dd789150bdd889d346ce71bbd78 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 13:50:42 +0300 Subject: [PATCH 0611/1165] Remove LowCardinality in AggregatingSortedBlockInputStream. --- dbms/src/DataStreams/AggregatingSortedBlockInputStream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/DataStreams/AggregatingSortedBlockInputStream.cpp b/dbms/src/DataStreams/AggregatingSortedBlockInputStream.cpp index ca00eacb61b..e89c1b0bfb1 100644 --- a/dbms/src/DataStreams/AggregatingSortedBlockInputStream.cpp +++ b/dbms/src/DataStreams/AggregatingSortedBlockInputStream.cpp @@ -68,7 +68,7 @@ AggregatingSortedBlockInputStream::AggregatingSortedBlockInputStream( ColumnWithTypeAndName & column = header.safeGetByPosition(i); /// We leave only states of aggregate functions. - if (!dynamic_cast(column.type.get()) && !dynamic_cast(column.type->getCustomName())) + if (!dynamic_cast(column.type.get()) && !dynamic_cast(column.type->getCustomName())) { column_numbers_not_to_aggregate.push_back(i); continue; From 77ca4acf67516cb35f00bc20d608b367a6258a2c Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 13:54:40 +0300 Subject: [PATCH 0612/1165] Remove LowCardinality in AggregatingSortedBlockInputStream. --- dbms/src/DataStreams/AggregatingSortedBlockInputStream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/DataStreams/AggregatingSortedBlockInputStream.cpp b/dbms/src/DataStreams/AggregatingSortedBlockInputStream.cpp index e89c1b0bfb1..44e8e7386da 100644 --- a/dbms/src/DataStreams/AggregatingSortedBlockInputStream.cpp +++ b/dbms/src/DataStreams/AggregatingSortedBlockInputStream.cpp @@ -22,7 +22,7 @@ public: RemovingLowCardinalityBlockInputStream(BlockInputStreamPtr input_, ColumnNumbers positions_) : input(std::move(input_)), positions(std::move(positions_)) { - header = transform(input_->getHeader()); + header = transform(input->getHeader()); } Block transform(Block block) From 48818aef7ff252699bcf157599da89ae8eb6dbd0 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 15:41:21 +0300 Subject: [PATCH 0613/1165] Update MySQLOutputFormat. --- .../Formats/Impl/MySQLOutputFormat.cpp | 33 ++++++++++--------- .../Formats/Impl/MySQLOutputFormat.h | 4 +-- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp b/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp index 446fd687503..0487d6334b1 100644 --- a/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.cpp @@ -17,9 +17,10 @@ using namespace MySQLProtocol; MySQLOutputFormat::MySQLOutputFormat(WriteBuffer & out_, const Block & header, const Context & context, const FormatSettings & settings) : IOutputFormat(header, out_) , context(context) - , packet_sender(std::make_shared(out, const_cast(context.mysql.sequence_id))) /// TODO: fix it + , packet_sender(out, const_cast(context.mysql.sequence_id)) /// TODO: fix it , format_settings(settings) { + packet_sender.max_packet_size = context.mysql.max_packet_size; } void MySQLOutputFormat::consume(Chunk chunk) @@ -30,22 +31,21 @@ void MySQLOutputFormat::consume(Chunk chunk) { initialized = true; - if (header.columns()) { - packet_sender->sendPacket(LengthEncodedNumber(header.columns())); + packet_sender.sendPacket(LengthEncodedNumber(header.columns())); for (const ColumnWithTypeAndName & column : header.getColumnsWithTypeAndName()) { ColumnDefinition column_definition(column.name, CharacterSet::binary, 0, ColumnType::MYSQL_TYPE_STRING, 0, 0); - packet_sender->sendPacket(column_definition); + packet_sender.sendPacket(column_definition); } if (!(context.mysql.client_capabilities & Capability::CLIENT_DEPRECATE_EOF)) { - packet_sender->sendPacket(EOF_Packet(0, 0)); + packet_sender.sendPacket(EOF_Packet(0, 0)); } } } @@ -58,14 +58,11 @@ void MySQLOutputFormat::consume(Chunk chunk) ResultsetRow row_packet; for (size_t col = 0; col < columns.size(); ++col) { - String column_value; - WriteBufferFromString ostr(column_value); + WriteBufferFromOwnString ostr; header.getByPosition(col).type->serializeAsText(*columns[col], i, ostr, format_settings); - ostr.finish(); - - row_packet.appendColumn(std::move(column_value)); + row_packet.appendColumn(std::move(ostr.str())); } - packet_sender->sendPacket(row_packet); + packet_sender.sendPacket(row_packet); } } @@ -84,15 +81,19 @@ void MySQLOutputFormat::finalize() << formatReadableSizeWithBinarySuffix(info.read_bytes / info.elapsed_seconds) << "/sec."; } - auto & header = getPort(PortKind::Main).getHeader(); - + const auto & header = getPort(PortKind::Main).getHeader(); if (header.columns() == 0) - packet_sender->sendPacket(OK_Packet(0x0, context.mysql.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); + packet_sender.sendPacket(OK_Packet(0x0, context.mysql.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); else if (context.mysql.client_capabilities & CLIENT_DEPRECATE_EOF) - packet_sender->sendPacket(OK_Packet(0xfe, context.mysql.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); + packet_sender.sendPacket(OK_Packet(0xfe, context.mysql.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); else - packet_sender->sendPacket(EOF_Packet(0, 0), true); + packet_sender.sendPacket(EOF_Packet(0, 0), true); +} + +void MySQLOutputFormat::flush() +{ + packet_sender.out->next(); } void registerOutputFormatProcessorMySQLWrite(FormatFactory & factory) diff --git a/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.h b/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.h index b959342ca4d..b9457a6369d 100644 --- a/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.h +++ b/dbms/src/Processors/Formats/Impl/MySQLOutputFormat.h @@ -25,13 +25,13 @@ public: void consume(Chunk) override; void finalize() override; - + void flush() override; private: bool initialized = false; const Context & context; - std::shared_ptr packet_sender; + MySQLProtocol::PacketSender packet_sender; FormatSettings format_settings; }; From d86c072147ac0611ee0417a2f975d0fddd3835d7 Mon Sep 17 00:00:00 2001 From: proller Date: Fri, 28 Jun 2019 20:15:48 +0300 Subject: [PATCH 0614/1165] wip --- cmake/Modules/FindODBC.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Modules/FindODBC.cmake b/cmake/Modules/FindODBC.cmake index 55318b52061..9e209c15777 100644 --- a/cmake/Modules/FindODBC.cmake +++ b/cmake/Modules/FindODBC.cmake @@ -129,7 +129,7 @@ find_package_handle_standard_args(ODBC ) if(ODBC_FOUND) - set(ODBC_LIBRARIES ${ODBC_LIBRARY} ${_odbc_required_libs_paths}) + set(ODBC_LIBRARIES ${ODBC_LIBRARY} ${_odbc_required_libs_paths} ${LTDL_LIBRARY}) set(ODBC_INCLUDE_DIRS ${ODBC_INCLUDE_DIR}) set(ODBC_DEFINITIONS ${PC_ODBC_CFLAGS_OTHER}) endif() From b1b46e6dee9df003cb91c968cfc879dcec847573 Mon Sep 17 00:00:00 2001 From: proller Date: Fri, 2 Aug 2019 17:23:17 +0300 Subject: [PATCH 0615/1165] Fix --- contrib/libunwind-cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/libunwind-cmake/CMakeLists.txt b/contrib/libunwind-cmake/CMakeLists.txt index 993323d56c0..4f24fe249f5 100644 --- a/contrib/libunwind-cmake/CMakeLists.txt +++ b/contrib/libunwind-cmake/CMakeLists.txt @@ -26,7 +26,7 @@ set(LIBUNWIND_SOURCES add_library(unwind_static ${LIBUNWIND_SOURCES}) -target_include_directories(unwind_static PUBLIC ${LIBUNWIND_SOURCE_DIR}/include) +target_include_directories(unwind_static SYSTEM BEFORE PUBLIC ${LIBUNWIND_SOURCE_DIR}/include) target_compile_definitions(unwind_static PRIVATE -D_LIBUNWIND_NO_HEAP=1 -D_DEBUG -D_LIBUNWIND_IS_NATIVE_ONLY) target_compile_options(unwind_static PRIVATE -fno-exceptions -funwind-tables -fno-sanitize=all -nostdinc++ -fno-rtti) target_link_libraries(unwind_static PRIVATE Threads::Threads ${CMAKE_DL_LIBS}) From fcc6a2c2be219daf9fae798486785a4c79030c83 Mon Sep 17 00:00:00 2001 From: chertus Date: Fri, 2 Aug 2019 17:31:15 +0300 Subject: [PATCH 0616/1165] fix crash on CAST exotic types to decimal --- dbms/src/DataTypes/IDataType.h | 5 ++--- dbms/src/Functions/FunctionsConversion.h | 11 +++++++++++ .../0_stateless/00879_cast_to_decimal_crash.reference | 0 .../0_stateless/00879_cast_to_decimal_crash.sql | 1 + 4 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00879_cast_to_decimal_crash.reference create mode 100644 dbms/tests/queries/0_stateless/00879_cast_to_decimal_crash.sql diff --git a/dbms/src/DataTypes/IDataType.h b/dbms/src/DataTypes/IDataType.h index f4c22ff9ac8..e5020fe19de 100644 --- a/dbms/src/DataTypes/IDataType.h +++ b/dbms/src/DataTypes/IDataType.h @@ -463,9 +463,8 @@ struct WhichDataType { TypeIndex idx; - /// For late initialization. - WhichDataType() - : idx(TypeIndex::Nothing) + WhichDataType(TypeIndex idx_ = TypeIndex::Nothing) + : idx(idx_) {} WhichDataType(const IDataType & data_type) diff --git a/dbms/src/Functions/FunctionsConversion.h b/dbms/src/Functions/FunctionsConversion.h index 7d1d277752f..a83ae586d80 100644 --- a/dbms/src/Functions/FunctionsConversion.h +++ b/dbms/src/Functions/FunctionsConversion.h @@ -1634,6 +1634,17 @@ private: TypeIndex type_index = from_type->getTypeId(); UInt32 scale = to_type->getScale(); + WhichDataType which(type_index); + bool ok = which.isNativeInt() || + which.isNativeUInt() || + which.isDecimal() || + which.isFloat() || + which.isDateOrDateTime() || + which.isStringOrFixedString(); + if (!ok) + throw Exception{"Conversion from " + from_type->getName() + " to " + to_type->getName() + " is not supported", + ErrorCodes::CANNOT_CONVERT_TYPE}; + return [type_index, scale] (Block & block, const ColumnNumbers & arguments, const size_t result, size_t input_rows_count) { callOnIndexAndDataType(type_index, [&](const auto & types) -> bool diff --git a/dbms/tests/queries/0_stateless/00879_cast_to_decimal_crash.reference b/dbms/tests/queries/0_stateless/00879_cast_to_decimal_crash.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dbms/tests/queries/0_stateless/00879_cast_to_decimal_crash.sql b/dbms/tests/queries/0_stateless/00879_cast_to_decimal_crash.sql new file mode 100644 index 00000000000..d07a54ecd5a --- /dev/null +++ b/dbms/tests/queries/0_stateless/00879_cast_to_decimal_crash.sql @@ -0,0 +1 @@ +select cast(toIntervalDay(1) as Nullable(Decimal(10, 10))); -- { serverError 70 } From 49632a74b73f7748d7a5d96147b16d70739c7406 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 17:41:19 +0300 Subject: [PATCH 0617/1165] Update FormatFactory. --- dbms/src/Formats/FormatFactory.cpp | 72 +++++++++++++++--------------- dbms/src/Formats/FormatFactory.h | 19 ++++---- 2 files changed, 46 insertions(+), 45 deletions(-) diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 640682c2e64..820be203c6a 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -22,23 +22,15 @@ namespace ErrorCodes extern const int FORMAT_IS_NOT_SUITABLE_FOR_OUTPUT; } -// -//const FormatFactory::Creators & FormatFactory::getCreators(const String & name) const -//{ -// auto it = dict.find(name); -// if (dict.end() != it) -// return it->second; -// throw Exception("Unknown format " + name, ErrorCodes::UNKNOWN_FORMAT); -//} - -const FormatFactory::ProcessorCreators & FormatFactory::getProcessorCreators(const String & name) const +const FormatFactory::Creators & FormatFactory::getCreators(const String & name) const { - auto it = processors_dict.find(name); - if (processors_dict.end() != it) + auto it = dict.find(name); + if (dict.end() != it) return it->second; throw Exception("Unknown format " + name, ErrorCodes::UNKNOWN_FORMAT); } + static FormatSettings getInputFormatSetting(const Settings & settings) { FormatSettings format_settings; @@ -90,6 +82,9 @@ BlockInputStreamPtr FormatFactory::getInput( if (name == "Native") return std::make_shared(buf, sample, 0); + if (!getCreators(name).input_processor_creator) + return getInput(name, buf, sample, context, max_block_size, rows_portion_size, std::move(callback)); + auto format = getInputFormat(name, buf, sample, context, max_block_size, rows_portion_size, std::move(callback)); return std::make_shared(std::move(format)); } @@ -97,18 +92,21 @@ BlockInputStreamPtr FormatFactory::getInput( BlockOutputStreamPtr FormatFactory::getOutput(const String & name, WriteBuffer & buf, const Block & sample, const Context & context) const { - if (name == "PrettyCompactMonoBlock") - { - /// TODO: rewrite - auto format = getOutputFormat("PrettyCompact", buf, sample, context); - auto res = std::make_shared( - std::make_shared(format), - sample, context.getSettingsRef().output_format_pretty_max_rows, 0); +// if (name == "PrettyCompactMonoBlock") +// { +// /// TODO: rewrite +// auto format = getOutputFormat("PrettyCompact", buf, sample, context); +// auto res = std::make_shared( +// std::make_shared(format), +// sample, context.getSettingsRef().output_format_pretty_max_rows, 0); +// +// res->disableFlush(); +// +// return std::make_shared(res, sample); +// } - res->disableFlush(); - - return std::make_shared(res, sample); - } + if (!getCreators(name).output_processor_creator) + return getOutput(name, buf, sample, context); auto format = getOutputFormat(name, buf, sample, context); @@ -128,7 +126,7 @@ InputFormatPtr FormatFactory::getInputFormat( UInt64 rows_portion_size, ReadCallback callback) const { - const auto & input_getter = getProcessorCreators(name).first; + const auto & input_getter = getCreators(name).input_processor_creator; if (!input_getter) throw Exception("Format " + name + " is not suitable for input", ErrorCodes::FORMAT_IS_NOT_SUITABLE_FOR_INPUT); @@ -150,7 +148,7 @@ InputFormatPtr FormatFactory::getInputFormat( OutputFormatPtr FormatFactory::getOutputFormat(const String & name, WriteBuffer & buf, const Block & sample, const Context & context) const { - const auto & output_getter = getProcessorCreators(name).second; + const auto & output_getter = getCreators(name).output_processor_creator; if (!output_getter) throw Exception("Format " + name + " is not suitable for output", ErrorCodes::FORMAT_IS_NOT_SUITABLE_FOR_OUTPUT); @@ -164,25 +162,25 @@ OutputFormatPtr FormatFactory::getOutputFormat(const String & name, WriteBuffer } -void FormatFactory::registerInputFormat(const String & /*name*/, InputCreator /*input_creator*/) +void FormatFactory::registerInputFormat(const String & name, InputCreator input_creator) { -// auto & target = dict[name].first; -// if (target) -// throw Exception("FormatFactory: Input format " + name + " is already registered", ErrorCodes::LOGICAL_ERROR); -// target = std::move(input_creator); + auto & target = dict[name].inout_creator; + if (target) + throw Exception("FormatFactory: Input format " + name + " is already registered", ErrorCodes::LOGICAL_ERROR); + target = std::move(input_creator); } -void FormatFactory::registerOutputFormat(const String & /*name*/, OutputCreator /*output_creator*/) +void FormatFactory::registerOutputFormat(const String & name, OutputCreator output_creator) { -// auto & target = dict[name].second; -// if (target) -// throw Exception("FormatFactory: Output format " + name + " is already registered", ErrorCodes::LOGICAL_ERROR); -// target = std::move(output_creator); + auto & target = dict[name].output_creator; + if (target) + throw Exception("FormatFactory: Output format " + name + " is already registered", ErrorCodes::LOGICAL_ERROR); + target = std::move(output_creator); } void FormatFactory::registerInputFormatProcessor(const String & name, InputProcessorCreator input_creator) { - auto & target = processors_dict[name].first; + auto & target = dict[name].input_processor_creator; if (target) throw Exception("FormatFactory: Input format " + name + " is already registered", ErrorCodes::LOGICAL_ERROR); target = std::move(input_creator); @@ -190,7 +188,7 @@ void FormatFactory::registerInputFormatProcessor(const String & name, InputProce void FormatFactory::registerOutputFormatProcessor(const String & name, OutputProcessorCreator output_creator) { - auto & target = processors_dict[name].second; + auto & target = dict[name].output_processor_creator; if (target) throw Exception("FormatFactory: Output format " + name + " is already registered", ErrorCodes::LOGICAL_ERROR); target = std::move(output_creator); diff --git a/dbms/src/Formats/FormatFactory.h b/dbms/src/Formats/FormatFactory.h index 23fd71aa9ad..83728c96cd2 100644 --- a/dbms/src/Formats/FormatFactory.h +++ b/dbms/src/Formats/FormatFactory.h @@ -70,11 +70,15 @@ private: const Context & context, const FormatSettings & settings)>; - using Creators = std::pair; - using ProcessorCreators = std::pair; + struct Creators + { + InputCreator inout_creator; + OutputCreator output_creator; + InputProcessorCreator input_processor_creator; + OutputProcessorCreator output_processor_creator; + }; using FormatsDictionary = std::unordered_map; - using FormatProcessorsDictionary = std::unordered_map; public: BlockInputStreamPtr getInput( @@ -108,20 +112,19 @@ public: void registerInputFormatProcessor(const String & name, InputProcessorCreator input_creator); void registerOutputFormatProcessor(const String & name, OutputProcessorCreator output_creator); - const FormatProcessorsDictionary & getAllFormats() const + const FormatsDictionary & getAllFormats() const { - return processors_dict; + return dict; } private: /// FormatsDictionary dict; - FormatProcessorsDictionary processors_dict; + FormatsDictionary dict; FormatFactory(); friend class ext::singleton; - //const Creators & getCreators(const String & name) const; - const ProcessorCreators & getProcessorCreators(const String & name) const; + const Creators & getCreators(const String & name) const; }; } From 18ade1708c029c78e6f159ea4454972aea2c0606 Mon Sep 17 00:00:00 2001 From: proller Date: Thu, 1 Aug 2019 12:56:17 +0000 Subject: [PATCH 0618/1165] Fix arm build --- dbms/src/Common/QueryProfiler.cpp | 5 ++++- dbms/src/Common/StackTrace.cpp | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index db977903c3b..def1d6c3f6e 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -186,7 +186,10 @@ QueryProfilerBase::QueryProfilerBase(const Int32 thread_id, const throw; } #else - UNUSED(thread_id, clock_type, period, pause_signal); + UNUSED(thread_id); + UNUSED(clock_type); + UNUSED(period); + UNUSED(pause_signal); throw Exception("QueryProfiler cannot work with stock libunwind", ErrorCodes::NOT_IMPLEMENTED); #endif } diff --git a/dbms/src/Common/StackTrace.cpp b/dbms/src/Common/StackTrace.cpp index a39eaf484e4..35399dd90d5 100644 --- a/dbms/src/Common/StackTrace.cpp +++ b/dbms/src/Common/StackTrace.cpp @@ -31,6 +31,8 @@ std::string signalToErrorMessage(int sig, const siginfo_t & info, const ucontext error << " Access: write."; else error << " Access: read."; +#else + UNUSED(context); #endif switch (info.si_code) From dd909322229eecb201e14a6fa83596aa578b2e33 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 18:06:31 +0300 Subject: [PATCH 0619/1165] Update FormatFactory. --- dbms/src/Storages/System/StorageSystemFormats.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dbms/src/Storages/System/StorageSystemFormats.cpp b/dbms/src/Storages/System/StorageSystemFormats.cpp index 96ce7ea7ed9..f0d97db5a98 100644 --- a/dbms/src/Storages/System/StorageSystemFormats.cpp +++ b/dbms/src/Storages/System/StorageSystemFormats.cpp @@ -20,9 +20,9 @@ void StorageSystemFormats::fillData(MutableColumns & res_columns, const Context const auto & formats = FormatFactory::instance().getAllFormats(); for (const auto & pair : formats) { - const auto & [name, creator_pair] = pair; - UInt64 has_input_format(creator_pair.first != nullptr); - UInt64 has_output_format(creator_pair.second != nullptr); + const auto & [name, creators] = pair; + UInt64 has_input_format(creators.inout_creator != nullptr || creators.input_processor_creator != nullptr); + UInt64 has_output_format(creators.output_creator != nullptr || creators.output_processor_creator != nullptr); res_columns[0]->insert(name); res_columns[1]->insert(has_input_format); res_columns[2]->insert(has_output_format); From 03ece9dc997cd925610477b2fd7fe1f8d66e7fea Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 18:21:48 +0300 Subject: [PATCH 0620/1165] Remove BinaryRowInputStream. --- dbms/src/Formats/BinaryRowInputStream.cpp | 91 ----------------------- dbms/src/Formats/BinaryRowInputStream.h | 30 -------- dbms/src/Formats/FormatFactory.cpp | 2 - 3 files changed, 123 deletions(-) delete mode 100644 dbms/src/Formats/BinaryRowInputStream.cpp delete mode 100644 dbms/src/Formats/BinaryRowInputStream.h diff --git a/dbms/src/Formats/BinaryRowInputStream.cpp b/dbms/src/Formats/BinaryRowInputStream.cpp deleted file mode 100644 index 9177a70bb18..00000000000 --- a/dbms/src/Formats/BinaryRowInputStream.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include -#include -#include -#include -#include - - -namespace DB -{ - -BinaryRowInputStream::BinaryRowInputStream(ReadBuffer & istr_, const Block & header_, bool with_names_, bool with_types_) - : istr(istr_), header(header_), with_names(with_names_), with_types(with_types_) -{ -} - - -bool BinaryRowInputStream::read(MutableColumns & columns, RowReadExtension &) -{ - if (istr.eof()) - return false; - - size_t num_columns = columns.size(); - for (size_t i = 0; i < num_columns; ++i) - header.getByPosition(i).type->deserializeBinary(*columns[i], istr); - - return true; -} - - -void BinaryRowInputStream::readPrefix() -{ - /// NOTE The header is completely ignored. This can be easily improved. - - UInt64 columns = 0; - String tmp; - - if (with_names || with_types) - { - readVarUInt(columns, istr); - } - - if (with_names) - { - for (size_t i = 0; i < columns; ++i) - { - readStringBinary(tmp, istr); - } - } - - if (with_types) - { - for (size_t i = 0; i < columns; ++i) - { - readStringBinary(tmp, istr); - } - } -} - - -void registerInputFormatRowBinary(FormatFactory & factory) -{ - factory.registerInputFormat("RowBinary", []( - ReadBuffer & buf, - const Block & sample, - const Context &, - UInt64 max_block_size, - UInt64 rows_portion_size, - FormatFactory::ReadCallback callback, - const FormatSettings & settings) - { - return std::make_shared( - std::make_shared(buf, sample, false, false), - sample, max_block_size, rows_portion_size, callback, settings); - }); - - factory.registerInputFormat("RowBinaryWithNamesAndTypes", []( - ReadBuffer & buf, - const Block & sample, - const Context &, - UInt64 max_block_size, - UInt64 rows_portion_size, - FormatFactory::ReadCallback callback, - const FormatSettings & settings) - { - return std::make_shared( - std::make_shared(buf, sample, true, true), - sample, max_block_size, rows_portion_size, callback, settings); - }); -} - -} diff --git a/dbms/src/Formats/BinaryRowInputStream.h b/dbms/src/Formats/BinaryRowInputStream.h deleted file mode 100644 index 43af4076f9c..00000000000 --- a/dbms/src/Formats/BinaryRowInputStream.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include - - -namespace DB -{ - -class ReadBuffer; - - -/** A stream for inputting data in a binary line-by-line format. - */ -class BinaryRowInputStream : public IRowInputStream -{ -public: - BinaryRowInputStream(ReadBuffer & istr_, const Block & sample_, bool with_names_, bool with_types_); - - bool read(MutableColumns & columns, RowReadExtension &) override; - void readPrefix() override; - -private: - ReadBuffer & istr; - Block header; - bool with_names; - bool with_types; -}; - -} diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 820be203c6a..7a83ff2e7ae 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -199,7 +199,6 @@ void FormatFactory::registerOutputFormatProcessor(const String & name, OutputPro void registerInputFormatNative(FormatFactory & factory); void registerOutputFormatNative(FormatFactory & factory); -void registerInputFormatRowBinary(FormatFactory & factory); void registerOutputFormatRowBinary(FormatFactory & factory); void registerInputFormatTabSeparated(FormatFactory & factory); void registerOutputFormatTabSeparated(FormatFactory & factory); @@ -271,7 +270,6 @@ FormatFactory::FormatFactory() { registerInputFormatNative(*this); registerOutputFormatNative(*this); - registerInputFormatRowBinary(*this); registerOutputFormatRowBinary(*this); registerInputFormatTabSeparated(*this); registerOutputFormatTabSeparated(*this); From 342f044241a6d73de36cf2a56622a44bce8689c3 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 18:25:32 +0300 Subject: [PATCH 0621/1165] Remove BinaryRowOutputStream. --- dbms/src/Formats/BinaryRowOutputStream.cpp | 77 ---------------------- dbms/src/Formats/BinaryRowOutputStream.h | 37 ----------- dbms/src/Formats/FormatFactory.cpp | 2 - 3 files changed, 116 deletions(-) delete mode 100644 dbms/src/Formats/BinaryRowOutputStream.cpp delete mode 100644 dbms/src/Formats/BinaryRowOutputStream.h diff --git a/dbms/src/Formats/BinaryRowOutputStream.cpp b/dbms/src/Formats/BinaryRowOutputStream.cpp deleted file mode 100644 index bbc01f5db04..00000000000 --- a/dbms/src/Formats/BinaryRowOutputStream.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - - -namespace DB -{ - -BinaryRowOutputStream::BinaryRowOutputStream(WriteBuffer & ostr_, const Block & sample_, bool with_names_, bool with_types_) - : ostr(ostr_), with_names(with_names_), with_types(with_types_), sample(sample_) -{ -} - -void BinaryRowOutputStream::writePrefix() -{ - size_t columns = sample.columns(); - - if (with_names || with_types) - { - writeVarUInt(columns, ostr); - } - - if (with_names) - { - for (size_t i = 0; i < columns; ++i) - { - writeStringBinary(sample.safeGetByPosition(i).name, ostr); - } - } - - if (with_types) - { - for (size_t i = 0; i < columns; ++i) - { - writeStringBinary(sample.safeGetByPosition(i).type->getName(), ostr); - } - } -} - -void BinaryRowOutputStream::flush() -{ - ostr.next(); -} - -void BinaryRowOutputStream::writeField(const IColumn & column, const IDataType & type, size_t row_num) -{ - type.serializeBinary(column, row_num, ostr); -} - -void registerOutputFormatRowBinary(FormatFactory & factory) -{ - factory.registerOutputFormat("RowBinary", []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings &) - { - return std::make_shared( - std::make_shared(buf, sample, false, false), sample); - }); - - factory.registerOutputFormat("RowBinaryWithNamesAndTypes", []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings &) - { - return std::make_shared( - std::make_shared(buf, sample, true, true), sample); - }); -} - -} diff --git a/dbms/src/Formats/BinaryRowOutputStream.h b/dbms/src/Formats/BinaryRowOutputStream.h deleted file mode 100644 index d16bcfa6c03..00000000000 --- a/dbms/src/Formats/BinaryRowOutputStream.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include -#include - - -namespace DB -{ - -class IColumn; -class IDataType; -class WriteBuffer; - - -/** A stream for outputting data in a binary line-by-line format. - */ -class BinaryRowOutputStream : public IRowOutputStream -{ -public: - BinaryRowOutputStream(WriteBuffer & ostr_, const Block & sample_, bool with_names_, bool with_types_); - - void writeField(const IColumn & column, const IDataType & type, size_t row_num) override; - void writePrefix() override; - - void flush() override; - - String getContentType() const override { return "application/octet-stream"; } - -protected: - WriteBuffer & ostr; - bool with_names; - bool with_types; - const Block sample; -}; - -} - diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 7a83ff2e7ae..ee569b3fa60 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -199,7 +199,6 @@ void FormatFactory::registerOutputFormatProcessor(const String & name, OutputPro void registerInputFormatNative(FormatFactory & factory); void registerOutputFormatNative(FormatFactory & factory); -void registerOutputFormatRowBinary(FormatFactory & factory); void registerInputFormatTabSeparated(FormatFactory & factory); void registerOutputFormatTabSeparated(FormatFactory & factory); void registerInputFormatValues(FormatFactory & factory); @@ -270,7 +269,6 @@ FormatFactory::FormatFactory() { registerInputFormatNative(*this); registerOutputFormatNative(*this); - registerOutputFormatRowBinary(*this); registerInputFormatTabSeparated(*this); registerOutputFormatTabSeparated(*this); registerInputFormatValues(*this); From 2833ca6d2f210923f5693c9b29985f2c651a2c5b Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 18:28:13 +0300 Subject: [PATCH 0622/1165] Remove CapnProtoRowInputStream. --- dbms/src/Formats/CapnProtoRowInputStream.cpp | 334 ------------------- dbms/src/Formats/CapnProtoRowInputStream.h | 76 ----- dbms/src/Formats/FormatFactory.cpp | 4 - 3 files changed, 414 deletions(-) delete mode 100644 dbms/src/Formats/CapnProtoRowInputStream.cpp delete mode 100644 dbms/src/Formats/CapnProtoRowInputStream.h diff --git a/dbms/src/Formats/CapnProtoRowInputStream.cpp b/dbms/src/Formats/CapnProtoRowInputStream.cpp deleted file mode 100644 index 96c3c5fded3..00000000000 --- a/dbms/src/Formats/CapnProtoRowInputStream.cpp +++ /dev/null @@ -1,334 +0,0 @@ -#include "config_formats.h" -#if USE_CAPNP - -#include "CapnProtoRowInputStream.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace DB -{ - -namespace ErrorCodes -{ - extern const int BAD_TYPE_OF_FIELD; - extern const int BAD_ARGUMENTS; - extern const int THERE_IS_NO_COLUMN; - extern const int LOGICAL_ERROR; -} - -CapnProtoRowInputStream::NestedField split(const Block & header, size_t i) -{ - CapnProtoRowInputStream::NestedField field = {{}, i}; - - // Remove leading dot in field definition, e.g. ".msg" -> "msg" - String name(header.safeGetByPosition(i).name); - if (name.size() > 0 && name[0] == '.') - name.erase(0, 1); - - boost::split(field.tokens, name, boost::is_any_of("._")); - return field; -} - - -Field convertNodeToField(capnp::DynamicValue::Reader value) -{ - switch (value.getType()) - { - case capnp::DynamicValue::UNKNOWN: - throw Exception("Unknown field type", ErrorCodes::BAD_TYPE_OF_FIELD); - case capnp::DynamicValue::VOID: - return Field(); - case capnp::DynamicValue::BOOL: - return value.as() ? 1u : 0u; - case capnp::DynamicValue::INT: - return value.as(); - case capnp::DynamicValue::UINT: - return value.as(); - case capnp::DynamicValue::FLOAT: - return value.as(); - case capnp::DynamicValue::TEXT: - { - auto arr = value.as(); - return String(arr.begin(), arr.size()); - } - case capnp::DynamicValue::DATA: - { - auto arr = value.as().asChars(); - return String(arr.begin(), arr.size()); - } - case capnp::DynamicValue::LIST: - { - auto listValue = value.as(); - Array res(listValue.size()); - for (auto i : kj::indices(listValue)) - res[i] = convertNodeToField(listValue[i]); - - return res; - } - case capnp::DynamicValue::ENUM: - return value.as().getRaw(); - case capnp::DynamicValue::STRUCT: - { - auto structValue = value.as(); - const auto & fields = structValue.getSchema().getFields(); - - Field field = Tuple(TupleBackend(fields.size())); - TupleBackend & tuple = get(field).toUnderType(); - for (auto i : kj::indices(fields)) - tuple[i] = convertNodeToField(structValue.get(fields[i])); - - return field; - } - case capnp::DynamicValue::CAPABILITY: - throw Exception("CAPABILITY type not supported", ErrorCodes::BAD_TYPE_OF_FIELD); - case capnp::DynamicValue::ANY_POINTER: - throw Exception("ANY_POINTER type not supported", ErrorCodes::BAD_TYPE_OF_FIELD); - } - return Field(); -} - -capnp::StructSchema::Field getFieldOrThrow(capnp::StructSchema node, const std::string & field) -{ - KJ_IF_MAYBE(child, node.findFieldByName(field)) - return *child; - else - throw Exception("Field " + field + " doesn't exist in schema " + node.getShortDisplayName().cStr(), ErrorCodes::THERE_IS_NO_COLUMN); -} - - -void CapnProtoRowInputStream::createActions(const NestedFieldList & sorted_fields, capnp::StructSchema reader) -{ - /// Columns in a table can map to fields in Cap'n'Proto or to structs. - - /// Store common parents and their tokens in order to backtrack. - std::vector parents; - std::vector parent_tokens; - - capnp::StructSchema cur_reader = reader; - - for (const auto & field : sorted_fields) - { - if (field.tokens.empty()) - throw Exception("Logical error in CapnProtoRowInputStream", ErrorCodes::LOGICAL_ERROR); - - // Backtrack to common parent - while (field.tokens.size() < parent_tokens.size() + 1 - || !std::equal(parent_tokens.begin(), parent_tokens.end(), field.tokens.begin())) - { - actions.push_back({Action::POP}); - parents.pop_back(); - parent_tokens.pop_back(); - - if (parents.empty()) - { - cur_reader = reader; - break; - } - else - cur_reader = parents.back().getType().asStruct(); - } - - // Go forward - while (parent_tokens.size() + 1 < field.tokens.size()) - { - const auto & token = field.tokens[parents.size()]; - auto node = getFieldOrThrow(cur_reader, token); - if (node.getType().isStruct()) - { - // Descend to field structure - parents.emplace_back(node); - parent_tokens.emplace_back(token); - cur_reader = node.getType().asStruct(); - actions.push_back({Action::PUSH, node}); - } - else if (node.getType().isList()) - { - break; // Collect list - } - else - throw Exception("Field " + token + " is neither Struct nor List", ErrorCodes::BAD_TYPE_OF_FIELD); - } - - // Read field from the structure - auto node = getFieldOrThrow(cur_reader, field.tokens[parents.size()]); - if (node.getType().isList() && actions.size() > 0 && actions.back().field == node) - { - // The field list here flattens Nested elements into multiple arrays - // In order to map Nested types in Cap'nProto back, they need to be collected - // Since the field names are sorted, the order of field positions must be preserved - // For example, if the fields are { b @0 :Text, a @1 :Text }, the `a` would come first - // even though it's position is second. - auto & columns = actions.back().columns; - auto it = std::upper_bound(columns.cbegin(), columns.cend(), field.pos); - columns.insert(it, field.pos); - } - else - { - actions.push_back({Action::READ, node, {field.pos}}); - } - } -} - -CapnProtoRowInputStream::CapnProtoRowInputStream(ReadBuffer & istr_, const Block & header_, const FormatSchemaInfo& info) - : istr(istr_), header(header_), parser(std::make_shared()) -{ - // Parse the schema and fetch the root object - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - auto schema = parser->impl.parseDiskFile(info.schemaPath(), info.absoluteSchemaPath(), {}); -#pragma GCC diagnostic pop - - root = schema.getNested(info.messageName()).asStruct(); - - /** - * The schema typically consists of fields in various nested structures. - * Here we gather the list of fields and sort them in a way so that fields in the same structure are adjacent, - * and the nesting level doesn't decrease to make traversal easier. - */ - NestedFieldList list; - size_t num_columns = header.columns(); - for (size_t i = 0; i < num_columns; ++i) - list.push_back(split(header, i)); - - // Order list first by value of strings then by length of string vector. - std::sort(list.begin(), list.end(), [](const NestedField & a, const NestedField & b) { return a.tokens < b.tokens; }); - createActions(list, root); -} - -kj::Array CapnProtoRowInputStream::readMessage() -{ - uint32_t segment_count; - istr.readStrict(reinterpret_cast(&segment_count), sizeof(uint32_t)); - - // one for segmentCount and one because segmentCount starts from 0 - const auto prefix_size = (2 + segment_count) * sizeof(uint32_t); - const auto words_prefix_size = (segment_count + 1) / 2 + 1; - auto prefix = kj::heapArray(words_prefix_size); - auto prefix_chars = prefix.asChars(); - ::memcpy(prefix_chars.begin(), &segment_count, sizeof(uint32_t)); - - // read size of each segment - for (size_t i = 0; i <= segment_count; ++i) - istr.readStrict(prefix_chars.begin() + ((i + 1) * sizeof(uint32_t)), sizeof(uint32_t)); - - // calculate size of message - const auto expected_words = capnp::expectedSizeInWordsFromPrefix(prefix); - const auto expected_bytes = expected_words * sizeof(capnp::word); - const auto data_size = expected_bytes - prefix_size; - auto msg = kj::heapArray(expected_words); - auto msg_chars = msg.asChars(); - - // read full message - ::memcpy(msg_chars.begin(), prefix_chars.begin(), prefix_size); - istr.readStrict(msg_chars.begin() + prefix_size, data_size); - - return msg; -} - -bool CapnProtoRowInputStream::read(MutableColumns & columns, RowReadExtension &) -{ - if (istr.eof()) - return false; - - auto array = readMessage(); - -#if CAPNP_VERSION >= 8000 - capnp::UnalignedFlatArrayMessageReader msg(array); -#else - capnp::FlatArrayMessageReader msg(array); -#endif - std::vector stack; - stack.push_back(msg.getRoot(root)); - - for (auto action : actions) - { - switch (action.type) - { - case Action::READ: - { - Field value = convertNodeToField(stack.back().get(action.field)); - if (action.columns.size() > 1) - { - // Nested columns must be flattened into several arrays - // e.g. Array(Tuple(x ..., y ...)) -> Array(x ...), Array(y ...) - const Array & collected = DB::get(value); - size_t size = collected.size(); - // The flattened array contains an array of a part of the nested tuple - Array flattened(size); - for (size_t column_index = 0; column_index < action.columns.size(); ++column_index) - { - // Populate array with a single tuple elements - for (size_t off = 0; off < size; ++off) - { - const TupleBackend & tuple = DB::get(collected[off]).toUnderType(); - flattened[off] = tuple[column_index]; - } - auto & col = columns[action.columns[column_index]]; - col->insert(flattened); - } - } - else - { - auto & col = columns[action.columns[0]]; - col->insert(value); - } - - break; - } - case Action::POP: - stack.pop_back(); - break; - case Action::PUSH: - stack.push_back(stack.back().get(action.field).as()); - break; - } - } - - return true; -} - -void registerInputFormatCapnProto(FormatFactory & factory) -{ - factory.registerInputFormat( - "CapnProto", - [](ReadBuffer & buf, - const Block & sample, - const Context & context, - UInt64 max_block_size, - UInt64 rows_portion_size, - FormatFactory::ReadCallback callback, - const FormatSettings & settings) - { - return std::make_shared( - std::make_shared(buf, sample, FormatSchemaInfo(context, "CapnProto")), - sample, - max_block_size, - rows_portion_size, - callback, - settings); - }); -} - -} - -#else - -namespace DB -{ - class FormatFactory; - void registerInputFormatCapnProto(FormatFactory &) {} -} - -#endif // USE_CAPNP diff --git a/dbms/src/Formats/CapnProtoRowInputStream.h b/dbms/src/Formats/CapnProtoRowInputStream.h deleted file mode 100644 index 07023c3eb4c..00000000000 --- a/dbms/src/Formats/CapnProtoRowInputStream.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once -#include "config_formats.h" -#if USE_CAPNP - -#include -#include -#include - -namespace DB -{ - -class FormatSchemaInfo; -class ReadBuffer; - -/** A stream for reading messages in Cap'n Proto format in given schema. - * Like Protocol Buffers and Thrift (but unlike JSON or MessagePack), - * Cap'n Proto messages are strongly-typed and not self-describing. - * The schema in this case cannot be compiled in, so it uses a runtime schema parser. - * See https://capnproto.org/cxx.html - */ -class CapnProtoRowInputStream : public IRowInputStream -{ -public: - struct NestedField - { - std::vector tokens; - size_t pos; - }; - using NestedFieldList = std::vector; - - /** schema_dir - base path for schema files - * schema_file - location of the capnproto schema, e.g. "schema.capnp" - * root_object - name to the root object, e.g. "Message" - */ - CapnProtoRowInputStream(ReadBuffer & istr_, const Block & header_, const FormatSchemaInfo & info); - - bool read(MutableColumns & columns, RowReadExtension &) override; - -private: - kj::Array readMessage(); - - // Build a traversal plan from a sorted list of fields - void createActions(const NestedFieldList & sortedFields, capnp::StructSchema reader); - - /* Action for state machine for traversing nested structures. */ - using BlockPositionList = std::vector; - struct Action - { - enum Type { POP, PUSH, READ }; - Type type{}; - capnp::StructSchema::Field field{}; - BlockPositionList columns{}; - }; - - // Wrapper for classes that could throw in destructor - // https://github.com/capnproto/capnproto/issues/553 - template - struct DestructorCatcher - { - T impl; - template - DestructorCatcher(Arg && ... args) : impl(kj::fwd(args)...) {} - ~DestructorCatcher() noexcept try { } catch (...) { return; } - }; - using SchemaParser = DestructorCatcher; - - ReadBuffer & istr; - Block header; - std::shared_ptr parser; - capnp::StructSchema root; - std::vector actions; -}; - -} - -#endif // USE_CAPNP diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index ee569b3fa60..7cc02f0938d 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -260,11 +260,8 @@ void registerOutputFormatProcessorNull(FormatFactory & factory); void registerOutputFormatProcessorMySQLWrite(FormatFactory & factory); /// Input only formats. - -void registerInputFormatCapnProto(FormatFactory & factory); void registerInputFormatProcessorCapnProto(FormatFactory & factory); - FormatFactory::FormatFactory() { registerInputFormatNative(*this); @@ -281,7 +278,6 @@ FormatFactory::FormatFactory() registerOutputFormatJSONEachRow(*this); registerInputFormatProtobuf(*this); registerOutputFormatProtobuf(*this); - registerInputFormatCapnProto(*this); registerInputFormatParquet(*this); registerOutputFormatParquet(*this); From cd299bb162f2d55fb5e5772f6ecf77b63cf69cfd Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 18:32:07 +0300 Subject: [PATCH 0623/1165] Remove JSONCompactRowOutputStream. --- dbms/src/Formats/FormatFactory.cpp | 2 - .../Formats/JSONCompactRowOutputStream.cpp | 120 ------------------ dbms/src/Formats/JSONCompactRowOutputStream.h | 31 ----- 3 files changed, 153 deletions(-) delete mode 100644 dbms/src/Formats/JSONCompactRowOutputStream.cpp delete mode 100644 dbms/src/Formats/JSONCompactRowOutputStream.h diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 7cc02f0938d..0448e45a444 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -240,7 +240,6 @@ void registerOutputFormatPrettyCompact(FormatFactory & factory); void registerOutputFormatPrettySpace(FormatFactory & factory); void registerOutputFormatVertical(FormatFactory & factory); void registerOutputFormatJSON(FormatFactory & factory); -void registerOutputFormatJSONCompact(FormatFactory & factory); void registerOutputFormatXML(FormatFactory & factory); void registerOutputFormatODBCDriver(FormatFactory & factory); void registerOutputFormatODBCDriver2(FormatFactory & factory); @@ -308,7 +307,6 @@ FormatFactory::FormatFactory() registerOutputFormatPrettySpace(*this); registerOutputFormatVertical(*this); registerOutputFormatJSON(*this); - registerOutputFormatJSONCompact(*this); registerOutputFormatXML(*this); registerOutputFormatODBCDriver(*this); registerOutputFormatODBCDriver2(*this); diff --git a/dbms/src/Formats/JSONCompactRowOutputStream.cpp b/dbms/src/Formats/JSONCompactRowOutputStream.cpp deleted file mode 100644 index b9d54604c51..00000000000 --- a/dbms/src/Formats/JSONCompactRowOutputStream.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include -#include - -#include - - -namespace DB -{ - -JSONCompactRowOutputStream::JSONCompactRowOutputStream(WriteBuffer & ostr_, const Block & sample_, const FormatSettings & settings_) - : JSONRowOutputStream(ostr_, sample_, settings_) -{ -} - - -void JSONCompactRowOutputStream::writeField(const IColumn & column, const IDataType & type, size_t row_num) -{ - type.serializeAsTextJSON(column, row_num, *ostr, settings); - ++field_number; -} - - -void JSONCompactRowOutputStream::writeFieldDelimiter() -{ - writeCString(", ", *ostr); -} - - -void JSONCompactRowOutputStream::writeRowStartDelimiter() -{ - if (row_count > 0) - writeCString(",\n", *ostr); - writeCString("\t\t[", *ostr); -} - - -void JSONCompactRowOutputStream::writeRowEndDelimiter() -{ - writeChar(']', *ostr); - field_number = 0; - ++row_count; -} - - -void JSONCompactRowOutputStream::writeTotals() -{ - if (totals) - { - writeCString(",\n", *ostr); - writeChar('\n', *ostr); - writeCString("\t\"totals\": [", *ostr); - - size_t totals_columns = totals.columns(); - for (size_t i = 0; i < totals_columns; ++i) - { - if (i != 0) - writeChar(',', *ostr); - - const ColumnWithTypeAndName & column = totals.safeGetByPosition(i); - column.type->serializeAsTextJSON(*column.column.get(), 0, *ostr, settings); - } - - writeChar(']', *ostr); - } -} - - -static void writeExtremesElement(const char * title, const Block & extremes, size_t row_num, WriteBuffer & ostr, const FormatSettings & settings) -{ - writeCString("\t\t\"", ostr); - writeCString(title, ostr); - writeCString("\": [", ostr); - - size_t extremes_columns = extremes.columns(); - for (size_t i = 0; i < extremes_columns; ++i) - { - if (i != 0) - writeChar(',', ostr); - - const ColumnWithTypeAndName & column = extremes.safeGetByPosition(i); - column.type->serializeAsTextJSON(*column.column.get(), row_num, ostr, settings); - } - - writeChar(']', ostr); -} - -void JSONCompactRowOutputStream::writeExtremes() -{ - if (extremes) - { - writeCString(",\n", *ostr); - writeChar('\n', *ostr); - writeCString("\t\"extremes\":\n", *ostr); - writeCString("\t{\n", *ostr); - - writeExtremesElement("min", extremes, 0, *ostr, settings); - writeCString(",\n", *ostr); - writeExtremesElement("max", extremes, 1, *ostr, settings); - - writeChar('\n', *ostr); - writeCString("\t}", *ostr); - } -} - - -void registerOutputFormatJSONCompact(FormatFactory & factory) -{ - factory.registerOutputFormat("JSONCompact", []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & format_settings) - { - return std::make_shared( - std::make_shared(buf, sample, format_settings), sample); - }); -} - -} diff --git a/dbms/src/Formats/JSONCompactRowOutputStream.h b/dbms/src/Formats/JSONCompactRowOutputStream.h deleted file mode 100644 index 726e0d4acaa..00000000000 --- a/dbms/src/Formats/JSONCompactRowOutputStream.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include -#include -#include -#include - - -namespace DB -{ - -struct FormatSettings; - -/** The stream for outputting data in the JSONCompact format. - */ -class JSONCompactRowOutputStream : public JSONRowOutputStream -{ -public: - JSONCompactRowOutputStream(WriteBuffer & ostr_, const Block & sample_, const FormatSettings & settings); - - void writeField(const IColumn & column, const IDataType & type, size_t row_num) override; - void writeFieldDelimiter() override; - void writeRowStartDelimiter() override; - void writeRowEndDelimiter() override; - -protected: - void writeTotals() override; - void writeExtremes() override; -}; - -} From ae50ab69073211a408978833ab40a5875ea19fe1 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 18:36:36 +0300 Subject: [PATCH 0624/1165] Remove JSONEachRowRowInputStream. --- dbms/src/Formats/FormatFactory.cpp | 2 - .../src/Formats/JSONEachRowRowInputStream.cpp | 272 ------------------ dbms/src/Formats/JSONEachRowRowInputStream.h | 68 ----- .../Formats/Impl/JSONEachRowRowInputFormat.h | 2 +- 4 files changed, 1 insertion(+), 343 deletions(-) delete mode 100644 dbms/src/Formats/JSONEachRowRowInputStream.cpp delete mode 100644 dbms/src/Formats/JSONEachRowRowInputStream.h diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 0448e45a444..d49c630cd82 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -207,7 +207,6 @@ void registerInputFormatCSV(FormatFactory & factory); void registerOutputFormatCSV(FormatFactory & factory); void registerInputFormatTSKV(FormatFactory & factory); void registerOutputFormatTSKV(FormatFactory & factory); -void registerInputFormatJSONEachRow(FormatFactory & factory); void registerOutputFormatJSONEachRow(FormatFactory & factory); void registerInputFormatParquet(FormatFactory & factory); void registerOutputFormatParquet(FormatFactory & factory); @@ -273,7 +272,6 @@ FormatFactory::FormatFactory() registerOutputFormatCSV(*this); registerInputFormatTSKV(*this); registerOutputFormatTSKV(*this); - registerInputFormatJSONEachRow(*this); registerOutputFormatJSONEachRow(*this); registerInputFormatProtobuf(*this); registerOutputFormatProtobuf(*this); diff --git a/dbms/src/Formats/JSONEachRowRowInputStream.cpp b/dbms/src/Formats/JSONEachRowRowInputStream.cpp deleted file mode 100644 index 72acf722ae7..00000000000 --- a/dbms/src/Formats/JSONEachRowRowInputStream.cpp +++ /dev/null @@ -1,272 +0,0 @@ -#include - -#include -#include -#include -#include - -namespace DB -{ - -namespace ErrorCodes -{ - extern const int INCORRECT_DATA; - extern const int CANNOT_READ_ALL_DATA; - extern const int LOGICAL_ERROR; -} - -namespace -{ - -enum -{ - UNKNOWN_FIELD = size_t(-1), - NESTED_FIELD = size_t(-2) -}; - -} - - -JSONEachRowRowInputStream::JSONEachRowRowInputStream(ReadBuffer & istr_, const Block & header_, const FormatSettings & format_settings) - : istr(istr_), header(header_), format_settings(format_settings), name_map(header.columns()) -{ - /// In this format, BOM at beginning of stream cannot be confused with value, so it is safe to skip it. - skipBOMIfExists(istr); - - size_t num_columns = header.columns(); - for (size_t i = 0; i < num_columns; ++i) - { - const String & colname = columnName(i); - name_map[colname] = i; /// NOTE You could place names more cache-locally. - if (format_settings.import_nested_json) - { - const auto splitted = Nested::splitName(colname); - if (!splitted.second.empty()) - { - const StringRef table_name(colname.data(), splitted.first.size()); - name_map[table_name] = NESTED_FIELD; - } - } - } - - prev_positions.assign(num_columns, name_map.end()); -} - -const String & JSONEachRowRowInputStream::columnName(size_t i) const -{ - return header.getByPosition(i).name; -} - -inline size_t JSONEachRowRowInputStream::columnIndex(const StringRef & name, size_t key_index) -{ - /// Optimization by caching the order of fields (which is almost always the same) - /// and a quick check to match the next expected field, instead of searching the hash table. - - if (prev_positions.size() > key_index - && prev_positions[key_index] != name_map.end() - && name == prev_positions[key_index]->getFirst()) - { - return prev_positions[key_index]->getSecond(); - } - else - { - const auto it = name_map.find(name); - - if (name_map.end() != it) - { - if (key_index < prev_positions.size()) - prev_positions[key_index] = it; - - return it->getSecond(); - } - else - return UNKNOWN_FIELD; - } -} - -/** Read the field name and convert it to column name - * (taking into account the current nested name prefix) - * Resulting StringRef is valid only before next read from buf. - */ -StringRef JSONEachRowRowInputStream::readColumnName(ReadBuffer & buf) -{ - // This is just an optimization: try to avoid copying the name into current_column_name - - if (nested_prefix_length == 0 && buf.position() + 1 < buf.buffer().end()) - { - char * next_pos = find_first_symbols<'\\', '"'>(buf.position() + 1, buf.buffer().end()); - - if (next_pos != buf.buffer().end() && *next_pos != '\\') - { - /// The most likely option is that there is no escape sequence in the key name, and the entire name is placed in the buffer. - assertChar('"', buf); - StringRef res(buf.position(), next_pos - buf.position()); - buf.position() = next_pos + 1; - return res; - } - } - - current_column_name.resize(nested_prefix_length); - readJSONStringInto(current_column_name, buf); - return current_column_name; -} - - -static inline void skipColonDelimeter(ReadBuffer & istr) -{ - skipWhitespaceIfAny(istr); - assertChar(':', istr); - skipWhitespaceIfAny(istr); -} - -void JSONEachRowRowInputStream::skipUnknownField(const StringRef & name_ref) -{ - if (!format_settings.skip_unknown_fields) - throw Exception("Unknown field found while parsing JSONEachRow format: " + name_ref.toString(), ErrorCodes::INCORRECT_DATA); - - skipJSONField(istr, name_ref); -} - -void JSONEachRowRowInputStream::readField(size_t index, MutableColumns & columns) -{ - if (read_columns[index]) - throw Exception("Duplicate field found while parsing JSONEachRow format: " + columnName(index), ErrorCodes::INCORRECT_DATA); - - try - { - header.getByPosition(index).type->deserializeAsTextJSON(*columns[index], istr, format_settings); - } - catch (Exception & e) - { - e.addMessage("(while read the value of key " + columnName(index) + ")"); - throw; - } - - read_columns[index] = true; -} - -inline bool JSONEachRowRowInputStream::advanceToNextKey(size_t key_index) -{ - skipWhitespaceIfAny(istr); - - if (istr.eof()) - throw Exception("Unexpected end of stream while parsing JSONEachRow format", ErrorCodes::CANNOT_READ_ALL_DATA); - else if (*istr.position() == '}') - { - ++istr.position(); - return false; - } - - if (key_index > 0) - { - assertChar(',', istr); - skipWhitespaceIfAny(istr); - } - return true; -} - -void JSONEachRowRowInputStream::readJSONObject(MutableColumns & columns) -{ - assertChar('{', istr); - - for (size_t key_index = 0; advanceToNextKey(key_index); ++key_index) - { - StringRef name_ref = readColumnName(istr); - const size_t column_index = columnIndex(name_ref, key_index); - - if (unlikely(ssize_t(column_index) < 0)) - { - /// name_ref may point directly to the input buffer - /// and input buffer may be filled with new data on next read - /// If we want to use name_ref after another reads from buffer, we must copy it to temporary string. - - current_column_name.assign(name_ref.data, name_ref.size); - name_ref = StringRef(current_column_name); - - skipColonDelimeter(istr); - - if (column_index == UNKNOWN_FIELD) - skipUnknownField(name_ref); - else if (column_index == NESTED_FIELD) - readNestedData(name_ref.toString(), columns); - else - throw Exception("Logical error: illegal value of column_index", ErrorCodes::LOGICAL_ERROR); - } - else - { - skipColonDelimeter(istr); - readField(column_index, columns); - } - } -} - -void JSONEachRowRowInputStream::readNestedData(const String & name, MutableColumns & columns) -{ - current_column_name = name; - current_column_name.push_back('.'); - nested_prefix_length = current_column_name.size(); - readJSONObject(columns); - nested_prefix_length = 0; -} - - -bool JSONEachRowRowInputStream::read(MutableColumns & columns, RowReadExtension & ext) -{ - skipWhitespaceIfAny(istr); - - /// We consume ;, or \n before scanning a new row, instead scanning to next row at the end. - /// The reason is that if we want an exact number of rows read with LIMIT x - /// from a streaming table engine with text data format, like File or Kafka - /// then seeking to next ;, or \n would trigger reading of an extra row at the end. - - /// Semicolon is added for convenience as it could be used at end of INSERT query. - if (!istr.eof() && (*istr.position() == ',' || *istr.position() == ';')) - ++istr.position(); - - skipWhitespaceIfAny(istr); - if (istr.eof()) - return false; - - size_t num_columns = columns.size(); - - /// Set of columns for which the values were read. The rest will be filled with default values. - read_columns.assign(num_columns, false); - - nested_prefix_length = 0; - readJSONObject(columns); - - /// Fill non-visited columns with the default values. - for (size_t i = 0; i < num_columns; ++i) - if (!read_columns[i]) - header.getByPosition(i).type->insertDefaultInto(*columns[i]); - - /// return info about defaults set - ext.read_columns = read_columns; - return true; -} - - -void JSONEachRowRowInputStream::syncAfterError() -{ - skipToUnescapedNextLineOrEOF(istr); -} - - -void registerInputFormatJSONEachRow(FormatFactory & factory) -{ - factory.registerInputFormat("JSONEachRow", []( - ReadBuffer & buf, - const Block & sample, - const Context &, - UInt64 max_block_size, - UInt64 rows_portion_size, - FormatFactory::ReadCallback callback, - const FormatSettings & settings) - { - return std::make_shared( - std::make_shared(buf, sample, settings), - sample, max_block_size, rows_portion_size, callback, settings); - }); -} - -} diff --git a/dbms/src/Formats/JSONEachRowRowInputStream.h b/dbms/src/Formats/JSONEachRowRowInputStream.h deleted file mode 100644 index 726b63b084e..00000000000 --- a/dbms/src/Formats/JSONEachRowRowInputStream.h +++ /dev/null @@ -1,68 +0,0 @@ -#pragma once - -#include -#include -#include -#include - - -namespace DB -{ - -class ReadBuffer; - - -/** A stream for reading data in JSON format, where each row is represented by a separate JSON object. - * Objects can be separated by line feed, other whitespace characters in any number and possibly a comma. - * Fields can be listed in any order (including, in different lines there may be different order), - * and some fields may be missing. - */ -class JSONEachRowRowInputStream : public IRowInputStream -{ -public: - JSONEachRowRowInputStream(ReadBuffer & istr_, const Block & header_, const FormatSettings & format_settings); - - bool read(MutableColumns & columns, RowReadExtension & ext) override; - bool allowSyncAfterError() const override { return true; } - void syncAfterError() override; - -private: - const String & columnName(size_t i) const; - size_t columnIndex(const StringRef & name, size_t key_index); - bool advanceToNextKey(size_t key_index); - void skipUnknownField(const StringRef & name_ref); - StringRef readColumnName(ReadBuffer & buf); - void readField(size_t index, MutableColumns & columns); - void readJSONObject(MutableColumns & columns); - void readNestedData(const String & name, MutableColumns & columns); - -private: - ReadBuffer & istr; - Block header; - - const FormatSettings format_settings; - - /// Buffer for the read from the stream field name. Used when you have to copy it. - /// Also, if processing of Nested data is in progress, it holds the common prefix - /// of the nested column names (so that appending the field name to it produces - /// the full column name) - String current_column_name; - - /// If processing Nested data, holds the length of the common prefix - /// of the names of related nested columns. For example, for a table - /// created as follows - /// CREATE TABLE t (n Nested (i Int32, s String)) - /// the nested column names are 'n.i' and 'n.s' and the nested prefix is 'n.' - size_t nested_prefix_length = 0; - - std::vector read_columns; - - /// Hash table match `field name -> position in the block`. NOTE You can use perfect hash map. - using NameMap = HashMap; - NameMap name_map; - - /// Cached search results for previous row (keyed as index in JSON object) - used as a hint. - std::vector prev_positions; -}; - -} diff --git a/dbms/src/Processors/Formats/Impl/JSONEachRowRowInputFormat.h b/dbms/src/Processors/Formats/Impl/JSONEachRowRowInputFormat.h index 901e35af6e8..1aed7c9dc49 100644 --- a/dbms/src/Processors/Formats/Impl/JSONEachRowRowInputFormat.h +++ b/dbms/src/Processors/Formats/Impl/JSONEachRowRowInputFormat.h @@ -13,7 +13,7 @@ class ReadBuffer; /** A stream for reading data in JSON format, where each row is represented by a separate JSON object. - * Objects can be separated by feed return, other whitespace characters in any number and possibly a comma. + * Objects can be separated by line feed, other whitespace characters in any number and possibly a comma. * Fields can be listed in any order (including, in different lines there may be different order), * and some fields may be missing. */ From d808fafa8ff7ba692e5eeda28c0574544cf113cb Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov Date: Fri, 2 Aug 2019 18:35:34 +0300 Subject: [PATCH 0625/1165] Disable consecutive key optimization for UInt8/16. These types use a FixedHashMap for aggregation, which makes lookup almost free, so we don't have to cache the last lookup result. This is a part of StringHashMap PR #5417 by Amos Bird. --- dbms/src/Interpreters/Aggregator.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/dbms/src/Interpreters/Aggregator.h b/dbms/src/Interpreters/Aggregator.h index 8c67271b1d5..5fb554f74f4 100644 --- a/dbms/src/Interpreters/Aggregator.h +++ b/dbms/src/Interpreters/Aggregator.h @@ -155,7 +155,9 @@ using AggregatedDataWithNullableStringKeyTwoLevel = AggregationDataWithNullKeyTw /// For the case where there is one numeric key. -template /// UInt8/16/32/64 for any type with corresponding bit width. +/// FieldType is UInt8/16/32/64 for any type with corresponding bit width. +template struct AggregationMethodOneNumber { using Data = TData; @@ -172,7 +174,8 @@ struct AggregationMethodOneNumber AggregationMethodOneNumber(const Other & other) : data(other.data) {} /// To use one `Method` in different threads, use different `State`. - using State = ColumnsHashing::HashMethodOneNumber; + using State = ColumnsHashing::HashMethodOneNumber; /// Use optimization for low cardinality. static const bool low_cardinality_optimization = false; @@ -421,8 +424,10 @@ struct AggregatedDataVariants : private boost::noncopyable */ AggregatedDataWithoutKey without_key = nullptr; - std::unique_ptr> key8; - std::unique_ptr> key16; + // Disable consecutive key optimization for Uint8/16, because they use a FixedHashMap + // and the lookup there is almost free, so we don't need to cache the last lookup result + std::unique_ptr> key8; + std::unique_ptr> key16; std::unique_ptr> key32; std::unique_ptr> key64; From ce712d881ab80eaaa9401088dd2c449bf53f4fd0 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 18:39:12 +0300 Subject: [PATCH 0626/1165] Remove JSONEachRowRowOutputStream. --- dbms/src/Formats/FormatFactory.cpp | 2 - .../Formats/JSONEachRowRowOutputStream.cpp | 67 ------------------- dbms/src/Formats/JSONEachRowRowOutputStream.h | 39 ----------- 3 files changed, 108 deletions(-) delete mode 100644 dbms/src/Formats/JSONEachRowRowOutputStream.cpp delete mode 100644 dbms/src/Formats/JSONEachRowRowOutputStream.h diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index d49c630cd82..85b215aac33 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -207,7 +207,6 @@ void registerInputFormatCSV(FormatFactory & factory); void registerOutputFormatCSV(FormatFactory & factory); void registerInputFormatTSKV(FormatFactory & factory); void registerOutputFormatTSKV(FormatFactory & factory); -void registerOutputFormatJSONEachRow(FormatFactory & factory); void registerInputFormatParquet(FormatFactory & factory); void registerOutputFormatParquet(FormatFactory & factory); void registerInputFormatProtobuf(FormatFactory & factory); @@ -272,7 +271,6 @@ FormatFactory::FormatFactory() registerOutputFormatCSV(*this); registerInputFormatTSKV(*this); registerOutputFormatTSKV(*this); - registerOutputFormatJSONEachRow(*this); registerInputFormatProtobuf(*this); registerOutputFormatProtobuf(*this); registerInputFormatParquet(*this); diff --git a/dbms/src/Formats/JSONEachRowRowOutputStream.cpp b/dbms/src/Formats/JSONEachRowRowOutputStream.cpp deleted file mode 100644 index 6850060dbfb..00000000000 --- a/dbms/src/Formats/JSONEachRowRowOutputStream.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include -#include -#include -#include - - -namespace DB -{ - - -JSONEachRowRowOutputStream::JSONEachRowRowOutputStream(WriteBuffer & ostr_, const Block & sample, const FormatSettings & settings) - : ostr(ostr_), settings(settings) -{ - size_t columns = sample.columns(); - fields.resize(columns); - - for (size_t i = 0; i < columns; ++i) - { - WriteBufferFromString out(fields[i]); - writeJSONString(sample.getByPosition(i).name, out, settings); - } -} - - -void JSONEachRowRowOutputStream::writeField(const IColumn & column, const IDataType & type, size_t row_num) -{ - writeString(fields[field_number], ostr); - writeChar(':', ostr); - type.serializeAsTextJSON(column, row_num, ostr, settings); - ++field_number; -} - - -void JSONEachRowRowOutputStream::writeFieldDelimiter() -{ - writeChar(',', ostr); -} - - -void JSONEachRowRowOutputStream::writeRowStartDelimiter() -{ - writeChar('{', ostr); -} - - -void JSONEachRowRowOutputStream::writeRowEndDelimiter() -{ - writeCString("}\n", ostr); - field_number = 0; -} - - -void registerOutputFormatJSONEachRow(FormatFactory & factory) -{ - factory.registerOutputFormat("JSONEachRow", []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & format_settings) - { - return std::make_shared( - std::make_shared(buf, sample, format_settings), sample); - }); -} - -} diff --git a/dbms/src/Formats/JSONEachRowRowOutputStream.h b/dbms/src/Formats/JSONEachRowRowOutputStream.h deleted file mode 100644 index 4f2dc690aed..00000000000 --- a/dbms/src/Formats/JSONEachRowRowOutputStream.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include -#include -#include -#include - - -namespace DB -{ - -/** The stream for outputting data in JSON format, by object per line. - * Does not validate UTF-8. - */ -class JSONEachRowRowOutputStream : public IRowOutputStream -{ -public: - JSONEachRowRowOutputStream(WriteBuffer & ostr_, const Block & sample, const FormatSettings & settings); - - void writeField(const IColumn & column, const IDataType & type, size_t row_num) override; - void writeFieldDelimiter() override; - void writeRowStartDelimiter() override; - void writeRowEndDelimiter() override; - - void flush() override - { - ostr.next(); - } - -private: - WriteBuffer & ostr; - size_t field_number = 0; - Names fields; - - FormatSettings settings; -}; - -} - From 4019f5e102bfd314406d4566185c5dad5d399748 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 18:42:33 +0300 Subject: [PATCH 0627/1165] Remove JSONRowOutputStream. --- dbms/src/Formats/FormatFactory.cpp | 2 - dbms/src/Formats/JSONRowOutputStream.cpp | 246 ----------------------- dbms/src/Formats/JSONRowOutputStream.h | 74 ------- 3 files changed, 322 deletions(-) delete mode 100644 dbms/src/Formats/JSONRowOutputStream.cpp delete mode 100644 dbms/src/Formats/JSONRowOutputStream.h diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 85b215aac33..f7e00693f9b 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -237,7 +237,6 @@ void registerOutputFormatPretty(FormatFactory & factory); void registerOutputFormatPrettyCompact(FormatFactory & factory); void registerOutputFormatPrettySpace(FormatFactory & factory); void registerOutputFormatVertical(FormatFactory & factory); -void registerOutputFormatJSON(FormatFactory & factory); void registerOutputFormatXML(FormatFactory & factory); void registerOutputFormatODBCDriver(FormatFactory & factory); void registerOutputFormatODBCDriver2(FormatFactory & factory); @@ -302,7 +301,6 @@ FormatFactory::FormatFactory() registerOutputFormatPrettyCompact(*this); registerOutputFormatPrettySpace(*this); registerOutputFormatVertical(*this); - registerOutputFormatJSON(*this); registerOutputFormatXML(*this); registerOutputFormatODBCDriver(*this); registerOutputFormatODBCDriver2(*this); diff --git a/dbms/src/Formats/JSONRowOutputStream.cpp b/dbms/src/Formats/JSONRowOutputStream.cpp deleted file mode 100644 index f008e83899a..00000000000 --- a/dbms/src/Formats/JSONRowOutputStream.cpp +++ /dev/null @@ -1,246 +0,0 @@ -#include -#include -#include -#include -#include - - -namespace DB -{ - -JSONRowOutputStream::JSONRowOutputStream(WriteBuffer & ostr_, const Block & sample_, const FormatSettings & settings) - : dst_ostr(ostr_), settings(settings) -{ - NamesAndTypesList columns(sample_.getNamesAndTypesList()); - fields.assign(columns.begin(), columns.end()); - - bool need_validate_utf8 = false; - for (size_t i = 0; i < sample_.columns(); ++i) - { - if (!sample_.getByPosition(i).type->textCanContainOnlyValidUTF8()) - need_validate_utf8 = true; - - WriteBufferFromOwnString out; - writeJSONString(fields[i].name, out, settings); - - fields[i].name = out.str(); - } - - if (need_validate_utf8) - { - validating_ostr = std::make_unique(dst_ostr); - ostr = validating_ostr.get(); - } - else - ostr = &dst_ostr; -} - - -void JSONRowOutputStream::writePrefix() -{ - writeCString("{\n", *ostr); - writeCString("\t\"meta\":\n", *ostr); - writeCString("\t[\n", *ostr); - - for (size_t i = 0; i < fields.size(); ++i) - { - writeCString("\t\t{\n", *ostr); - - writeCString("\t\t\t\"name\": ", *ostr); - writeString(fields[i].name, *ostr); - writeCString(",\n", *ostr); - writeCString("\t\t\t\"type\": ", *ostr); - writeJSONString(fields[i].type->getName(), *ostr, settings); - writeChar('\n', *ostr); - - writeCString("\t\t}", *ostr); - if (i + 1 < fields.size()) - writeChar(',', *ostr); - writeChar('\n', *ostr); - } - - writeCString("\t],\n", *ostr); - writeChar('\n', *ostr); - writeCString("\t\"data\":\n", *ostr); - writeCString("\t[\n", *ostr); -} - - -void JSONRowOutputStream::writeField(const IColumn & column, const IDataType & type, size_t row_num) -{ - writeCString("\t\t\t", *ostr); - writeString(fields[field_number].name, *ostr); - writeCString(": ", *ostr); - type.serializeAsTextJSON(column, row_num, *ostr, settings); - ++field_number; -} - - -void JSONRowOutputStream::writeFieldDelimiter() -{ - writeCString(",\n", *ostr); -} - - -void JSONRowOutputStream::writeRowStartDelimiter() -{ - if (row_count > 0) - writeCString(",\n", *ostr); - writeCString("\t\t{\n", *ostr); -} - - -void JSONRowOutputStream::writeRowEndDelimiter() -{ - writeChar('\n', *ostr); - writeCString("\t\t}", *ostr); - field_number = 0; - ++row_count; -} - - -void JSONRowOutputStream::writeSuffix() -{ - writeChar('\n', *ostr); - writeCString("\t]", *ostr); - - writeTotals(); - writeExtremes(); - - writeCString(",\n\n", *ostr); - writeCString("\t\"rows\": ", *ostr); - writeIntText(row_count, *ostr); - - writeRowsBeforeLimitAtLeast(); - - if (settings.write_statistics) - writeStatistics(); - - writeChar('\n', *ostr); - writeCString("}\n", *ostr); - ostr->next(); -} - -void JSONRowOutputStream::writeRowsBeforeLimitAtLeast() -{ - if (applied_limit) - { - writeCString(",\n\n", *ostr); - writeCString("\t\"rows_before_limit_at_least\": ", *ostr); - writeIntText(rows_before_limit, *ostr); - } -} - -void JSONRowOutputStream::writeTotals() -{ - if (totals) - { - writeCString(",\n", *ostr); - writeChar('\n', *ostr); - writeCString("\t\"totals\":\n", *ostr); - writeCString("\t{\n", *ostr); - - size_t totals_columns = totals.columns(); - for (size_t i = 0; i < totals_columns; ++i) - { - const ColumnWithTypeAndName & column = totals.safeGetByPosition(i); - - if (i != 0) - writeCString(",\n", *ostr); - - writeCString("\t\t", *ostr); - writeJSONString(column.name, *ostr, settings); - writeCString(": ", *ostr); - column.type->serializeAsTextJSON(*column.column.get(), 0, *ostr, settings); - } - - writeChar('\n', *ostr); - writeCString("\t}", *ostr); - } -} - - -static void writeExtremesElement(const char * title, const Block & extremes, size_t row_num, WriteBuffer & ostr, const FormatSettings & settings) -{ - writeCString("\t\t\"", ostr); - writeCString(title, ostr); - writeCString("\":\n", ostr); - writeCString("\t\t{\n", ostr); - - size_t extremes_columns = extremes.columns(); - for (size_t i = 0; i < extremes_columns; ++i) - { - const ColumnWithTypeAndName & column = extremes.safeGetByPosition(i); - - if (i != 0) - writeCString(",\n", ostr); - - writeCString("\t\t\t", ostr); - writeJSONString(column.name, ostr, settings); - writeCString(": ", ostr); - column.type->serializeAsTextJSON(*column.column.get(), row_num, ostr, settings); - } - - writeChar('\n', ostr); - writeCString("\t\t}", ostr); -} - -void JSONRowOutputStream::writeExtremes() -{ - if (extremes) - { - writeCString(",\n", *ostr); - writeChar('\n', *ostr); - writeCString("\t\"extremes\":\n", *ostr); - writeCString("\t{\n", *ostr); - - writeExtremesElement("min", extremes, 0, *ostr, settings); - writeCString(",\n", *ostr); - writeExtremesElement("max", extremes, 1, *ostr, settings); - - writeChar('\n', *ostr); - writeCString("\t}", *ostr); - } -} - - -void JSONRowOutputStream::onProgress(const Progress & value) -{ - progress.incrementPiecewiseAtomically(value); -} - - -void JSONRowOutputStream::writeStatistics() -{ - writeCString(",\n\n", *ostr); - writeCString("\t\"statistics\":\n", *ostr); - writeCString("\t{\n", *ostr); - - writeCString("\t\t\"elapsed\": ", *ostr); - writeText(watch.elapsedSeconds(), *ostr); - writeCString(",\n", *ostr); - writeCString("\t\t\"rows_read\": ", *ostr); - writeText(progress.read_rows.load(), *ostr); - writeCString(",\n", *ostr); - writeCString("\t\t\"bytes_read\": ", *ostr); - writeText(progress.read_bytes.load(), *ostr); - writeChar('\n', *ostr); - - writeCString("\t}", *ostr); -} - - -void registerOutputFormatJSON(FormatFactory & factory) -{ - factory.registerOutputFormat("JSON", []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & format_settings) - { - return std::make_shared( - std::make_shared(buf, sample, format_settings), sample); - }); -} - -} diff --git a/dbms/src/Formats/JSONRowOutputStream.h b/dbms/src/Formats/JSONRowOutputStream.h deleted file mode 100644 index 99f94762bcc..00000000000 --- a/dbms/src/Formats/JSONRowOutputStream.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - - -namespace DB -{ - -/** Stream for output data in JSON format. - */ -class JSONRowOutputStream : public IRowOutputStream -{ -public: - JSONRowOutputStream(WriteBuffer & ostr_, const Block & sample_, const FormatSettings & settings); - - void writeField(const IColumn & column, const IDataType & type, size_t row_num) override; - void writeFieldDelimiter() override; - void writeRowStartDelimiter() override; - void writeRowEndDelimiter() override; - void writePrefix() override; - void writeSuffix() override; - - void flush() override - { - ostr->next(); - - if (validating_ostr) - dst_ostr.next(); - } - - void setRowsBeforeLimit(size_t rows_before_limit_) override - { - applied_limit = true; - rows_before_limit = rows_before_limit_; - } - - void setTotals(const Block & totals_) override { totals = totals_; } - void setExtremes(const Block & extremes_) override { extremes = extremes_; } - - void onProgress(const Progress & value) override; - - String getContentType() const override { return "application/json; charset=UTF-8"; } - -protected: - - void writeRowsBeforeLimitAtLeast(); - virtual void writeTotals(); - virtual void writeExtremes(); - void writeStatistics(); - - WriteBuffer & dst_ostr; - std::unique_ptr validating_ostr; /// Validates UTF-8 sequences, replaces bad sequences with replacement character. - WriteBuffer * ostr; - - size_t field_number = 0; - size_t row_count = 0; - bool applied_limit = false; - size_t rows_before_limit = 0; - NamesAndTypes fields; - Block totals; - Block extremes; - - Progress progress; - Stopwatch watch; - FormatSettings settings; -}; - -} - From d57d8a609f7f13712628e59bc1b4bbbaca57e356 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 18:45:21 +0300 Subject: [PATCH 0628/1165] Remove MySQLWireBlockOutputStream. --- dbms/src/Formats/FormatFactory.cpp | 3 - .../Formats/MySQLWireBlockOutputStream.cpp | 85 ------------------- dbms/src/Formats/MySQLWireBlockOutputStream.h | 36 -------- dbms/src/Formats/MySQLWireFormat.cpp | 19 ----- 4 files changed, 143 deletions(-) delete mode 100644 dbms/src/Formats/MySQLWireBlockOutputStream.cpp delete mode 100644 dbms/src/Formats/MySQLWireBlockOutputStream.h delete mode 100644 dbms/src/Formats/MySQLWireFormat.cpp diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index f7e00693f9b..4a51e6e1189 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -241,7 +241,6 @@ void registerOutputFormatXML(FormatFactory & factory); void registerOutputFormatODBCDriver(FormatFactory & factory); void registerOutputFormatODBCDriver2(FormatFactory & factory); void registerOutputFormatNull(FormatFactory & factory); -void registerOutputFormatMySQLWire(FormatFactory & factory); void registerOutputFormatProcessorPretty(FormatFactory & factory); void registerOutputFormatProcessorPrettyCompact(FormatFactory & factory); @@ -275,8 +274,6 @@ FormatFactory::FormatFactory() registerInputFormatParquet(*this); registerOutputFormatParquet(*this); - registerOutputFormatMySQLWire(*this); - registerInputFormatProcessorNative(*this); registerOutputFormatProcessorNative(*this); registerInputFormatProcessorRowBinary(*this); diff --git a/dbms/src/Formats/MySQLWireBlockOutputStream.cpp b/dbms/src/Formats/MySQLWireBlockOutputStream.cpp deleted file mode 100644 index f032d5b84d4..00000000000 --- a/dbms/src/Formats/MySQLWireBlockOutputStream.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "MySQLWireBlockOutputStream.h" -#include -#include -#include -#include - -namespace DB -{ - -using namespace MySQLProtocol; - -MySQLWireBlockOutputStream::MySQLWireBlockOutputStream(WriteBuffer & buf, const Block & header, Context & context) - : header(header) - , context(context) - , packet_sender(buf, context.mysql.sequence_id) -{ - packet_sender.max_packet_size = context.mysql.max_packet_size; -} - -void MySQLWireBlockOutputStream::writePrefix() -{ - if (header.columns() == 0) - return; - - packet_sender.sendPacket(LengthEncodedNumber(header.columns())); - - for (const ColumnWithTypeAndName & column : header.getColumnsWithTypeAndName()) - { - ColumnDefinition column_definition(column.name, CharacterSet::binary, 0, ColumnType::MYSQL_TYPE_STRING, 0, 0); - packet_sender.sendPacket(column_definition); - } - - if (!(context.mysql.client_capabilities & Capability::CLIENT_DEPRECATE_EOF)) - { - packet_sender.sendPacket(EOF_Packet(0, 0)); - } -} - -void MySQLWireBlockOutputStream::write(const Block & block) -{ - size_t rows = block.rows(); - - for (size_t i = 0; i < rows; i++) - { - ResultsetRow row_packet; - for (const ColumnWithTypeAndName & column : block) - { - WriteBufferFromOwnString ostr; - column.type->serializeAsText(*column.column.get(), i, ostr, format_settings); - row_packet.appendColumn(std::move(ostr.str())); - } - packet_sender.sendPacket(row_packet); - } -} - -void MySQLWireBlockOutputStream::writeSuffix() -{ - size_t affected_rows = 0; - std::stringstream human_readable_info; - if (QueryStatus * process_list_elem = context.getProcessListElement()) - { - CurrentThread::finalizePerformanceCounters(); - QueryStatusInfo info = process_list_elem->getInfo(); - affected_rows = info.written_rows; - human_readable_info << std::fixed << std::setprecision(3) - << "Read " << info.read_rows << " rows, " << formatReadableSizeWithBinarySuffix(info.read_bytes) << " in " << info.elapsed_seconds << " sec., " - << static_cast(info.read_rows / info.elapsed_seconds) << " rows/sec., " - << formatReadableSizeWithBinarySuffix(info.read_bytes / info.elapsed_seconds) << "/sec."; - } - - if (header.columns() == 0) - packet_sender.sendPacket(OK_Packet(0x0, context.mysql.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); - else - if (context.mysql.client_capabilities & CLIENT_DEPRECATE_EOF) - packet_sender.sendPacket(OK_Packet(0xfe, context.mysql.client_capabilities, affected_rows, 0, 0, "", human_readable_info.str()), true); - else - packet_sender.sendPacket(EOF_Packet(0, 0), true); -} - -void MySQLWireBlockOutputStream::flush() -{ - packet_sender.out->next(); -} - -} diff --git a/dbms/src/Formats/MySQLWireBlockOutputStream.h b/dbms/src/Formats/MySQLWireBlockOutputStream.h deleted file mode 100644 index f54bc83eabc..00000000000 --- a/dbms/src/Formats/MySQLWireBlockOutputStream.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -namespace DB -{ - -/** Interface for writing rows in MySQL Client/Server Protocol format. - */ -class MySQLWireBlockOutputStream : public IBlockOutputStream -{ -public: - MySQLWireBlockOutputStream(WriteBuffer & buf, const Block & header, Context & context); - - Block getHeader() const { return header; } - - void write(const Block & block); - - void writePrefix(); - void writeSuffix(); - - void flush(); -private: - Block header; - Context & context; - MySQLProtocol::PacketSender packet_sender; - FormatSettings format_settings; -}; - -using MySQLWireBlockOutputStreamPtr = std::shared_ptr; - -} diff --git a/dbms/src/Formats/MySQLWireFormat.cpp b/dbms/src/Formats/MySQLWireFormat.cpp deleted file mode 100644 index c0694cd5a54..00000000000 --- a/dbms/src/Formats/MySQLWireFormat.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include - - -namespace DB -{ - -void registerOutputFormatMySQLWire(FormatFactory & factory) -{ - factory.registerOutputFormat("MySQLWire", []( - WriteBuffer & buf, - const Block & sample, - const Context & context, - const FormatSettings &) - { - return std::make_shared(buf, sample, const_cast(context)); - }); -} - -} From 51bd715781bbb551a9c7d20589e0ed3d756fd33a Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 18:49:46 +0300 Subject: [PATCH 0629/1165] Remove ODBCDriver2BlockOutputStream. --- dbms/src/Formats/FormatFactory.cpp | 2 - .../Formats/ODBCDriver2BlockOutputStream.cpp | 103 ------------------ .../Formats/ODBCDriver2BlockOutputStream.h | 51 --------- 3 files changed, 156 deletions(-) delete mode 100644 dbms/src/Formats/ODBCDriver2BlockOutputStream.cpp delete mode 100644 dbms/src/Formats/ODBCDriver2BlockOutputStream.h diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 4a51e6e1189..9a18608d1d7 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -239,7 +239,6 @@ void registerOutputFormatPrettySpace(FormatFactory & factory); void registerOutputFormatVertical(FormatFactory & factory); void registerOutputFormatXML(FormatFactory & factory); void registerOutputFormatODBCDriver(FormatFactory & factory); -void registerOutputFormatODBCDriver2(FormatFactory & factory); void registerOutputFormatNull(FormatFactory & factory); void registerOutputFormatProcessorPretty(FormatFactory & factory); @@ -300,7 +299,6 @@ FormatFactory::FormatFactory() registerOutputFormatVertical(*this); registerOutputFormatXML(*this); registerOutputFormatODBCDriver(*this); - registerOutputFormatODBCDriver2(*this); registerOutputFormatNull(*this); registerOutputFormatProcessorPretty(*this); diff --git a/dbms/src/Formats/ODBCDriver2BlockOutputStream.cpp b/dbms/src/Formats/ODBCDriver2BlockOutputStream.cpp deleted file mode 100644 index 8e9dbfdd5c2..00000000000 --- a/dbms/src/Formats/ODBCDriver2BlockOutputStream.cpp +++ /dev/null @@ -1,103 +0,0 @@ -#include -#include -#include -#include -#include -#include - -namespace DB -{ -ODBCDriver2BlockOutputStream::ODBCDriver2BlockOutputStream( - WriteBuffer & out_, const Block & header_, const FormatSettings & format_settings) - : out(out_), header(header_), format_settings(format_settings) -{ -} - -void ODBCDriver2BlockOutputStream::flush() -{ - out.next(); -} - -void writeODBCString(WriteBuffer & out, const std::string & str) -{ - writeIntBinary(Int32(str.size()), out); - out.write(str.data(), str.size()); -} - -static void writeRow(const Block & block, size_t row_idx, WriteBuffer & out, const FormatSettings & format_settings, std::string & buffer) -{ - size_t columns = block.columns(); - for (size_t column_idx = 0; column_idx < columns; ++column_idx) - { - buffer.clear(); - const ColumnWithTypeAndName & col = block.getByPosition(column_idx); - - if (col.column->isNullAt(row_idx)) - { - writeIntBinary(Int32(-1), out); - } - else - { - { - WriteBufferFromString text_out(buffer); - col.type->serializeAsText(*col.column, row_idx, text_out, format_settings); - } - writeODBCString(out, buffer); - } - } -} - -void ODBCDriver2BlockOutputStream::write(const Block & block) -{ - String text_value; - const size_t rows = block.rows(); - for (size_t i = 0; i < rows; ++i) - writeRow(block, i, out, format_settings, text_value); -} - -void ODBCDriver2BlockOutputStream::writeSuffix() -{ - if (totals) - write(totals); -} - -void ODBCDriver2BlockOutputStream::writePrefix() -{ - const size_t columns = header.columns(); - - /// Number of header rows. - writeIntBinary(Int32(2), out); - - /// Names of columns. - /// Number of columns + 1 for first name column. - writeIntBinary(Int32(columns + 1), out); - writeODBCString(out, "name"); - for (size_t i = 0; i < columns; ++i) - { - const ColumnWithTypeAndName & col = header.getByPosition(i); - writeODBCString(out, col.name); - } - - /// Types of columns. - writeIntBinary(Int32(columns + 1), out); - writeODBCString(out, "type"); - for (size_t i = 0; i < columns; ++i) - { - auto type = header.getByPosition(i).type; - if (type->lowCardinality()) - type = recursiveRemoveLowCardinality(type); - writeODBCString(out, type->getName()); - } -} - - -void registerOutputFormatODBCDriver2(FormatFactory & factory) -{ - factory.registerOutputFormat( - "ODBCDriver2", [](WriteBuffer & buf, const Block & sample, const Context &, const FormatSettings & format_settings) - { - return std::make_shared(buf, sample, format_settings); - }); -} - -} diff --git a/dbms/src/Formats/ODBCDriver2BlockOutputStream.h b/dbms/src/Formats/ODBCDriver2BlockOutputStream.h deleted file mode 100644 index 096204e5b94..00000000000 --- a/dbms/src/Formats/ODBCDriver2BlockOutputStream.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include -#include -#include -#include - - -namespace DB -{ -class WriteBuffer; - - -/** A data format designed to simplify the implementation of the ODBC driver. - * ODBC driver is designed to be build for different platforms without dependencies from the main code, - * so the format is made that way so that it can be as easy as possible to parse it. - * A header is displayed with the required information. - * The data is then output in the order of the rows. Each value is displayed as follows: length in Int32 format (-1 for NULL), then data in text form. - */ -class ODBCDriver2BlockOutputStream final : public IBlockOutputStream -{ -public: - ODBCDriver2BlockOutputStream(WriteBuffer & out_, const Block & header_, const FormatSettings & format_settings); - - Block getHeader() const override - { - return header; - } - void write(const Block & block) override; - void writePrefix() override; - void writeSuffix() override; - - void flush() override; - std::string getContentType() const override - { - return "application/octet-stream"; - } - void setTotals(const Block & totals_) override { totals = totals_; } - -private: - WriteBuffer & out; - const Block header; - const FormatSettings format_settings; - -protected: - Block totals; -}; - - - -} From 978bdc4bfc197a81d0a877ac61d812d9eb7a1962 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 18:51:27 +0300 Subject: [PATCH 0630/1165] Remove ODBCDriverBlockOutputStream. --- dbms/src/Formats/FormatFactory.cpp | 2 - .../Formats/ODBCDriverBlockOutputStream.cpp | 74 ------------------- .../src/Formats/ODBCDriverBlockOutputStream.h | 39 ---------- 3 files changed, 115 deletions(-) delete mode 100644 dbms/src/Formats/ODBCDriverBlockOutputStream.cpp delete mode 100644 dbms/src/Formats/ODBCDriverBlockOutputStream.h diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 9a18608d1d7..7094f1280fc 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -238,7 +238,6 @@ void registerOutputFormatPrettyCompact(FormatFactory & factory); void registerOutputFormatPrettySpace(FormatFactory & factory); void registerOutputFormatVertical(FormatFactory & factory); void registerOutputFormatXML(FormatFactory & factory); -void registerOutputFormatODBCDriver(FormatFactory & factory); void registerOutputFormatNull(FormatFactory & factory); void registerOutputFormatProcessorPretty(FormatFactory & factory); @@ -298,7 +297,6 @@ FormatFactory::FormatFactory() registerOutputFormatPrettySpace(*this); registerOutputFormatVertical(*this); registerOutputFormatXML(*this); - registerOutputFormatODBCDriver(*this); registerOutputFormatNull(*this); registerOutputFormatProcessorPretty(*this); diff --git a/dbms/src/Formats/ODBCDriverBlockOutputStream.cpp b/dbms/src/Formats/ODBCDriverBlockOutputStream.cpp deleted file mode 100644 index 3cd1ad3c1d6..00000000000 --- a/dbms/src/Formats/ODBCDriverBlockOutputStream.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include -#include -#include -#include - - -namespace DB -{ - -ODBCDriverBlockOutputStream::ODBCDriverBlockOutputStream(WriteBuffer & out_, const Block & header_, const FormatSettings & format_settings) - : out(out_), header(header_), format_settings(format_settings) -{ -} - -void ODBCDriverBlockOutputStream::flush() -{ - out.next(); -} - -void ODBCDriverBlockOutputStream::write(const Block & block) -{ - const size_t rows = block.rows(); - const size_t columns = block.columns(); - String text_value; - - for (size_t i = 0; i < rows; ++i) - { - for (size_t j = 0; j < columns; ++j) - { - text_value.resize(0); - const ColumnWithTypeAndName & col = block.getByPosition(j); - - { - WriteBufferFromString text_out(text_value); - col.type->serializeAsText(*col.column, i, text_out, format_settings); - } - - writeStringBinary(text_value, out); - } - } -} - -void ODBCDriverBlockOutputStream::writePrefix() -{ - const size_t columns = header.columns(); - - /// Number of columns. - writeVarUInt(columns, out); - - /// Names and types of columns. - for (size_t i = 0; i < columns; ++i) - { - const ColumnWithTypeAndName & col = header.getByPosition(i); - - writeStringBinary(col.name, out); - writeStringBinary(col.type->getName(), out); - } -} - - -void registerOutputFormatODBCDriver(FormatFactory & factory) -{ - factory.registerOutputFormat("ODBCDriver", []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & format_settings) - { - return std::make_shared(buf, sample, format_settings); - }); -} - -} diff --git a/dbms/src/Formats/ODBCDriverBlockOutputStream.h b/dbms/src/Formats/ODBCDriverBlockOutputStream.h deleted file mode 100644 index 7dbde1c5814..00000000000 --- a/dbms/src/Formats/ODBCDriverBlockOutputStream.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include -#include -#include -#include - - -namespace DB -{ - -class WriteBuffer; - - -/** A data format designed to simplify the implementation of the ODBC driver. - * ODBC driver is designed to be build for different platforms without dependencies from the main code, - * so the format is made that way so that it can be as easy as possible to parse it. - * A header is displayed with the required information. - * The data is then output in the order of the rows. Each value is displayed as follows: length in VarUInt format, then data in text form. - */ -class ODBCDriverBlockOutputStream : public IBlockOutputStream -{ -public: - ODBCDriverBlockOutputStream(WriteBuffer & out_, const Block & header_, const FormatSettings & format_settings); - - Block getHeader() const override { return header; } - void write(const Block & block) override; - void writePrefix() override; - - void flush() override; - std::string getContentType() const override { return "application/octet-stream"; } - -private: - WriteBuffer & out; - const Block header; - const FormatSettings format_settings; -}; - -} From fcecbbda73ae5fed196f0712720e92f854bf7b45 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 19:00:24 +0300 Subject: [PATCH 0631/1165] Remove OParquetBlockInputStream --- dbms/src/Formats/FormatFactory.cpp | 2 - dbms/src/Formats/ParquetBlockInputStream.cpp | 495 ------------------ dbms/src/Formats/ParquetBlockInputStream.h | 43 -- .../Formats/Impl/ParquetBlockInputFormat.cpp | 8 +- .../Formats/Impl/ParquetBlockInputFormat.h | 8 +- 5 files changed, 4 insertions(+), 552 deletions(-) delete mode 100644 dbms/src/Formats/ParquetBlockInputStream.cpp delete mode 100644 dbms/src/Formats/ParquetBlockInputStream.h diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 7094f1280fc..0d346027d49 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -207,7 +207,6 @@ void registerInputFormatCSV(FormatFactory & factory); void registerOutputFormatCSV(FormatFactory & factory); void registerInputFormatTSKV(FormatFactory & factory); void registerOutputFormatTSKV(FormatFactory & factory); -void registerInputFormatParquet(FormatFactory & factory); void registerOutputFormatParquet(FormatFactory & factory); void registerInputFormatProtobuf(FormatFactory & factory); void registerOutputFormatProtobuf(FormatFactory & factory); @@ -269,7 +268,6 @@ FormatFactory::FormatFactory() registerOutputFormatTSKV(*this); registerInputFormatProtobuf(*this); registerOutputFormatProtobuf(*this); - registerInputFormatParquet(*this); registerOutputFormatParquet(*this); registerInputFormatProcessorNative(*this); diff --git a/dbms/src/Formats/ParquetBlockInputStream.cpp b/dbms/src/Formats/ParquetBlockInputStream.cpp deleted file mode 100644 index deba953bab4..00000000000 --- a/dbms/src/Formats/ParquetBlockInputStream.cpp +++ /dev/null @@ -1,495 +0,0 @@ -#include "config_formats.h" -#if USE_PARQUET -# include "ParquetBlockInputStream.h" - -# include -# include -# include -// TODO: clear includes -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace DB -{ -namespace ErrorCodes -{ - extern const int UNKNOWN_TYPE; - extern const int VALUE_IS_OUT_OF_RANGE_OF_DATA_TYPE; - extern const int CANNOT_READ_ALL_DATA; - extern const int EMPTY_DATA_PASSED; - extern const int SIZES_OF_COLUMNS_DOESNT_MATCH; - extern const int CANNOT_CONVERT_TYPE; - extern const int CANNOT_INSERT_NULL_IN_ORDINARY_COLUMN; - extern const int THERE_IS_NO_COLUMN; -} - -ParquetBlockInputStream::ParquetBlockInputStream(ReadBuffer & istr_, const Block & header_, const Context & context_) - : istr{istr_}, header{header_}, context{context_} -{ -} - -Block ParquetBlockInputStream::getHeader() const -{ - return header; -} - -/// Inserts numeric data right into internal column data to reduce an overhead -template > -void fillColumnWithNumericData(std::shared_ptr & arrow_column, MutableColumnPtr & internal_column) -{ - auto & column_data = static_cast(*internal_column).getData(); - column_data.reserve(arrow_column->length()); - - for (size_t chunk_i = 0, num_chunks = static_cast(arrow_column->data()->num_chunks()); chunk_i < num_chunks; ++chunk_i) - { - std::shared_ptr chunk = arrow_column->data()->chunk(chunk_i); - /// buffers[0] is a null bitmap and buffers[1] are actual values - std::shared_ptr buffer = chunk->data()->buffers[1]; - - const auto * raw_data = reinterpret_cast(buffer->data()); - column_data.insert_assume_reserved(raw_data, raw_data + chunk->length()); - } -} - -/// Inserts chars and offsets right into internal column data to reduce an overhead. -/// Internal offsets are shifted by one to the right in comparison with Arrow ones. So the last offset should map to the end of all chars. -/// Also internal strings are null terminated. -void fillColumnWithStringData(std::shared_ptr & arrow_column, MutableColumnPtr & internal_column) -{ - PaddedPODArray & column_chars_t = static_cast(*internal_column).getChars(); - PaddedPODArray & column_offsets = static_cast(*internal_column).getOffsets(); - - size_t chars_t_size = 0; - for (size_t chunk_i = 0, num_chunks = static_cast(arrow_column->data()->num_chunks()); chunk_i < num_chunks; ++chunk_i) - { - arrow::BinaryArray & chunk = static_cast(*(arrow_column->data()->chunk(chunk_i))); - const size_t chunk_length = chunk.length(); - - chars_t_size += chunk.value_offset(chunk_length - 1) + chunk.value_length(chunk_length - 1); - chars_t_size += chunk_length; /// additional space for null bytes - } - - column_chars_t.reserve(chars_t_size); - column_offsets.reserve(arrow_column->length()); - - for (size_t chunk_i = 0, num_chunks = static_cast(arrow_column->data()->num_chunks()); chunk_i < num_chunks; ++chunk_i) - { - arrow::BinaryArray & chunk = static_cast(*(arrow_column->data()->chunk(chunk_i))); - std::shared_ptr buffer = chunk.value_data(); - const size_t chunk_length = chunk.length(); - - for (size_t offset_i = 0; offset_i != chunk_length; ++offset_i) - { - if (!chunk.IsNull(offset_i) && buffer) - { - const UInt8 * raw_data = buffer->data() + chunk.value_offset(offset_i); - column_chars_t.insert_assume_reserved(raw_data, raw_data + chunk.value_length(offset_i)); - } - column_chars_t.emplace_back('\0'); - - column_offsets.emplace_back(column_chars_t.size()); - } - } -} - -void fillColumnWithBooleanData(std::shared_ptr & arrow_column, MutableColumnPtr & internal_column) -{ - auto & column_data = static_cast &>(*internal_column).getData(); - column_data.resize(arrow_column->length()); - - for (size_t chunk_i = 0, num_chunks = static_cast(arrow_column->data()->num_chunks()); chunk_i < num_chunks; ++chunk_i) - { - arrow::BooleanArray & chunk = static_cast(*(arrow_column->data()->chunk(chunk_i))); - /// buffers[0] is a null bitmap and buffers[1] are actual values - std::shared_ptr buffer = chunk.data()->buffers[1]; - - for (size_t bool_i = 0; bool_i != static_cast(chunk.length()); ++bool_i) - column_data[bool_i] = chunk.Value(bool_i); - } -} - -/// Arrow stores Parquet::DATE in Int32, while ClickHouse stores Date in UInt16. Therefore, it should be checked before saving -void fillColumnWithDate32Data(std::shared_ptr & arrow_column, MutableColumnPtr & internal_column) -{ - PaddedPODArray & column_data = static_cast &>(*internal_column).getData(); - column_data.reserve(arrow_column->length()); - - for (size_t chunk_i = 0, num_chunks = static_cast(arrow_column->data()->num_chunks()); chunk_i < num_chunks; ++chunk_i) - { - arrow::Date32Array & chunk = static_cast(*(arrow_column->data()->chunk(chunk_i))); - - for (size_t value_i = 0, length = static_cast(chunk.length()); value_i < length; ++value_i) - { - UInt32 days_num = static_cast(chunk.Value(value_i)); - if (days_num > DATE_LUT_MAX_DAY_NUM) - { - // TODO: will it rollback correctly? - throw Exception{"Input value " + std::to_string(days_num) + " of a column \"" + arrow_column->name() - + "\" is greater than " - "max allowed Date value, which is " - + std::to_string(DATE_LUT_MAX_DAY_NUM), - ErrorCodes::VALUE_IS_OUT_OF_RANGE_OF_DATA_TYPE}; - } - - column_data.emplace_back(days_num); - } - } -} - -/// Arrow stores Parquet::DATETIME in Int64, while ClickHouse stores DateTime in UInt32. Therefore, it should be checked before saving -void fillColumnWithDate64Data(std::shared_ptr & arrow_column, MutableColumnPtr & internal_column) -{ - auto & column_data = static_cast &>(*internal_column).getData(); - column_data.reserve(arrow_column->length()); - - for (size_t chunk_i = 0, num_chunks = static_cast(arrow_column->data()->num_chunks()); chunk_i < num_chunks; ++chunk_i) - { - auto & chunk = static_cast(*(arrow_column->data()->chunk(chunk_i))); - for (size_t value_i = 0, length = static_cast(chunk.length()); value_i < length; ++value_i) - { - auto timestamp = static_cast(chunk.Value(value_i) / 1000); // Always? in ms - column_data.emplace_back(timestamp); - } - } -} - -void fillColumnWithTimestampData(std::shared_ptr & arrow_column, MutableColumnPtr & internal_column) -{ - auto & column_data = static_cast &>(*internal_column).getData(); - column_data.reserve(arrow_column->length()); - - for (size_t chunk_i = 0, num_chunks = static_cast(arrow_column->data()->num_chunks()); chunk_i < num_chunks; ++chunk_i) - { - auto & chunk = static_cast(*(arrow_column->data()->chunk(chunk_i))); - const auto & type = static_cast(*chunk.type()); - - UInt32 divide = 1; - const auto unit = type.unit(); - switch (unit) - { - case arrow::TimeUnit::SECOND: - divide = 1; - break; - case arrow::TimeUnit::MILLI: - divide = 1000; - break; - case arrow::TimeUnit::MICRO: - divide = 1000000; - break; - case arrow::TimeUnit::NANO: - divide = 1000000000; - break; - } - - for (size_t value_i = 0, length = static_cast(chunk.length()); value_i < length; ++value_i) - { - auto timestamp = static_cast(chunk.Value(value_i) / divide); // ms! TODO: check other 's' 'ns' ... - column_data.emplace_back(timestamp); - } - } -} - -void fillColumnWithDecimalData(std::shared_ptr & arrow_column, MutableColumnPtr & internal_column) -{ - auto & column = static_cast &>(*internal_column); - auto & column_data = column.getData(); - column_data.reserve(arrow_column->length()); - - for (size_t chunk_i = 0, num_chunks = static_cast(arrow_column->data()->num_chunks()); chunk_i < num_chunks; ++chunk_i) - { - auto & chunk = static_cast(*(arrow_column->data()->chunk(chunk_i))); - for (size_t value_i = 0, length = static_cast(chunk.length()); value_i < length; ++value_i) - { - column_data.emplace_back( - chunk.IsNull(value_i) ? Decimal128(0) : *reinterpret_cast(chunk.Value(value_i))); // TODO: copy column - } - } -} - -/// Creates a null bytemap from arrow's null bitmap -void fillByteMapFromArrowColumn(std::shared_ptr & arrow_column, MutableColumnPtr & bytemap) -{ - PaddedPODArray & bytemap_data = static_cast &>(*bytemap).getData(); - bytemap_data.reserve(arrow_column->length()); - - for (size_t chunk_i = 0; chunk_i != static_cast(arrow_column->data()->num_chunks()); ++chunk_i) - { - std::shared_ptr chunk = arrow_column->data()->chunk(chunk_i); - - for (size_t value_i = 0; value_i != static_cast(chunk->length()); ++value_i) - bytemap_data.emplace_back(chunk->IsNull(value_i)); - } -} - -# define FOR_ARROW_NUMERIC_TYPES(M) \ - M(arrow::Type::UINT8, UInt8) \ - M(arrow::Type::INT8, Int8) \ - M(arrow::Type::UINT16, UInt16) \ - M(arrow::Type::INT16, Int16) \ - M(arrow::Type::UINT32, UInt32) \ - M(arrow::Type::INT32, Int32) \ - M(arrow::Type::UINT64, UInt64) \ - M(arrow::Type::INT64, Int64) \ - M(arrow::Type::FLOAT, Float32) \ - M(arrow::Type::DOUBLE, Float64) -//M(arrow::Type::HALF_FLOAT, Float32) // TODO - - -using NameToColumnPtr = std::unordered_map>; - - -Block ParquetBlockInputStream::readImpl() -{ - static const std::unordered_map> arrow_type_to_internal_type = { - //{arrow::Type::DECIMAL, std::make_shared()}, - {arrow::Type::UINT8, std::make_shared()}, - {arrow::Type::INT8, std::make_shared()}, - {arrow::Type::UINT16, std::make_shared()}, - {arrow::Type::INT16, std::make_shared()}, - {arrow::Type::UINT32, std::make_shared()}, - {arrow::Type::INT32, std::make_shared()}, - {arrow::Type::UINT64, std::make_shared()}, - {arrow::Type::INT64, std::make_shared()}, - {arrow::Type::HALF_FLOAT, std::make_shared()}, - {arrow::Type::FLOAT, std::make_shared()}, - {arrow::Type::DOUBLE, std::make_shared()}, - - {arrow::Type::BOOL, std::make_shared()}, - //{arrow::Type::DATE32, std::make_shared()}, - {arrow::Type::DATE32, std::make_shared()}, - //{arrow::Type::DATE32, std::make_shared()}, - {arrow::Type::DATE64, std::make_shared()}, - {arrow::Type::TIMESTAMP, std::make_shared()}, - //{arrow::Type::TIME32, std::make_shared()}, - - - {arrow::Type::STRING, std::make_shared()}, - {arrow::Type::BINARY, std::make_shared()}, - //{arrow::Type::FIXED_SIZE_BINARY, std::make_shared()}, - //{arrow::Type::UUID, std::make_shared()}, - - - // TODO: add other types that are convertable to internal ones: - // 0. ENUM? - // 1. UUID -> String - // 2. JSON -> String - // Full list of types: contrib/arrow/cpp/src/arrow/type.h - }; - - - Block res; - - if (!istr.eof()) - { - /* - First we load whole stream into string (its very bad and limiting .parquet file size to half? of RAM) - Then producing blocks for every row_group (dont load big .parquet files with one row_group - it can eat x10+ RAM from .parquet file size) - */ - - if (row_group_current < row_group_total) - throw Exception{"Got new data, but data from previous chunks not readed " + std::to_string(row_group_current) + "/" - + std::to_string(row_group_total), - ErrorCodes::CANNOT_READ_ALL_DATA}; - - file_data.clear(); - { - WriteBufferFromString file_buffer(file_data); - copyData(istr, file_buffer); - } - - buffer = std::make_unique(file_data); - // TODO: maybe use parquet::RandomAccessSource? - auto reader = parquet::ParquetFileReader::Open(std::make_shared<::arrow::io::BufferReader>(*buffer)); - file_reader = std::make_unique(::arrow::default_memory_pool(), std::move(reader)); - row_group_total = file_reader->num_row_groups(); - row_group_current = 0; - } - if (row_group_current >= row_group_total) - return res; - - // TODO: also catch a ParquetException thrown by filereader? - //arrow::Status read_status = filereader.ReadTable(&table); - std::shared_ptr table; - arrow::Status read_status = file_reader->ReadRowGroup(row_group_current, &table); - - if (!read_status.ok()) - throw Exception{"Error while reading parquet data: " + read_status.ToString(), ErrorCodes::CANNOT_READ_ALL_DATA}; - - if (0 == table->num_rows()) - throw Exception{"Empty table in input data", ErrorCodes::EMPTY_DATA_PASSED}; - - if (header.columns() > static_cast(table->num_columns())) - // TODO: What if some columns were not presented? Insert NULLs? What if a column is not nullable? - throw Exception{"Number of columns is less than the table has", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH}; - - ++row_group_current; - - NameToColumnPtr name_to_column_ptr; - for (size_t i = 0, num_columns = static_cast(table->num_columns()); i < num_columns; ++i) - { - std::shared_ptr arrow_column = table->column(i); - name_to_column_ptr[arrow_column->name()] = arrow_column; - } - - for (size_t column_i = 0, columns = header.columns(); column_i < columns; ++column_i) - { - ColumnWithTypeAndName header_column = header.getByPosition(column_i); - - if (name_to_column_ptr.find(header_column.name) == name_to_column_ptr.end()) - // TODO: What if some columns were not presented? Insert NULLs? What if a column is not nullable? - throw Exception{"Column \"" + header_column.name + "\" is not presented in input data", ErrorCodes::THERE_IS_NO_COLUMN}; - - std::shared_ptr arrow_column = name_to_column_ptr[header_column.name]; - arrow::Type::type arrow_type = arrow_column->type()->id(); - - // TODO: check if a column is const? - if (!header_column.type->isNullable() && arrow_column->null_count()) - { - throw Exception{"Can not insert NULL data into non-nullable column \"" + header_column.name + "\"", - ErrorCodes::CANNOT_INSERT_NULL_IN_ORDINARY_COLUMN}; - } - - const bool target_column_is_nullable = header_column.type->isNullable() || arrow_column->null_count(); - - DataTypePtr internal_nested_type; - - if (arrow_type == arrow::Type::DECIMAL) - { - const auto decimal_type = static_cast(arrow_column->type().get()); - internal_nested_type = std::make_shared>(decimal_type->precision(), decimal_type->scale()); - } - else if (arrow_type_to_internal_type.find(arrow_type) != arrow_type_to_internal_type.end()) - { - internal_nested_type = arrow_type_to_internal_type.at(arrow_type); - } - else - { - throw Exception{"The type \"" + arrow_column->type()->name() + "\" of an input column \"" + arrow_column->name() - + "\" is not supported for conversion from a Parquet data format", - ErrorCodes::CANNOT_CONVERT_TYPE}; - } - - const DataTypePtr internal_type = target_column_is_nullable ? makeNullable(internal_nested_type) : internal_nested_type; - const std::string internal_nested_type_name = internal_nested_type->getName(); - - const DataTypePtr column_nested_type = header_column.type->isNullable() - ? static_cast(header_column.type.get())->getNestedType() - : header_column.type; - - const DataTypePtr column_type = header_column.type; - - const std::string column_nested_type_name = column_nested_type->getName(); - - ColumnWithTypeAndName column; - column.name = header_column.name; - column.type = internal_type; - - /// Data - MutableColumnPtr read_column = internal_nested_type->createColumn(); - switch (arrow_type) - { - case arrow::Type::STRING: - case arrow::Type::BINARY: - //case arrow::Type::FIXED_SIZE_BINARY: - fillColumnWithStringData(arrow_column, read_column); - break; - case arrow::Type::BOOL: - fillColumnWithBooleanData(arrow_column, read_column); - break; - case arrow::Type::DATE32: - fillColumnWithDate32Data(arrow_column, read_column); - break; - case arrow::Type::DATE64: - fillColumnWithDate64Data(arrow_column, read_column); - break; - case arrow::Type::TIMESTAMP: - fillColumnWithTimestampData(arrow_column, read_column); - break; - case arrow::Type::DECIMAL: - //fillColumnWithNumericData>(arrow_column, read_column); // Have problems with trash values under NULL, but faster - fillColumnWithDecimalData(arrow_column, read_column /*, internal_nested_type*/); - break; -# define DISPATCH(ARROW_NUMERIC_TYPE, CPP_NUMERIC_TYPE) \ - case ARROW_NUMERIC_TYPE: \ - fillColumnWithNumericData(arrow_column, read_column); \ - break; - - FOR_ARROW_NUMERIC_TYPES(DISPATCH) -# undef DISPATCH - // TODO: support TIMESTAMP_MICROS and TIMESTAMP_MILLIS with truncated micro- and milliseconds? - // TODO: read JSON as a string? - // TODO: read UUID as a string? - default: - throw Exception{"Unsupported parquet type \"" + arrow_column->type()->name() + "\" of an input column \"" - + arrow_column->name() + "\"", - ErrorCodes::UNKNOWN_TYPE}; - } - - if (column.type->isNullable()) - { - MutableColumnPtr null_bytemap = DataTypeUInt8().createColumn(); - fillByteMapFromArrowColumn(arrow_column, null_bytemap); - column.column = ColumnNullable::create(std::move(read_column), std::move(null_bytemap)); - } - else - { - column.column = std::move(read_column); - } - - column.column = castColumn(column, column_type, context); - column.type = column_type; - - res.insert(std::move(column)); - } - - return res; -} - -void registerInputFormatParquet(FormatFactory & factory) -{ - factory.registerInputFormat( - "Parquet", - [](ReadBuffer & buf, - const Block & sample, - const Context & context, - UInt64 /* max_block_size */, - UInt64 /* rows_portion_size */, - FormatFactory::ReadCallback /* callback */, - const FormatSettings & /* settings */) { return std::make_shared(buf, sample, context); }); -} - -} - -#else - -namespace DB -{ -class FormatFactory; -void registerInputFormatParquet(FormatFactory &) -{ -} -} - -#endif diff --git a/dbms/src/Formats/ParquetBlockInputStream.h b/dbms/src/Formats/ParquetBlockInputStream.h deleted file mode 100644 index 636f0cec7b8..00000000000 --- a/dbms/src/Formats/ParquetBlockInputStream.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include "config_formats.h" -#if USE_PARQUET -# include - - -namespace parquet { namespace arrow { class FileReader; } } -namespace arrow { class Buffer; } - -namespace DB -{ -class Context; - -class ParquetBlockInputStream : public IBlockInputStream -{ -public: - ParquetBlockInputStream(ReadBuffer & istr_, const Block & header_, const Context & context_); - - String getName() const override { return "Parquet"; } - Block getHeader() const override; - -protected: - Block readImpl() override; - -private: - ReadBuffer & istr; - Block header; - - // TODO: check that this class implements every part of its parent - - const Context & context; - - std::unique_ptr file_reader; - std::string file_data; - std::unique_ptr buffer; - int row_group_total = 0; - int row_group_current = 0; -}; - -} - -#endif diff --git a/dbms/src/Processors/Formats/Impl/ParquetBlockInputFormat.cpp b/dbms/src/Processors/Formats/Impl/ParquetBlockInputFormat.cpp index 9e19f0881ed..597c6cb4af1 100644 --- a/dbms/src/Processors/Formats/Impl/ParquetBlockInputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/ParquetBlockInputFormat.cpp @@ -1,7 +1,7 @@ #include "config_formats.h" #if USE_PARQUET -#include "ParquetBlockInputFormat.h" +#include #include #include @@ -29,15 +29,9 @@ #include #include #include -//#include -//#include #include -//#include -//#include #include -#include // REMOVE ME - namespace DB { namespace ErrorCodes diff --git a/dbms/src/Processors/Formats/Impl/ParquetBlockInputFormat.h b/dbms/src/Processors/Formats/Impl/ParquetBlockInputFormat.h index bbb7abdd5d4..8fa9013fbd1 100644 --- a/dbms/src/Processors/Formats/Impl/ParquetBlockInputFormat.h +++ b/dbms/src/Processors/Formats/Impl/ParquetBlockInputFormat.h @@ -1,11 +1,9 @@ #pragma once -#include +#include "config_formats.h" #if USE_PARQUET -# include -//# include -//# include -//# include + +#include namespace parquet { namespace arrow { class FileReader; } } From 529e06e5cbeb102e3231cab3247dc6ca4356bab7 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 19:09:52 +0300 Subject: [PATCH 0632/1165] Remove ParquetBlockOutputStream. --- dbms/src/Formats/FormatFactory.cpp | 3 +- dbms/src/Formats/ParquetBlockOutputStream.cpp | 451 ------------------ dbms/src/Formats/ParquetBlockOutputStream.h | 46 -- .../Formats/Impl/ParquetBlockOutputFormat.cpp | 2 +- .../Formats/Impl/ParquetBlockOutputFormat.h | 2 +- 5 files changed, 3 insertions(+), 501 deletions(-) delete mode 100644 dbms/src/Formats/ParquetBlockOutputStream.cpp delete mode 100644 dbms/src/Formats/ParquetBlockOutputStream.h diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 0d346027d49..258786a93c9 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -207,7 +207,7 @@ void registerInputFormatCSV(FormatFactory & factory); void registerOutputFormatCSV(FormatFactory & factory); void registerInputFormatTSKV(FormatFactory & factory); void registerOutputFormatTSKV(FormatFactory & factory); -void registerOutputFormatParquet(FormatFactory & factory); +void registerOutputFormatTSKV(FormatFactory & factory); void registerInputFormatProtobuf(FormatFactory & factory); void registerOutputFormatProtobuf(FormatFactory & factory); @@ -268,7 +268,6 @@ FormatFactory::FormatFactory() registerOutputFormatTSKV(*this); registerInputFormatProtobuf(*this); registerOutputFormatProtobuf(*this); - registerOutputFormatParquet(*this); registerInputFormatProcessorNative(*this); registerOutputFormatProcessorNative(*this); diff --git a/dbms/src/Formats/ParquetBlockOutputStream.cpp b/dbms/src/Formats/ParquetBlockOutputStream.cpp deleted file mode 100644 index f03aa181bc3..00000000000 --- a/dbms/src/Formats/ParquetBlockOutputStream.cpp +++ /dev/null @@ -1,451 +0,0 @@ -#include "config_formats.h" -#if USE_PARQUET -# include "ParquetBlockOutputStream.h" - -// TODO: clean includes -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -namespace DB -{ -namespace ErrorCodes -{ - extern const int UNKNOWN_EXCEPTION; - extern const int UNKNOWN_TYPE; -} - -ParquetBlockOutputStream::ParquetBlockOutputStream(WriteBuffer & ostr, const Block & header, const FormatSettings & format_settings) : ostr{ostr}, header{header}, format_settings{format_settings} -{ -} - -void ParquetBlockOutputStream::flush() -{ - ostr.next(); -} - -void checkStatus(arrow::Status & status, const std::string & column_name) -{ - if (!status.ok()) - throw Exception{"Error with a parquet column \"" + column_name + "\": " + status.ToString(), ErrorCodes::UNKNOWN_EXCEPTION}; -} - -template -void fillArrowArrayWithNumericColumnData( - ColumnPtr write_column, std::shared_ptr & arrow_array, const PaddedPODArray * null_bytemap) -{ - const PaddedPODArray & internal_data = static_cast &>(*write_column).getData(); - ArrowBuilderType builder; - arrow::Status status; - - const UInt8 * arrow_null_bytemap_raw_ptr = nullptr; - PaddedPODArray arrow_null_bytemap; - if (null_bytemap) - { - /// Invert values since Arrow interprets 1 as a non-null value, while CH as a null - arrow_null_bytemap.reserve(null_bytemap->size()); - for (size_t i = 0, size = null_bytemap->size(); i < size; ++i) - arrow_null_bytemap.emplace_back(1 ^ (*null_bytemap)[i]); - - arrow_null_bytemap_raw_ptr = arrow_null_bytemap.data(); - } - - status = builder.AppendValues(internal_data.data(), internal_data.size(), arrow_null_bytemap_raw_ptr); - checkStatus(status, write_column->getName()); - - status = builder.Finish(&arrow_array); - checkStatus(status, write_column->getName()); -} - -template -void fillArrowArrayWithStringColumnData( - ColumnPtr write_column, std::shared_ptr & arrow_array, const PaddedPODArray * null_bytemap) -{ - const auto & internal_column = static_cast(*write_column); - arrow::StringBuilder builder; - arrow::Status status; - - for (size_t string_i = 0, size = internal_column.size(); string_i < size; ++string_i) - { - if (null_bytemap && (*null_bytemap)[string_i]) - { - status = builder.AppendNull(); - } - else - { - StringRef string_ref = internal_column.getDataAt(string_i); - status = builder.Append(string_ref.data, string_ref.size); - } - - checkStatus(status, write_column->getName()); - } - - status = builder.Finish(&arrow_array); - checkStatus(status, write_column->getName()); -} - -void fillArrowArrayWithDateColumnData( - ColumnPtr write_column, std::shared_ptr & arrow_array, const PaddedPODArray * null_bytemap) -{ - const PaddedPODArray & internal_data = static_cast &>(*write_column).getData(); - //arrow::Date32Builder date_builder; - arrow::UInt16Builder builder; - arrow::Status status; - - for (size_t value_i = 0, size = internal_data.size(); value_i < size; ++value_i) - { - if (null_bytemap && (*null_bytemap)[value_i]) - status = builder.AppendNull(); - else - /// Implicitly converts UInt16 to Int32 - status = builder.Append(internal_data[value_i]); - checkStatus(status, write_column->getName()); - } - - status = builder.Finish(&arrow_array); - checkStatus(status, write_column->getName()); -} - -void fillArrowArrayWithDateTimeColumnData( - ColumnPtr write_column, std::shared_ptr & arrow_array, const PaddedPODArray * null_bytemap) -{ - auto & internal_data = static_cast &>(*write_column).getData(); - //arrow::Date64Builder builder; - arrow::UInt32Builder builder; - arrow::Status status; - - for (size_t value_i = 0, size = internal_data.size(); value_i < size; ++value_i) - { - if (null_bytemap && (*null_bytemap)[value_i]) - status = builder.AppendNull(); - else - /// Implicitly converts UInt16 to Int32 - //status = date_builder.Append(static_cast(internal_data[value_i]) * 1000); // now ms. TODO check other units - status = builder.Append(internal_data[value_i]); - - checkStatus(status, write_column->getName()); - } - - status = builder.Finish(&arrow_array); - checkStatus(status, write_column->getName()); -} - -template -void fillArrowArrayWithDecimalColumnData( - ColumnPtr write_column, - std::shared_ptr & arrow_array, - const PaddedPODArray * null_bytemap, - const DataType * decimal_type) -{ - const auto & column = static_cast(*write_column); - arrow::DecimalBuilder builder(arrow::decimal(decimal_type->getPrecision(), decimal_type->getScale())); - arrow::Status status; - - for (size_t value_i = 0, size = column.size(); value_i < size; ++value_i) - { - if (null_bytemap && (*null_bytemap)[value_i]) - status = builder.AppendNull(); - else - status = builder.Append( - arrow::Decimal128(reinterpret_cast(&column.getElement(value_i).value))); // TODO: try copy column - - checkStatus(status, write_column->getName()); - } - status = builder.Finish(&arrow_array); - checkStatus(status, write_column->getName()); - -/* TODO column copy - const auto & internal_data = static_cast(*write_column).getData(); - //ArrowBuilderType numeric_builder; - arrow::DecimalBuilder builder(arrow::decimal(decimal_type->getPrecision(), decimal_type->getScale())); - arrow::Status status; - - const uint8_t * arrow_null_bytemap_raw_ptr = nullptr; - PaddedPODArray arrow_null_bytemap; - if (null_bytemap) - { - /// Invert values since Arrow interprets 1 as a non-null value, while CH as a null - arrow_null_bytemap.reserve(null_bytemap->size()); - for (size_t i = 0, size = null_bytemap->size(); i < size; ++i) - arrow_null_bytemap.emplace_back(1 ^ (*null_bytemap)[i]); - - arrow_null_bytemap_raw_ptr = arrow_null_bytemap.data(); - } - - status = builder.AppendValues(reinterpret_cast(internal_data.data()), internal_data.size(), arrow_null_bytemap_raw_ptr); - checkStatus(status, write_column->getName()); - - status = builder.Finish(&arrow_array); - checkStatus(status, write_column->getName()); -*/ -} - -# define FOR_INTERNAL_NUMERIC_TYPES(M) \ - M(UInt8, arrow::UInt8Builder) \ - M(Int8, arrow::Int8Builder) \ - M(UInt16, arrow::UInt16Builder) \ - M(Int16, arrow::Int16Builder) \ - M(UInt32, arrow::UInt32Builder) \ - M(Int32, arrow::Int32Builder) \ - M(UInt64, arrow::UInt64Builder) \ - M(Int64, arrow::Int64Builder) \ - M(Float32, arrow::FloatBuilder) \ - M(Float64, arrow::DoubleBuilder) - -const std::unordered_map> internal_type_to_arrow_type = { - {"UInt8", arrow::uint8()}, - {"Int8", arrow::int8()}, - {"UInt16", arrow::uint16()}, - {"Int16", arrow::int16()}, - {"UInt32", arrow::uint32()}, - {"Int32", arrow::int32()}, - {"UInt64", arrow::uint64()}, - {"Int64", arrow::int64()}, - {"Float32", arrow::float32()}, - {"Float64", arrow::float64()}, - - //{"Date", arrow::date64()}, - //{"Date", arrow::date32()}, - {"Date", arrow::uint16()}, // CHECK - //{"DateTime", arrow::date64()}, // BUG! saves as date32 - {"DateTime", arrow::uint32()}, - - // TODO: ClickHouse can actually store non-utf8 strings! - {"String", arrow::utf8()}, - {"FixedString", arrow::utf8()}, -}; - -const PaddedPODArray * extractNullBytemapPtr(ColumnPtr column) -{ - ColumnPtr null_column = static_cast(*column).getNullMapColumnPtr(); - const PaddedPODArray & null_bytemap = static_cast &>(*null_column).getData(); - return &null_bytemap; -} - - -class OstreamOutputStream : public parquet::OutputStream -{ -public: - explicit OstreamOutputStream(WriteBuffer & ostr_) : ostr(ostr_) {} - virtual ~OstreamOutputStream() {} - virtual void Close() {} - virtual int64_t Tell() { return total_length; } - virtual void Write(const uint8_t * data, int64_t length) - { - ostr.write(reinterpret_cast(data), length); - total_length += length; - } - -private: - WriteBuffer & ostr; - int64_t total_length = 0; - - PARQUET_DISALLOW_COPY_AND_ASSIGN(OstreamOutputStream); -}; - - -void ParquetBlockOutputStream::write(const Block & block) -{ - block.checkNumberOfRows(); - - const size_t columns_num = block.columns(); - - /// For arrow::Schema and arrow::Table creation - std::vector> arrow_fields; - std::vector> arrow_arrays; - arrow_fields.reserve(columns_num); - arrow_arrays.reserve(columns_num); - - for (size_t column_i = 0; column_i < columns_num; ++column_i) - { - // TODO: constructed every iteration - const ColumnWithTypeAndName & column = block.safeGetByPosition(column_i); - - const bool is_column_nullable = column.type->isNullable(); - const auto & column_nested_type - = is_column_nullable ? static_cast(column.type.get())->getNestedType() : column.type; - const std::string column_nested_type_name = column_nested_type->getFamilyName(); - - if (isDecimal(column_nested_type)) - { - const auto add_decimal_field = [&](const auto & types) -> bool { - using Types = std::decay_t; - using ToDataType = typename Types::LeftType; - - if constexpr ( - std::is_same_v< - ToDataType, - DataTypeDecimal< - Decimal32>> || std::is_same_v> || std::is_same_v>) - { - const auto & decimal_type = static_cast(column_nested_type.get()); - arrow_fields.emplace_back(std::make_shared( - column.name, arrow::decimal(decimal_type->getPrecision(), decimal_type->getScale()), is_column_nullable)); - } - - return false; - }; - callOnIndexAndDataType(column_nested_type->getTypeId(), add_decimal_field); - } - else - { - if (internal_type_to_arrow_type.find(column_nested_type_name) == internal_type_to_arrow_type.end()) - { - throw Exception{"The type \"" + column_nested_type_name + "\" of a column \"" + column.name - + "\"" - " is not supported for conversion into a Parquet data format", - ErrorCodes::UNKNOWN_TYPE}; - } - - arrow_fields.emplace_back(std::make_shared(column.name, internal_type_to_arrow_type.at(column_nested_type_name), is_column_nullable)); - } - - std::shared_ptr arrow_array; - - ColumnPtr nested_column - = is_column_nullable ? static_cast(*column.column).getNestedColumnPtr() : column.column; - const PaddedPODArray * null_bytemap = is_column_nullable ? extractNullBytemapPtr(column.column) : nullptr; - - if ("String" == column_nested_type_name) - { - fillArrowArrayWithStringColumnData(nested_column, arrow_array, null_bytemap); - } - else if ("FixedString" == column_nested_type_name) - { - fillArrowArrayWithStringColumnData(nested_column, arrow_array, null_bytemap); - } - else if ("Date" == column_nested_type_name) - { - fillArrowArrayWithDateColumnData(nested_column, arrow_array, null_bytemap); - } - else if ("DateTime" == column_nested_type_name) - { - fillArrowArrayWithDateTimeColumnData(nested_column, arrow_array, null_bytemap); - } - - else if (isDecimal(column_nested_type)) - { - auto fill_decimal = [&](const auto & types) -> bool - { - using Types = std::decay_t; - using ToDataType = typename Types::LeftType; - if constexpr ( - std::is_same_v< - ToDataType, - DataTypeDecimal< - Decimal32>> || std::is_same_v> || std::is_same_v>) - { - const auto & decimal_type = static_cast(column_nested_type.get()); - fillArrowArrayWithDecimalColumnData(nested_column, arrow_array, null_bytemap, decimal_type); - } - return false; - }; - callOnIndexAndDataType(column_nested_type->getTypeId(), fill_decimal); - } -# define DISPATCH(CPP_NUMERIC_TYPE, ARROW_BUILDER_TYPE) \ - else if (#CPP_NUMERIC_TYPE == column_nested_type_name) \ - { \ - fillArrowArrayWithNumericColumnData(nested_column, arrow_array, null_bytemap); \ - } - - FOR_INTERNAL_NUMERIC_TYPES(DISPATCH) -# undef DISPATCH - else - { - throw Exception{"Internal type \"" + column_nested_type_name + "\" of a column \"" + column.name - + "\"" - " is not supported for conversion into a Parquet data format", - ErrorCodes::UNKNOWN_TYPE}; - } - - - arrow_arrays.emplace_back(std::move(arrow_array)); - } - - std::shared_ptr arrow_schema = std::make_shared(std::move(arrow_fields)); - - std::shared_ptr arrow_table = arrow::Table::Make(arrow_schema, arrow_arrays); - - auto sink = std::make_shared(ostr); - - if (!file_writer) - { - - parquet::WriterProperties::Builder builder; -#if USE_SNAPPY - builder.compression(parquet::Compression::SNAPPY); -#endif - auto props = builder.build(); - auto status = parquet::arrow::FileWriter::Open( - *arrow_table->schema(), - arrow::default_memory_pool(), - sink, - props, /*parquet::default_writer_properties(),*/ - parquet::arrow::default_arrow_writer_properties(), - &file_writer); - if (!status.ok()) - throw Exception{"Error while opening a table: " + status.ToString(), ErrorCodes::UNKNOWN_EXCEPTION}; - } - - // TODO: calculate row_group_size depending on a number of rows and table size - auto status = file_writer->WriteTable(*arrow_table, format_settings.parquet.row_group_size); - - if (!status.ok()) - throw Exception{"Error while writing a table: " + status.ToString(), ErrorCodes::UNKNOWN_EXCEPTION}; -} - -void ParquetBlockOutputStream::writeSuffix() -{ - if (file_writer) - { - auto status = file_writer->Close(); - if (!status.ok()) - throw Exception{"Error while closing a table: " + status.ToString(), ErrorCodes::UNKNOWN_EXCEPTION}; - } -} - - -void registerOutputFormatParquet(FormatFactory & factory) -{ - factory.registerOutputFormat( - "Parquet", [](WriteBuffer & buf, const Block & sample, const Context & /*context*/, const FormatSettings & format_settings) - { - BlockOutputStreamPtr impl = std::make_shared(buf, sample, format_settings); - auto res = std::make_shared(impl, impl->getHeader(), format_settings.parquet.row_group_size, 0); - res->disableFlush(); - return res; - }); -} - -} - - -#else - -namespace DB -{ -class FormatFactory; -void registerOutputFormatParquet(FormatFactory &) -{ -} -} - - -#endif diff --git a/dbms/src/Formats/ParquetBlockOutputStream.h b/dbms/src/Formats/ParquetBlockOutputStream.h deleted file mode 100644 index 7cd484fc52b..00000000000 --- a/dbms/src/Formats/ParquetBlockOutputStream.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include "config_formats.h" -#if USE_PARQUET -# include -# include - -namespace arrow -{ -class Array; -class DataType; -} - -namespace parquet -{ -namespace arrow -{ - class FileWriter; -} -} - -namespace DB -{ -class ParquetBlockOutputStream : public IBlockOutputStream -{ -public: - ParquetBlockOutputStream(WriteBuffer & ostr_, const Block & header_, const FormatSettings & format_settings); - - Block getHeader() const override { return header; } - void write(const Block & block) override; - void writeSuffix() override; - void flush() override; - - String getContentType() const override { return "application/octet-stream"; } - -private: - WriteBuffer & ostr; - Block header; - const FormatSettings format_settings; - - std::unique_ptr file_writer; -}; - -} - -#endif diff --git a/dbms/src/Processors/Formats/Impl/ParquetBlockOutputFormat.cpp b/dbms/src/Processors/Formats/Impl/ParquetBlockOutputFormat.cpp index 26b3dd84f14..5b546e863de 100644 --- a/dbms/src/Processors/Formats/Impl/ParquetBlockOutputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/ParquetBlockOutputFormat.cpp @@ -1,7 +1,7 @@ #include "config_formats.h" #if USE_PARQUET -# include "ParquetBlockOutputFormat.h" +# include // TODO: clean includes # include diff --git a/dbms/src/Processors/Formats/Impl/ParquetBlockOutputFormat.h b/dbms/src/Processors/Formats/Impl/ParquetBlockOutputFormat.h index de2deba50b3..f7ca6f11f00 100644 --- a/dbms/src/Processors/Formats/Impl/ParquetBlockOutputFormat.h +++ b/dbms/src/Processors/Formats/Impl/ParquetBlockOutputFormat.h @@ -1,6 +1,6 @@ #pragma once -#include +#include "config_formats.h" #if USE_PARQUET # include # include From 5f7ebb18eda0ff629984d90f2443a95b50940f1f Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Fri, 2 Aug 2019 19:16:18 +0300 Subject: [PATCH 0633/1165] more optimal ranges selection at reading in order --- .../FinishSortingBlockInputStream.cpp | 2 -- dbms/src/Interpreters/InterpreterSelectQuery.cpp | 16 +++++++++++----- .../MergeTree/MergeTreeDataSelectExecutor.cpp | 14 +++++--------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/dbms/src/DataStreams/FinishSortingBlockInputStream.cpp b/dbms/src/DataStreams/FinishSortingBlockInputStream.cpp index 461a1b36a65..e7382bf8b6d 100644 --- a/dbms/src/DataStreams/FinishSortingBlockInputStream.cpp +++ b/dbms/src/DataStreams/FinishSortingBlockInputStream.cpp @@ -102,8 +102,6 @@ Block FinishSortingBlockInputStream::readImpl() if (block.rows() == 0) continue; - // We need to sort each block separately before merging. - sortBlock(block, description_to_sort, limit); removeConstantsFromBlock(block); diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.cpp b/dbms/src/Interpreters/InterpreterSelectQuery.cpp index 11d90fd4f4a..a2beadc3ddf 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSelectQuery.cpp @@ -1915,13 +1915,12 @@ void InterpreterSelectQuery::executeOrder(Pipeline & pipeline, SortingInfoPtr so * At this stage we merge per-thread streams into one. */ - if (sorting_info->prefix_order_descr.size() < order_descr.size()) + bool need_finish_sorting = (sorting_info->prefix_order_descr.size() < order_descr.size()); + if (need_finish_sorting) { pipeline.transform([&](auto & stream) { - stream = std::make_shared( - stream, sorting_info->prefix_order_descr, - order_descr, settings.max_block_size, limit); + stream = std::make_shared(stream, order_descr, limit); }); } @@ -1933,10 +1932,17 @@ void InterpreterSelectQuery::executeOrder(Pipeline & pipeline, SortingInfoPtr so }); pipeline.firstStream() = std::make_shared( - pipeline.streams, order_descr, + pipeline.streams, sorting_info->prefix_order_descr, settings.max_block_size, limit); pipeline.streams.resize(1); } + + if (need_finish_sorting) + { + pipeline.firstStream() = std::make_shared( + pipeline.firstStream(), sorting_info->prefix_order_descr, + order_descr, settings.max_block_size, limit); + } } else { diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index d528755005b..d1179787d9a 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -867,25 +867,20 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsWithO if (sum_marks == 0) return streams; - /// In case of reverse order let's split ranges to avoid reading much data. + /// Let's split ranges to avoid reading much data. auto split_ranges = [rows_granularity = data.settings.index_granularity, max_block_size](const auto & ranges, int direction) { - if (direction == 1) - return ranges; - MarkRanges new_ranges; - - /// Probably it useful to make it larger. const size_t max_marks_in_range = (max_block_size + rows_granularity - 1) / rows_granularity; - size_t marks_in_range = 1; for (auto range : ranges) { + size_t marks_in_range = 1; while (range.begin + marks_in_range < range.end) { if (direction == 1) { - /// Comment + /// Split first few ranges to avoid reading much data. new_ranges.emplace_back(range.begin, range.begin + marks_in_range); range.begin += marks_in_range; marks_in_range *= 2; @@ -895,7 +890,8 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsWithO } else { - /// Comment + /// Split all ranges to avoid reading much data, because we have to + /// store whole range in memory to reverse it. new_ranges.emplace_back(range.end - marks_in_range, range.end); range.end -= marks_in_range; marks_in_range = std::min(marks_in_range * 2, max_marks_in_range); From a0f61e8cb3c1391210f48d287c4620a0708ac675 Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Fri, 2 Aug 2019 19:17:18 +0300 Subject: [PATCH 0634/1165] better performance test for order by optimization --- dbms/tests/performance/order_by_read_in_order.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dbms/tests/performance/order_by_read_in_order.xml b/dbms/tests/performance/order_by_read_in_order.xml index f52c9a0ce55..d0c5350b3c6 100644 --- a/dbms/tests/performance/order_by_read_in_order.xml +++ b/dbms/tests/performance/order_by_read_in_order.xml @@ -25,9 +25,13 @@ - test.hits + default.hits_100m_single -SELECT CounterID FROM test.hits ORDER BY CounterID, EventDate DESC LIMIT 50 +SELECT * FROM hits_100m_single ORDER BY CounterID, EventDate LIMIT 100 +SELECT * FROM hits_100m_single ORDER BY CounterID DESC, toStartOfWeek(EventDate) DESC LIMIT 100 +SELECT * FROM hits_100m_single ORDER BY CounterID, EventDate, URL LIMIT 100 +SELECT * FROM hits_100m_single WHERE CounterID IN (152220, 168777, 149234, 149234) ORDER BY CounterID DESC, EventDate DESC LIMIT 100 +SELECT * FROM hits_100m_single WHERE UserID=1988954671305023629 ORDER BY CounterID, EventDate LIMIT 100 From bd4f0182e47d4bd3f135955ef0fd4b3aeaeb3e6a Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 19:20:25 +0300 Subject: [PATCH 0635/1165] Remove PrettyBlockOutputStreams. --- dbms/src/Formats/FormatFactory.cpp | 7 +- dbms/src/Formats/PrettyBlockOutputStream.cpp | 277 ------------------ dbms/src/Formats/PrettyBlockOutputStream.h | 55 ---- .../PrettyCompactBlockOutputStream.cpp | 161 ---------- .../Formats/PrettyCompactBlockOutputStream.h | 25 -- .../Formats/PrettySpaceBlockOutputStream.cpp | 116 -------- .../Formats/PrettySpaceBlockOutputStream.h | 21 -- 7 files changed, 1 insertion(+), 661 deletions(-) delete mode 100644 dbms/src/Formats/PrettyBlockOutputStream.cpp delete mode 100644 dbms/src/Formats/PrettyBlockOutputStream.h delete mode 100644 dbms/src/Formats/PrettyCompactBlockOutputStream.cpp delete mode 100644 dbms/src/Formats/PrettyCompactBlockOutputStream.h delete mode 100644 dbms/src/Formats/PrettySpaceBlockOutputStream.cpp delete mode 100644 dbms/src/Formats/PrettySpaceBlockOutputStream.h diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 258786a93c9..af0bd2e6c88 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -232,9 +232,6 @@ void registerOutputFormatProcessorProtobuf(FormatFactory & factory); /// Output only (presentational) formats. -void registerOutputFormatPretty(FormatFactory & factory); -void registerOutputFormatPrettyCompact(FormatFactory & factory); -void registerOutputFormatPrettySpace(FormatFactory & factory); void registerOutputFormatVertical(FormatFactory & factory); void registerOutputFormatXML(FormatFactory & factory); void registerOutputFormatNull(FormatFactory & factory); @@ -289,9 +286,7 @@ FormatFactory::FormatFactory() registerInputFormatProcessorParquet(*this); registerOutputFormatProcessorParquet(*this); - registerOutputFormatPretty(*this); - registerOutputFormatPrettyCompact(*this); - registerOutputFormatPrettySpace(*this); + registerOutputFormatVertical(*this); registerOutputFormatXML(*this); registerOutputFormatNull(*this); diff --git a/dbms/src/Formats/PrettyBlockOutputStream.cpp b/dbms/src/Formats/PrettyBlockOutputStream.cpp deleted file mode 100644 index 9c4c9a20965..00000000000 --- a/dbms/src/Formats/PrettyBlockOutputStream.cpp +++ /dev/null @@ -1,277 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace DB -{ - -namespace ErrorCodes -{ - extern const int ILLEGAL_COLUMN; -} - - -PrettyBlockOutputStream::PrettyBlockOutputStream( - WriteBuffer & ostr_, const Block & header_, const FormatSettings & format_settings) - : ostr(ostr_), header(header_), format_settings(format_settings) -{ - struct winsize w; - if (0 == ioctl(STDOUT_FILENO, TIOCGWINSZ, &w)) - terminal_width = w.ws_col; -} - - -void PrettyBlockOutputStream::flush() -{ - ostr.next(); -} - - -/// Evaluate the visible width of the values and column names. -/// Note that number of code points is just a rough approximation of visible string width. -void PrettyBlockOutputStream::calculateWidths( - const Block & block, WidthsPerColumn & widths, Widths & max_widths, Widths & name_widths, const FormatSettings & format_settings) -{ - size_t rows = block.rows(); - size_t columns = block.columns(); - - widths.resize(columns); - max_widths.resize_fill(columns); - name_widths.resize(columns); - - /// Calculate widths of all values. - String serialized_value; - size_t prefix = 2; // Tab character adjustment - for (size_t i = 0; i < columns; ++i) - { - const ColumnWithTypeAndName & elem = block.getByPosition(i); - - widths[i].resize(rows); - - for (size_t j = 0; j < rows; ++j) - { - { - WriteBufferFromString out(serialized_value); - elem.type->serializeAsText(*elem.column, j, out, format_settings); - } - - widths[i][j] = std::min(format_settings.pretty.max_column_pad_width, - UTF8::computeWidth(reinterpret_cast(serialized_value.data()), serialized_value.size(), prefix)); - max_widths[i] = std::max(max_widths[i], widths[i][j]); - } - - /// And also calculate widths for names of columns. - { - // name string doesn't contain Tab, no need to pass `prefix` - name_widths[i] = std::min(format_settings.pretty.max_column_pad_width, - UTF8::computeWidth(reinterpret_cast(elem.name.data()), elem.name.size())); - max_widths[i] = std::max(max_widths[i], name_widths[i]); - } - prefix += max_widths[i] + 3; - } -} - - -void PrettyBlockOutputStream::write(const Block & block) -{ - UInt64 max_rows = format_settings.pretty.max_rows; - - if (total_rows >= max_rows) - { - total_rows += block.rows(); - return; - } - - size_t rows = block.rows(); - size_t columns = block.columns(); - - WidthsPerColumn widths; - Widths max_widths; - Widths name_widths; - calculateWidths(block, widths, max_widths, name_widths, format_settings); - - /// Create separators - std::stringstream top_separator; - std::stringstream middle_names_separator; - std::stringstream middle_values_separator; - std::stringstream bottom_separator; - - top_separator << "┏"; - middle_names_separator << "┡"; - middle_values_separator << "├"; - bottom_separator << "└"; - for (size_t i = 0; i < columns; ++i) - { - if (i != 0) - { - top_separator << "┳"; - middle_names_separator << "╇"; - middle_values_separator << "┼"; - bottom_separator << "┴"; - } - - for (size_t j = 0; j < max_widths[i] + 2; ++j) - { - top_separator << "━"; - middle_names_separator << "━"; - middle_values_separator << "─"; - bottom_separator << "─"; - } - } - top_separator << "┓\n"; - middle_names_separator << "┩\n"; - middle_values_separator << "┤\n"; - bottom_separator << "┘\n"; - - std::string top_separator_s = top_separator.str(); - std::string middle_names_separator_s = middle_names_separator.str(); - std::string middle_values_separator_s = middle_values_separator.str(); - std::string bottom_separator_s = bottom_separator.str(); - - /// Output the block - writeString(top_separator_s, ostr); - - /// Names - writeCString("┃ ", ostr); - for (size_t i = 0; i < columns; ++i) - { - if (i != 0) - writeCString(" ┃ ", ostr); - - const ColumnWithTypeAndName & col = block.getByPosition(i); - - if (format_settings.pretty.color) - writeCString("\033[1m", ostr); - - if (col.type->shouldAlignRightInPrettyFormats()) - { - for (size_t k = 0; k < max_widths[i] - name_widths[i]; ++k) - writeChar(' ', ostr); - - writeString(col.name, ostr); - } - else - { - writeString(col.name, ostr); - - for (size_t k = 0; k < max_widths[i] - name_widths[i]; ++k) - writeChar(' ', ostr); - } - - if (format_settings.pretty.color) - writeCString("\033[0m", ostr); - } - writeCString(" ┃\n", ostr); - - writeString(middle_names_separator_s, ostr); - - for (size_t i = 0; i < rows && total_rows + i < max_rows; ++i) - { - if (i != 0) - writeString(middle_values_separator_s, ostr); - - writeCString("│ ", ostr); - - for (size_t j = 0; j < columns; ++j) - { - if (j != 0) - writeCString(" │ ", ostr); - - writeValueWithPadding(block.getByPosition(j), i, widths[j].empty() ? max_widths[j] : widths[j][i], max_widths[j]); - } - - writeCString(" │\n", ostr); - } - - writeString(bottom_separator_s, ostr); - - total_rows += rows; -} - - -void PrettyBlockOutputStream::writeValueWithPadding(const ColumnWithTypeAndName & elem, size_t row_num, size_t value_width, size_t pad_to_width) -{ - auto writePadding = [&]() - { - for (size_t k = 0; k < pad_to_width - value_width; ++k) - writeChar(' ', ostr); - }; - - if (elem.type->shouldAlignRightInPrettyFormats()) - { - writePadding(); - elem.type->serializeAsText(*elem.column.get(), row_num, ostr, format_settings); - } - else - { - elem.type->serializeAsText(*elem.column.get(), row_num, ostr, format_settings); - writePadding(); - } -} - - -void PrettyBlockOutputStream::writeSuffix() -{ - if (total_rows >= format_settings.pretty.max_rows) - { - writeCString(" Showed first ", ostr); - writeIntText(format_settings.pretty.max_rows, ostr); - writeCString(".\n", ostr); - } - - total_rows = 0; - writeTotals(); - writeExtremes(); -} - - -void PrettyBlockOutputStream::writeTotals() -{ - if (totals) - { - writeCString("\nTotals:\n", ostr); - write(totals); - } -} - - -void PrettyBlockOutputStream::writeExtremes() -{ - if (extremes) - { - writeCString("\nExtremes:\n", ostr); - write(extremes); - } -} - - -void registerOutputFormatPretty(FormatFactory & factory) -{ - factory.registerOutputFormat("Pretty", []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & format_settings) - { - return std::make_shared(buf, sample, format_settings); - }); - - factory.registerOutputFormat("PrettyNoEscapes", []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & format_settings) - { - FormatSettings changed_settings = format_settings; - changed_settings.pretty.color = false; - return std::make_shared(buf, sample, changed_settings); - }); -} - -} diff --git a/dbms/src/Formats/PrettyBlockOutputStream.h b/dbms/src/Formats/PrettyBlockOutputStream.h deleted file mode 100644 index ca23ba2cf61..00000000000 --- a/dbms/src/Formats/PrettyBlockOutputStream.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include -#include -#include - - -namespace DB -{ - -class WriteBuffer; -class Context; - - -/** Prints the result in the form of beautiful tables. - */ -class PrettyBlockOutputStream : public IBlockOutputStream -{ -public: - /// no_escapes - do not use ANSI escape sequences - to display in the browser, not in the console. - PrettyBlockOutputStream(WriteBuffer & ostr_, const Block & header_, const FormatSettings & format_settings); - - Block getHeader() const override { return header; } - void write(const Block & block) override; - void writeSuffix() override; - - void flush() override; - - void setTotals(const Block & totals_) override { totals = totals_; } - void setExtremes(const Block & extremes_) override { extremes = extremes_; } - -protected: - void writeTotals(); - void writeExtremes(); - - WriteBuffer & ostr; - const Block header; - size_t total_rows = 0; - size_t terminal_width = 0; - - const FormatSettings format_settings; - - Block totals; - Block extremes; - - using Widths = PODArray; - using WidthsPerColumn = std::vector; - - static void calculateWidths( - const Block & block, WidthsPerColumn & widths, Widths & max_widths, Widths & name_widths, const FormatSettings & format_settings); - - void writeValueWithPadding(const ColumnWithTypeAndName & elem, size_t row_num, size_t value_width, size_t pad_to_width); -}; - -} diff --git a/dbms/src/Formats/PrettyCompactBlockOutputStream.cpp b/dbms/src/Formats/PrettyCompactBlockOutputStream.cpp deleted file mode 100644 index b4085fb256b..00000000000 --- a/dbms/src/Formats/PrettyCompactBlockOutputStream.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include -#include -#include -#include -#include - - -namespace DB -{ - -namespace ErrorCodes -{ - -extern const int ILLEGAL_COLUMN; - -} - -void PrettyCompactBlockOutputStream::writeHeader( - const Block & block, - const Widths & max_widths, - const Widths & name_widths) -{ - /// Names - writeCString("┌─", ostr); - for (size_t i = 0; i < max_widths.size(); ++i) - { - if (i != 0) - writeCString("─┬─", ostr); - - const ColumnWithTypeAndName & col = block.getByPosition(i); - - if (col.type->shouldAlignRightInPrettyFormats()) - { - for (size_t k = 0; k < max_widths[i] - name_widths[i]; ++k) - writeCString("─", ostr); - - if (format_settings.pretty.color) - writeCString("\033[1m", ostr); - writeString(col.name, ostr); - if (format_settings.pretty.color) - writeCString("\033[0m", ostr); - } - else - { - if (format_settings.pretty.color) - writeCString("\033[1m", ostr); - writeString(col.name, ostr); - if (format_settings.pretty.color) - writeCString("\033[0m", ostr); - - for (size_t k = 0; k < max_widths[i] - name_widths[i]; ++k) - writeCString("─", ostr); - } - } - writeCString("─┐\n", ostr); -} - -void PrettyCompactBlockOutputStream::writeBottom(const Widths & max_widths) -{ - /// Create delimiters - std::stringstream bottom_separator; - - bottom_separator << "└"; - for (size_t i = 0; i < max_widths.size(); ++i) - { - if (i != 0) - bottom_separator << "┴"; - - for (size_t j = 0; j < max_widths[i] + 2; ++j) - bottom_separator << "─"; - } - bottom_separator << "┘\n"; - - writeString(bottom_separator.str(), ostr); -} - -void PrettyCompactBlockOutputStream::writeRow( - size_t row_num, - const Block & block, - const WidthsPerColumn & widths, - const Widths & max_widths) -{ - size_t columns = max_widths.size(); - - writeCString("│ ", ostr); - - for (size_t j = 0; j < columns; ++j) - { - if (j != 0) - writeCString(" │ ", ostr); - - writeValueWithPadding(block.getByPosition(j), row_num, widths[j].empty() ? max_widths[j] : widths[j][row_num], max_widths[j]); - } - - writeCString(" │\n", ostr); -} - -void PrettyCompactBlockOutputStream::write(const Block & block) -{ - UInt64 max_rows = format_settings.pretty.max_rows; - - if (total_rows >= max_rows) - { - total_rows += block.rows(); - return; - } - - size_t rows = block.rows(); - - WidthsPerColumn widths; - Widths max_widths; - Widths name_widths; - calculateWidths(block, widths, max_widths, name_widths, format_settings); - - writeHeader(block, max_widths, name_widths); - - for (size_t i = 0; i < rows && total_rows + i < max_rows; ++i) - writeRow(i, block, widths, max_widths); - - writeBottom(max_widths); - - total_rows += rows; -} - - -void registerOutputFormatPrettyCompact(FormatFactory & factory) -{ - factory.registerOutputFormat("PrettyCompact", []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & format_settings) - { - return std::make_shared(buf, sample, format_settings); - }); - - factory.registerOutputFormat("PrettyCompactNoEscapes", []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & format_settings) - { - FormatSettings changed_settings = format_settings; - changed_settings.pretty.color = false; - return std::make_shared(buf, sample, changed_settings); - }); - - factory.registerOutputFormat("PrettyCompactMonoBlock", []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & format_settings) - { - BlockOutputStreamPtr impl = std::make_shared(buf, sample, format_settings); - auto res = std::make_shared(impl, impl->getHeader(), format_settings.pretty.max_rows, 0); - res->disableFlush(); - return res; - }); -} - -} diff --git a/dbms/src/Formats/PrettyCompactBlockOutputStream.h b/dbms/src/Formats/PrettyCompactBlockOutputStream.h deleted file mode 100644 index d0e3826bece..00000000000 --- a/dbms/src/Formats/PrettyCompactBlockOutputStream.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include - - -namespace DB -{ - -/** Prints the result in the form of beautiful tables, but with fewer delimiter lines. - */ -class PrettyCompactBlockOutputStream : public PrettyBlockOutputStream -{ -public: - PrettyCompactBlockOutputStream(WriteBuffer & ostr_, const Block & header_, const FormatSettings & format_settings_) - : PrettyBlockOutputStream(ostr_, header_, format_settings_) {} - - void write(const Block & block) override; - -protected: - void writeHeader(const Block & block, const Widths & max_widths, const Widths & name_widths); - void writeBottom(const Widths & max_widths); - void writeRow(size_t row_num, const Block & block, const WidthsPerColumn & widths, const Widths & max_widths); -}; - -} diff --git a/dbms/src/Formats/PrettySpaceBlockOutputStream.cpp b/dbms/src/Formats/PrettySpaceBlockOutputStream.cpp deleted file mode 100644 index b210af2551a..00000000000 --- a/dbms/src/Formats/PrettySpaceBlockOutputStream.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include -#include -#include - - -namespace DB -{ - -void PrettySpaceBlockOutputStream::write(const Block & block) -{ - UInt64 max_rows = format_settings.pretty.max_rows; - - if (total_rows >= max_rows) - { - total_rows += block.rows(); - return; - } - - size_t rows = block.rows(); - size_t columns = block.columns(); - - WidthsPerColumn widths; - Widths max_widths; - Widths name_widths; - calculateWidths(block, widths, max_widths, name_widths, format_settings); - - /// Names - for (size_t i = 0; i < columns; ++i) - { - if (i != 0) - writeCString(" ", ostr); - - const ColumnWithTypeAndName & col = block.getByPosition(i); - - if (col.type->shouldAlignRightInPrettyFormats()) - { - for (ssize_t k = 0; k < std::max(static_cast(0), static_cast(max_widths[i] - name_widths[i])); ++k) - writeChar(' ', ostr); - - if (format_settings.pretty.color) - writeCString("\033[1m", ostr); - writeString(col.name, ostr); - if (format_settings.pretty.color) - writeCString("\033[0m", ostr); - } - else - { - if (format_settings.pretty.color) - writeCString("\033[1m", ostr); - writeString(col.name, ostr); - if (format_settings.pretty.color) - writeCString("\033[0m", ostr); - - for (ssize_t k = 0; k < std::max(static_cast(0), static_cast(max_widths[i] - name_widths[i])); ++k) - writeChar(' ', ostr); - } - } - writeCString("\n\n", ostr); - - for (size_t i = 0; i < rows && total_rows + i < max_rows; ++i) - { - for (size_t j = 0; j < columns; ++j) - { - if (j != 0) - writeCString(" ", ostr); - - writeValueWithPadding(block.getByPosition(j), i, widths[j].empty() ? max_widths[j] : widths[j][i], max_widths[j]); - } - - writeChar('\n', ostr); - } - - total_rows += rows; -} - - -void PrettySpaceBlockOutputStream::writeSuffix() -{ - if (total_rows >= format_settings.pretty.max_rows) - { - writeCString("\nShowed first ", ostr); - writeIntText(format_settings.pretty.max_rows, ostr); - writeCString(".\n", ostr); - } - - total_rows = 0; - writeTotals(); - writeExtremes(); -} - - -void registerOutputFormatPrettySpace(FormatFactory & factory) -{ - factory.registerOutputFormat("PrettySpace", []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & format_settings) - { - return std::make_shared(buf, sample, format_settings); - }); - - factory.registerOutputFormat("PrettySpaceNoEscapes", []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & format_settings) - { - FormatSettings changed_settings = format_settings; - changed_settings.pretty.color = false; - return std::make_shared(buf, sample, changed_settings); - }); -} - -} diff --git a/dbms/src/Formats/PrettySpaceBlockOutputStream.h b/dbms/src/Formats/PrettySpaceBlockOutputStream.h deleted file mode 100644 index 9807bf85767..00000000000 --- a/dbms/src/Formats/PrettySpaceBlockOutputStream.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - - -namespace DB -{ - -/** Prints the result, aligned with spaces. - */ -class PrettySpaceBlockOutputStream : public PrettyBlockOutputStream -{ -public: - PrettySpaceBlockOutputStream(WriteBuffer & ostr_, const Block & header_, const FormatSettings & format_settings_) - : PrettyBlockOutputStream(ostr_, header_, format_settings_) {} - - void write(const Block & block) override; - void writeSuffix() override; -}; - -} From 8c66d106e4fb16b4e1d3b4bc24519206b80796b3 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 19:23:44 +0300 Subject: [PATCH 0636/1165] Remove ProtobufRowInputStream. --- dbms/src/Formats/FormatFactory.cpp | 2 - dbms/src/Formats/ProtobufRowInputStream.cpp | 96 ------------------- dbms/src/Formats/ProtobufRowInputStream.h | 40 -------- .../Formats/Impl/ProtobufRowInputFormat.cpp | 2 +- .../Formats/Impl/ProtobufRowInputFormat.h | 8 +- 5 files changed, 8 insertions(+), 140 deletions(-) delete mode 100644 dbms/src/Formats/ProtobufRowInputStream.cpp delete mode 100644 dbms/src/Formats/ProtobufRowInputStream.h diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index af0bd2e6c88..30a08b37153 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -208,7 +208,6 @@ void registerOutputFormatCSV(FormatFactory & factory); void registerInputFormatTSKV(FormatFactory & factory); void registerOutputFormatTSKV(FormatFactory & factory); void registerOutputFormatTSKV(FormatFactory & factory); -void registerInputFormatProtobuf(FormatFactory & factory); void registerOutputFormatProtobuf(FormatFactory & factory); void registerInputFormatProcessorNative(FormatFactory & factory); @@ -263,7 +262,6 @@ FormatFactory::FormatFactory() registerOutputFormatCSV(*this); registerInputFormatTSKV(*this); registerOutputFormatTSKV(*this); - registerInputFormatProtobuf(*this); registerOutputFormatProtobuf(*this); registerInputFormatProcessorNative(*this); diff --git a/dbms/src/Formats/ProtobufRowInputStream.cpp b/dbms/src/Formats/ProtobufRowInputStream.cpp deleted file mode 100644 index 799b53c9d6e..00000000000 --- a/dbms/src/Formats/ProtobufRowInputStream.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include "config_formats.h" -#if USE_PROTOBUF - -#include "ProtobufRowInputStream.h" - -#include -#include -#include -#include -#include - - -namespace DB -{ - -ProtobufRowInputStream::ProtobufRowInputStream(ReadBuffer & in_, const Block & header, const FormatSchemaInfo & format_schema) - : data_types(header.getDataTypes()), reader(in_, ProtobufSchemas::instance().getMessageTypeForFormatSchema(format_schema), header.getNames()) -{ -} - -ProtobufRowInputStream::~ProtobufRowInputStream() = default; - -bool ProtobufRowInputStream::read(MutableColumns & columns, RowReadExtension & extra) -{ - if (!reader.startMessage()) - return false; // EOF reached, no more messages. - - // Set of columns for which the values were read. The rest will be filled with default values. - auto & read_columns = extra.read_columns; - read_columns.assign(columns.size(), false); - - // Read values from this message and put them to the columns while it's possible. - size_t column_index; - while (reader.readColumnIndex(column_index)) - { - bool allow_add_row = !static_cast(read_columns[column_index]); - do - { - bool row_added; - data_types[column_index]->deserializeProtobuf(*columns[column_index], reader, allow_add_row, row_added); - if (row_added) - { - read_columns[column_index] = true; - allow_add_row = false; - } - } while (reader.canReadMoreValues()); - } - - // Fill non-visited columns with the default values. - for (column_index = 0; column_index < read_columns.size(); ++column_index) - if (!read_columns[column_index]) - data_types[column_index]->insertDefaultInto(*columns[column_index]); - - reader.endMessage(); - return true; -} - -bool ProtobufRowInputStream::allowSyncAfterError() const -{ - return true; -} - -void ProtobufRowInputStream::syncAfterError() -{ - reader.endMessage(true); -} - - -void registerInputFormatProtobuf(FormatFactory & factory) -{ - factory.registerInputFormat("Protobuf", []( - ReadBuffer & buf, - const Block & sample, - const Context & context, - UInt64 max_block_size, - UInt64 rows_portion_size, - FormatFactory::ReadCallback callback, - const FormatSettings & settings) - { - return std::make_shared( - std::make_shared(buf, sample, FormatSchemaInfo(context, "Protobuf")), - sample, max_block_size, rows_portion_size, callback, settings); - }); -} - -} - -#else - -namespace DB -{ -class FormatFactory; -void registerInputFormatProtobuf(FormatFactory &) {} -} - -#endif diff --git a/dbms/src/Formats/ProtobufRowInputStream.h b/dbms/src/Formats/ProtobufRowInputStream.h deleted file mode 100644 index 1dcfeaf0246..00000000000 --- a/dbms/src/Formats/ProtobufRowInputStream.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include "config_formats.h" -#if USE_PROTOBUF - -#include -#include -#include - -namespace DB -{ -class Block; -class FormatSchemaInfo; - - -/** Stream designed to deserialize data from the google protobuf format. - * Each row is read as a separated message. - * These messages are delimited according to documentation - * https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/util/delimited_message_util.h - * Serializing in the protobuf format requires the 'format_schema' setting to be set, e.g. - * INSERT INTO table FORMAT Protobuf SETTINGS format_schema = 'schema:Message' - * where schema is the name of "schema.proto" file specifying protobuf schema. - */ -class ProtobufRowInputStream : public IRowInputStream -{ -public: - ProtobufRowInputStream(ReadBuffer & in_, const Block & header, const FormatSchemaInfo & format_schema); - ~ProtobufRowInputStream() override; - - bool read(MutableColumns & columns, RowReadExtension & extra) override; - bool allowSyncAfterError() const override; - void syncAfterError() override; - -private: - DataTypes data_types; - ProtobufReader reader; -}; - -} -#endif diff --git a/dbms/src/Processors/Formats/Impl/ProtobufRowInputFormat.cpp b/dbms/src/Processors/Formats/Impl/ProtobufRowInputFormat.cpp index 448b6b3efa1..d67bad4320c 100644 --- a/dbms/src/Processors/Formats/Impl/ProtobufRowInputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/ProtobufRowInputFormat.cpp @@ -75,7 +75,7 @@ void registerInputFormatProcessorProtobuf(FormatFactory & factory) IRowInputFormat::Params params, const FormatSettings &) { - return std::make_shared(buf, sample, params, FormatSchemaInfo(context, "Protobuf")); + return std::make_shared(buf, sample, std::move(params), FormatSchemaInfo(context, "Protobuf")); }); } diff --git a/dbms/src/Processors/Formats/Impl/ProtobufRowInputFormat.h b/dbms/src/Processors/Formats/Impl/ProtobufRowInputFormat.h index 77c6350d371..89ace7fec90 100644 --- a/dbms/src/Processors/Formats/Impl/ProtobufRowInputFormat.h +++ b/dbms/src/Processors/Formats/Impl/ProtobufRowInputFormat.h @@ -13,7 +13,13 @@ class Block; class FormatSchemaInfo; -/** Interface of stream, that allows to read data by rows. +/** Stream designed to deserialize data from the google protobuf format. + * Each row is read as a separated message. + * These messages are delimited according to documentation + * https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/util/delimited_message_util.h + * Serializing in the protobuf format requires the 'format_schema' setting to be set, e.g. + * INSERT INTO table FORMAT Protobuf SETTINGS format_schema = 'schema:Message' + * where schema is the name of "schema.proto" file specifying protobuf schema. */ class ProtobufRowInputFormat : public IRowInputFormat { From 5fb548c99454abf04917bcfea2264819d4783fd2 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 19:31:17 +0300 Subject: [PATCH 0637/1165] Remove ProtobufRowOutputStream. --- dbms/src/Formats/FormatFactory.cpp | 3 - dbms/src/Formats/ProtobufRowOutputStream.cpp | 55 ------------------- dbms/src/Formats/ProtobufRowOutputStream.h | 44 --------------- ...Format.cpp => ProtobufRowOutputFormat.cpp} | 30 ++++------ ...tputFormat.h => ProtobufRowOutputFormat.h} | 11 ++-- 5 files changed, 17 insertions(+), 126 deletions(-) delete mode 100644 dbms/src/Formats/ProtobufRowOutputStream.cpp delete mode 100644 dbms/src/Formats/ProtobufRowOutputStream.h rename dbms/src/Processors/Formats/Impl/{ProtobufBlockOutputFormat.cpp => ProtobufRowOutputFormat.cpp} (56%) rename dbms/src/Processors/Formats/Impl/{ProtobufBlockOutputFormat.h => ProtobufRowOutputFormat.h} (80%) diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 30a08b37153..5ef86844b67 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -207,8 +207,6 @@ void registerInputFormatCSV(FormatFactory & factory); void registerOutputFormatCSV(FormatFactory & factory); void registerInputFormatTSKV(FormatFactory & factory); void registerOutputFormatTSKV(FormatFactory & factory); -void registerOutputFormatTSKV(FormatFactory & factory); -void registerOutputFormatProtobuf(FormatFactory & factory); void registerInputFormatProcessorNative(FormatFactory & factory); void registerOutputFormatProcessorNative(FormatFactory & factory); @@ -262,7 +260,6 @@ FormatFactory::FormatFactory() registerOutputFormatCSV(*this); registerInputFormatTSKV(*this); registerOutputFormatTSKV(*this); - registerOutputFormatProtobuf(*this); registerInputFormatProcessorNative(*this); registerOutputFormatProcessorNative(*this); diff --git a/dbms/src/Formats/ProtobufRowOutputStream.cpp b/dbms/src/Formats/ProtobufRowOutputStream.cpp deleted file mode 100644 index dfa43a1c7e8..00000000000 --- a/dbms/src/Formats/ProtobufRowOutputStream.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include - -#include "config_formats.h" -#if USE_PROTOBUF - -#include "ProtobufRowOutputStream.h" - -#include -#include -#include -#include -#include - - -namespace DB -{ -ProtobufRowOutputStream::ProtobufRowOutputStream(WriteBuffer & out, const Block & header, const FormatSchemaInfo & format_schema) - : data_types(header.getDataTypes()), writer(out, ProtobufSchemas::instance().getMessageTypeForFormatSchema(format_schema), header.getNames()) -{ - value_indices.resize(header.columns()); -} - -void ProtobufRowOutputStream::write(const Block & block, size_t row_num) -{ - writer.startMessage(); - std::fill(value_indices.begin(), value_indices.end(), 0); - size_t column_index; - while (writer.writeField(column_index)) - data_types[column_index]->serializeProtobuf( - *block.getByPosition(column_index).column, row_num, writer, value_indices[column_index]); - writer.endMessage(); -} - - -void registerOutputFormatProtobuf(FormatFactory & factory) -{ - factory.registerOutputFormat( - "Protobuf", [](WriteBuffer & buf, const Block & header, const Context & context, const FormatSettings &) - { - return std::make_shared( - std::make_shared(buf, header, FormatSchemaInfo(context, "Protobuf")), header); - }); -} - -} - -#else - -namespace DB -{ - class FormatFactory; - void registerOutputFormatProtobuf(FormatFactory &) {} -} - -#endif diff --git a/dbms/src/Formats/ProtobufRowOutputStream.h b/dbms/src/Formats/ProtobufRowOutputStream.h deleted file mode 100644 index 2bc1ebb32c9..00000000000 --- a/dbms/src/Formats/ProtobufRowOutputStream.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include -#include -#include - - -namespace google -{ -namespace protobuf -{ - class Message; -} -} - - -namespace DB -{ -class Block; -class FormatSchemaInfo; - -/** Stream designed to serialize data in the google protobuf format. - * Each row is written as a separated message. - * These messages are delimited according to documentation - * https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/util/delimited_message_util.h - * Serializing in the protobuf format requires the 'format_schema' setting to be set, e.g. - * SELECT * from table FORMAT Protobuf SETTINGS format_schema = 'schema:Message' - * where schema is the name of "schema.proto" file specifying protobuf schema. - */ -class ProtobufRowOutputStream : public IRowOutputStream -{ -public: - ProtobufRowOutputStream(WriteBuffer & out, const Block & header, const FormatSchemaInfo & format_schema); - - void write(const Block & block, size_t row_num) override; - std::string getContentType() const override { return "application/octet-stream"; } - -private: - DataTypes data_types; - ProtobufWriter writer; - std::vector value_indices; -}; - -} diff --git a/dbms/src/Processors/Formats/Impl/ProtobufBlockOutputFormat.cpp b/dbms/src/Processors/Formats/Impl/ProtobufRowOutputFormat.cpp similarity index 56% rename from dbms/src/Processors/Formats/Impl/ProtobufBlockOutputFormat.cpp rename to dbms/src/Processors/Formats/Impl/ProtobufRowOutputFormat.cpp index 03c8ef1b2ac..50f79dda993 100644 --- a/dbms/src/Processors/Formats/Impl/ProtobufBlockOutputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/ProtobufRowOutputFormat.cpp @@ -3,7 +3,7 @@ #include "config_formats.h" #if USE_PROTOBUF -#include +#include #include #include @@ -22,32 +22,26 @@ namespace ErrorCodes } -ProtobufBlockOutputFormat::ProtobufBlockOutputFormat( +ProtobufRowOutputFormat::ProtobufRowOutputFormat( WriteBuffer & out_, const Block & header, const FormatSchemaInfo & format_schema) - : IOutputFormat(header, out_) + : IRowOutputFormat(header, out_) , data_types(header.getDataTypes()) , writer(out, ProtobufSchemas::instance().getMessageTypeForFormatSchema(format_schema), header.getNames()) { value_indices.resize(header.columns()); } -void ProtobufBlockOutputFormat::consume(Chunk chunk) +void ProtobufRowOutputFormat::write(const Columns & columns, size_t row_num) { - auto & columns = chunk.getColumns(); - auto num_rows = chunk.getNumRows(); - - for (UInt64 row_num = 0; row_num < num_rows; ++row_num) - { - writer.startMessage(); - std::fill(value_indices.begin(), value_indices.end(), 0); - size_t column_index; - while (writer.writeField(column_index)) - data_types[column_index]->serializeProtobuf( - *columns[column_index], row_num, writer, value_indices[column_index]); - writer.endMessage(); - } + writer.startMessage(); + std::fill(value_indices.begin(), value_indices.end(), 0); + size_t column_index; + while (writer.writeField(column_index)) + data_types[column_index]->serializeProtobuf( + *columns[column_index], row_num, writer, value_indices[column_index]); + writer.endMessage(); } @@ -56,7 +50,7 @@ void registerOutputFormatProcessorProtobuf(FormatFactory & factory) factory.registerOutputFormatProcessor( "Protobuf", [](WriteBuffer & buf, const Block & header, const Context & context, const FormatSettings &) { - return std::make_shared(buf, header, FormatSchemaInfo(context, "Protobuf")); + return std::make_shared(buf, header, FormatSchemaInfo(context, "Protobuf")); }); } diff --git a/dbms/src/Processors/Formats/Impl/ProtobufBlockOutputFormat.h b/dbms/src/Processors/Formats/Impl/ProtobufRowOutputFormat.h similarity index 80% rename from dbms/src/Processors/Formats/Impl/ProtobufBlockOutputFormat.h rename to dbms/src/Processors/Formats/Impl/ProtobufRowOutputFormat.h index 9cc5c7af68e..bdc6f5e2492 100644 --- a/dbms/src/Processors/Formats/Impl/ProtobufBlockOutputFormat.h +++ b/dbms/src/Processors/Formats/Impl/ProtobufRowOutputFormat.h @@ -7,7 +7,7 @@ #include #include #include -#include +#include namespace google @@ -29,18 +29,17 @@ namespace DB * SELECT * from table FORMAT Protobuf SETTINGS format_schema = 'schema:Message' * where schema is the name of "schema.proto" file specifying protobuf schema. */ -class ProtobufBlockOutputFormat : public IOutputFormat +class ProtobufRowOutputFormat : public IRowOutputFormat { public: - ProtobufBlockOutputFormat( + ProtobufRowOutputFormat( WriteBuffer & out_, const Block & header, const FormatSchemaInfo & format_schema); - String getName() const override { return "ProtobufBlockOutputFormat"; } - - void consume(Chunk) override; + String getName() const override { return "ProtobufRowOutputFormat"; } + void write(const Columns & columns, size_t row_num) override; std::string getContentType() const override { return "application/octet-stream"; } private: From e5d67cbe616ebd5cc6cfac1b417ac47f79b531ef Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 19:34:20 +0300 Subject: [PATCH 0638/1165] Remove ProtobufRowOutputStream. --- dbms/src/Processors/Formats/Impl/ProtobufRowOutputFormat.h | 1 + 1 file changed, 1 insertion(+) diff --git a/dbms/src/Processors/Formats/Impl/ProtobufRowOutputFormat.h b/dbms/src/Processors/Formats/Impl/ProtobufRowOutputFormat.h index bdc6f5e2492..b6ca906ab83 100644 --- a/dbms/src/Processors/Formats/Impl/ProtobufRowOutputFormat.h +++ b/dbms/src/Processors/Formats/Impl/ProtobufRowOutputFormat.h @@ -40,6 +40,7 @@ public: String getName() const override { return "ProtobufRowOutputFormat"; } void write(const Columns & columns, size_t row_num) override; + void writeField(const IColumn &, const IDataType &, size_t) override {} std::string getContentType() const override { return "application/octet-stream"; } private: From afb3c20778eaab63e6a8240061ca187fa588f3ac Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 19:37:33 +0300 Subject: [PATCH 0639/1165] Remove CSVRowOutputStream. --- dbms/src/Formats/CSVRowOutputStream.cpp | 134 ------------------------ dbms/src/Formats/CSVRowOutputStream.h | 56 ---------- dbms/src/Formats/FormatFactory.cpp | 2 - 3 files changed, 192 deletions(-) delete mode 100644 dbms/src/Formats/CSVRowOutputStream.cpp delete mode 100644 dbms/src/Formats/CSVRowOutputStream.h diff --git a/dbms/src/Formats/CSVRowOutputStream.cpp b/dbms/src/Formats/CSVRowOutputStream.cpp deleted file mode 100644 index 94ed300eaf8..00000000000 --- a/dbms/src/Formats/CSVRowOutputStream.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include -#include -#include - -#include - - -namespace DB -{ - - -CSVRowOutputStream::CSVRowOutputStream(WriteBuffer & ostr_, const Block & sample_, bool with_names_, const FormatSettings & format_settings) - : ostr(ostr_), sample(sample_), with_names(with_names_), format_settings(format_settings) -{ - size_t columns = sample.columns(); - data_types.resize(columns); - for (size_t i = 0; i < columns; ++i) - data_types[i] = sample.safeGetByPosition(i).type; -} - - -void CSVRowOutputStream::flush() -{ - ostr.next(); -} - - -void CSVRowOutputStream::writePrefix() -{ - size_t columns = sample.columns(); - - if (with_names) - { - for (size_t i = 0; i < columns; ++i) - { - writeCSVString(sample.safeGetByPosition(i).name, ostr); - writeChar(i == columns - 1 ? '\n' : format_settings.csv.delimiter, ostr); - } - } -} - - -void CSVRowOutputStream::writeField(const IColumn & column, const IDataType & type, size_t row_num) -{ - type.serializeAsTextCSV(column, row_num, ostr, format_settings); -} - - -void CSVRowOutputStream::writeFieldDelimiter() -{ - writeChar(format_settings.csv.delimiter, ostr); -} - - -void CSVRowOutputStream::writeRowEndDelimiter() -{ - writeChar('\n', ostr); -} - - -void CSVRowOutputStream::writeSuffix() -{ - writeTotals(); - writeExtremes(); -} - - -void CSVRowOutputStream::writeTotals() -{ - if (totals) - { - size_t columns = totals.columns(); - - writeChar('\n', ostr); - writeRowStartDelimiter(); - - for (size_t j = 0; j < columns; ++j) - { - if (j != 0) - writeFieldDelimiter(); - writeField(*totals.getByPosition(j).column.get(), *totals.getByPosition(j).type.get(), 0); - } - - writeRowEndDelimiter(); - } -} - - -void CSVRowOutputStream::writeExtremes() -{ - if (extremes) - { - size_t rows = extremes.rows(); - size_t columns = extremes.columns(); - - writeChar('\n', ostr); - - for (size_t i = 0; i < rows; ++i) - { - if (i != 0) - writeRowBetweenDelimiter(); - - writeRowStartDelimiter(); - - for (size_t j = 0; j < columns; ++j) - { - if (j != 0) - writeFieldDelimiter(); - writeField(*extremes.getByPosition(j).column.get(), *extremes.getByPosition(j).type.get(), i); - } - - writeRowEndDelimiter(); - } - } -} - - -void registerOutputFormatCSV(FormatFactory & factory) -{ - for (bool with_names : {false, true}) - { - factory.registerOutputFormat(with_names ? "CSVWithNames" : "CSV", [=]( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & format_settings) - { - return std::make_shared( - std::make_shared(buf, sample, with_names, format_settings), sample); - }); - } -} - -} diff --git a/dbms/src/Formats/CSVRowOutputStream.h b/dbms/src/Formats/CSVRowOutputStream.h deleted file mode 100644 index ab4bb3a503b..00000000000 --- a/dbms/src/Formats/CSVRowOutputStream.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include -#include -#include - - -namespace DB -{ - -class WriteBuffer; - - -/** The stream for outputting data in csv format. - * Does not conform with https://tools.ietf.org/html/rfc4180 because it uses LF, not CR LF. - */ -class CSVRowOutputStream : public IRowOutputStream -{ -public: - /** with_names - output in the first line a header with column names - * with_types - output in the next line header with the names of the types - */ - CSVRowOutputStream(WriteBuffer & ostr_, const Block & sample_, bool with_names_, const FormatSettings & format_settings); - - void writeField(const IColumn & column, const IDataType & type, size_t row_num) override; - void writeFieldDelimiter() override; - void writeRowEndDelimiter() override; - void writePrefix() override; - void writeSuffix() override; - - void flush() override; - - void setTotals(const Block & totals_) override { totals = totals_; } - void setExtremes(const Block & extremes_) override { extremes = extremes_; } - - /// https://www.iana.org/assignments/media-types/text/csv - String getContentType() const override - { - return String("text/csv; charset=UTF-8; header=") + (with_names ? "present" : "absent"); - } - -protected: - void writeTotals(); - void writeExtremes(); - - WriteBuffer & ostr; - const Block sample; - bool with_names; - const FormatSettings format_settings; - DataTypes data_types; - Block totals; - Block extremes; -}; - -} - diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 5ef86844b67..ff9607249c4 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -204,7 +204,6 @@ void registerOutputFormatTabSeparated(FormatFactory & factory); void registerInputFormatValues(FormatFactory & factory); void registerOutputFormatValues(FormatFactory & factory); void registerInputFormatCSV(FormatFactory & factory); -void registerOutputFormatCSV(FormatFactory & factory); void registerInputFormatTSKV(FormatFactory & factory); void registerOutputFormatTSKV(FormatFactory & factory); @@ -257,7 +256,6 @@ FormatFactory::FormatFactory() registerInputFormatValues(*this); registerOutputFormatValues(*this); registerInputFormatCSV(*this); - registerOutputFormatCSV(*this); registerInputFormatTSKV(*this); registerOutputFormatTSKV(*this); From a6e85a331a58a58a11176c00fbe5ee3726c2840b Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Fri, 2 Aug 2019 19:37:43 +0300 Subject: [PATCH 0640/1165] more optimal ranges selection at reading in order --- dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index d1179787d9a..db73b54f288 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -885,7 +885,7 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsWithO range.begin += marks_in_range; marks_in_range *= 2; - if (marks_in_range > max_block_size) + if (marks_in_range * rows_granularity > max_block_size) break; } else From f809de0949edd9eaf94c371e519ad3851cd08a61 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 19:48:50 +0300 Subject: [PATCH 0641/1165] Remove TabSeparatedRowOutputStream and TSKVRowOutputStream. --- dbms/src/Formats/FormatFactory.cpp | 4 - dbms/src/Formats/TSKVRowOutputStream.cpp | 56 ------ dbms/src/Formats/TSKVRowOutputStream.h | 27 --- .../Formats/TabSeparatedRowOutputStream.cpp | 179 ------------------ .../src/Formats/TabSeparatedRowOutputStream.h | 51 ----- .../Formats/tests/block_row_transforms.cpp | 7 +- .../Formats/tests/tab_separated_streams.cpp | 10 +- 7 files changed, 10 insertions(+), 324 deletions(-) delete mode 100644 dbms/src/Formats/TSKVRowOutputStream.cpp delete mode 100644 dbms/src/Formats/TSKVRowOutputStream.h delete mode 100644 dbms/src/Formats/TabSeparatedRowOutputStream.cpp delete mode 100644 dbms/src/Formats/TabSeparatedRowOutputStream.h diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index ff9607249c4..c0ca5ffacd0 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -200,12 +200,10 @@ void FormatFactory::registerOutputFormatProcessor(const String & name, OutputPro void registerInputFormatNative(FormatFactory & factory); void registerOutputFormatNative(FormatFactory & factory); void registerInputFormatTabSeparated(FormatFactory & factory); -void registerOutputFormatTabSeparated(FormatFactory & factory); void registerInputFormatValues(FormatFactory & factory); void registerOutputFormatValues(FormatFactory & factory); void registerInputFormatCSV(FormatFactory & factory); void registerInputFormatTSKV(FormatFactory & factory); -void registerOutputFormatTSKV(FormatFactory & factory); void registerInputFormatProcessorNative(FormatFactory & factory); void registerOutputFormatProcessorNative(FormatFactory & factory); @@ -252,12 +250,10 @@ FormatFactory::FormatFactory() registerInputFormatNative(*this); registerOutputFormatNative(*this); registerInputFormatTabSeparated(*this); - registerOutputFormatTabSeparated(*this); registerInputFormatValues(*this); registerOutputFormatValues(*this); registerInputFormatCSV(*this); registerInputFormatTSKV(*this); - registerOutputFormatTSKV(*this); registerInputFormatProcessorNative(*this); registerOutputFormatProcessorNative(*this); diff --git a/dbms/src/Formats/TSKVRowOutputStream.cpp b/dbms/src/Formats/TSKVRowOutputStream.cpp deleted file mode 100644 index edf952b45e3..00000000000 --- a/dbms/src/Formats/TSKVRowOutputStream.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include -#include -#include - - - -namespace DB -{ - -TSKVRowOutputStream::TSKVRowOutputStream(WriteBuffer & ostr_, const Block & sample_, const FormatSettings & format_settings_) - : TabSeparatedRowOutputStream(ostr_, sample_, false, false, format_settings_) -{ - NamesAndTypesList columns(sample_.getNamesAndTypesList()); - fields.assign(columns.begin(), columns.end()); - - for (auto & field : fields) - { - WriteBufferFromOwnString wb; - writeAnyEscapedString<'='>(field.name.data(), field.name.data() + field.name.size(), wb); - writeCString("=", wb); - field.name = wb.str(); - } -} - - -void TSKVRowOutputStream::writeField(const IColumn & column, const IDataType & type, size_t row_num) -{ - writeString(fields[field_number].name, ostr); - type.serializeAsTextEscaped(column, row_num, ostr, format_settings); - ++field_number; -} - - -void TSKVRowOutputStream::writeRowEndDelimiter() -{ - writeChar('\n', ostr); - field_number = 0; -} - - -void registerOutputFormatTSKV(FormatFactory & factory) -{ - factory.registerOutputFormat("TSKV", []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & settings) - { - return std::make_shared( - std::make_shared(buf, sample, settings), sample); - }); -} - -} diff --git a/dbms/src/Formats/TSKVRowOutputStream.h b/dbms/src/Formats/TSKVRowOutputStream.h deleted file mode 100644 index 3a2ee8b8291..00000000000 --- a/dbms/src/Formats/TSKVRowOutputStream.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include -#include - - -namespace DB -{ - -/** The stream for outputting data in the TSKV format. - * TSKV is similar to TabSeparated, but before every value, its name and equal sign are specified: name=value. - * This format is very inefficient. - */ -class TSKVRowOutputStream : public TabSeparatedRowOutputStream -{ -public: - TSKVRowOutputStream(WriteBuffer & ostr_, const Block & sample_, const FormatSettings & format_settings); - void writeField(const IColumn & column, const IDataType & type, size_t row_num) override; - void writeRowEndDelimiter() override; - -protected: - NamesAndTypes fields; - size_t field_number = 0; -}; - -} - diff --git a/dbms/src/Formats/TabSeparatedRowOutputStream.cpp b/dbms/src/Formats/TabSeparatedRowOutputStream.cpp deleted file mode 100644 index dca1207dd24..00000000000 --- a/dbms/src/Formats/TabSeparatedRowOutputStream.cpp +++ /dev/null @@ -1,179 +0,0 @@ -#include -#include -#include -#include - -#include - - -namespace DB -{ - -TabSeparatedRowOutputStream::TabSeparatedRowOutputStream( - WriteBuffer & ostr_, const Block & sample_, bool with_names_, bool with_types_, const FormatSettings & format_settings) - : ostr(ostr_), sample(sample_), with_names(with_names_), with_types(with_types_), format_settings(format_settings) -{ -} - - -void TabSeparatedRowOutputStream::flush() -{ - ostr.next(); -} - - -void TabSeparatedRowOutputStream::writePrefix() -{ - size_t columns = sample.columns(); - - if (with_names) - { - for (size_t i = 0; i < columns; ++i) - { - writeEscapedString(sample.safeGetByPosition(i).name, ostr); - writeChar(i == columns - 1 ? '\n' : '\t', ostr); - } - } - - if (with_types) - { - for (size_t i = 0; i < columns; ++i) - { - writeEscapedString(sample.safeGetByPosition(i).type->getName(), ostr); - writeChar(i == columns - 1 ? '\n' : '\t', ostr); - } - } -} - - -void TabSeparatedRowOutputStream::writeField(const IColumn & column, const IDataType & type, size_t row_num) -{ - type.serializeAsTextEscaped(column, row_num, ostr, format_settings); -} - - -void TabSeparatedRowOutputStream::writeFieldDelimiter() -{ - writeChar('\t', ostr); -} - - -void TabSeparatedRowOutputStream::writeRowEndDelimiter() -{ - writeChar('\n', ostr); -} - - -void TabSeparatedRowOutputStream::writeSuffix() -{ - writeTotals(); - writeExtremes(); -} - - -void TabSeparatedRowOutputStream::writeTotals() -{ - if (totals) - { - size_t columns = totals.columns(); - - writeChar('\n', ostr); - writeRowStartDelimiter(); - - for (size_t j = 0; j < columns; ++j) - { - if (j != 0) - writeFieldDelimiter(); - writeField(*totals.getByPosition(j).column.get(), *totals.getByPosition(j).type.get(), 0); - } - - writeRowEndDelimiter(); - } -} - - -void TabSeparatedRowOutputStream::writeExtremes() -{ - if (extremes) - { - size_t rows = extremes.rows(); - size_t columns = extremes.columns(); - - writeChar('\n', ostr); - - for (size_t i = 0; i < rows; ++i) - { - if (i != 0) - writeRowBetweenDelimiter(); - - writeRowStartDelimiter(); - - for (size_t j = 0; j < columns; ++j) - { - if (j != 0) - writeFieldDelimiter(); - writeField(*extremes.getByPosition(j).column.get(), *extremes.getByPosition(j).type.get(), i); - } - - writeRowEndDelimiter(); - } - } -} - - -void registerOutputFormatTabSeparated(FormatFactory & factory) -{ - for (auto name : {"TabSeparated", "TSV"}) - { - factory.registerOutputFormat(name, []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & settings) - { - return std::make_shared( - std::make_shared(buf, sample, false, false, settings), sample); - }); - } - - for (auto name : {"TabSeparatedRaw", "TSVRaw"}) - { - factory.registerOutputFormat(name, []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & settings) - { - return std::make_shared( - std::make_shared(buf, sample, false, false, settings), sample); - }); - } - - for (auto name : {"TabSeparatedWithNames", "TSVWithNames"}) - { - factory.registerOutputFormat(name, []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & settings) - { - return std::make_shared( - std::make_shared(buf, sample, true, false, settings), sample); - }); - } - - for (auto name : {"TabSeparatedWithNamesAndTypes", "TSVWithNamesAndTypes"}) - { - factory.registerOutputFormat(name, []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & settings) - { - return std::make_shared( - std::make_shared(buf, sample, true, true, settings), sample); - }); - } -} - -} diff --git a/dbms/src/Formats/TabSeparatedRowOutputStream.h b/dbms/src/Formats/TabSeparatedRowOutputStream.h deleted file mode 100644 index 31d03a4a7e7..00000000000 --- a/dbms/src/Formats/TabSeparatedRowOutputStream.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include -#include -#include - - -namespace DB -{ - -class WriteBuffer; - -/** A stream for outputting data in tsv format. - */ -class TabSeparatedRowOutputStream : public IRowOutputStream -{ -public: - /** with_names - output in the first line a header with column names - * with_types - output the next line header with the names of the types - */ - TabSeparatedRowOutputStream(WriteBuffer & ostr_, const Block & sample_, bool with_names_, bool with_types_, const FormatSettings & format_settings); - - void writeField(const IColumn & column, const IDataType & type, size_t row_num) override; - void writeFieldDelimiter() override; - void writeRowEndDelimiter() override; - void writePrefix() override; - void writeSuffix() override; - - void flush() override; - - void setTotals(const Block & totals_) override { totals = totals_; } - void setExtremes(const Block & extremes_) override { extremes = extremes_; } - - /// https://www.iana.org/assignments/media-types/text/tab-separated-values - String getContentType() const override { return "text/tab-separated-values; charset=UTF-8"; } - -protected: - void writeTotals(); - void writeExtremes(); - - WriteBuffer & ostr; - const Block sample; - bool with_names; - bool with_types; - const FormatSettings format_settings; - Block totals; - Block extremes; -}; - -} - diff --git a/dbms/src/Formats/tests/block_row_transforms.cpp b/dbms/src/Formats/tests/block_row_transforms.cpp index 9d38a37f833..092b30405d2 100644 --- a/dbms/src/Formats/tests/block_row_transforms.cpp +++ b/dbms/src/Formats/tests/block_row_transforms.cpp @@ -18,6 +18,8 @@ #include #include +#include +#include int main(int, char **) @@ -46,10 +48,9 @@ try RowInputStreamPtr row_input = std::make_shared(in_buf, sample, false, false, format_settings); BlockInputStreamFromRowInputStream block_input(row_input, sample, DEFAULT_INSERT_BLOCK_SIZE, 0, []{}, format_settings); - RowOutputStreamPtr row_output = std::make_shared(out_buf, sample, false, false, format_settings); - BlockOutputStreamFromRowOutputStream block_output(row_output, sample); + BlockOutputStreamPtr block_output = std::make_shared(std::make_shared(out_buf, sample, false, false, format_settings), sample); - copyData(block_input, block_output); + copyData(block_input, *block_output); } catch (const DB::Exception & e) { diff --git a/dbms/src/Formats/tests/tab_separated_streams.cpp b/dbms/src/Formats/tests/tab_separated_streams.cpp index 11895699c3b..64fd5fac35d 100644 --- a/dbms/src/Formats/tests/tab_separated_streams.cpp +++ b/dbms/src/Formats/tests/tab_separated_streams.cpp @@ -15,6 +15,8 @@ #include #include +#include +#include using namespace DB; @@ -40,12 +42,12 @@ try FormatSettings format_settings; RowInputStreamPtr row_input = std::make_shared(in_buf, sample, false, false, format_settings); - RowOutputStreamPtr row_output = std::make_shared(out_buf, sample, false, false, format_settings); - BlockInputStreamFromRowInputStream block_input(row_input, sample, DEFAULT_INSERT_BLOCK_SIZE, 0, []{}, format_settings); - BlockOutputStreamFromRowOutputStream block_output(row_output, sample); - copyData(block_input, block_output); + BlockOutputStreamPtr block_output = std::make_shared( + std::make_shared(out_buf, sample, false, false, format_settings), sample); + + copyData(block_input, *block_output); return 0; } catch (...) From 6ab2e194105dfb64811865785cc149a6bdbdda75 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 19:51:33 +0300 Subject: [PATCH 0642/1165] Remove TSKVRowInputStream. --- dbms/src/Formats/FormatFactory.cpp | 2 - dbms/src/Formats/TSKVRowInputStream.cpp | 211 ------------------------ dbms/src/Formats/TSKVRowInputStream.h | 48 ------ 3 files changed, 261 deletions(-) delete mode 100644 dbms/src/Formats/TSKVRowInputStream.cpp delete mode 100644 dbms/src/Formats/TSKVRowInputStream.h diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index c0ca5ffacd0..65b0c283327 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -203,7 +203,6 @@ void registerInputFormatTabSeparated(FormatFactory & factory); void registerInputFormatValues(FormatFactory & factory); void registerOutputFormatValues(FormatFactory & factory); void registerInputFormatCSV(FormatFactory & factory); -void registerInputFormatTSKV(FormatFactory & factory); void registerInputFormatProcessorNative(FormatFactory & factory); void registerOutputFormatProcessorNative(FormatFactory & factory); @@ -253,7 +252,6 @@ FormatFactory::FormatFactory() registerInputFormatValues(*this); registerOutputFormatValues(*this); registerInputFormatCSV(*this); - registerInputFormatTSKV(*this); registerInputFormatProcessorNative(*this); registerOutputFormatProcessorNative(*this); diff --git a/dbms/src/Formats/TSKVRowInputStream.cpp b/dbms/src/Formats/TSKVRowInputStream.cpp deleted file mode 100644 index d86ee22bc4b..00000000000 --- a/dbms/src/Formats/TSKVRowInputStream.cpp +++ /dev/null @@ -1,211 +0,0 @@ -#include -#include -#include -#include - - -namespace DB -{ - -namespace ErrorCodes -{ - extern const int INCORRECT_DATA; - extern const int CANNOT_PARSE_ESCAPE_SEQUENCE; - extern const int CANNOT_READ_ALL_DATA; - extern const int CANNOT_PARSE_INPUT_ASSERTION_FAILED; -} - - -TSKVRowInputStream::TSKVRowInputStream(ReadBuffer & istr_, const Block & header_, const FormatSettings & format_settings) - : istr(istr_), header(header_), format_settings(format_settings), name_map(header.columns()) -{ - /// In this format, we assume that column name cannot contain BOM, - /// so BOM at beginning of stream cannot be confused with name of field, and it is safe to skip it. - skipBOMIfExists(istr); - - size_t num_columns = header.columns(); - for (size_t i = 0; i < num_columns; ++i) - name_map[header.safeGetByPosition(i).name] = i; /// NOTE You could place names more cache-locally. -} - - -/** Read the field name in the `tskv` format. - * Return true if the field is followed by an equal sign, - * otherwise (field with no value) return false. - * The reference to the field name will be written to `ref`. - * A temporary `tmp` buffer can also be used to copy the field name to it. - * When reading, skips the name and the equal sign after it. - */ -static bool readName(ReadBuffer & buf, StringRef & ref, String & tmp) -{ - tmp.clear(); - - while (!buf.eof()) - { - const char * next_pos = find_first_symbols<'\t', '\n', '\\', '='>(buf.position(), buf.buffer().end()); - - if (next_pos == buf.buffer().end()) - { - tmp.append(buf.position(), next_pos - buf.position()); - buf.next(); - continue; - } - - /// Came to the end of the name. - if (*next_pos != '\\') - { - bool have_value = *next_pos == '='; - if (tmp.empty()) - { - /// No need to copy data, you can refer directly to the `buf`. - ref = StringRef(buf.position(), next_pos - buf.position()); - buf.position() += next_pos + have_value - buf.position(); - } - else - { - /// Copy the data to a temporary string and return a reference to it. - tmp.append(buf.position(), next_pos - buf.position()); - buf.position() += next_pos + have_value - buf.position(); - ref = StringRef(tmp); - } - return have_value; - } - /// The name has an escape sequence. - else - { - tmp.append(buf.position(), next_pos - buf.position()); - buf.position() += next_pos + 1 - buf.position(); - if (buf.eof()) - throw Exception("Cannot parse escape sequence", ErrorCodes::CANNOT_PARSE_ESCAPE_SEQUENCE); - - tmp.push_back(parseEscapeSequence(*buf.position())); - ++buf.position(); - continue; - } - } - - throw Exception("Unexpected end of stream while reading key name from TSKV format", ErrorCodes::CANNOT_READ_ALL_DATA); -} - - -bool TSKVRowInputStream::read(MutableColumns & columns, RowReadExtension & ext) -{ - if (istr.eof()) - return false; - - size_t num_columns = columns.size(); - - /// Set of columns for which the values were read. The rest will be filled with default values. - read_columns.assign(num_columns, false); - - if (unlikely(*istr.position() == '\n')) - { - /// An empty string. It is permissible, but it is unclear why. - ++istr.position(); - } - else - { - while (true) - { - StringRef name_ref; - bool has_value = readName(istr, name_ref, name_buf); - ssize_t index = -1; - - if (has_value) - { - /// NOTE Optimization is possible by caching the order of fields (which is almost always the same) - /// and quickly checking for the next expected field, instead of searching the hash table. - - auto it = name_map.find(name_ref); - if (name_map.end() == it) - { - if (!format_settings.skip_unknown_fields) - throw Exception("Unknown field found while parsing TSKV format: " + name_ref.toString(), ErrorCodes::INCORRECT_DATA); - - /// If the key is not found, skip the value. - NullSink sink; - readEscapedStringInto(sink, istr); - } - else - { - index = it->getSecond(); - - if (read_columns[index]) - throw Exception("Duplicate field found while parsing TSKV format: " + name_ref.toString(), ErrorCodes::INCORRECT_DATA); - - read_columns[index] = true; - - header.getByPosition(index).type->deserializeAsTextEscaped(*columns[index], istr, format_settings); - } - } - else - { - /// The only thing that can go without value is `tskv` fragment that is ignored. - if (!(name_ref.size == 4 && 0 == memcmp(name_ref.data, "tskv", 4))) - throw Exception("Found field without value while parsing TSKV format: " + name_ref.toString(), ErrorCodes::INCORRECT_DATA); - } - - if (istr.eof()) - { - throw Exception("Unexpected end of stream after field in TSKV format: " + name_ref.toString(), ErrorCodes::CANNOT_READ_ALL_DATA); - } - else if (*istr.position() == '\t') - { - ++istr.position(); - continue; - } - else if (*istr.position() == '\n') - { - ++istr.position(); - break; - } - else - { - /// Possibly a garbage was written into column, remove it - if (index >= 0) - { - columns[index]->popBack(1); - read_columns[index] = false; - } - - throw Exception("Found garbage after field in TSKV format: " + name_ref.toString(), ErrorCodes::CANNOT_PARSE_INPUT_ASSERTION_FAILED); - } - } - } - - /// Fill in the not met columns with default values. - for (size_t i = 0; i < num_columns; ++i) - if (!read_columns[i]) - header.getByPosition(i).type->insertDefaultInto(*columns[i]); - - /// return info about defaults set - ext.read_columns = read_columns; - - return true; -} - - -void TSKVRowInputStream::syncAfterError() -{ - skipToUnescapedNextLineOrEOF(istr); -} - - -void registerInputFormatTSKV(FormatFactory & factory) -{ - factory.registerInputFormat("TSKV", []( - ReadBuffer & buf, - const Block & sample, - const Context &, - UInt64 max_block_size, - UInt64 rows_portion_size, - FormatFactory::ReadCallback callback, - const FormatSettings & settings) - { - return std::make_shared( - std::make_shared(buf, sample, settings), - sample, max_block_size, rows_portion_size, callback, settings); - }); -} - -} diff --git a/dbms/src/Formats/TSKVRowInputStream.h b/dbms/src/Formats/TSKVRowInputStream.h deleted file mode 100644 index ada2ba3ed66..00000000000 --- a/dbms/src/Formats/TSKVRowInputStream.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include -#include -#include -#include - - -namespace DB -{ - -class ReadBuffer; - - -/** Stream for reading data in TSKV format. - * TSKV is a very inefficient data format. - * Similar to TSV, but each field is written as key=value. - * Fields can be listed in any order (including, in different lines there may be different order), - * and some fields may be missing. - * An equal sign can be escaped in the field name. - * Also, as an additional element there may be a useless tskv fragment - it needs to be ignored. - */ -class TSKVRowInputStream : public IRowInputStream -{ -public: - TSKVRowInputStream(ReadBuffer & istr_, const Block & header_, const FormatSettings & format_settings); - - bool read(MutableColumns & columns, RowReadExtension &) override; - bool allowSyncAfterError() const override { return true; } - void syncAfterError() override; - -private: - ReadBuffer & istr; - Block header; - - const FormatSettings format_settings; - - /// Buffer for the read from the stream the field name. Used when you have to copy it. - String name_buf; - - /// Hash table matching `field name -> position in the block`. NOTE You can use perfect hash map. - using NameMap = HashMap; - NameMap name_map; - - std::vector read_columns; -}; - -} From ab914010e15d1e06f5d87310b6b5532f60910465 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 19:56:16 +0300 Subject: [PATCH 0643/1165] Remove TSKVRowInputStream. --- dbms/src/IO/tests/write_buffer_aio.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/dbms/src/IO/tests/write_buffer_aio.cpp b/dbms/src/IO/tests/write_buffer_aio.cpp index 5794e277848..9274e5abee5 100644 --- a/dbms/src/IO/tests/write_buffer_aio.cpp +++ b/dbms/src/IO/tests/write_buffer_aio.cpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace { From 422b593570a02644c76e636469515e0ceb7fcf49 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 19:56:52 +0300 Subject: [PATCH 0644/1165] Remove TSKVRowInputStream. --- dbms/src/Formats/tests/tab_separated_streams.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/dbms/src/Formats/tests/tab_separated_streams.cpp b/dbms/src/Formats/tests/tab_separated_streams.cpp index 64fd5fac35d..e3bc551f6da 100644 --- a/dbms/src/Formats/tests/tab_separated_streams.cpp +++ b/dbms/src/Formats/tests/tab_separated_streams.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include From c336c514fbc9a76eece3dddd48a30d75f476ff8d Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 19:58:52 +0300 Subject: [PATCH 0645/1165] Remove TSKVRowInputStream. --- dbms/programs/odbc-bridge/MainHandler.cpp | 1 - dbms/src/Formats/tests/block_row_transforms.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/dbms/programs/odbc-bridge/MainHandler.cpp b/dbms/programs/odbc-bridge/MainHandler.cpp index cb5dfa70c9c..162e93dc3db 100644 --- a/dbms/programs/odbc-bridge/MainHandler.cpp +++ b/dbms/programs/odbc-bridge/MainHandler.cpp @@ -5,7 +5,6 @@ #include #include #include "ODBCBlockInputStream.h" -#include #include #include #include diff --git a/dbms/src/Formats/tests/block_row_transforms.cpp b/dbms/src/Formats/tests/block_row_transforms.cpp index 092b30405d2..c580f9af392 100644 --- a/dbms/src/Formats/tests/block_row_transforms.cpp +++ b/dbms/src/Formats/tests/block_row_transforms.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include From f820fff7942747675536e7e63b4d52a984118456 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 19:59:50 +0300 Subject: [PATCH 0646/1165] Remove TSKVRowInputStream. --- dbms/src/Formats/tests/tab_separated_streams.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Formats/tests/tab_separated_streams.cpp b/dbms/src/Formats/tests/tab_separated_streams.cpp index e3bc551f6da..bb5e657229d 100644 --- a/dbms/src/Formats/tests/tab_separated_streams.cpp +++ b/dbms/src/Formats/tests/tab_separated_streams.cpp @@ -44,7 +44,7 @@ try BlockInputStreamFromRowInputStream block_input(row_input, sample, DEFAULT_INSERT_BLOCK_SIZE, 0, []{}, format_settings); BlockOutputStreamPtr block_output = std::make_shared( - std::make_shared(out_buf, sample, false, false, format_settings), sample); + std::make_shared(out_buf, sample, false, false, format_settings)); copyData(block_input, *block_output); return 0; From e6b3f3f03acb6ff430be82ffe8ac77c520fc3b5f Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 20:00:38 +0300 Subject: [PATCH 0647/1165] Remove TSKVRowInputStream. --- dbms/src/Formats/tests/block_row_transforms.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Formats/tests/block_row_transforms.cpp b/dbms/src/Formats/tests/block_row_transforms.cpp index c580f9af392..b2fe876fb2a 100644 --- a/dbms/src/Formats/tests/block_row_transforms.cpp +++ b/dbms/src/Formats/tests/block_row_transforms.cpp @@ -47,7 +47,7 @@ try RowInputStreamPtr row_input = std::make_shared(in_buf, sample, false, false, format_settings); BlockInputStreamFromRowInputStream block_input(row_input, sample, DEFAULT_INSERT_BLOCK_SIZE, 0, []{}, format_settings); - BlockOutputStreamPtr block_output = std::make_shared(std::make_shared(out_buf, sample, false, false, format_settings), sample); + BlockOutputStreamPtr block_output = std::make_shared(std::make_shared(out_buf, sample, false, false, format_settings)); copyData(block_input, *block_output); } From 67d91c4b88ba6817899c951c9d1a21840a03236b Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 2 Aug 2019 20:14:04 +0300 Subject: [PATCH 0648/1165] Fixed the possibility of hanging queries when server is overloaded --- dbms/src/Common/ThreadPool.cpp | 34 +++++++- dbms/src/Common/ThreadPool.h | 10 ++- .../tests/gtest_thread_pool_global_full.cpp | 81 +++++++++++++++++++ 3 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 dbms/src/Common/tests/gtest_thread_pool_global_full.cpp diff --git a/dbms/src/Common/ThreadPool.cpp b/dbms/src/Common/ThreadPool.cpp index cb08fa944a9..ce004ed7674 100644 --- a/dbms/src/Common/ThreadPool.cpp +++ b/dbms/src/Common/ThreadPool.cpp @@ -1,7 +1,6 @@ #include #include -#include #include @@ -34,6 +33,28 @@ ThreadPoolImpl::ThreadPoolImpl(size_t max_threads, size_t max_free_threa { } +template +void ThreadPoolImpl::setMaxThreads(size_t value) +{ + std::lock_guard lock(mutex); + max_threads = value; +} + +template +void ThreadPoolImpl::setMaxFreeThreads(size_t value) +{ + std::lock_guard lock(mutex); + max_free_threads = value; +} + +template +void ThreadPoolImpl::setQueueSize(size_t value) +{ + std::lock_guard lock(mutex); + queue_size = value; +} + + template template ReturnType ThreadPoolImpl::scheduleImpl(Job job, int priority, std::optional wait_microseconds) @@ -59,7 +80,7 @@ ReturnType ThreadPoolImpl::scheduleImpl(Job job, int priority, std::opti auto pred = [this] { return !queue_size || scheduled_jobs < queue_size || shutdown; }; - if (wait_microseconds) + if (wait_microseconds) /// Check for optional. Condition is true if the optional is set and the value is zero. { if (!job_finished.wait_for(lock, std::chrono::microseconds(*wait_microseconds), pred)) return on_error(); @@ -83,6 +104,15 @@ ReturnType ThreadPoolImpl::scheduleImpl(Job job, int priority, std::opti catch (...) { threads.pop_front(); + + /// Remove the job and return error to caller. + /// Note that if we have allocated at least one thread, we may continue + /// (one thread is enough to process all jobs). + /// But this condition indicate an error nevertheless and better to refuse. + + jobs.pop(); + --scheduled_jobs; + return on_error(); } } } diff --git a/dbms/src/Common/ThreadPool.h b/dbms/src/Common/ThreadPool.h index a0dae3f810c..23c0848e931 100644 --- a/dbms/src/Common/ThreadPool.h +++ b/dbms/src/Common/ThreadPool.h @@ -60,14 +60,18 @@ public: /// Returns number of running and scheduled jobs. size_t active() const; + void setMaxThreads(size_t value); + void setMaxFreeThreads(size_t value); + void setQueueSize(size_t value); + private: mutable std::mutex mutex; std::condition_variable job_finished; std::condition_variable new_job_or_shutdown; - const size_t max_threads; - const size_t max_free_threads; - const size_t queue_size; + size_t max_threads; + size_t max_free_threads; + size_t queue_size; size_t scheduled_jobs = 0; bool shutdown = false; diff --git a/dbms/src/Common/tests/gtest_thread_pool_global_full.cpp b/dbms/src/Common/tests/gtest_thread_pool_global_full.cpp new file mode 100644 index 00000000000..48858fa40ef --- /dev/null +++ b/dbms/src/Common/tests/gtest_thread_pool_global_full.cpp @@ -0,0 +1,81 @@ +#include + +#include + +#include + + +/// Test what happens if local ThreadPool cannot create a ThreadFromGlobalPool. +/// There was a bug: if local ThreadPool cannot allocate even a single thread, +/// the job will be scheduled but never get executed. + + +TEST(ThreadPool, GlobalFull1) +{ + GlobalThreadPool & global_pool = GlobalThreadPool::instance(); + + static constexpr size_t capacity = 5; + + global_pool.setMaxThreads(capacity); + global_pool.setMaxFreeThreads(1); + global_pool.setQueueSize(capacity); + global_pool.wait(); + + std::atomic counter = 0; + static constexpr size_t num_jobs = capacity + 1; + + auto func = [&] { ++counter; while (counter != num_jobs) {} }; + + ThreadPool pool(num_jobs); + + for (size_t i = 0; i < capacity; ++i) + pool.schedule(func); + + for (size_t i = capacity; i < num_jobs; ++i) + { + EXPECT_THROW(pool.schedule(func), DB::Exception); + ++counter; + } + + pool.wait(); + EXPECT_EQ(counter, num_jobs); +} + + +TEST(ThreadPool, GlobalFull2) +{ + GlobalThreadPool & global_pool = GlobalThreadPool::instance(); + + static constexpr size_t capacity = 5; + + global_pool.setMaxThreads(capacity); + global_pool.setMaxFreeThreads(1); + global_pool.setQueueSize(capacity); + + /// ThreadFromGlobalPool from local thread pools from previous test case have exited + /// but their threads from global_pool may not have finished (they still have to exit). + /// If we will not wait here, we can get "Cannot schedule a task exception" earlier than we expect in this test. + global_pool.wait(); + + std::atomic counter = 0; + auto func = [&] { ++counter; while (counter != capacity + 1) {} }; + + ThreadPool pool(capacity, 0, capacity); + for (size_t i = 0; i < capacity; ++i) + pool.schedule(func); + + ThreadPool another_pool(1); + EXPECT_THROW(another_pool.schedule(func), DB::Exception); + + ++counter; + + pool.wait(); + + global_pool.wait(); + + for (size_t i = 0; i < capacity; ++i) + another_pool.schedule([&] { ++counter; }); + + another_pool.wait(); + EXPECT_EQ(counter, capacity * 2 + 1); +} From 1f6a16b03a92cdf5d531e805a4d62bcb16565b17 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 20:16:58 +0300 Subject: [PATCH 0649/1165] Remove ValuesRowInputStream. --- dbms/src/Formats/FormatFactory.cpp | 2 - .../Formats/TabSeparatedRawRowOutputStream.h | 25 --- dbms/src/Formats/ValuesRowInputStream.cpp | 168 ------------------ dbms/src/Formats/ValuesRowInputStream.h | 35 ---- .../Formats/Impl/ValuesRowInputFormat.cpp | 2 +- dbms/src/Storages/MergeTree/MergeTreeData.cpp | 11 +- 6 files changed, 6 insertions(+), 237 deletions(-) delete mode 100644 dbms/src/Formats/TabSeparatedRawRowOutputStream.h delete mode 100644 dbms/src/Formats/ValuesRowInputStream.cpp delete mode 100644 dbms/src/Formats/ValuesRowInputStream.h diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 65b0c283327..c38767a3055 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -200,7 +200,6 @@ void FormatFactory::registerOutputFormatProcessor(const String & name, OutputPro void registerInputFormatNative(FormatFactory & factory); void registerOutputFormatNative(FormatFactory & factory); void registerInputFormatTabSeparated(FormatFactory & factory); -void registerInputFormatValues(FormatFactory & factory); void registerOutputFormatValues(FormatFactory & factory); void registerInputFormatCSV(FormatFactory & factory); @@ -249,7 +248,6 @@ FormatFactory::FormatFactory() registerInputFormatNative(*this); registerOutputFormatNative(*this); registerInputFormatTabSeparated(*this); - registerInputFormatValues(*this); registerOutputFormatValues(*this); registerInputFormatCSV(*this); diff --git a/dbms/src/Formats/TabSeparatedRawRowOutputStream.h b/dbms/src/Formats/TabSeparatedRawRowOutputStream.h deleted file mode 100644 index 86eaa2bbb58..00000000000 --- a/dbms/src/Formats/TabSeparatedRawRowOutputStream.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include - -namespace DB -{ -struct FormatSettings; - -/** A stream for outputting data in tsv format, but without escaping individual values. - * (That is, the output is irreversible.) - */ -class TabSeparatedRawRowOutputStream : public TabSeparatedRowOutputStream -{ -public: - TabSeparatedRawRowOutputStream(WriteBuffer & ostr_, const Block & sample_, bool with_names_, bool with_types_, const FormatSettings & format_settings_) - : TabSeparatedRowOutputStream(ostr_, sample_, with_names_, with_types_, format_settings_) {} - - void writeField(const IColumn & column, const IDataType & type, size_t row_num) override - { - type.serializeAsText(column, row_num, ostr, format_settings); - } -}; - -} - diff --git a/dbms/src/Formats/ValuesRowInputStream.cpp b/dbms/src/Formats/ValuesRowInputStream.cpp deleted file mode 100644 index 33799a95549..00000000000 --- a/dbms/src/Formats/ValuesRowInputStream.cpp +++ /dev/null @@ -1,168 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace DB -{ - -namespace ErrorCodes -{ - extern const int CANNOT_PARSE_INPUT_ASSERTION_FAILED; - extern const int CANNOT_PARSE_QUOTED_STRING; - extern const int CANNOT_PARSE_NUMBER; - extern const int CANNOT_PARSE_DATE; - extern const int CANNOT_PARSE_DATETIME; - extern const int CANNOT_READ_ARRAY_FROM_TEXT; - extern const int CANNOT_PARSE_DATE; - extern const int SYNTAX_ERROR; - extern const int VALUE_IS_OUT_OF_RANGE_OF_DATA_TYPE; -} - - -ValuesRowInputStream::ValuesRowInputStream(ReadBuffer & istr_, const Block & header_, const Context & context_, const FormatSettings & format_settings) - : istr(istr_), header(header_), context(std::make_unique(context_)), format_settings(format_settings) -{ - /// In this format, BOM at beginning of stream cannot be confused with value, so it is safe to skip it. - skipBOMIfExists(istr); -} - - -bool ValuesRowInputStream::read(MutableColumns & columns, RowReadExtension &) -{ - size_t num_columns = columns.size(); - - skipWhitespaceIfAny(istr); - - if (istr.eof() || *istr.position() == ';') - return false; - - /** Typically, this is the usual format for streaming parsing. - * But as an exception, it also supports processing arbitrary expressions instead of values. - * This is very inefficient. But if there are no expressions, then there is no overhead. - */ - ParserExpression parser; - - assertChar('(', istr); - - for (size_t i = 0; i < num_columns; ++i) - { - skipWhitespaceIfAny(istr); - - char * prev_istr_position = istr.position(); - size_t prev_istr_bytes = istr.count() - istr.offset(); - - bool rollback_on_exception = false; - try - { - header.getByPosition(i).type->deserializeAsTextQuoted(*columns[i], istr, format_settings); - rollback_on_exception = true; - skipWhitespaceIfAny(istr); - - if (i != num_columns - 1) - assertChar(',', istr); - else - assertChar(')', istr); - } - catch (const Exception & e) - { - if (!format_settings.values.interpret_expressions) - throw; - - /** The normal streaming parser could not parse the value. - * Let's try to parse it with a SQL parser as a constant expression. - * This is an exceptional case. - */ - if (e.code() == ErrorCodes::CANNOT_PARSE_INPUT_ASSERTION_FAILED - || e.code() == ErrorCodes::CANNOT_PARSE_QUOTED_STRING - || e.code() == ErrorCodes::CANNOT_PARSE_NUMBER - || e.code() == ErrorCodes::CANNOT_PARSE_DATE - || e.code() == ErrorCodes::CANNOT_PARSE_DATETIME - || e.code() == ErrorCodes::CANNOT_READ_ARRAY_FROM_TEXT) - { - /// TODO Case when the expression does not fit entirely in the buffer. - - /// If the beginning of the value is no longer in the buffer. - if (istr.count() - istr.offset() != prev_istr_bytes) - throw; - - if (rollback_on_exception) - columns[i]->popBack(1); - - const IDataType & type = *header.getByPosition(i).type; - - Expected expected; - - Tokens tokens(prev_istr_position, istr.buffer().end()); - TokenIterator token_iterator(tokens); - - ASTPtr ast; - if (!parser.parse(token_iterator, ast, expected)) - throw Exception("Cannot parse expression of type " + type.getName() + " here: " - + String(prev_istr_position, std::min(SHOW_CHARS_ON_SYNTAX_ERROR, istr.buffer().end() - prev_istr_position)), - ErrorCodes::SYNTAX_ERROR); - - istr.position() = const_cast(token_iterator->begin); - - std::pair value_raw = evaluateConstantExpression(ast, *context); - Field value = convertFieldToType(value_raw.first, type, value_raw.second.get()); - - /// Check that we are indeed allowed to insert a NULL. - if (value.isNull()) - { - if (!type.isNullable()) - throw Exception{"Expression returns value " + applyVisitor(FieldVisitorToString(), value) - + ", that is out of range of type " + type.getName() - + ", at: " + String(prev_istr_position, std::min(SHOW_CHARS_ON_SYNTAX_ERROR, istr.buffer().end() - prev_istr_position)), - ErrorCodes::VALUE_IS_OUT_OF_RANGE_OF_DATA_TYPE}; - } - - columns[i]->insert(value); - - skipWhitespaceIfAny(istr); - - if (i != num_columns - 1) - assertChar(',', istr); - else - assertChar(')', istr); - } - else - throw; - } - } - - skipWhitespaceIfAny(istr); - if (!istr.eof() && *istr.position() == ',') - ++istr.position(); - - return true; -} - - -void registerInputFormatValues(FormatFactory & factory) -{ - factory.registerInputFormat("Values", []( - ReadBuffer & buf, - const Block & sample, - const Context & context, - UInt64 max_block_size, - UInt64 rows_portion_size, - FormatFactory::ReadCallback callback, - const FormatSettings & settings) - { - return std::make_shared( - std::make_shared(buf, sample, context, settings), - sample, max_block_size, rows_portion_size, callback, settings); - }); -} - -} diff --git a/dbms/src/Formats/ValuesRowInputStream.h b/dbms/src/Formats/ValuesRowInputStream.h deleted file mode 100644 index 372619d4e27..00000000000 --- a/dbms/src/Formats/ValuesRowInputStream.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include -#include -#include - - -namespace DB -{ - -class Context; -class ReadBuffer; - - -/** Stream to read data in VALUES format (as in INSERT query). - */ -class ValuesRowInputStream : public IRowInputStream -{ -public: - /** Data is parsed using fast, streaming parser. - * If interpret_expressions is true, it will, in addition, try to use SQL parser and interpreter - * in case when streaming parser could not parse field (this is very slow). - */ - ValuesRowInputStream(ReadBuffer & istr_, const Block & header_, const Context & context_, const FormatSettings & format_settings); - - bool read(MutableColumns & columns, RowReadExtension &) override; - -private: - ReadBuffer & istr; - Block header; - std::unique_ptr context; /// pimpl - const FormatSettings format_settings; -}; - -} diff --git a/dbms/src/Processors/Formats/Impl/ValuesRowInputFormat.cpp b/dbms/src/Processors/Formats/Impl/ValuesRowInputFormat.cpp index 7b0287596ad..337085198a3 100644 --- a/dbms/src/Processors/Formats/Impl/ValuesRowInputFormat.cpp +++ b/dbms/src/Processors/Formats/Impl/ValuesRowInputFormat.cpp @@ -159,7 +159,7 @@ void registerInputFormatProcessorValues(FormatFactory & factory) IRowInputFormat::Params params, const FormatSettings & settings) { - return std::make_shared(buf, sample, params, context, settings); + return std::make_shared(buf, sample, std::move(params), context, settings); }); } diff --git a/dbms/src/Storages/MergeTree/MergeTreeData.cpp b/dbms/src/Storages/MergeTree/MergeTreeData.cpp index b32470f9f77..dfc59654629 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeData.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeData.cpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -2488,17 +2488,16 @@ String MergeTreeData::getPartitionIDFromQuery(const ASTPtr & ast, const Context ReadBufferFromMemory right_paren_buf(")", 1); ConcatReadBuffer buf({&left_paren_buf, &fields_buf, &right_paren_buf}); - ValuesRowInputStream input_stream(buf, partition_key_sample, context, format_settings); - MutableColumns columns = partition_key_sample.cloneEmptyColumns(); + auto input_stream = FormatFactory::instance().getInput("Values", buf, partition_key_sample, context, context.getSettingsRef().max_block_size); - RowReadExtension unused; - if (!input_stream.read(columns, unused)) + auto block = input_stream->read(); + if (!block || !block.rows()) throw Exception( "Could not parse partition value: `" + partition_ast.fields_str.toString() + "`", ErrorCodes::INVALID_PARTITION_VALUE); for (size_t i = 0; i < fields_count; ++i) - columns[i]->get(0, partition_row[i]); + block.getByPosition(i).column->get(0, partition_row[i]); } MergeTreePartition partition(std::move(partition_row)); From 6234cb865a828b267ddb0141a1bd093e1c8fc042 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 20:19:10 +0300 Subject: [PATCH 0650/1165] Remove ValuesRowOutputStream. --- dbms/src/Formats/FormatFactory.cpp | 2 - dbms/src/Formats/ValuesRowOutputStream.cpp | 63 ---------------------- dbms/src/Formats/ValuesRowOutputStream.h | 33 ------------ 3 files changed, 98 deletions(-) delete mode 100644 dbms/src/Formats/ValuesRowOutputStream.cpp delete mode 100644 dbms/src/Formats/ValuesRowOutputStream.h diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index c38767a3055..4e71f6042fb 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -200,7 +200,6 @@ void FormatFactory::registerOutputFormatProcessor(const String & name, OutputPro void registerInputFormatNative(FormatFactory & factory); void registerOutputFormatNative(FormatFactory & factory); void registerInputFormatTabSeparated(FormatFactory & factory); -void registerOutputFormatValues(FormatFactory & factory); void registerInputFormatCSV(FormatFactory & factory); void registerInputFormatProcessorNative(FormatFactory & factory); @@ -248,7 +247,6 @@ FormatFactory::FormatFactory() registerInputFormatNative(*this); registerOutputFormatNative(*this); registerInputFormatTabSeparated(*this); - registerOutputFormatValues(*this); registerInputFormatCSV(*this); registerInputFormatProcessorNative(*this); diff --git a/dbms/src/Formats/ValuesRowOutputStream.cpp b/dbms/src/Formats/ValuesRowOutputStream.cpp deleted file mode 100644 index eacc7e31eba..00000000000 --- a/dbms/src/Formats/ValuesRowOutputStream.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include -#include - -#include -#include -#include - - -namespace DB -{ - - -ValuesRowOutputStream::ValuesRowOutputStream(WriteBuffer & ostr_, const FormatSettings & format_settings) - : ostr(ostr_), format_settings(format_settings) -{ -} - -void ValuesRowOutputStream::flush() -{ - ostr.next(); -} - -void ValuesRowOutputStream::writeField(const IColumn & column, const IDataType & type, size_t row_num) -{ - type.serializeAsTextQuoted(column, row_num, ostr, format_settings); -} - -void ValuesRowOutputStream::writeFieldDelimiter() -{ - writeChar(',', ostr); -} - -void ValuesRowOutputStream::writeRowStartDelimiter() -{ - writeChar('(', ostr); -} - -void ValuesRowOutputStream::writeRowEndDelimiter() -{ - writeChar(')', ostr); -} - -void ValuesRowOutputStream::writeRowBetweenDelimiter() -{ - writeCString(",", ostr); -} - - -void registerOutputFormatValues(FormatFactory & factory) -{ - factory.registerOutputFormat("Values", []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & settings) - { - return std::make_shared( - std::make_shared(buf, settings), sample); - }); -} - -} diff --git a/dbms/src/Formats/ValuesRowOutputStream.h b/dbms/src/Formats/ValuesRowOutputStream.h deleted file mode 100644 index 55cbad2acb1..00000000000 --- a/dbms/src/Formats/ValuesRowOutputStream.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include -#include - - -namespace DB -{ - -class WriteBuffer; - - -/** A stream for outputting data in the VALUES format (as in the INSERT request). - */ -class ValuesRowOutputStream : public IRowOutputStream -{ -public: - ValuesRowOutputStream(WriteBuffer & ostr_, const FormatSettings & format_settings); - - void writeField(const IColumn & column, const IDataType & type, size_t row_num) override; - void writeFieldDelimiter() override; - void writeRowStartDelimiter() override; - void writeRowEndDelimiter() override; - void writeRowBetweenDelimiter() override; - void flush() override; - -private: - WriteBuffer & ostr; - const FormatSettings format_settings; -}; - -} - From e06a53a5d90f454b4c1e6849095bfca5c20a29fd Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Fri, 2 Aug 2019 20:34:29 +0300 Subject: [PATCH 0651/1165] fix ranges selection at reading in order --- .../Interpreters/InterpreterSelectQuery.cpp | 3 +- .../MergeTree/MergeTreeDataSelectExecutor.cpp | 32 +++++++++----- .../00940_order_by_read_in_order.sql | 43 +++++++++---------- 3 files changed, 44 insertions(+), 34 deletions(-) diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.cpp b/dbms/src/Interpreters/InterpreterSelectQuery.cpp index a2beadc3ddf..0b9f24590fb 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSelectQuery.cpp @@ -1931,9 +1931,10 @@ void InterpreterSelectQuery::executeOrder(Pipeline & pipeline, SortingInfoPtr so stream = std::make_shared(stream); }); + UInt64 limit_for_merging = (need_finish_sorting ? 0 : limit); pipeline.firstStream() = std::make_shared( pipeline.streams, sorting_info->prefix_order_descr, - settings.max_block_size, limit); + settings.max_block_size, limit_for_merging); pipeline.streams.resize(1); } diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index db73b54f288..394f5ddc326 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -872,32 +872,42 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongStreamsWithO { MarkRanges new_ranges; const size_t max_marks_in_range = (max_block_size + rows_granularity - 1) / rows_granularity; + size_t marks_in_range = 1; - for (auto range : ranges) + if (direction == 1) { - size_t marks_in_range = 1; - while (range.begin + marks_in_range < range.end) + /// Split first few ranges to avoid reading much data. + bool splitted = false; + for (auto range : ranges) { - if (direction == 1) + while (!splitted && range.begin + marks_in_range < range.end) { - /// Split first few ranges to avoid reading much data. new_ranges.emplace_back(range.begin, range.begin + marks_in_range); range.begin += marks_in_range; marks_in_range *= 2; - if (marks_in_range * rows_granularity > max_block_size) - break; + if (marks_in_range > max_marks_in_range) + splitted = true; } - else + new_ranges.emplace_back(range.begin, range.end); + } + } + else + { + /// Split all ranges to avoid reading much data, because we have to + /// store whole range in memory to reverse it. + for (auto it = ranges.rbegin(); it != ranges.rend(); ++it) + { + auto range = *it; + while (range.begin + marks_in_range < range.end) { - /// Split all ranges to avoid reading much data, because we have to - /// store whole range in memory to reverse it. new_ranges.emplace_back(range.end - marks_in_range, range.end); range.end -= marks_in_range; marks_in_range = std::min(marks_in_range * 2, max_marks_in_range); } + new_ranges.emplace_back(range.begin, range.end); } - new_ranges.emplace_back(range.begin, range.end); + std::reverse(new_ranges.begin(), new_ranges.end()); } return new_ranges; diff --git a/dbms/tests/queries/0_stateless/00940_order_by_read_in_order.sql b/dbms/tests/queries/0_stateless/00940_order_by_read_in_order.sql index 55fca9700dd..34c0d16716e 100644 --- a/dbms/tests/queries/0_stateless/00940_order_by_read_in_order.sql +++ b/dbms/tests/queries/0_stateless/00940_order_by_read_in_order.sql @@ -1,33 +1,32 @@ -CREATE DATABASE IF NOT EXISTS test; -DROP TABLE IF EXISTS test.pk_order; +DROP TABLE IF EXISTS pk_order; SET optimize_read_in_order = 1; -CREATE TABLE test.pk_order(a UInt64, b UInt64, c UInt64, d UInt64) ENGINE=MergeTree() ORDER BY (a, b); -INSERT INTO test.pk_order(a, b, c, d) VALUES (1, 1, 101, 1), (1, 2, 102, 1), (1, 3, 103, 1), (1, 4, 104, 1); -INSERT INTO test.pk_order(a, b, c, d) VALUES (1, 5, 104, 1), (1, 6, 105, 1), (2, 1, 106, 2), (2, 1, 107, 2); +CREATE TABLE pk_order(a UInt64, b UInt64, c UInt64, d UInt64) ENGINE=MergeTree() ORDER BY (a, b); +INSERT INTO pk_order(a, b, c, d) VALUES (1, 1, 101, 1), (1, 2, 102, 1), (1, 3, 103, 1), (1, 4, 104, 1); +INSERT INTO pk_order(a, b, c, d) VALUES (1, 5, 104, 1), (1, 6, 105, 1), (2, 1, 106, 2), (2, 1, 107, 2); -INSERT INTO test.pk_order(a, b, c, d) VALUES (2, 2, 107, 2), (2, 3, 108, 2), (2, 4, 109, 2); +INSERT INTO pk_order(a, b, c, d) VALUES (2, 2, 107, 2), (2, 3, 108, 2), (2, 4, 109, 2); -SELECT b FROM test.pk_order ORDER BY a, b; -SELECT a FROM test.pk_order ORDER BY a, b; +SELECT b FROM pk_order ORDER BY a, b; +SELECT a FROM pk_order ORDER BY a, b; -SELECT a, b FROM test.pk_order ORDER BY a, b; -SELECT a, b FROM test.pk_order ORDER BY a DESC, b; -SELECT a, b FROM test.pk_order ORDER BY a, b DESC; -SELECT a, b FROM test.pk_order ORDER BY a DESC, b DESC; -SELECT a FROM test.pk_order ORDER BY a DESC; +SELECT a, b FROM pk_order ORDER BY a, b; +SELECT a, b FROM pk_order ORDER BY a DESC, b; +SELECT a, b FROM pk_order ORDER BY a, b DESC; +SELECT a, b FROM pk_order ORDER BY a DESC, b DESC; +SELECT a FROM pk_order ORDER BY a DESC; -SELECT a, b, c FROM test.pk_order ORDER BY a, b, c; -SELECT a, b, c FROM test.pk_order ORDER BY a DESC, b, c; -SELECT a, b, c FROM test.pk_order ORDER BY a, b DESC, c; -SELECT a, b, c FROM test.pk_order ORDER BY a, b, c DESC; -SELECT a, b, c FROM test.pk_order ORDER BY a DESC, b DESC, c; -SELECT a, b, c FROM test.pk_order ORDER BY a DESC, b, c DESC; -SELECT a, b, c FROM test.pk_order ORDER BY a, b DESC, c DESC; -SELECT a, b, c FROM test.pk_order ORDER BY a DESC, b DESC, c DESC; +SELECT a, b, c FROM pk_order ORDER BY a, b, c; +SELECT a, b, c FROM pk_order ORDER BY a DESC, b, c; +SELECT a, b, c FROM pk_order ORDER BY a, b DESC, c; +SELECT a, b, c FROM pk_order ORDER BY a, b, c DESC; +SELECT a, b, c FROM pk_order ORDER BY a DESC, b DESC, c; +SELECT a, b, c FROM pk_order ORDER BY a DESC, b, c DESC; +SELECT a, b, c FROM pk_order ORDER BY a, b DESC, c DESC; +SELECT a, b, c FROM pk_order ORDER BY a DESC, b DESC, c DESC; -DROP TABLE IF EXISTS test.pk_order; +DROP TABLE IF EXISTS pk_order; CREATE TABLE pk_order (d DateTime, a Int32, b Int32) ENGINE = MergeTree ORDER BY (d, a) PARTITION BY toDate(d) SETTINGS index_granularity=1; From 6e3274ef98b43b4ea9f3f4ccfd367cba018e58aa Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 20:37:24 +0300 Subject: [PATCH 0652/1165] Remove VerticalRowOutputStream. --- dbms/src/Formats/FormatFactory.cpp | 2 - dbms/src/Formats/VerticalRowOutputStream.cpp | 184 ------------------- dbms/src/Formats/VerticalRowOutputStream.h | 55 ------ 3 files changed, 241 deletions(-) delete mode 100644 dbms/src/Formats/VerticalRowOutputStream.cpp delete mode 100644 dbms/src/Formats/VerticalRowOutputStream.h diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index 4e71f6042fb..ea38b62e71e 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -223,7 +223,6 @@ void registerOutputFormatProcessorProtobuf(FormatFactory & factory); /// Output only (presentational) formats. -void registerOutputFormatVertical(FormatFactory & factory); void registerOutputFormatXML(FormatFactory & factory); void registerOutputFormatNull(FormatFactory & factory); @@ -270,7 +269,6 @@ FormatFactory::FormatFactory() registerOutputFormatProcessorParquet(*this); - registerOutputFormatVertical(*this); registerOutputFormatXML(*this); registerOutputFormatNull(*this); diff --git a/dbms/src/Formats/VerticalRowOutputStream.cpp b/dbms/src/Formats/VerticalRowOutputStream.cpp deleted file mode 100644 index 6a994cf9303..00000000000 --- a/dbms/src/Formats/VerticalRowOutputStream.cpp +++ /dev/null @@ -1,184 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include - - -namespace DB -{ - -VerticalRowOutputStream::VerticalRowOutputStream( - WriteBuffer & ostr_, const Block & sample_, const FormatSettings & format_settings) - : ostr(ostr_), sample(sample_), format_settings(format_settings) -{ - size_t columns = sample.columns(); - - using Widths = std::vector; - Widths name_widths(columns); - size_t max_name_width = 0; - - String serialized_value; - - for (size_t i = 0; i < columns; ++i) - { - /// Note that number of code points is just a rough approximation of visible string width. - const String & name = sample.getByPosition(i).name; - - name_widths[i] = UTF8::computeWidth(reinterpret_cast(name.data()), name.size()); - - if (name_widths[i] > max_name_width) - max_name_width = name_widths[i]; - } - - names_and_paddings.resize(columns); - for (size_t i = 0; i < columns; ++i) - { - WriteBufferFromString out(names_and_paddings[i]); - writeString(sample.getByPosition(i).name, out); - writeCString(": ", out); - } - - for (size_t i = 0; i < columns; ++i) - { - size_t new_size = max_name_width - name_widths[i] + names_and_paddings[i].size(); - names_and_paddings[i].resize(new_size, ' '); - } -} - - -void VerticalRowOutputStream::flush() -{ - ostr.next(); -} - - -void VerticalRowOutputStream::writeField(const IColumn & column, const IDataType & type, size_t row_num) -{ - if (row_number > format_settings.pretty.max_rows) - return; - - writeString(names_and_paddings[field_number], ostr); - writeValue(column, type, row_num); - writeChar('\n', ostr); - - ++field_number; -} - - -void VerticalRowOutputStream::writeValue(const IColumn & column, const IDataType & type, size_t row_num) const -{ - type.serializeAsText(column, row_num, ostr, format_settings); -} - - -void VerticalRowOutputStream::writeRowStartDelimiter() -{ - ++row_number; - - if (row_number > format_settings.pretty.max_rows) - return; - - writeCString("Row ", ostr); - writeIntText(row_number, ostr); - writeCString(":\n", ostr); - - size_t width = log10(row_number + 1) + 1 + strlen("Row :"); - for (size_t i = 0; i < width; ++i) - writeCString("─", ostr); - writeChar('\n', ostr); -} - - -void VerticalRowOutputStream::writeRowBetweenDelimiter() -{ - if (row_number > format_settings.pretty.max_rows) - return; - - writeCString("\n", ostr); - field_number = 0; -} - - -void VerticalRowOutputStream::writeSuffix() -{ - if (row_number > format_settings.pretty.max_rows) - { - writeCString("Showed first ", ostr); - writeIntText(format_settings.pretty.max_rows, ostr); - writeCString(".\n", ostr); - } - - if (totals || extremes) - { - writeCString("\n", ostr); - writeTotals(); - writeExtremes(); - } -} - - -void VerticalRowOutputStream::writeSpecialRow(const Block & block, size_t row_num, const char * title) -{ - writeCString("\n", ostr); - - row_number = 0; - field_number = 0; - - size_t columns = block.columns(); - - writeCString(title, ostr); - writeCString(":\n", ostr); - - size_t width = strlen(title) + 1; - for (size_t i = 0; i < width; ++i) - writeCString("─", ostr); - writeChar('\n', ostr); - - for (size_t i = 0; i < columns; ++i) - { - if (i != 0) - writeFieldDelimiter(); - - auto & col = block.getByPosition(i); - writeField(*col.column, *col.type, row_num); - } -} - - -void VerticalRowOutputStream::writeTotals() -{ - if (totals) - { - writeSpecialRow(totals, 0, "Totals"); - } -} - - -void VerticalRowOutputStream::writeExtremes() -{ - if (extremes) - { - writeSpecialRow(extremes, 0, "Min"); - writeSpecialRow(extremes, 1, "Max"); - } -} - - -void registerOutputFormatVertical(FormatFactory & factory) -{ - factory.registerOutputFormat("Vertical", []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & settings) - { - return std::make_shared( - std::make_shared(buf, sample, settings), sample); - }); -} - -} diff --git a/dbms/src/Formats/VerticalRowOutputStream.h b/dbms/src/Formats/VerticalRowOutputStream.h deleted file mode 100644 index 0d9d1122b77..00000000000 --- a/dbms/src/Formats/VerticalRowOutputStream.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include -#include -#include - - -namespace DB -{ - -class WriteBuffer; -class Context; - - -/** Stream to output data in format "each value in separate row". - * Usable to show few rows with many columns. - */ -class VerticalRowOutputStream : public IRowOutputStream -{ -public: - VerticalRowOutputStream(WriteBuffer & ostr_, const Block & sample_, const FormatSettings & format_settings); - - void writeField(const IColumn & column, const IDataType & type, size_t row_num) override; - void writeRowStartDelimiter() override; - void writeRowBetweenDelimiter() override; - void writeSuffix() override; - - void flush() override; - - void setTotals(const Block & totals_) override { totals = totals_; } - void setExtremes(const Block & extremes_) override { extremes = extremes_; } - -protected: - virtual void writeValue(const IColumn & column, const IDataType & type, size_t row_num) const; - - void writeTotals(); - void writeExtremes(); - /// For totals and extremes. - void writeSpecialRow(const Block & block, size_t row_num, const char * title); - - WriteBuffer & ostr; - const Block sample; - const FormatSettings format_settings; - size_t field_number = 0; - size_t row_number = 0; - - using NamesAndPaddings = std::vector; - NamesAndPaddings names_and_paddings; - - Block totals; - Block extremes; -}; - -} - From a92f0866009270b0698e306a617563f05f7374fa Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 2 Aug 2019 20:39:24 +0300 Subject: [PATCH 0653/1165] Remove XMLRowOutputStream. --- dbms/src/Formats/FormatFactory.cpp | 2 - dbms/src/Formats/XMLRowOutputStream.cpp | 240 ------------------------ dbms/src/Formats/XMLRowOutputStream.h | 74 -------- 3 files changed, 316 deletions(-) delete mode 100644 dbms/src/Formats/XMLRowOutputStream.cpp delete mode 100644 dbms/src/Formats/XMLRowOutputStream.h diff --git a/dbms/src/Formats/FormatFactory.cpp b/dbms/src/Formats/FormatFactory.cpp index ea38b62e71e..2d05ff3da43 100644 --- a/dbms/src/Formats/FormatFactory.cpp +++ b/dbms/src/Formats/FormatFactory.cpp @@ -223,7 +223,6 @@ void registerOutputFormatProcessorProtobuf(FormatFactory & factory); /// Output only (presentational) formats. -void registerOutputFormatXML(FormatFactory & factory); void registerOutputFormatNull(FormatFactory & factory); void registerOutputFormatProcessorPretty(FormatFactory & factory); @@ -269,7 +268,6 @@ FormatFactory::FormatFactory() registerOutputFormatProcessorParquet(*this); - registerOutputFormatXML(*this); registerOutputFormatNull(*this); registerOutputFormatProcessorPretty(*this); diff --git a/dbms/src/Formats/XMLRowOutputStream.cpp b/dbms/src/Formats/XMLRowOutputStream.cpp deleted file mode 100644 index 9b4a33a6263..00000000000 --- a/dbms/src/Formats/XMLRowOutputStream.cpp +++ /dev/null @@ -1,240 +0,0 @@ -#include -#include -#include -#include -#include - - -namespace DB -{ - -XMLRowOutputStream::XMLRowOutputStream(WriteBuffer & ostr_, const Block & sample_, const FormatSettings & format_settings) - : dst_ostr(ostr_), format_settings(format_settings) -{ - NamesAndTypesList columns(sample_.getNamesAndTypesList()); - fields.assign(columns.begin(), columns.end()); - field_tag_names.resize(sample_.columns()); - - bool need_validate_utf8 = false; - for (size_t i = 0; i < sample_.columns(); ++i) - { - if (!sample_.getByPosition(i).type->textCanContainOnlyValidUTF8()) - need_validate_utf8 = true; - - /// As element names, we will use the column name if it has a valid form, or "field", otherwise. - /// The condition below is more strict than the XML standard requires. - bool is_column_name_suitable = true; - const char * begin = fields[i].name.data(); - const char * end = begin + fields[i].name.size(); - for (const char * pos = begin; pos != end; ++pos) - { - char c = *pos; - if (!(isAlphaASCII(c) - || (pos != begin && isNumericASCII(c)) - || c == '_' - || c == '-' - || c == '.')) - { - is_column_name_suitable = false; - break; - } - } - - field_tag_names[i] = is_column_name_suitable - ? fields[i].name - : "field"; - } - - if (need_validate_utf8) - { - validating_ostr = std::make_unique(dst_ostr); - ostr = validating_ostr.get(); - } - else - ostr = &dst_ostr; -} - - -void XMLRowOutputStream::writePrefix() -{ - writeCString("\n", *ostr); - writeCString("\n", *ostr); - writeCString("\t\n", *ostr); - writeCString("\t\t\n", *ostr); - - for (size_t i = 0; i < fields.size(); ++i) - { - writeCString("\t\t\t\n", *ostr); - - writeCString("\t\t\t\t", *ostr); - writeXMLString(fields[i].name, *ostr); - writeCString("\n", *ostr); - writeCString("\t\t\t\t", *ostr); - writeXMLString(fields[i].type->getName(), *ostr); - writeCString("\n", *ostr); - - writeCString("\t\t\t\n", *ostr); - } - - writeCString("\t\t\n", *ostr); - writeCString("\t\n", *ostr); - writeCString("\t\n", *ostr); -} - - -void XMLRowOutputStream::writeField(const IColumn & column, const IDataType & type, size_t row_num) -{ - writeCString("\t\t\t<", *ostr); - writeString(field_tag_names[field_number], *ostr); - writeCString(">", *ostr); - type.serializeAsTextXML(column, row_num, *ostr, format_settings); - writeCString("\n", *ostr); - ++field_number; -} - - -void XMLRowOutputStream::writeRowStartDelimiter() -{ - writeCString("\t\t\n", *ostr); -} - - -void XMLRowOutputStream::writeRowEndDelimiter() -{ - writeCString("\t\t\n", *ostr); - field_number = 0; - ++row_count; -} - - -void XMLRowOutputStream::writeSuffix() -{ - writeCString("\t\n", *ostr); - - writeTotals(); - writeExtremes(); - - writeCString("\t", *ostr); - writeIntText(row_count, *ostr); - writeCString("\n", *ostr); - - writeRowsBeforeLimitAtLeast(); - - if (format_settings.write_statistics) - writeStatistics(); - - writeCString("\n", *ostr); - ostr->next(); -} - -void XMLRowOutputStream::writeRowsBeforeLimitAtLeast() -{ - if (applied_limit) - { - writeCString("\t", *ostr); - writeIntText(rows_before_limit, *ostr); - writeCString("\n", *ostr); - } -} - -void XMLRowOutputStream::writeTotals() -{ - if (totals) - { - writeCString("\t\n", *ostr); - - size_t totals_columns = totals.columns(); - for (size_t i = 0; i < totals_columns; ++i) - { - const ColumnWithTypeAndName & column = totals.safeGetByPosition(i); - - writeCString("\t\t<", *ostr); - writeString(field_tag_names[i], *ostr); - writeCString(">", *ostr); - column.type->serializeAsTextXML(*column.column.get(), 0, *ostr, format_settings); - writeCString("\n", *ostr); - } - - writeCString("\t\n", *ostr); - } -} - - -static void writeExtremesElement( - const char * title, const Block & extremes, size_t row_num, const Names & field_tag_names, WriteBuffer & ostr, const FormatSettings & format_settings) -{ - writeCString("\t\t<", ostr); - writeCString(title, ostr); - writeCString(">\n", ostr); - - size_t extremes_columns = extremes.columns(); - for (size_t i = 0; i < extremes_columns; ++i) - { - const ColumnWithTypeAndName & column = extremes.safeGetByPosition(i); - - writeCString("\t\t\t<", ostr); - writeString(field_tag_names[i], ostr); - writeCString(">", ostr); - column.type->serializeAsTextXML(*column.column.get(), row_num, ostr, format_settings); - writeCString("\n", ostr); - } - - writeCString("\t\t\n", ostr); -} - -void XMLRowOutputStream::writeExtremes() -{ - if (extremes) - { - writeCString("\t\n", *ostr); - writeExtremesElement("min", extremes, 0, field_tag_names, *ostr, format_settings); - writeExtremesElement("max", extremes, 1, field_tag_names, *ostr, format_settings); - writeCString("\t\n", *ostr); - } -} - - -void XMLRowOutputStream::onProgress(const Progress & value) -{ - progress.incrementPiecewiseAtomically(value); -} - - -void XMLRowOutputStream::writeStatistics() -{ - writeCString("\t\n", *ostr); - writeCString("\t\t", *ostr); - writeText(watch.elapsedSeconds(), *ostr); - writeCString("\n", *ostr); - writeCString("\t\t", *ostr); - writeText(progress.read_rows.load(), *ostr); - writeCString("\n", *ostr); - writeCString("\t\t", *ostr); - writeText(progress.read_bytes.load(), *ostr); - writeCString("\n", *ostr); - writeCString("\t\n", *ostr); -} - - -void registerOutputFormatXML(FormatFactory & factory) -{ - factory.registerOutputFormat("XML", []( - WriteBuffer & buf, - const Block & sample, - const Context &, - const FormatSettings & settings) - { - return std::make_shared( - std::make_shared(buf, sample, settings), sample); - }); -} - -} diff --git a/dbms/src/Formats/XMLRowOutputStream.h b/dbms/src/Formats/XMLRowOutputStream.h deleted file mode 100644 index 6a77cfcbeb8..00000000000 --- a/dbms/src/Formats/XMLRowOutputStream.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - - -namespace DB -{ - -/** A stream for outputting data in XML format. - */ -class XMLRowOutputStream : public IRowOutputStream -{ -public: - XMLRowOutputStream(WriteBuffer & ostr_, const Block & sample_, const FormatSettings & format_settings); - - void writeField(const IColumn & column, const IDataType & type, size_t row_num) override; - void writeRowStartDelimiter() override; - void writeRowEndDelimiter() override; - void writePrefix() override; - void writeSuffix() override; - - void flush() override - { - ostr->next(); - - if (validating_ostr) - dst_ostr.next(); - } - - void setRowsBeforeLimit(size_t rows_before_limit_) override - { - applied_limit = true; - rows_before_limit = rows_before_limit_; - } - - void setTotals(const Block & totals_) override { totals = totals_; } - void setExtremes(const Block & extremes_) override { extremes = extremes_; } - - void onProgress(const Progress & value) override; - - String getContentType() const override { return "application/xml; charset=UTF-8"; } - -protected: - - void writeRowsBeforeLimitAtLeast(); - virtual void writeTotals(); - virtual void writeExtremes(); - void writeStatistics(); - - WriteBuffer & dst_ostr; - std::unique_ptr validating_ostr; /// Validates UTF-8 sequences, replaces bad sequences with replacement character. - WriteBuffer * ostr; - - size_t field_number = 0; - size_t row_count = 0; - bool applied_limit = false; - size_t rows_before_limit = 0; - NamesAndTypes fields; - Names field_tag_names; - Block totals; - Block extremes; - - Progress progress; - Stopwatch watch; - const FormatSettings format_settings; -}; - -} - From 994ef14393a53baf29907d0ed235d4006ca241c3 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 2 Aug 2019 21:51:39 +0300 Subject: [PATCH 0654/1165] Fixed "unbundled" build --- dbms/programs/server/Server.cpp | 4 ++++ dbms/src/Common/QueryProfiler.cpp | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/dbms/programs/server/Server.cpp b/dbms/programs/server/Server.cpp index 563fff6a0bc..495cc359f26 100644 --- a/dbms/programs/server/Server.cpp +++ b/dbms/programs/server/Server.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -510,8 +511,11 @@ int Server::main(const std::vector & /*args*/) LOG_DEBUG(log, "Loaded metadata."); /// Init trace collector only after trace_log system table was created +#if USE_INTERNAL_UNWIND_LIBRARY + /// QueryProfiler cannot work reliably with any other libunwind or without PHDR cache. if (hasPHDRCache()) global_context->initializeTraceCollector(); +#endif global_context->setCurrentDatabase(default_database); diff --git a/dbms/src/Common/QueryProfiler.cpp b/dbms/src/Common/QueryProfiler.cpp index bcdfcb5ae24..c908bebcc42 100644 --- a/dbms/src/Common/QueryProfiler.cpp +++ b/dbms/src/Common/QueryProfiler.cpp @@ -181,7 +181,11 @@ QueryProfilerBase::QueryProfilerBase(const Int32 thread_id, const throw; } #else - UNUSED(thread_id, clock_type, period, pause_signal); + UNUSED(thread_id); + UNUSED(clock_type); + UNUSED(period); + UNUSED(pause_signal); + throw Exception("QueryProfiler cannot work with stock libunwind", ErrorCodes::NOT_IMPLEMENTED); #endif } From a5105f85cf563d557e4f8bf0c45a1c7be6cb56cd Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Thu, 1 Aug 2019 20:04:19 +0300 Subject: [PATCH 0655/1165] Removed table function "catBoostPool" and storage "CatBoostPool" --- dbms/src/Storages/StorageCatBoostPool.cpp | 303 ------------------ dbms/src/Storages/StorageCatBoostPool.h | 82 ----- .../TableFunctionCatBoostPool.cpp | 56 ---- .../TableFunctionCatBoostPool.h | 21 -- .../TableFunctions/registerTableFunctions.cpp | 2 - 5 files changed, 464 deletions(-) delete mode 100644 dbms/src/Storages/StorageCatBoostPool.cpp delete mode 100644 dbms/src/Storages/StorageCatBoostPool.h delete mode 100644 dbms/src/TableFunctions/TableFunctionCatBoostPool.cpp delete mode 100644 dbms/src/TableFunctions/TableFunctionCatBoostPool.h diff --git a/dbms/src/Storages/StorageCatBoostPool.cpp b/dbms/src/Storages/StorageCatBoostPool.cpp deleted file mode 100644 index a9e2acedcce..00000000000 --- a/dbms/src/Storages/StorageCatBoostPool.cpp +++ /dev/null @@ -1,303 +0,0 @@ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace DB -{ - -namespace ErrorCodes -{ - extern const int CANNOT_OPEN_FILE; - extern const int CANNOT_PARSE_TEXT; - extern const int DATABASE_ACCESS_DENIED; -} - -namespace -{ -class CatBoostDatasetBlockInputStream : public IBlockInputStream -{ -public: - - CatBoostDatasetBlockInputStream(const std::string & file_name, const std::string & format_name, - const Block & sample_block, const Context & context, UInt64 max_block_size) - : file_name(file_name), format_name(format_name) - { - read_buf = std::make_unique(file_name); - reader = FormatFactory::instance().getInput(format_name, *read_buf, sample_block, context, max_block_size); - } - - String getName() const override - { - return "CatBoostDataset"; - } - - Block readImpl() override - { - return reader->read(); - } - - void readPrefixImpl() override - { - reader->readPrefix(); - } - - void readSuffixImpl() override - { - reader->readSuffix(); - } - - Block getHeader() const override { return reader->getHeader(); } - -private: - std::unique_ptr read_buf; - BlockInputStreamPtr reader; - std::string file_name; - std::string format_name; -}; - -} - -static boost::filesystem::path canonicalPath(std::string && path) -{ - return boost::filesystem::canonical(boost::filesystem::path(path)); -} - -static std::string resolvePath(const boost::filesystem::path & base_path, std::string && path) -{ - boost::filesystem::path resolved_path(path); - if (!resolved_path.is_absolute()) - return boost::filesystem::canonical(resolved_path, base_path).string(); - return boost::filesystem::canonical(resolved_path).string(); -} - -static void checkCreationIsAllowed(const String & base_path, const String & path) -{ - if (base_path != path.substr(0, base_path.size())) - throw Exception( - "Using file descriptor or user specified path as source of storage isn't allowed for server daemons", - ErrorCodes::DATABASE_ACCESS_DENIED); -} - - -StorageCatBoostPool::StorageCatBoostPool( - const String & database_name_, - const String & table_name_, - const Context & context, - String column_description_file_name_, - String data_description_file_name_) - : table_name(table_name_) - , database_name(database_name_) - , column_description_file_name(std::move(column_description_file_name_)) - , data_description_file_name(std::move(data_description_file_name_)) -{ - auto base_path = canonicalPath(context.getPath()); - column_description_file_name = resolvePath(base_path, std::move(column_description_file_name)); - data_description_file_name = resolvePath(base_path, std::move(data_description_file_name)); - if (context.getApplicationType() == Context::ApplicationType::SERVER) - { - const auto & base_path_str = base_path.string(); - checkCreationIsAllowed(base_path_str, column_description_file_name); - checkCreationIsAllowed(base_path_str, data_description_file_name); - } - - parseColumnDescription(); - createSampleBlockAndColumns(); -} - -std::string StorageCatBoostPool::getColumnTypesString(const ColumnTypesMap & columnTypesMap) -{ - std::string types_string; - bool first = true; - for (const auto & value : columnTypesMap) - { - if (!first) - types_string.append(", "); - - first = false; - types_string += value.first; - } - - return types_string; -} - -void StorageCatBoostPool::checkDatasetDescription() -{ - std::ifstream in(data_description_file_name); - if (!in.good()) - throw Exception("Cannot open file: " + data_description_file_name, ErrorCodes::CANNOT_OPEN_FILE); - - std::string line; - if (!std::getline(in, line)) - throw Exception("File is empty: " + data_description_file_name, ErrorCodes::CANNOT_PARSE_TEXT); - - size_t columns_count = 1; - for (char sym : line) - if (sym == '\t') - ++columns_count; - - columns_description.resize(columns_count); -} - -void StorageCatBoostPool::parseColumnDescription() -{ - /// NOTE: simple parsing - /// TODO: use ReadBufferFromFile - - checkDatasetDescription(); - - std::ifstream in(column_description_file_name); - if (!in.good()) - throw Exception("Cannot open file: " + column_description_file_name, ErrorCodes::CANNOT_OPEN_FILE); - - std::string line; - size_t line_num = 0; - auto column_types_map = getColumnTypesMap(); - auto column_types_string = getColumnTypesString(column_types_map); - - /// Enumerate default names for columns as Auxiliary, Auxiliary1, Auxiliary2, ... - std::map columns_per_type_count; - - while (std::getline(in, line)) - { - ++line_num; - std::string str_line_num = std::to_string(line_num); - - if (line.empty()) - continue; - - std::istringstream iss(line); - std::vector tokens; - std::string token; - while (std::getline(iss, token, '\t')) - tokens.push_back(token); - - if (tokens.size() != 2 && tokens.size() != 3) - throw Exception("Cannot parse column description at line " + str_line_num + " '" + line + "' " - + ": expected 2 or 3 columns, got " + std::to_string(tokens.size()), - ErrorCodes::CANNOT_PARSE_TEXT); - - std::string str_id = tokens[0]; - std::string col_type = tokens[1]; - std::string col_alias = tokens.size() > 2 ? tokens[2] : ""; - - size_t num_id; - try - { - num_id = std::stoull(str_id); - } - catch (std::exception & e) - { - throw Exception("Cannot parse column index at row " + str_line_num + ": " + e.what(), - ErrorCodes::CANNOT_PARSE_TEXT); - } - - if (num_id >= columns_description.size()) - throw Exception("Invalid index at row " + str_line_num + ": " + str_id - + ", expected in range [0, " + std::to_string(columns_description.size()) + ")", - ErrorCodes::CANNOT_PARSE_TEXT); - - if (column_types_map.count(col_type) == 0) - throw Exception("Invalid column type: " + col_type + ", expected: " + column_types_string, - ErrorCodes::CANNOT_PARSE_TEXT); - - auto type = column_types_map[col_type]; - - std::string col_name; - - bool is_feature_column = type == DatasetColumnType::Num || type == DatasetColumnType::Categ; - auto & col_number = columns_per_type_count[type]; - /// If column is not feature skip '0' after the name (to use 'Target' instead of 'Target0'). - col_name = col_type + (is_feature_column || col_number ? std::to_string(col_number) : ""); - ++col_number; - - columns_description[num_id] = ColumnDescription(col_name, col_alias, type); - } -} - -void StorageCatBoostPool::createSampleBlockAndColumns() -{ - ColumnsDescription columns; - NamesAndTypesList cat_columns; - NamesAndTypesList num_columns; - NamesAndTypesList other_columns; - sample_block.clear(); - - auto get_type = [](DatasetColumnType column_type) -> DataTypePtr - { - if (column_type == DatasetColumnType::Categ - || column_type == DatasetColumnType::Auxiliary - || column_type == DatasetColumnType::DocId) - return std::make_shared(); - else - return std::make_shared(); - }; - - for (auto & desc : columns_description) - { - DataTypePtr type = get_type(desc.column_type); - - if (desc.column_type == DatasetColumnType::Categ) - cat_columns.emplace_back(desc.column_name, type); - else if (desc.column_type == DatasetColumnType::Num) - num_columns.emplace_back(desc.column_name, type); - else - other_columns.emplace_back(desc.column_name, type); - - sample_block.insert(ColumnWithTypeAndName(type, desc.column_name)); - } - - /// Order is important: first numeric columns, then categorial, then all others. - for (const auto & column : num_columns) - columns.add(DB::ColumnDescription(column.name, column.type, false)); - for (const auto & column : cat_columns) - columns.add(DB::ColumnDescription(column.name, column.type, false)); - for (const auto & column : other_columns) - { - DB::ColumnDescription column_desc(column.name, column.type, false); - /// We assign Materialized kind to the column so that it doesn't show in SELECT *. - /// Because the table is readonly, we do not need default expression. - column_desc.default_desc.kind = ColumnDefaultKind::Materialized; - columns.add(std::move(column_desc)); - } - - for (auto & desc : columns_description) - { - if (!desc.alias.empty()) - { - DB::ColumnDescription column(desc.alias, get_type(desc.column_type), false); - column.default_desc.kind = ColumnDefaultKind::Alias; - column.default_desc.expression = std::make_shared(desc.column_name); - columns.add(std::move(column)); - } - } - - setColumns(columns); -} - -BlockInputStreams StorageCatBoostPool::read( - const Names & column_names, - const SelectQueryInfo & /*query_info*/, - const Context & context, - QueryProcessingStage::Enum /*processed_stage*/, - size_t max_block_size, - unsigned /*threads*/) -{ - auto stream = std::make_shared( - data_description_file_name, "TSV", sample_block, context, max_block_size); - - auto filter_stream = std::make_shared(stream, column_names, false); - return { filter_stream }; -} - -} diff --git a/dbms/src/Storages/StorageCatBoostPool.h b/dbms/src/Storages/StorageCatBoostPool.h deleted file mode 100644 index 0cc457fabc0..00000000000 --- a/dbms/src/Storages/StorageCatBoostPool.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace DB -{ - -class StorageCatBoostPool : public ext::shared_ptr_helper, public IStorage -{ -public: - std::string getName() const override { return "CatBoostPool"; } - std::string getTableName() const override { return table_name; } - std::string getDatabaseName() const override { return database_name; } - - BlockInputStreams read(const Names & column_names, - const SelectQueryInfo & query_info, - const Context & context, - QueryProcessingStage::Enum processed_stage, - size_t max_block_size, - unsigned threads) override; - -private: - String table_name; - String database_name; - - String column_description_file_name; - String data_description_file_name; - Block sample_block; - - enum class DatasetColumnType - { - Target, - Num, - Categ, - Auxiliary, - DocId, - Weight, - Baseline - }; - - using ColumnTypesMap = std::map; - - ColumnTypesMap getColumnTypesMap() const - { - return - { - {"Target", DatasetColumnType::Target}, - {"Num", DatasetColumnType::Num}, - {"Categ", DatasetColumnType::Categ}, - {"Auxiliary", DatasetColumnType::Auxiliary}, - {"DocId", DatasetColumnType::DocId}, - {"Weight", DatasetColumnType::Weight}, - {"Baseline", DatasetColumnType::Baseline}, - }; - } - - std::string getColumnTypesString(const ColumnTypesMap & columnTypesMap); - - struct ColumnDescription - { - std::string column_name; - std::string alias; - DatasetColumnType column_type; - - ColumnDescription() : column_type(DatasetColumnType::Num) {} - ColumnDescription(std::string column_name, std::string alias, DatasetColumnType column_type) - : column_name(std::move(column_name)), alias(std::move(alias)), column_type(column_type) {} - }; - - std::vector columns_description; - - void checkDatasetDescription(); - void parseColumnDescription(); - void createSampleBlockAndColumns(); - -protected: - StorageCatBoostPool(const String & database_name_, const String & table_name_, const Context & context, String column_description_file_name, String data_description_file_name); -}; - -} diff --git a/dbms/src/TableFunctions/TableFunctionCatBoostPool.cpp b/dbms/src/TableFunctions/TableFunctionCatBoostPool.cpp deleted file mode 100644 index 74fab72fd19..00000000000 --- a/dbms/src/TableFunctions/TableFunctionCatBoostPool.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include -#include -#include -#include - - -namespace DB -{ - -namespace ErrorCodes -{ - extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; - extern const int BAD_ARGUMENTS; -} - - -StoragePtr TableFunctionCatBoostPool::executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const -{ - ASTs & args_func = ast_function->children; - - std::string err = "Table function '" + getName() + "' requires 2 parameters: " - + "column descriptions file, dataset description file"; - - if (args_func.size() != 1) - throw Exception(err, ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); - - ASTs & args = args_func.at(0)->children; - - if (args.size() != 2) - throw Exception(err, ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); - - auto getStringLiteral = [](const IAST & node, const char * description) - { - const auto * lit = node.as(); - if (!lit) - throw Exception(description + String(" must be string literal (in single quotes)."), ErrorCodes::BAD_ARGUMENTS); - - if (lit->value.getType() != Field::Types::String) - throw Exception(description + String(" must be string literal (in single quotes)."), ErrorCodes::BAD_ARGUMENTS); - - return safeGet(lit->value); - }; - String column_descriptions_file = getStringLiteral(*args[0], "Column descriptions file"); - String dataset_description_file = getStringLiteral(*args[1], "Dataset description file"); - - return StorageCatBoostPool::create(getDatabaseName(), table_name, context, column_descriptions_file, dataset_description_file); -} - -void registerTableFunctionCatBoostPool(TableFunctionFactory & factory) -{ - factory.registerFunction(); -} - -} diff --git a/dbms/src/TableFunctions/TableFunctionCatBoostPool.h b/dbms/src/TableFunctions/TableFunctionCatBoostPool.h deleted file mode 100644 index cf93308b60c..00000000000 --- a/dbms/src/TableFunctions/TableFunctionCatBoostPool.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - - -namespace DB -{ - -/* catboostPool('column_descriptions_file', 'dataset_description_file') - * Create storage from CatBoost dataset. - */ -class TableFunctionCatBoostPool : public ITableFunction -{ -public: - static constexpr auto name = "catBoostPool"; - std::string getName() const override { return name; } -private: - StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const override; -}; - -} diff --git a/dbms/src/TableFunctions/registerTableFunctions.cpp b/dbms/src/TableFunctions/registerTableFunctions.cpp index 76eeb23f6cc..61d0ec23f7d 100644 --- a/dbms/src/TableFunctions/registerTableFunctions.cpp +++ b/dbms/src/TableFunctions/registerTableFunctions.cpp @@ -10,7 +10,6 @@ namespace DB void registerTableFunctionMerge(TableFunctionFactory & factory); void registerTableFunctionRemote(TableFunctionFactory & factory); void registerTableFunctionNumbers(TableFunctionFactory & factory); -void registerTableFunctionCatBoostPool(TableFunctionFactory & factory); void registerTableFunctionFile(TableFunctionFactory & factory); void registerTableFunctionURL(TableFunctionFactory & factory); void registerTableFunctionValues(TableFunctionFactory & factory); @@ -37,7 +36,6 @@ void registerTableFunctions() registerTableFunctionMerge(factory); registerTableFunctionRemote(factory); registerTableFunctionNumbers(factory); - registerTableFunctionCatBoostPool(factory); registerTableFunctionFile(factory); registerTableFunctionURL(factory); registerTableFunctionValues(factory); From 35a71506a572aee28961134633186e52632f6ad2 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 2 Aug 2019 21:59:19 +0300 Subject: [PATCH 0656/1165] Fixed error --- dbms/src/Functions/sigmoid.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Functions/sigmoid.cpp b/dbms/src/Functions/sigmoid.cpp index ef63d4b5494..e878a48046d 100644 --- a/dbms/src/Functions/sigmoid.cpp +++ b/dbms/src/Functions/sigmoid.cpp @@ -30,7 +30,7 @@ using FunctionSigmoid = FunctionMathUnary; static double sigmoid(double x) { - return 1.0 / (1.0 + exp(x)); + return 1.0 / (1.0 + exp(-x)); } using FunctionSigmoid = FunctionMathUnary>; From 73faf623f2f8535d10184fe1c55005ab0039b35d Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 2 Aug 2019 22:00:22 +0300 Subject: [PATCH 0657/1165] Adjusted precision in test --- contrib/fastops | 2 +- dbms/tests/queries/0_stateless/00978_ml_math.sql | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/fastops b/contrib/fastops index b969b7aee07..3a7cd7a6271 160000 --- a/contrib/fastops +++ b/contrib/fastops @@ -1 +1 @@ -Subproject commit b969b7aee07651248da8b7367b8e4338be8bca2a +Subproject commit 3a7cd7a6271f011025441bea178e7729d155c36b diff --git a/dbms/tests/queries/0_stateless/00978_ml_math.sql b/dbms/tests/queries/0_stateless/00978_ml_math.sql index dfad34e12ca..8523eb05aa1 100644 --- a/dbms/tests/queries/0_stateless/00978_ml_math.sql +++ b/dbms/tests/queries/0_stateless/00978_ml_math.sql @@ -1,4 +1,4 @@ -SELECT - round(sigmoid(x), 6), round(sigmoid(toFloat32(x)), 6), round(sigmoid(toFloat64(x)), 6), - round(tanh(x), 6), round(TANH(toFloat32(x)), 6), round(TANh(toFloat64(x)), 6) +SELECT + round(sigmoid(x), 5), round(sigmoid(toFloat32(x)), 5), round(sigmoid(toFloat64(x)), 5), + round(tanh(x), 5), round(TANH(toFloat32(x)), 5), round(TANh(toFloat64(x)), 5) FROM (SELECT arrayJoin([-1, 0, 1]) AS x); From aaf7480c150d2e3017118670e538118f4bc2b704 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 2 Aug 2019 22:04:20 +0300 Subject: [PATCH 0658/1165] Updated test --- .../00232_format_readable_size.reference | 96 +++++++++---------- .../00232_format_readable_size.sql | 2 +- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00232_format_readable_size.reference b/dbms/tests/queries/0_stateless/00232_format_readable_size.reference index 51fdbd330f5..0f723e968d9 100644 --- a/dbms/tests/queries/0_stateless/00232_format_readable_size.reference +++ b/dbms/tests/queries/0_stateless/00232_format_readable_size.reference @@ -20,51 +20,51 @@ 170.21 MiB 170.21 MiB 170.21 MiB 462.69 MiB 462.69 MiB 462.69 MiB 1.23 GiB 1.23 GiB 1.23 GiB -3.34 GiB 3.34 GiB -677.16 MiB -9.08 GiB 9.08 GiB 1.08 GiB -24.67 GiB 24.67 GiB 686.00 MiB -67.06 GiB 67.06 GiB -962.78 MiB -182.29 GiB 182.29 GiB -1.71 GiB -495.51 GiB 495.51 GiB -503.26 MiB -1.32 TiB 1.32 TiB -1.07 GiB -3.58 TiB 3.58 TiB 1.34 GiB -9.72 TiB 9.72 TiB 568.34 MiB -26.42 TiB 26.42 TiB 1.85 GiB -71.82 TiB 71.82 TiB -12.93 MiB -195.22 TiB 195.22 TiB -1.59 GiB -530.66 TiB 530.66 TiB -929.55 MiB -1.41 PiB 1.41 PiB -1.87 GiB -3.83 PiB 3.83 PiB -753.44 MiB -10.41 PiB 10.41 PiB 1.85 GiB -28.29 PiB 28.29 PiB 389.95 MiB -76.91 PiB 76.91 PiB 642.59 MiB -209.06 PiB 209.06 PiB 755.06 MiB -568.30 PiB 568.30 PiB 1.75 GiB -1.51 EiB 1.51 EiB 511.72 MiB -4.10 EiB 4.10 EiB 1.92 GiB -11.15 EiB 11.15 EiB -1.57 GiB -30.30 EiB 0.00 B 0.00 B -82.37 EiB 0.00 B 0.00 B -223.89 EiB 0.00 B 0.00 B -608.60 EiB 0.00 B 0.00 B -1.62 ZiB 0.00 B 0.00 B -4.39 ZiB 0.00 B 0.00 B -11.94 ZiB 0.00 B 0.00 B -32.45 ZiB 0.00 B 0.00 B -88.21 ZiB 0.00 B 0.00 B -239.77 ZiB 0.00 B 0.00 B -651.77 ZiB 0.00 B 0.00 B -1.73 YiB 0.00 B 0.00 B -4.70 YiB 0.00 B 0.00 B -12.78 YiB 0.00 B 0.00 B -34.75 YiB 0.00 B 0.00 B -94.46 YiB 0.00 B 0.00 B -256.78 YiB 0.00 B 0.00 B -698.00 YiB 0.00 B 0.00 B -1897.37 YiB 0.00 B 0.00 B -5157.59 YiB 0.00 B 0.00 B -14019.80 YiB 0.00 B 0.00 B -38109.75 YiB 0.00 B 0.00 B -103593.05 YiB 0.00 B 0.00 B -281595.11 YiB 0.00 B 0.00 B -765454.88 YiB 0.00 B 0.00 B +3.34 GiB 3.34 GiB -2.00 GiB +9.08 GiB 9.08 GiB -2.00 GiB +24.67 GiB 24.67 GiB -2.00 GiB +67.06 GiB 67.06 GiB -2.00 GiB +182.29 GiB 182.29 GiB -2.00 GiB +495.51 GiB 495.51 GiB -2.00 GiB +1.32 TiB 1.32 TiB -2.00 GiB +3.58 TiB 3.58 TiB -2.00 GiB +9.72 TiB 9.72 TiB -2.00 GiB +26.42 TiB 26.42 TiB -2.00 GiB +71.82 TiB 71.82 TiB -2.00 GiB +195.22 TiB 195.22 TiB -2.00 GiB +530.66 TiB 530.66 TiB -2.00 GiB +1.41 PiB 1.41 PiB -2.00 GiB +3.83 PiB 3.83 PiB -2.00 GiB +10.41 PiB 10.41 PiB -2.00 GiB +28.29 PiB 28.29 PiB -2.00 GiB +76.91 PiB 76.91 PiB -2.00 GiB +209.06 PiB 209.06 PiB -2.00 GiB +568.30 PiB 568.30 PiB -2.00 GiB +1.51 EiB 1.51 EiB -2.00 GiB +4.10 EiB 4.10 EiB -2.00 GiB +11.15 EiB 11.15 EiB -2.00 GiB +30.30 EiB 0.00 B -2.00 GiB +82.37 EiB 0.00 B -2.00 GiB +223.89 EiB 0.00 B -2.00 GiB +608.60 EiB 0.00 B -2.00 GiB +1.62 ZiB 0.00 B -2.00 GiB +4.39 ZiB 0.00 B -2.00 GiB +11.94 ZiB 0.00 B -2.00 GiB +32.45 ZiB 0.00 B -2.00 GiB +88.21 ZiB 0.00 B -2.00 GiB +239.77 ZiB 0.00 B -2.00 GiB +651.77 ZiB 0.00 B -2.00 GiB +1.73 YiB 0.00 B -2.00 GiB +4.70 YiB 0.00 B -2.00 GiB +12.78 YiB 0.00 B -2.00 GiB +34.75 YiB 0.00 B -2.00 GiB +94.46 YiB 0.00 B -2.00 GiB +256.78 YiB 0.00 B -2.00 GiB +698.00 YiB 0.00 B -2.00 GiB +1897.37 YiB 0.00 B -2.00 GiB +5157.59 YiB 0.00 B -2.00 GiB +14019.80 YiB 0.00 B -2.00 GiB +38109.75 YiB 0.00 B -2.00 GiB +103593.05 YiB 0.00 B -2.00 GiB +281595.11 YiB 0.00 B -2.00 GiB +765454.88 YiB 0.00 B -2.00 GiB diff --git a/dbms/tests/queries/0_stateless/00232_format_readable_size.sql b/dbms/tests/queries/0_stateless/00232_format_readable_size.sql index c3891c63c6f..952ee82b81a 100644 --- a/dbms/tests/queries/0_stateless/00232_format_readable_size.sql +++ b/dbms/tests/queries/0_stateless/00232_format_readable_size.sql @@ -1,4 +1,4 @@ -WITH round(exp(number), 6) AS x, toUInt64(x) AS y, toInt32(y) AS z +WITH round(exp(number), 6) AS x, toUInt64(x) AS y, toInt32(x) AS z SELECT formatReadableSize(x), formatReadableSize(y), formatReadableSize(z) FROM system.numbers LIMIT 70; From 0dfca33e5bb937ea0358ed1c593afab0114e9ea2 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 2 Aug 2019 22:06:09 +0300 Subject: [PATCH 0659/1165] Fixed "splitted" build --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 69082f36c62..e8d622ec09f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -559,4 +559,5 @@ if (GLIBC_COMPATIBILITY OR USE_INTERNAL_UNWIND_LIBRARY_FOR_EXCEPTION_HANDLING) add_default_dependencies(base64) add_default_dependencies(readpassphrase) add_default_dependencies(unwind_static) + add_default_dependencies(fastops) endif () From bfa9a2c86f3720ab215d1ef48299af701e1b229c Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Fri, 2 Aug 2019 22:21:55 +0300 Subject: [PATCH 0660/1165] fixed index condition --- dbms/src/Functions/bitBoolMaskAnd.cpp | 40 +++++++++++++++++++ dbms/src/Functions/bitBoolMaskOr.cpp | 40 +++++++++++++++++++ .../{bitNotFunc.cpp => bitWrapperFunc.cpp} | 14 +++---- .../Functions/registerFunctionsArithmetic.cpp | 8 +++- .../Storages/MergeTree/MergeTreeIndexSet.cpp | 13 +++--- .../0_stateless/00838_unique_index.reference | 18 +++++++++ .../queries/0_stateless/00838_unique_index.sh | 7 ++++ 7 files changed, 126 insertions(+), 14 deletions(-) create mode 100644 dbms/src/Functions/bitBoolMaskAnd.cpp create mode 100644 dbms/src/Functions/bitBoolMaskOr.cpp rename dbms/src/Functions/{bitNotFunc.cpp => bitWrapperFunc.cpp} (57%) diff --git a/dbms/src/Functions/bitBoolMaskAnd.cpp b/dbms/src/Functions/bitBoolMaskAnd.cpp new file mode 100644 index 00000000000..f1ecea1bbcb --- /dev/null +++ b/dbms/src/Functions/bitBoolMaskAnd.cpp @@ -0,0 +1,40 @@ +#include +#include +#include + +namespace DB +{ + + template + struct BitBoolMaskAndImpl + { + using ResultType = UInt8; + + template + static inline Result apply(A left, B right) + { + return static_cast( + ((static_cast(left) & static_cast(right)) & 1) + | ((((static_cast(left) >> 1) | (static_cast(right) >> 1)) & 1) << 1)); + } + +#if USE_EMBEDDED_COMPILER + static constexpr bool compilable = false; + + static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool) + { + if (!left->getType()->isIntegerTy() && !right->getType()->isIntegerTy()) + throw Exception("__bitBoolMaskAnd expected an integral type", ErrorCodes::LOGICAL_ERROR); + } +#endif + }; + + struct NameBitBoolMaskAnd { static constexpr auto name = "__bitBoolMaskAnd"; }; + using FunctionBitBoolMaskAnd = FunctionBinaryArithmetic; + + void registerFunctionBitBoolMaskAnd(FunctionFactory & factory) + { + factory.registerFunction(); + } + +} diff --git a/dbms/src/Functions/bitBoolMaskOr.cpp b/dbms/src/Functions/bitBoolMaskOr.cpp new file mode 100644 index 00000000000..e79e04c7eaa --- /dev/null +++ b/dbms/src/Functions/bitBoolMaskOr.cpp @@ -0,0 +1,40 @@ +#include +#include +#include + +namespace DB +{ + + template + struct BitBoolMaskOrImpl + { + using ResultType = UInt8; + + template + static inline Result apply(A left, B right) + { + return static_cast( + ((static_cast(left) & 1) | (static_cast(right) & 1)) + | ((((static_cast(left) >> 1) & (static_cast(right) >> 1)) & 1) << 1)); + } + +#if USE_EMBEDDED_COMPILER + static constexpr bool compilable = false; + + static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool) + { + if (!left->getType()->isIntegerTy() && !right->getType()->isIntegerTy()) + throw Exception("__bitBoolMaskOr expected an integral type", ErrorCodes::LOGICAL_ERROR); + } +#endif + }; + + struct NameBitBoolMaskOr { static constexpr auto name = "__bitBoolMaskOr"; }; + using FunctionBitBoolMaskOr = FunctionBinaryArithmetic; + + void registerFunctionBitBoolMaskOr(FunctionFactory & factory) + { + factory.registerFunction(); + } + +} diff --git a/dbms/src/Functions/bitNotFunc.cpp b/dbms/src/Functions/bitWrapperFunc.cpp similarity index 57% rename from dbms/src/Functions/bitNotFunc.cpp rename to dbms/src/Functions/bitWrapperFunc.cpp index b5057e72801..362740d3ac3 100644 --- a/dbms/src/Functions/bitNotFunc.cpp +++ b/dbms/src/Functions/bitWrapperFunc.cpp @@ -6,13 +6,13 @@ namespace DB { template - struct BitNotFuncImpl + struct BitWrapperFuncImpl { using ResultType = UInt8; static inline ResultType NO_SANITIZE_UNDEFINED apply(A a) { - return a == 0 ? static_cast(0b10) : static_cast(0b1); + return a == static_cast(0) ? static_cast(0b10) : static_cast(0b1); } #if USE_EMBEDDED_COMPILER @@ -21,10 +21,10 @@ namespace DB #endif }; - struct NameBitNotFunc { static constexpr auto name = "__bitNotFunc"; }; - using FunctionBitNotFunc = FunctionUnaryArithmetic; + struct NameBitWrapperFunc { static constexpr auto name = "__bitWrapperFunc"; }; + using FunctionBitWrapperFunc = FunctionUnaryArithmetic; - template <> struct FunctionUnaryArithmeticMonotonicity + template <> struct FunctionUnaryArithmeticMonotonicity { static bool has() { return false; } static IFunction::Monotonicity get(const Field &, const Field &) @@ -33,9 +33,9 @@ namespace DB } }; - void registerFunctionBitNotFunc(FunctionFactory & factory) + void registerFunctionBitWrapperFunc(FunctionFactory & factory) { - factory.registerFunction(); + factory.registerFunction(); } } diff --git a/dbms/src/Functions/registerFunctionsArithmetic.cpp b/dbms/src/Functions/registerFunctionsArithmetic.cpp index 0ac0223a822..1faa28e395e 100644 --- a/dbms/src/Functions/registerFunctionsArithmetic.cpp +++ b/dbms/src/Functions/registerFunctionsArithmetic.cpp @@ -33,7 +33,9 @@ void registerFunctionRoundToExp2(FunctionFactory & factory); void registerFunctionRoundDuration(FunctionFactory & factory); void registerFunctionRoundAge(FunctionFactory & factory); -void registerFunctionBitNotFunc(FunctionFactory & factory); +void registerFunctionBitBoolMaskOr(FunctionFactory & factory); +void registerFunctionBitBoolMaskAnd(FunctionFactory & factory); +void registerFunctionBitWrapperFunc(FunctionFactory & factory); void registerFunctionBitSwapLastTwo(FunctionFactory & factory); void registerFunctionsArithmetic(FunctionFactory & factory) @@ -69,7 +71,9 @@ void registerFunctionsArithmetic(FunctionFactory & factory) registerFunctionRoundAge(factory); /// Not for external use. - registerFunctionBitNotFunc(factory); + registerFunctionBitBoolMaskOr(factory); + registerFunctionBitBoolMaskAnd(factory); + registerFunctionBitWrapperFunc(factory); registerFunctionBitSwapLastTwo(factory); } diff --git a/dbms/src/Storages/MergeTree/MergeTreeIndexSet.cpp b/dbms/src/Storages/MergeTree/MergeTreeIndexSet.cpp index 0371bd9e1a7..06c873ea7c9 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeIndexSet.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeIndexSet.cpp @@ -306,7 +306,10 @@ void MergeTreeIndexConditionSet::traverseAST(ASTPtr & node) const } if (atomFromAST(node)) - node = makeASTFunction("__bitNotFunc", node); + { + if (node->as() || node->as()) + node = makeASTFunction("__bitWrapperFunc", node); + } else node = std::make_shared(UNKNOWN_FIELD); } @@ -366,12 +369,12 @@ bool MergeTreeIndexConditionSet::operatorFromAST(ASTPtr & node) const ASTPtr new_func; if (args.size() > 1) new_func = makeASTFunction( - "bitAnd", + "__bitBoolMaskAnd", node, last_arg); else new_func = makeASTFunction( - "bitAnd", + "__bitBoolMaskAnd", args.back(), last_arg); @@ -385,12 +388,12 @@ bool MergeTreeIndexConditionSet::operatorFromAST(ASTPtr & node) const ASTPtr new_func; if (args.size() > 1) new_func = makeASTFunction( - "bitOr", + "__bitBoolMaskOr", node, last_arg); else new_func = makeASTFunction( - "bitOr", + "__bitBoolMaskOr", args.back(), last_arg); diff --git a/dbms/tests/queries/0_stateless/00838_unique_index.reference b/dbms/tests/queries/0_stateless/00838_unique_index.reference index 9ba14877884..1686ed17bb2 100644 --- a/dbms/tests/queries/0_stateless/00838_unique_index.reference +++ b/dbms/tests/queries/0_stateless/00838_unique_index.reference @@ -3,4 +3,22 @@ 12 5 4.7 6.50 cba b 2014-06-11 13 5 4.7 6.50 cba b 2015-01-01 "rows_read": 4, +2 2 4.5 2.50 abc a 2014-01-01 +6 2 4.5 2.50 abc a 2014-02-11 +7 5 6.9 1.57 bac c 2014-04-11 +8 2 4.5 2.50 abc a 2014-05-11 +9 5 6.9 1.57 bac c 2014-07-11 +5 5 6.9 1.57 bac c 2014-11-11 +4 2 4.5 2.50 abc a 2016-01-01 +3 5 6.9 1.57 bac c 2017-01-01 + "rows_read": 8, "rows_read": 2, +2 2 4.5 2.50 abc a 2014-01-01 +6 2 4.5 2.50 abc a 2014-02-11 +7 5 6.9 1.57 bac c 2014-04-11 +8 2 4.5 2.50 abc a 2014-05-11 +9 5 6.9 1.57 bac c 2014-07-11 +5 5 6.9 1.57 bac c 2014-11-11 +4 2 4.5 2.50 abc a 2016-01-01 +3 5 6.9 1.57 bac c 2017-01-01 + "rows_read": 8, \ No newline at end of file diff --git a/dbms/tests/queries/0_stateless/00838_unique_index.sh b/dbms/tests/queries/0_stateless/00838_unique_index.sh index 9445d6af98a..ede8326c49a 100755 --- a/dbms/tests/queries/0_stateless/00838_unique_index.sh +++ b/dbms/tests/queries/0_stateless/00838_unique_index.sh @@ -43,8 +43,15 @@ $CLICKHOUSE_CLIENT --query="INSERT INTO set_idx VALUES $CLICKHOUSE_CLIENT --query="SELECT * FROM set_idx WHERE i32 = 5 AND i32 + f64 < 12 AND 3 < d AND d < 7 AND (s = 'bac' OR s = 'cba') ORDER BY dt" $CLICKHOUSE_CLIENT --query="SELECT * FROM set_idx WHERE i32 = 5 AND i32 + f64 < 12 AND 3 < d AND d < 7 AND (s = 'bac' OR s = 'cba') ORDER BY dt FORMAT JSON" | grep "rows_read" +$CLICKHOUSE_CLIENT --query="SELECT * FROM set_idx WHERE NOT (i32 = 5 AND i32 + f64 < 12 AND 3 < d AND d < 7 AND (s = 'bac' OR s = 'cba')) ORDER BY dt" +$CLICKHOUSE_CLIENT --query="SELECT * FROM set_idx WHERE NOT (i32 = 5 AND i32 + f64 < 12 AND 3 < d AND d < 7 AND (s = 'bac' OR s = 'cba')) ORDER BY dt FORMAT JSON" | grep "rows_read" + # select with hole made by primary key $CLICKHOUSE_CLIENT --query="SELECT * FROM set_idx WHERE (u64 < 2 OR u64 > 10) AND s != 'cba' ORDER BY dt" $CLICKHOUSE_CLIENT --query="SELECT * FROM set_idx WHERE (u64 < 2 OR u64 > 10) AND s != 'cba' ORDER BY dt FORMAT JSON" | grep "rows_read" +$CLICKHOUSE_CLIENT --query="SELECT * FROM set_idx WHERE (u64 < 2 OR NOT u64 > 10) AND NOT (s = 'cba') ORDER BY dt" +$CLICKHOUSE_CLIENT --query="SELECT * FROM set_idx WHERE (u64 < 2 OR NOT u64 > 10) AND NOT (s = 'cba') ORDER BY dt FORMAT JSON" | grep "rows_read" + + $CLICKHOUSE_CLIENT --query="DROP TABLE set_idx;" \ No newline at end of file From 5e942d2d797484e79d62e6996106ae42aee77ab9 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 2 Aug 2019 23:16:02 +0300 Subject: [PATCH 0661/1165] Added performance test to show degradation of performance in gcc-9 in more isolated way --- .../empty_string_deserialization.xml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 dbms/tests/performance/empty_string_deserialization.xml diff --git a/dbms/tests/performance/empty_string_deserialization.xml b/dbms/tests/performance/empty_string_deserialization.xml new file mode 100644 index 00000000000..99e7470c5e6 --- /dev/null +++ b/dbms/tests/performance/empty_string_deserialization.xml @@ -0,0 +1,20 @@ + + loop + + + + 10 + + + + + + CREATE TABLE empty_strings (s String) ENGINE = Log; + INSERT INTO empty_strings SELECT '' FROM numbers(1000000000); + + SELECT count() FROM empty_strings + + DROP TABLE IF EXISTS empty_strings + From 2fb71013af23c056344d61308be56607b65bd60f Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 2 Aug 2019 23:18:03 +0300 Subject: [PATCH 0662/1165] Added performance test to show degradation of performance in gcc-9 in more isolated way --- .../performance/empty_string_serialization.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 dbms/tests/performance/empty_string_serialization.xml diff --git a/dbms/tests/performance/empty_string_serialization.xml b/dbms/tests/performance/empty_string_serialization.xml new file mode 100644 index 00000000000..46c4bc0275c --- /dev/null +++ b/dbms/tests/performance/empty_string_serialization.xml @@ -0,0 +1,17 @@ + + loop + + + + 10 + + + + + + CREATE TABLE empty_strings (s String) ENGINE = Log; + INSERT INTO empty_strings SELECT '' FROM numbers(100000000); + DROP TABLE IF EXISTS empty_strings + From 21cb7de777656c09d4c08ad903e8dbcced61aada Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 2 Aug 2019 23:19:06 +0300 Subject: [PATCH 0663/1165] More validation of part_name --- dbms/src/Storages/MergeTree/DataPartsExchange.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dbms/src/Storages/MergeTree/DataPartsExchange.cpp b/dbms/src/Storages/MergeTree/DataPartsExchange.cpp index 80e521b32c1..f01b384d441 100644 --- a/dbms/src/Storages/MergeTree/DataPartsExchange.cpp +++ b/dbms/src/Storages/MergeTree/DataPartsExchange.cpp @@ -55,6 +55,9 @@ void Service::processQuery(const Poco::Net::HTMLForm & params, ReadBuffer & /*bo String part_name = params.get("part"); + /// Validation of the input that may come from malicious replica. + MergeTreePartInfo::fromPartName(part_name, data.format_version); + static std::atomic_uint total_sends {0}; if ((data.settings.replicated_max_parallel_sends && total_sends >= data.settings.replicated_max_parallel_sends) @@ -169,6 +172,9 @@ MergeTreeData::MutableDataPartPtr Fetcher::fetchPart( bool to_detached, const String & tmp_prefix_) { + /// Validation of the input that may come from malicious replica. + MergeTreePartInfo::fromPartName(part_name, data.format_version); + Poco::URI uri; uri.setScheme(interserver_scheme); uri.setHost(host); From 5774ef1ed1b587d8e0245c6f2fc1e84061248ec5 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 3 Aug 2019 00:49:50 +0300 Subject: [PATCH 0664/1165] Removed test --- .../00689_catboost_pool_files.reference | 1 - .../0_stateless/00689_catboost_pool_files.sh | 32 ------------------- 2 files changed, 33 deletions(-) delete mode 100644 dbms/tests/queries/0_stateless/00689_catboost_pool_files.reference delete mode 100755 dbms/tests/queries/0_stateless/00689_catboost_pool_files.sh diff --git a/dbms/tests/queries/0_stateless/00689_catboost_pool_files.reference b/dbms/tests/queries/0_stateless/00689_catboost_pool_files.reference deleted file mode 100644 index e965047ad7c..00000000000 --- a/dbms/tests/queries/0_stateless/00689_catboost_pool_files.reference +++ /dev/null @@ -1 +0,0 @@ -Hello diff --git a/dbms/tests/queries/0_stateless/00689_catboost_pool_files.sh b/dbms/tests/queries/0_stateless/00689_catboost_pool_files.sh deleted file mode 100755 index b859a7c3e34..00000000000 --- a/dbms/tests/queries/0_stateless/00689_catboost_pool_files.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -. $CURDIR/../shell_config.sh - -${CLICKHOUSE_CLIENT} --query="drop table if exists catboost_pool_desc;" -${CLICKHOUSE_CLIENT} --query="drop table if exists catboost_pool_vals;" -${CLICKHOUSE_CLIENT} --query="create table catboost_pool_desc (id String, type String) engine = File(TSV);" -${CLICKHOUSE_CLIENT} --query="insert into catboost_pool_desc select '0', 'Categ';" -${CLICKHOUSE_CLIENT} --query="create table catboost_pool_vals (str String) engine = File(TSV);" -${CLICKHOUSE_CLIENT} --query="insert into catboost_pool_vals select 'Hello';" -${CLICKHOUSE_CLIENT} --query="select * from catBoostPool('data/${CLICKHOUSE_DATABASE}/catboost_pool_desc/data.TSV', 'data/${CLICKHOUSE_DATABASE}/catboost_pool_vals/data.TSV');" - -${CLICKHOUSE_CLIENT} --query="select * from catBoostPool('data/${CLICKHOUSE_DATABASE}/catboost_pool_desc/data.TSV', '${CURDIR}/00689_file.txt');" 2>&1 | grep -o "Data" -${CLICKHOUSE_CLIENT} --query="select * from catBoostPool('data/${CLICKHOUSE_DATABASE}/catboost_pool_desc/data.TSV', '../${CURDIR}/00689_file.txt');" 2>&1 | grep -o "Data" -${CLICKHOUSE_CLIENT} --query="select * from catBoostPool('data/${CLICKHOUSE_DATABASE}/catboost_pool_desc/data.TSV', '../../${CURDIR}/00689_file.txt');" 2>&1 | grep -o "Data" -${CLICKHOUSE_CLIENT} --query="select * from catBoostPool('data/${CLICKHOUSE_DATABASE}/catboost_pool_desc/data.TSV', '../../../${CURDIR}/00689_file.txt');" 2>&1 | grep -o "Data" -${CLICKHOUSE_CLIENT} --query="select * from catBoostPool('data/${CLICKHOUSE_DATABASE}/catboost_pool_desc/data.TSV', '../../../../${CURDIR}/00689_file.txt');" 2>&1 | grep -o "Data" -${CLICKHOUSE_CLIENT} --query="select * from catBoostPool('data/${CLICKHOUSE_DATABASE}/catboost_pool_desc/data.TSV', '../../../../../${CURDIR}/00689_file.txt');" 2>&1 | grep -o "Data" -${CLICKHOUSE_CLIENT} --query="select * from catBoostPool('data/${CLICKHOUSE_DATABASE}/catboost_pool_desc/data.TSV', '../../../../../../${CURDIR}/00689_file.txt');" 2>&1 | grep -o "Data" -${CLICKHOUSE_CLIENT} --query="select * from catBoostPool('data/${CLICKHOUSE_DATABASE}/catboost_pool_desc/data.TSV', '../../../../../../../${CURDIR}/00689_file.txt');" 2>&1 | grep -o "Data" - -${CLICKHOUSE_CLIENT} --query="select * from catBoostPool('${CURDIR}/00689_file.txt', '${CURDIR}/00689_file.txt');" 2>&1 | grep -o "Data" -${CLICKHOUSE_CLIENT} --query="select * from catBoostPool('../${CURDIR}/00689_file.txt', '../${CURDIR}/00689_file.txt');" 2>&1 | grep -o "Data" -${CLICKHOUSE_CLIENT} --query="select * from catBoostPool('../../${CURDIR}/00689_file.txt', '../../${CURDIR}/00689_file.txt');" 2>&1 | grep -o "Data" -${CLICKHOUSE_CLIENT} --query="select * from catBoostPool('../../../${CURDIR}/00689_file.txt', '../../../${CURDIR}/00689_file.txt');" 2>&1 | grep -o "Data" -${CLICKHOUSE_CLIENT} --query="select * from catBoostPool('../../../../${CURDIR}/00689_file.txt', '../../../../${CURDIR}/00689_file.txt');" 2>&1 | grep -o "Data" -${CLICKHOUSE_CLIENT} --query="select * from catBoostPool('../../../../../${CURDIR}/00689_file.txt', '../../../../../${CURDIR}/00689_file.txt');" 2>&1 | grep -o "Data" -${CLICKHOUSE_CLIENT} --query="select * from catBoostPool('../../../../../../${CURDIR}/00689_file.txt', '../../../../../../${CURDIR}/00689_file.txt');" 2>&1 | grep -o "Data" - -${CLICKHOUSE_CLIENT} --query="drop table if exists catboost_pool_desc;" -${CLICKHOUSE_CLIENT} --query="drop table if exists catboost_pool_vals;" From 62053314bbbe5f7ce33f5c0486f662afb7351f1b Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 3 Aug 2019 01:40:28 +0300 Subject: [PATCH 0665/1165] Fixed FPE in yandexConsistentHash --- .../Functions/FunctionsConsistentHashing.h | 24 ++++++++++--------- libs/consistent-hashing/consistent_hashing.h | 4 ++-- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/dbms/src/Functions/FunctionsConsistentHashing.h b/dbms/src/Functions/FunctionsConsistentHashing.h index b7282c10dba..31a292bb9f2 100644 --- a/dbms/src/Functions/FunctionsConsistentHashing.h +++ b/dbms/src/Functions/FunctionsConsistentHashing.h @@ -29,11 +29,12 @@ struct YandexConsistentHashImpl static constexpr auto name = "yandexConsistentHash"; using HashType = UInt64; - /// Actually it supports UInt64, but it is effective only if n < 65536 - using ResultType = UInt32; - using BucketsCountType = ResultType; + /// Actually it supports UInt64, but it is efficient only if n <= 32768 + using ResultType = UInt16; + using BucketsType = ResultType; + static constexpr auto max_buckets = 32768; - static inline ResultType apply(UInt64 hash, BucketsCountType n) + static inline ResultType apply(UInt64 hash, BucketsType n) { return ConsistentHashing(hash, n); } @@ -59,9 +60,10 @@ struct JumpConsistentHashImpl using HashType = UInt64; using ResultType = Int32; - using BucketsCountType = ResultType; + using BucketsType = ResultType; + static constexpr auto max_buckets = static_cast(std::numeric_limits::max()); - static inline ResultType apply(UInt64 hash, BucketsCountType n) + static inline ResultType apply(UInt64 hash, BucketsType n) { return JumpConsistentHash(hash, n); } @@ -74,9 +76,10 @@ struct SumburConsistentHashImpl using HashType = UInt32; using ResultType = UInt16; - using BucketsCountType = ResultType; + using BucketsType = ResultType; + static constexpr auto max_buckets = static_cast(std::numeric_limits::max()); - static inline ResultType apply(HashType hash, BucketsCountType n) + static inline ResultType apply(HashType hash, BucketsType n) { return static_cast(sumburConsistentHash(hash, n)); } @@ -143,8 +146,7 @@ public: private: using HashType = typename Impl::HashType; using ResultType = typename Impl::ResultType; - using BucketsType = typename Impl::BucketsCountType; - static constexpr auto max_buckets = static_cast(std::numeric_limits::max()); + using BucketsType = typename Impl::BucketsType; template inline BucketsType checkBucketsRange(T buckets) @@ -153,7 +155,7 @@ private: throw Exception( "The second argument of function " + getName() + " (number of buckets) must be positive number", ErrorCodes::BAD_ARGUMENTS); - if (unlikely(static_cast(buckets) > max_buckets)) + if (unlikely(static_cast(buckets) > Impl::max_buckets)) throw Exception("The value of the second argument of function " + getName() + " (number of buckets) is not fit to " + DataTypeNumber().getName(), ErrorCodes::BAD_ARGUMENTS); diff --git a/libs/consistent-hashing/consistent_hashing.h b/libs/consistent-hashing/consistent_hashing.h index fba229c2bd4..a779dc2f3a6 100644 --- a/libs/consistent-hashing/consistent_hashing.h +++ b/libs/consistent-hashing/consistent_hashing.h @@ -15,5 +15,5 @@ * It requires O(1) memory and cpu to calculate. So, it is faster than classic * consistent hashing algos with points on circle. */ -std::size_t ConsistentHashing(std::uint64_t x, std::size_t n); // Works good for n < 65536 -std::size_t ConsistentHashing(std::uint64_t lo, std::uint64_t hi, std::size_t n); // Works good for n < 4294967296 +std::size_t ConsistentHashing(std::uint64_t x, std::size_t n); // Works for n <= 32768 +std::size_t ConsistentHashing(std::uint64_t lo, std::uint64_t hi, std::size_t n); // Works for n <= 2^31 From 7394d3e73a91bd4ed0b21b7151333c5b7a56abce Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 3 Aug 2019 01:42:21 +0300 Subject: [PATCH 0666/1165] Fixed exception message --- dbms/src/Functions/FunctionsConsistentHashing.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dbms/src/Functions/FunctionsConsistentHashing.h b/dbms/src/Functions/FunctionsConsistentHashing.h index 31a292bb9f2..04640e0ec57 100644 --- a/dbms/src/Functions/FunctionsConsistentHashing.h +++ b/dbms/src/Functions/FunctionsConsistentHashing.h @@ -156,9 +156,8 @@ private: "The second argument of function " + getName() + " (number of buckets) must be positive number", ErrorCodes::BAD_ARGUMENTS); if (unlikely(static_cast(buckets) > Impl::max_buckets)) - throw Exception("The value of the second argument of function " + getName() + " (number of buckets) is not fit to " - + DataTypeNumber().getName(), - ErrorCodes::BAD_ARGUMENTS); + throw Exception("The value of the second argument of function " + getName() + " (number of buckets) must not be greater than " + + std::to_string(Impl::max_buckets), ErrorCodes::BAD_ARGUMENTS); return static_cast(buckets); } From 9cdbc6c663e1fd00c35a6be57d06969acb62e36f Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 3 Aug 2019 01:45:25 +0300 Subject: [PATCH 0667/1165] Added a test --- .../0_stateless/00979_yandex_consistent_hash_fpe.reference | 0 .../queries/0_stateless/00979_yandex_consistent_hash_fpe.sql | 1 + 2 files changed, 1 insertion(+) create mode 100644 dbms/tests/queries/0_stateless/00979_yandex_consistent_hash_fpe.reference create mode 100644 dbms/tests/queries/0_stateless/00979_yandex_consistent_hash_fpe.sql diff --git a/dbms/tests/queries/0_stateless/00979_yandex_consistent_hash_fpe.reference b/dbms/tests/queries/0_stateless/00979_yandex_consistent_hash_fpe.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dbms/tests/queries/0_stateless/00979_yandex_consistent_hash_fpe.sql b/dbms/tests/queries/0_stateless/00979_yandex_consistent_hash_fpe.sql new file mode 100644 index 00000000000..79fabeae7ef --- /dev/null +++ b/dbms/tests/queries/0_stateless/00979_yandex_consistent_hash_fpe.sql @@ -0,0 +1 @@ +SELECT yandexConsistentHash(-1, 40000); -- { serverError 36 } From da2bd59237a94f637276b5ef0ae51f227bd5af7d Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 3 Aug 2019 02:08:04 +0300 Subject: [PATCH 0668/1165] Updated test --- dbms/tests/queries/0_stateless/00978_ml_math.reference | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00978_ml_math.reference b/dbms/tests/queries/0_stateless/00978_ml_math.reference index 1d1b5df35cf..7eb09a2a379 100644 --- a/dbms/tests/queries/0_stateless/00978_ml_math.reference +++ b/dbms/tests/queries/0_stateless/00978_ml_math.reference @@ -1,3 +1,3 @@ -0.268941 0.268941 0.268941 -0.761595 -0.761595 -0.761595 +0.26894 0.26894 0.26894 -0.76159 -0.76159 -0.76159 0.5 0.5 0.5 0 0 0 -0.731059 0.731059 0.731059 0.761595 0.761595 0.761595 +0.73106 0.73106 0.73106 0.76159 0.76159 0.76159 From eb4edb80a58715ed1be1cbbe0fb07e5def952921 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 3 Aug 2019 02:12:42 +0300 Subject: [PATCH 0669/1165] Updated submodule --- contrib/fastops | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/fastops b/contrib/fastops index 3a7cd7a6271..b969b7aee07 160000 --- a/contrib/fastops +++ b/contrib/fastops @@ -1 +1 @@ -Subproject commit 3a7cd7a6271f011025441bea178e7729d155c36b +Subproject commit b969b7aee07651248da8b7367b8e4338be8bca2a From 11762f6eec04f0bcd57a6e83364631a7566d6ed7 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 3 Aug 2019 02:24:50 +0300 Subject: [PATCH 0670/1165] Updated SIMDJSON --- contrib/simdjson | 2 +- dbms/src/Functions/FunctionsJSON.h | 2 +- dbms/src/Functions/SimdJSONParser.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/simdjson b/contrib/simdjson index 3bd3116cf8f..44722bddcf8 160000 --- a/contrib/simdjson +++ b/contrib/simdjson @@ -1 +1 @@ -Subproject commit 3bd3116cf8faf6d482dc31423b16533bfa2696f7 +Subproject commit 44722bddcf89a146e4aa266b31fea2a6d722a03f diff --git a/dbms/src/Functions/FunctionsJSON.h b/dbms/src/Functions/FunctionsJSON.h index a1826b22d30..a0aad24d0b9 100644 --- a/dbms/src/Functions/FunctionsJSON.h +++ b/dbms/src/Functions/FunctionsJSON.h @@ -64,7 +64,7 @@ public: { /// Choose JSONParser. #if USE_SIMDJSON - if (context.getSettings().allow_simdjson && Cpu::CpuFlagsCache::have_AVX2) + if (context.getSettings().allow_simdjson && Cpu::CpuFlagsCache::have_SSE42 && Cpu::CpuFlagsCache::have_PCLMUL) { Executor::run(block, arguments, result_pos, input_rows_count); return; diff --git a/dbms/src/Functions/SimdJSONParser.h b/dbms/src/Functions/SimdJSONParser.h index dfa28ccfd56..a12119c5c6d 100644 --- a/dbms/src/Functions/SimdJSONParser.h +++ b/dbms/src/Functions/SimdJSONParser.h @@ -25,14 +25,14 @@ struct SimdJSONParser void preallocate(size_t max_size) { - if (!pj.allocateCapacity(max_size)) + if (!pj.allocate_capacity(max_size)) throw Exception{"Can not allocate memory for " + std::to_string(max_size) + " units when parsing JSON", ErrorCodes::CANNOT_ALLOCATE_MEMORY}; } bool parse(const StringRef & json) { return !json_parse(json.data, json.size, pj); } - using Iterator = simdjson::ParsedJson::iterator; + using Iterator = simdjson::ParsedJson::Iterator; Iterator getRoot() { return Iterator{pj}; } static bool isInt64(const Iterator & it) { return it.is_integer(); } From 61541a76e66b324475f5aa25400e78fc42a0b8be Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 3 Aug 2019 03:15:17 +0300 Subject: [PATCH 0671/1165] Update hyperscan; avoid hyperscan rebuilds --- contrib/hyperscan | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/hyperscan b/contrib/hyperscan index 01e6b83f9fb..3058c9c20cb 160000 --- a/contrib/hyperscan +++ b/contrib/hyperscan @@ -1 +1 @@ -Subproject commit 01e6b83f9fbdb4020cd68a5287bf3a0471eeb272 +Subproject commit 3058c9c20cba3accdf92544d8513a26240c4ff70 From 9f6e26f14d805c0b70308cb59a4bb61fabe79561 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 3 Aug 2019 04:10:13 +0300 Subject: [PATCH 0672/1165] Fixed tests --- dbms/src/Common/tests/gtest_thread_pool_global_full.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dbms/src/Common/tests/gtest_thread_pool_global_full.cpp b/dbms/src/Common/tests/gtest_thread_pool_global_full.cpp index 48858fa40ef..5ed84b93a3c 100644 --- a/dbms/src/Common/tests/gtest_thread_pool_global_full.cpp +++ b/dbms/src/Common/tests/gtest_thread_pool_global_full.cpp @@ -39,6 +39,10 @@ TEST(ThreadPool, GlobalFull1) pool.wait(); EXPECT_EQ(counter, num_jobs); + + global_pool.setMaxThreads(10000); + global_pool.setMaxFreeThreads(1000); + global_pool.setQueueSize(10000); } @@ -78,4 +82,8 @@ TEST(ThreadPool, GlobalFull2) another_pool.wait(); EXPECT_EQ(counter, capacity * 2 + 1); + + global_pool.setMaxThreads(10000); + global_pool.setMaxFreeThreads(1000); + global_pool.setQueueSize(10000); } From fe90d499a3bd81495ec747e7ab3a851dd61971f1 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Sat, 3 Aug 2019 05:53:34 +0300 Subject: [PATCH 0673/1165] Update index.html --- website/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/index.html b/website/index.html index 44c5549fccc..26090e5d857 100644 --- a/website/index.html +++ b/website/index.html @@ -416,7 +416,7 @@ clickhouse-client
    - Upcoming Meetups: Mountain View on August 13, Moscow on September 5, Shenzhen on October 20 and Shanghai on October 27 + Upcoming Meetups: Moscow on September 5, Hong Kong on October 17, Shenzhen on October 20 and Shanghai on October 27
    From 4b9ae60bd12ed7124ab52f9beac91d7e8627ab88 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 13 Aug 2019 14:25:37 +0300 Subject: [PATCH 0917/1165] Check bad URIs in Poco library --- contrib/poco | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/poco b/contrib/poco index 7a2d304c215..6216cc01a10 160000 --- a/contrib/poco +++ b/contrib/poco @@ -1 +1 @@ -Subproject commit 7a2d304c21549427460428c9039009ef4bbfd899 +Subproject commit 6216cc01a107ce149863411ca29013a224f80343 From 10a199185519a877ed816765348d90175c3162f1 Mon Sep 17 00:00:00 2001 From: chertus Date: Tue, 13 Aug 2019 15:39:03 +0300 Subject: [PATCH 0918/1165] move getAggregates() into SyntaxAnalyzer --- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 63 ++++++-------------- dbms/src/Interpreters/ExpressionAnalyzer.h | 5 +- dbms/src/Interpreters/GetAggregatesVisitor.h | 8 +-- dbms/src/Interpreters/SyntaxAnalyzer.cpp | 26 ++++++++ dbms/src/Interpreters/SyntaxAnalyzer.h | 3 + 5 files changed, 54 insertions(+), 51 deletions(-) diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index edd3b44943d..f47a5eb3022 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -116,9 +116,6 @@ void ExpressionAnalyzer::analyzeAggregation() auto * select_query = query->as(); - if (select_query && (select_query->groupBy() || select_query->having())) - has_aggregation = true; - ExpressionActionsPtr temp_actions = std::make_shared(sourceColumns(), context); if (select_query) @@ -150,7 +147,9 @@ void ExpressionAnalyzer::analyzeAggregation() } } - getAggregates(query, temp_actions); + has_aggregation = makeAggregateDescriptions(temp_actions); + if (select_query && (select_query->groupBy() || select_query->having())) + has_aggregation = true; if (has_aggregation) { @@ -347,29 +346,10 @@ void ExpressionAnalyzer::getActionsFromJoinKeys(const ASTTableJoin & table_join, actions = actions_visitor.popActionsLevel(); } -void ExpressionAnalyzer::getAggregates(const ASTPtr & ast, ExpressionActionsPtr & actions) +bool ExpressionAnalyzer::makeAggregateDescriptions(ExpressionActionsPtr & actions) { - const auto * select_query = query->as(); - - /// If we are not analyzing a SELECT query, but a separate expression, then there can not be aggregate functions in it. - if (!select_query) + for (const ASTFunction * node : aggregates()) { - assertNoAggregates(ast, "in wrong place"); - return; - } - - /// There can not be aggregate functions inside the WHERE and PREWHERE. - if (select_query->where()) - assertNoAggregates(select_query->where(), "in WHERE"); - if (select_query->prewhere()) - assertNoAggregates(select_query->prewhere(), "in PREWHERE"); - - GetAggregatesVisitor::Data data; - GetAggregatesVisitor(data).visit(ast); - - for (const ASTFunction * node : data.aggregates) - { - has_aggregation = true; AggregateDescription aggregate; aggregate.column_name = node->getColumnName(); @@ -379,9 +359,6 @@ void ExpressionAnalyzer::getAggregates(const ASTPtr & ast, ExpressionActionsPtr for (size_t i = 0; i < arguments.size(); ++i) { - /// There can not be other aggregate functions within the aggregate functions. - assertNoAggregates(arguments[i], "inside another aggregate function"); - getRootActions(arguments[i], true, actions); const std::string & name = arguments[i]->getColumnName(); types[i] = actions->getSampleBlock().getByName(name).type; @@ -393,6 +370,8 @@ void ExpressionAnalyzer::getAggregates(const ASTPtr & ast, ExpressionActionsPtr aggregate_descriptions.push_back(aggregate); } + + return !aggregates().empty(); } @@ -724,13 +703,22 @@ void ExpressionAnalyzer::appendAggregateFunctionsArguments(ExpressionActionsChai } } - getActionsBeforeAggregation(select_query->select(), step.actions, only_types); + /// Collect aggregates removing duplicates by node.getColumnName() + /// It's not clear why we recollect aggregates (for query parts) while we're able to use previously collected ones (for entire query) + /// @note The original recollection logic didn't remove duplicates. + GetAggregatesVisitor::Data data; + GetAggregatesVisitor(data).visit(select_query->select()); if (select_query->having()) - getActionsBeforeAggregation(select_query->having(), step.actions, only_types); + GetAggregatesVisitor(data).visit(select_query->having()); if (select_query->orderBy()) - getActionsBeforeAggregation(select_query->orderBy(), step.actions, only_types); + GetAggregatesVisitor(data).visit(select_query->orderBy()); + + /// TODO: data.aggregates -> aggregates() + for (const ASTFunction * node : data.aggregates) + for (auto & argument : node->arguments->children) + getRootActions(argument, only_types, step.actions); } bool ExpressionAnalyzer::appendHaving(ExpressionActionsChain & chain, bool only_types) @@ -858,19 +846,6 @@ void ExpressionAnalyzer::appendExpression(ExpressionActionsChain & chain, const } -void ExpressionAnalyzer::getActionsBeforeAggregation(const ASTPtr & ast, ExpressionActionsPtr & actions, bool no_subqueries) -{ - const auto * node = ast->as(); - - if (node && AggregateFunctionFactory::instance().isAggregateFunctionName(node->name)) - for (auto & argument : node->arguments->children) - getRootActions(argument, no_subqueries, actions); - else - for (auto & child : ast->children) - getActionsBeforeAggregation(child, actions, no_subqueries); -} - - ExpressionActionsPtr ExpressionAnalyzer::getActions(bool add_aliases, bool project_result) { ExpressionActionsPtr actions = std::make_shared(sourceColumns(), context); diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.h b/dbms/src/Interpreters/ExpressionAnalyzer.h index 0749c644aee..c21ec500b92 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.h +++ b/dbms/src/Interpreters/ExpressionAnalyzer.h @@ -178,6 +178,7 @@ private: const AnalyzedJoin & analyzedJoin() const { return syntax->analyzed_join; } const NamesAndTypesList & sourceColumns() const { return syntax->required_source_columns; } const NamesAndTypesList & columnsAddedByJoin() const { return syntax->columns_added_by_join; } + const std::vector & aggregates() const { return syntax->aggregates; } /// Find global subqueries in the GLOBAL IN/JOIN sections. Fills in external_tables. void initGlobalSubqueriesAndExternalTables(); @@ -191,15 +192,13 @@ private: void getRootActions(const ASTPtr & ast, bool no_subqueries, ExpressionActionsPtr & actions, bool only_consts = false); - void getActionsBeforeAggregation(const ASTPtr & ast, ExpressionActionsPtr & actions, bool no_subqueries); - /** Add aggregation keys to aggregation_keys, aggregate functions to aggregate_descriptions, * Create a set of columns aggregated_columns resulting after the aggregation, if any, * or after all the actions that are normally performed before aggregation. * Set has_aggregation = true if there is GROUP BY or at least one aggregate function. */ void analyzeAggregation(); - void getAggregates(const ASTPtr & ast, ExpressionActionsPtr & actions); + bool makeAggregateDescriptions(ExpressionActionsPtr & actions); /// columns - the columns that are present before the transformations begin. void initChain(ExpressionActionsChain & chain, const NamesAndTypesList & columns) const; diff --git a/dbms/src/Interpreters/GetAggregatesVisitor.h b/dbms/src/Interpreters/GetAggregatesVisitor.h index fbd0b111ad1..ba1501fc624 100644 --- a/dbms/src/Interpreters/GetAggregatesVisitor.h +++ b/dbms/src/Interpreters/GetAggregatesVisitor.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace DB { @@ -17,8 +18,7 @@ public: struct Data { - bool assert_no_aggregates = false; - const char * description = nullptr; + const char * assert_no_aggregates = nullptr; std::unordered_set uniq_names; std::vector aggregates; }; @@ -46,7 +46,7 @@ private: return; if (data.assert_no_aggregates) - throw Exception("Aggregate function " + node.getColumnName() + " is found " + String(data.description) + " in query", + throw Exception("Aggregate function " + node.getColumnName() + " is found " + String(data.assert_no_aggregates) + " in query", ErrorCodes::ILLEGAL_AGGREGATION); String column_name = node.getColumnName(); @@ -68,7 +68,7 @@ using GetAggregatesVisitor = GetAggregatesMatcher::Visitor; inline void assertNoAggregates(const ASTPtr & ast, const char * description) { - GetAggregatesVisitor::Data data{true, description, {}, {}}; + GetAggregatesVisitor::Data data{description, {}, {}}; GetAggregatesVisitor(data).visit(ast); } diff --git a/dbms/src/Interpreters/SyntaxAnalyzer.cpp b/dbms/src/Interpreters/SyntaxAnalyzer.cpp index 282b19991b1..77f259820a7 100644 --- a/dbms/src/Interpreters/SyntaxAnalyzer.cpp +++ b/dbms/src/Interpreters/SyntaxAnalyzer.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -558,6 +559,30 @@ void checkJoin(const ASTTablesInSelectQueryElement * join) ErrorCodes::NOT_IMPLEMENTED); } +std::vector getAggregates(const ASTPtr & query) +{ + if (const auto * select_query = query->as()) + { + /// There can not be aggregate functions inside the WHERE and PREWHERE. + if (select_query->where()) + assertNoAggregates(select_query->where(), "in WHERE"); + if (select_query->prewhere()) + assertNoAggregates(select_query->prewhere(), "in PREWHERE"); + + GetAggregatesVisitor::Data data; + GetAggregatesVisitor(data).visit(query); + + /// There can not be other aggregate functions within the aggregate functions. + for (const ASTFunction * node : data.aggregates) + for (auto & arg : node->arguments->children) + assertNoAggregates(arg, "inside another aggregate function"); + return data.aggregates; + } + else + assertNoAggregates(query, "in wrong place"); + return {}; +} + } /// Calculate which columns are required to execute the expression. @@ -840,6 +865,7 @@ SyntaxAnalyzerResultPtr SyntaxAnalyzer::analyze( collectJoinedColumns(result.analyzed_join, *select_query, source_columns_set, result.aliases, settings.join_use_nulls); } + result.aggregates = getAggregates(query); result.collectUsedColumns(query, additional_source_columns); return std::make_shared(result); } diff --git a/dbms/src/Interpreters/SyntaxAnalyzer.h b/dbms/src/Interpreters/SyntaxAnalyzer.h index c7addb03526..a31dfef7e82 100644 --- a/dbms/src/Interpreters/SyntaxAnalyzer.h +++ b/dbms/src/Interpreters/SyntaxAnalyzer.h @@ -10,6 +10,8 @@ namespace DB NameSet removeDuplicateColumns(NamesAndTypesList & columns); +class ASTFunction; + struct SyntaxAnalyzerResult { StoragePtr storage; @@ -22,6 +24,7 @@ struct SyntaxAnalyzerResult NamesAndTypesList columns_added_by_join; Aliases aliases; + std::vector aggregates; /// Which column is needed to be ARRAY-JOIN'ed to get the specified. /// For example, for `SELECT s.v ... ARRAY JOIN a AS s` will get "s.v" -> "a.v". From 87fbc2a5cb67c8cc760b267ace743d76e6f92151 Mon Sep 17 00:00:00 2001 From: chertus Date: Tue, 13 Aug 2019 16:48:09 +0300 Subject: [PATCH 0919/1165] minor improvements --- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 64 +++++++------------- dbms/src/Interpreters/ExpressionAnalyzer.h | 16 ++--- 2 files changed, 27 insertions(+), 53 deletions(-) diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index f47a5eb3022..edd26dd3bd1 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -78,16 +78,15 @@ ExpressionAnalyzer::ExpressionAnalyzer( const Context & context_, const NameSet & required_result_columns_, size_t subquery_depth_, - bool do_global_, - const SubqueriesForSets & subqueries_for_sets_) - : ExpressionAnalyzerData(required_result_columns_, subqueries_for_sets_) + bool do_global) + : ExpressionAnalyzerData(required_result_columns_) , query(query_), context(context_), settings(context.getSettings()) - , subquery_depth(subquery_depth_), do_global(do_global_) + , subquery_depth(subquery_depth_) , syntax(syntax_analyzer_result_) { /// external_tables, subqueries_for_sets for global subqueries. /// Replaces global subqueries with the generated names of temporary tables that will be sent to remote servers. - initGlobalSubqueriesAndExternalTables(); + initGlobalSubqueriesAndExternalTables(do_global); /// has_aggregation, aggregation_keys, aggregate_descriptions, aggregated_columns. /// This analysis should be performed after processing global subqueries, because otherwise, @@ -153,7 +152,7 @@ void ExpressionAnalyzer::analyzeAggregation() if (has_aggregation) { - assertSelect(); + getSelectQuery(); /// assertSelect() /// Find out aggregation keys. if (select_query->groupBy()) @@ -222,7 +221,7 @@ void ExpressionAnalyzer::analyzeAggregation() } -void ExpressionAnalyzer::initGlobalSubqueriesAndExternalTables() +void ExpressionAnalyzer::initGlobalSubqueriesAndExternalTables(bool do_global) { /// Adds existing external tables (not subqueries) to the external_tables dictionary. ExternalTablesVisitor::Data tables_data{context, external_tables}; @@ -375,18 +374,19 @@ bool ExpressionAnalyzer::makeAggregateDescriptions(ExpressionActionsPtr & action } -void ExpressionAnalyzer::assertSelect() const +const ASTSelectQuery * ExpressionAnalyzer::getSelectQuery() const { const auto * select_query = query->as(); - if (!select_query) throw Exception("Not a select query", ErrorCodes::LOGICAL_ERROR); + return select_query; } -void ExpressionAnalyzer::assertAggregation() const +const ASTSelectQuery * ExpressionAnalyzer::getAggregatingQuery() const { if (!has_aggregation) throw Exception("No aggregation", ErrorCodes::LOGICAL_ERROR); + return getSelectQuery(); } void ExpressionAnalyzer::initChain(ExpressionActionsChain & chain, const NamesAndTypesList & columns) const @@ -416,9 +416,7 @@ void ExpressionAnalyzer::addMultipleArrayJoinAction(ExpressionActionsPtr & actio bool ExpressionAnalyzer::appendArrayJoin(ExpressionActionsChain & chain, bool only_types) { - const auto * select_query = query->as(); - - assertSelect(); + const auto * select_query = getSelectQuery(); bool is_array_join_left; ASTPtr array_join_expression_list = select_query->array_join_expression_list(is_array_join_left); @@ -460,9 +458,7 @@ static void appendRequiredColumns( bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_types) { - const auto * select_query = query->as(); - - assertSelect(); + const auto * select_query = getSelectQuery(); if (!select_query->join()) return false; @@ -571,9 +567,7 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty bool ExpressionAnalyzer::appendPrewhere( ExpressionActionsChain & chain, bool only_types, const Names & additional_required_columns) { - const auto * select_query = query->as(); - - assertSelect(); + const auto * select_query = getSelectQuery(); if (!select_query->prewhere()) return false; @@ -646,9 +640,7 @@ bool ExpressionAnalyzer::appendPrewhere( bool ExpressionAnalyzer::appendWhere(ExpressionActionsChain & chain, bool only_types) { - const auto * select_query = query->as(); - - assertSelect(); + const auto * select_query = getSelectQuery(); if (!select_query->where()) return false; @@ -666,9 +658,7 @@ bool ExpressionAnalyzer::appendWhere(ExpressionActionsChain & chain, bool only_t bool ExpressionAnalyzer::appendGroupBy(ExpressionActionsChain & chain, bool only_types) { - const auto * select_query = query->as(); - - assertAggregation(); + const auto * select_query = getAggregatingQuery(); if (!select_query->groupBy()) return false; @@ -688,9 +678,7 @@ bool ExpressionAnalyzer::appendGroupBy(ExpressionActionsChain & chain, bool only void ExpressionAnalyzer::appendAggregateFunctionsArguments(ExpressionActionsChain & chain, bool only_types) { - const auto * select_query = query->as(); - - assertAggregation(); + const auto * select_query = getAggregatingQuery(); initChain(chain, sourceColumns()); ExpressionActionsChain::Step & step = chain.steps.back(); @@ -723,9 +711,7 @@ void ExpressionAnalyzer::appendAggregateFunctionsArguments(ExpressionActionsChai bool ExpressionAnalyzer::appendHaving(ExpressionActionsChain & chain, bool only_types) { - const auto * select_query = query->as(); - - assertAggregation(); + const auto * select_query = getAggregatingQuery(); if (!select_query->having()) return false; @@ -741,9 +727,7 @@ bool ExpressionAnalyzer::appendHaving(ExpressionActionsChain & chain, bool only_ void ExpressionAnalyzer::appendSelect(ExpressionActionsChain & chain, bool only_types) { - const auto * select_query = query->as(); - - assertSelect(); + const auto * select_query = getSelectQuery(); initChain(chain, aggregated_columns); ExpressionActionsChain::Step & step = chain.steps.back(); @@ -756,9 +740,7 @@ void ExpressionAnalyzer::appendSelect(ExpressionActionsChain & chain, bool only_ bool ExpressionAnalyzer::appendOrderBy(ExpressionActionsChain & chain, bool only_types) { - const auto * select_query = query->as(); - - assertSelect(); + const auto * select_query = getSelectQuery(); if (!select_query->orderBy()) return false; @@ -782,9 +764,7 @@ bool ExpressionAnalyzer::appendOrderBy(ExpressionActionsChain & chain, bool only bool ExpressionAnalyzer::appendLimitBy(ExpressionActionsChain & chain, bool only_types) { - const auto * select_query = query->as(); - - assertSelect(); + const auto * select_query = getSelectQuery(); if (!select_query->limitBy()) return false; @@ -813,9 +793,7 @@ bool ExpressionAnalyzer::appendLimitBy(ExpressionActionsChain & chain, bool only void ExpressionAnalyzer::appendProjectResult(ExpressionActionsChain & chain) const { - const auto * select_query = query->as(); - - assertSelect(); + const auto * select_query = getSelectQuery(); initChain(chain, aggregated_columns); ExpressionActionsChain::Step & step = chain.steps.back(); diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.h b/dbms/src/Interpreters/ExpressionAnalyzer.h index c21ec500b92..5a530add810 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.h +++ b/dbms/src/Interpreters/ExpressionAnalyzer.h @@ -51,10 +51,8 @@ struct ExpressionAnalyzerData Tables external_tables; protected: - ExpressionAnalyzerData(const NameSet & required_result_columns_, - const SubqueriesForSets & subqueries_for_sets_) - : required_result_columns(required_result_columns_), - subqueries_for_sets(subqueries_for_sets_) + ExpressionAnalyzerData(const NameSet & required_result_columns_) + : required_result_columns(required_result_columns_) {} }; @@ -91,8 +89,7 @@ public: const Context & context_, const NameSet & required_result_columns_ = {}, size_t subquery_depth_ = 0, - bool do_global_ = false, - const SubqueriesForSets & subqueries_for_set_ = {}); + bool do_global_ = false); /// Does the expression have aggregate functions or a GROUP BY or HAVING section. bool hasAggregation() const { return has_aggregation; } @@ -170,7 +167,6 @@ private: const Context & context; const ExtractedSettings settings; size_t subquery_depth; - bool do_global; /// Do I need to prepare for execution global subqueries when analyzing the query. SyntaxAnalyzerResultPtr syntax; @@ -181,7 +177,7 @@ private: const std::vector & aggregates() const { return syntax->aggregates; } /// Find global subqueries in the GLOBAL IN/JOIN sections. Fills in external_tables. - void initGlobalSubqueriesAndExternalTables(); + void initGlobalSubqueriesAndExternalTables(bool do_global); void addMultipleArrayJoinAction(ExpressionActionsPtr & actions, bool is_left) const; @@ -203,8 +199,8 @@ private: /// columns - the columns that are present before the transformations begin. void initChain(ExpressionActionsChain & chain, const NamesAndTypesList & columns) const; - void assertSelect() const; - void assertAggregation() const; + const ASTSelectQuery * getSelectQuery() const; + const ASTSelectQuery * getAggregatingQuery() const; /** * Create Set from a subquery or a table expression in the query. The created set is suitable for using the index. From 7ae73befd6de39ab58e5e362efb0bb0d62d02329 Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Tue, 13 Aug 2019 17:07:36 +0300 Subject: [PATCH 0920/1165] wait for finish calculations at underlying streams while cancelling AsynchronousBlockInputStream --- dbms/src/DataStreams/AsynchronousBlockInputStream.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dbms/src/DataStreams/AsynchronousBlockInputStream.h b/dbms/src/DataStreams/AsynchronousBlockInputStream.h index 6cfa247ab44..c741d8090e9 100644 --- a/dbms/src/DataStreams/AsynchronousBlockInputStream.h +++ b/dbms/src/DataStreams/AsynchronousBlockInputStream.h @@ -73,6 +73,18 @@ public: Block getHeader() const override { return children.at(0)->getHeader(); } + void cancel(bool kill) override + { + IBlockInputStream::cancel(kill); + + /// Wait for some backgroud calculations to be sure, + /// that after end of stream nothing is being executing. + if (started) + { + pool.wait(); + started = false; + } + } ~AsynchronousBlockInputStream() override { From 8b9284be241460626b0017cc2a7eb7f8eb273281 Mon Sep 17 00:00:00 2001 From: Ivan <5627721+abyss7@users.noreply.github.com> Date: Tue, 13 Aug 2019 17:08:28 +0300 Subject: [PATCH 0921/1165] Fix shared build (#6453) * Fix shared build * Enable no-undefined check only in CI --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d369dca7e78..8466fa5d33d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -264,7 +264,9 @@ if (USE_STATIC_LIBRARIES AND HAVE_NO_PIE) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAG_NO_PIE}") endif () -if (NOT SANITIZE AND NOT SPLIT_SHARED_LIBRARIES) +# TODO: only make this extra-checks in CI builds, since a lot of contrib libs won't link - +# CI works around this problem by explicitly adding GLIBC_COMPATIBILITY flag. +if (NOT SANITIZE AND YANDEX_OFFICIAL_BUILD) set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined") set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") endif () @@ -328,7 +330,7 @@ if (OS_LINUX AND NOT UNBUNDLED AND (GLIBC_COMPATIBILITY OR USE_INTERNAL_UNWIND_L if (USE_INTERNAL_LIBCXX_LIBRARY) set (LIBCXX_LIBS "${ClickHouse_BINARY_DIR}/contrib/libcxx-cmake/libcxx_static${${CMAKE_POSTFIX_VARIABLE}}.a ${ClickHouse_BINARY_DIR}/contrib/libcxxabi-cmake/libcxxabi_static${${CMAKE_POSTFIX_VARIABLE}}.a") else () - set (LIBCXX_LIBS "-lc++ -lc++abi") + set (LIBCXX_LIBS "-lc++ -lc++abi -lc++fs") endif () set (DEFAULT_LIBS "${DEFAULT_LIBS} -Wl,-Bstatic ${LIBCXX_LIBS} ${EXCEPTION_HANDLING_LIBRARY} ${BUILTINS_LIB_PATH} -Wl,-Bdynamic") From a9681fa34629d34c7e53a900e9e05ca2c8c29ce0 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Tue, 13 Aug 2019 17:31:19 +0300 Subject: [PATCH 0922/1165] Fixed ZH docs build. --- docs/zh/data_types/{domain => domains}/ipv4.md | 0 docs/zh/data_types/{domain => domains}/ipv6.md | 0 docs/zh/data_types/{domain => domains}/overview.md | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename docs/zh/data_types/{domain => domains}/ipv4.md (100%) rename docs/zh/data_types/{domain => domains}/ipv6.md (100%) rename docs/zh/data_types/{domain => domains}/overview.md (100%) diff --git a/docs/zh/data_types/domain/ipv4.md b/docs/zh/data_types/domains/ipv4.md similarity index 100% rename from docs/zh/data_types/domain/ipv4.md rename to docs/zh/data_types/domains/ipv4.md diff --git a/docs/zh/data_types/domain/ipv6.md b/docs/zh/data_types/domains/ipv6.md similarity index 100% rename from docs/zh/data_types/domain/ipv6.md rename to docs/zh/data_types/domains/ipv6.md diff --git a/docs/zh/data_types/domain/overview.md b/docs/zh/data_types/domains/overview.md similarity index 100% rename from docs/zh/data_types/domain/overview.md rename to docs/zh/data_types/domains/overview.md From bbe20b3f9f083fa04979294c6025796891614eb3 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Tue, 13 Aug 2019 17:31:46 +0300 Subject: [PATCH 0923/1165] done --- dbms/src/Interpreters/Context.cpp | 17 +++-- dbms/src/Interpreters/Context.h | 2 + .../Interpreters/InterpreterSystemQuery.cpp | 4 +- dbms/src/Interpreters/MetricLog.cpp | 68 +++++++++++++++++++ dbms/src/Interpreters/MetricLog.h | 23 +++++++ dbms/src/Interpreters/SystemLog.cpp | 39 +++++++++++ dbms/src/Interpreters/SystemLog.h | 10 ++- .../MergeTreeSequentialBlockInputStream.cpp | 4 +- docker/test/stateful/Dockerfile | 1 + docker/test/stateful_with_coverage/run.sh | 1 + docker/test/stateless/Dockerfile | 1 + docker/test/stateless_with_coverage/run.sh | 1 + 12 files changed, 162 insertions(+), 9 deletions(-) create mode 100644 dbms/src/Interpreters/MetricLog.cpp create mode 100644 dbms/src/Interpreters/MetricLog.h diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index 83f3763bb11..ea78df25485 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -38,10 +38,6 @@ #include #include #include -#include -#include -#include -#include #include #include #include @@ -1701,6 +1697,7 @@ std::shared_ptr Context::getPartLog(const String & part_database) return shared->system_logs->part_log; } + std::shared_ptr Context::getTraceLog() { auto lock = getLock(); @@ -1711,6 +1708,7 @@ std::shared_ptr Context::getTraceLog() return shared->system_logs->trace_log; } + std::shared_ptr Context::getTextLog() { auto lock = getLock(); @@ -1722,6 +1720,17 @@ std::shared_ptr Context::getTextLog() } +std::shared_ptr Context::getMetricLog() +{ + auto lock = getLock(); + + if (!shared->system_logs || !shared->system_logs->metric_log) + return {}; + + return shared->system_logs->metric_log; +} + + CompressionCodecPtr Context::chooseCompressionCodec(size_t part_size, double part_size_ratio) const { auto lock = getLock(); diff --git a/dbms/src/Interpreters/Context.h b/dbms/src/Interpreters/Context.h index 50b7ab3eba2..2ef123b74b1 100644 --- a/dbms/src/Interpreters/Context.h +++ b/dbms/src/Interpreters/Context.h @@ -64,6 +64,7 @@ class QueryThreadLog; class PartLog; class TextLog; class TraceLog; +class MetricLog; struct MergeTreeSettings; class IDatabase; class DDLGuard; @@ -434,6 +435,7 @@ public: std::shared_ptr getQueryThreadLog(); std::shared_ptr getTraceLog(); std::shared_ptr getTextLog(); + std::shared_ptr getMetricLog(); /// Returns an object used to log opertaions with parts if it possible. /// Provide table name to make required cheks. diff --git a/dbms/src/Interpreters/InterpreterSystemQuery.cpp b/dbms/src/Interpreters/InterpreterSystemQuery.cpp index 818aae6d048..0797a3deab4 100644 --- a/dbms/src/Interpreters/InterpreterSystemQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSystemQuery.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -232,7 +233,8 @@ BlockIO InterpreterSystemQuery::execute() [&] () { if (auto part_log = context.getPartLog("")) part_log->flush(); }, [&] () { if (auto query_thread_log = context.getQueryThreadLog()) query_thread_log->flush(); }, [&] () { if (auto trace_log = context.getTraceLog()) trace_log->flush(); }, - [&] () { if (auto text_log = context.getTextLog()) text_log->flush(); } + [&] () { if (auto text_log = context.getTextLog()) text_log->flush(); }, + [&] () { if (auto metric_log = context.getMetricLog()) metric_log->flush(); } ); break; case Type::STOP_LISTEN_QUERIES: diff --git a/dbms/src/Interpreters/MetricLog.cpp b/dbms/src/Interpreters/MetricLog.cpp new file mode 100644 index 00000000000..69d9425b17e --- /dev/null +++ b/dbms/src/Interpreters/MetricLog.cpp @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include + +namespace DB +{ + +Block MetricLogElement::createBlock() +{ + ColumnsWithTypeAndName columns_with_type_and_name; + + columns_with_type_and_name.emplace_back(std::make_shared(), "event_date"); + columns_with_type_and_name.emplace_back(std::make_shared(), "event_time"); + + //ProfileEvents + for (size_t i = 0, end = ProfileEvents::end(); i < end; ++i) + { + std::string name; + name += "ProfileEvent_"; + name += ProfileEvents::getName(ProfileEvents::Event(i)); + columns_with_type_and_name.emplace_back(std::make_shared(), name); + } + + //CurrentMetrics + for (size_t i = 0, end = CurrentMetrics::end(); i < end; ++i) + { + + std::string name; + name += "CurrentMetric_"; + name += CurrentMetrics::getName(ProfileEvents::Event(i)); + columns_with_type_and_name.emplace_back(std::make_shared(), name); + + } + + return Block(columns_with_type_and_name); +} + +void MetricLogElement::appendToBlock(Block & block) const +{ + MutableColumns columns = block.mutateColumns(); + + size_t iter = 0; + + columns[iter++]->insert(DateLUT::instance().toDayNum(event_time)); + columns[iter++]->insert(event_time); + + //ProfileEvents + for (size_t i = 0, end = ProfileEvents::end(); i < end; ++i) + { + UInt64 value = ProfileEvents::global_counters[i]; + + columns[iter++]->insert(value); + + } + + //CurrentMetrics + for (size_t i = 0, end = CurrentMetrics::end(); i < end; ++i) + { + UInt64 value = CurrentMetrics::values[i]; + + columns[iter++]->insert(value); + + } +} + +} diff --git a/dbms/src/Interpreters/MetricLog.h b/dbms/src/Interpreters/MetricLog.h new file mode 100644 index 00000000000..13112d4934e --- /dev/null +++ b/dbms/src/Interpreters/MetricLog.h @@ -0,0 +1,23 @@ +#pragma once +#include +#include + +namespace DB +{ + +using Poco::Message; + +struct MetricLogElement +{ + time_t event_time{}; + static std::string name() { return "MetricLog"; } + static Block createBlock(); + void appendToBlock(Block & block) const; +}; + +class MetricLog : public SystemLog +{ + using SystemLog::SystemLog; +}; + +} diff --git a/dbms/src/Interpreters/SystemLog.cpp b/dbms/src/Interpreters/SystemLog.cpp index f1f65dfe883..6e63951d9ec 100644 --- a/dbms/src/Interpreters/SystemLog.cpp +++ b/dbms/src/Interpreters/SystemLog.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -48,7 +49,10 @@ SystemLogs::SystemLogs(Context & global_context, const Poco::Util::AbstractConfi part_log = createSystemLog(global_context, "system", "part_log", config, "part_log"); trace_log = createSystemLog(global_context, "system", "trace_log", config, "trace_log"); text_log = createSystemLog(global_context, "system", "text_log", config, "text_log"); + metric_log = createSystemLog(global_context, "system", "metric_log", config, "metric_log"); + if (metric_log) + metric_flush_thread = ThreadFromGlobalPool([this] { metricThreadFunction(); }); part_log_database = config.getString("part_log.database", "system"); } @@ -70,6 +74,41 @@ void SystemLogs::shutdown() trace_log->shutdown(); if (text_log) text_log->shutdown(); + if (metric_log) + { + bool old_val = false; + if (!is_shutdown_metric_thread.compare_exchange_strong(old_val, true)) + return; + metric_flush_thread.join(); + metric_log->shutdown(); + } +} + +void SystemLogs::metricThreadFunction() +{ + const size_t flush_interval_milliseconds = 1000; + while (true) + { + try + { + const auto prev_timepoint = std::chrono::system_clock::now(); + + if (is_shutdown_metric_thread) + break; + + MetricLogElement elem; + elem.event_time = std::time(nullptr); + metric_log->add(elem); + + const auto next_timepoint = prev_timepoint + std::chrono::milliseconds(flush_interval_milliseconds); + std::this_thread::sleep_until(next_timepoint); + } + catch (...) + { + tryLogCurrentException(__PRETTY_FUNCTION__); + } + + } } } diff --git a/dbms/src/Interpreters/SystemLog.h b/dbms/src/Interpreters/SystemLog.h index 3dd329d577b..545519aeb9d 100644 --- a/dbms/src/Interpreters/SystemLog.h +++ b/dbms/src/Interpreters/SystemLog.h @@ -61,6 +61,7 @@ class QueryThreadLog; class PartLog; class TextLog; class TraceLog; +class MetricLog; /// System logs should be destroyed in destructor of the last Context and before tables, /// because SystemLog destruction makes insert query while flushing data into underlying tables @@ -76,6 +77,11 @@ struct SystemLogs std::shared_ptr part_log; /// Used to log operations with parts std::shared_ptr trace_log; /// Used to log traces from query profiler std::shared_ptr text_log; /// Used to log all text messages. + std::shared_ptr metric_log; /// Used to log all metrics. + + ThreadFromGlobalPool metric_flush_thread; + void metricThreadFunction(); + std::atomic is_shutdown_metric_thread{false}; String part_log_database; }; @@ -115,6 +121,8 @@ public: /// Stop the background flush thread before destructor. No more data will be written. void shutdown(); + size_t getFlushInterval() { return flush_interval_milliseconds; } + protected: Context & context; const String database_name; @@ -179,7 +187,7 @@ SystemLog::SystemLog(Context & context_, flush_interval_milliseconds(flush_interval_milliseconds_) { log = &Logger::get("SystemLog (" + database_name + "." + table_name + ")"); - +qq data.reserve(DBMS_SYSTEM_LOG_QUEUE_SIZE); saving_thread = ThreadFromGlobalPool([this] { threadFunction(); }); } diff --git a/dbms/src/Storages/MergeTree/MergeTreeSequentialBlockInputStream.cpp b/dbms/src/Storages/MergeTree/MergeTreeSequentialBlockInputStream.cpp index 1c9c3457fe5..74cff479e5f 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeSequentialBlockInputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeSequentialBlockInputStream.cpp @@ -27,9 +27,7 @@ MergeTreeSequentialBlockInputStream::MergeTreeSequentialBlockInputStream( std::stringstream message; message << "Reading " << data_part->getMarksCount() << " marks from part " << data_part->name << ", total " << data_part->rows_count - << " rows starting from the beginning of the part, columns: "; - for (size_t i = 0, size = columns_to_read.size(); i < size; ++i) - message << (i == 0 ? "" : ", ") << columns_to_read[i]; + << " rows starting from the beginning of the part"; LOG_TRACE(log, message.rdbuf()); } diff --git a/docker/test/stateful/Dockerfile b/docker/test/stateful/Dockerfile index 516d63fa330..cab4ebbe8bb 100644 --- a/docker/test/stateful/Dockerfile +++ b/docker/test/stateful/Dockerfile @@ -20,6 +20,7 @@ CMD dpkg -i package_folder/clickhouse-common-static_*.deb; \ ln -s /usr/share/clickhouse-test/config/listen.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/part_log.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/text_log.xml /etc/clickhouse-server/config.d/; \ + ln -s /usr/share/clickhouse-test/config/metric_log.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/log_queries.xml /etc/clickhouse-server/users.d/; \ ln -s /usr/share/clickhouse-test/config/readonly.xml /etc/clickhouse-server/users.d/; \ ln -s /usr/share/clickhouse-test/config/ints_dictionary.xml /etc/clickhouse-server/; \ diff --git a/docker/test/stateful_with_coverage/run.sh b/docker/test/stateful_with_coverage/run.sh index 6253a07c745..a6d2ba0e9e8 100755 --- a/docker/test/stateful_with_coverage/run.sh +++ b/docker/test/stateful_with_coverage/run.sh @@ -46,6 +46,7 @@ ln -s /usr/share/clickhouse-test/config/zookeeper.xml /etc/clickhouse-server/con ln -s /usr/share/clickhouse-test/config/listen.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/part_log.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/text_log.xml /etc/clickhouse-server/config.d/; \ + ln -s /usr/share/clickhouse-test/config/metric_log.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/log_queries.xml /etc/clickhouse-server/users.d/; \ ln -s /usr/share/clickhouse-test/config/readonly.xml /etc/clickhouse-server/users.d/; \ ln -s /usr/share/clickhouse-test/config/ints_dictionary.xml /etc/clickhouse-server/; \ diff --git a/docker/test/stateless/Dockerfile b/docker/test/stateless/Dockerfile index eea48c3c032..60ab18cd5f2 100644 --- a/docker/test/stateless/Dockerfile +++ b/docker/test/stateless/Dockerfile @@ -40,6 +40,7 @@ CMD dpkg -i package_folder/clickhouse-common-static_*.deb; \ ln -s /usr/share/clickhouse-test/config/listen.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/part_log.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/text_log.xml /etc/clickhouse-server/config.d/; \ + ln -s /usr/share/clickhouse-test/config/metric_log.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/query_masking_rules.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/log_queries.xml /etc/clickhouse-server/users.d/; \ ln -s /usr/share/clickhouse-test/config/readonly.xml /etc/clickhouse-server/users.d/; \ diff --git a/docker/test/stateless_with_coverage/run.sh b/docker/test/stateless_with_coverage/run.sh index 5d63f9f49d0..ccf3e53f715 100755 --- a/docker/test/stateless_with_coverage/run.sh +++ b/docker/test/stateless_with_coverage/run.sh @@ -48,6 +48,7 @@ ln -s /usr/share/clickhouse-test/config/zookeeper.xml /etc/clickhouse-server/con ln -s /usr/share/clickhouse-test/config/listen.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/part_log.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/text_log.xml /etc/clickhouse-server/config.d/; \ + ln -s /usr/share/clickhouse-test/config/metric_log.xml /etc/clickhouse-server/config.d/; \ ln -s /usr/share/clickhouse-test/config/log_queries.xml /etc/clickhouse-server/users.d/; \ ln -s /usr/share/clickhouse-test/config/readonly.xml /etc/clickhouse-server/users.d/; \ ln -s /usr/share/clickhouse-test/config/ints_dictionary.xml /etc/clickhouse-server/; \ From 875d7aef8b690711a121799fd7eeaba634da5006 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Tue, 13 Aug 2019 17:32:32 +0300 Subject: [PATCH 0924/1165] better --- dbms/src/Interpreters/SystemLog.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Interpreters/SystemLog.h b/dbms/src/Interpreters/SystemLog.h index 545519aeb9d..da340fab5d5 100644 --- a/dbms/src/Interpreters/SystemLog.h +++ b/dbms/src/Interpreters/SystemLog.h @@ -187,7 +187,7 @@ SystemLog::SystemLog(Context & context_, flush_interval_milliseconds(flush_interval_milliseconds_) { log = &Logger::get("SystemLog (" + database_name + "." + table_name + ")"); -qq + data.reserve(DBMS_SYSTEM_LOG_QUEUE_SIZE); saving_thread = ThreadFromGlobalPool([this] { threadFunction(); }); } From c69684e807277d2e172ca6cd5512346fea4bce7a Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Tue, 13 Aug 2019 17:40:19 +0300 Subject: [PATCH 0925/1165] better --- contrib/arrow | 2 +- contrib/simdjson | 2 +- contrib/snappy | 2 +- contrib/thrift | 2 +- dbms/src/Interpreters/MetricLog.cpp | 9 +++------ dbms/src/Interpreters/SystemLog.cpp | 8 ++++++++ 6 files changed, 15 insertions(+), 10 deletions(-) diff --git a/contrib/arrow b/contrib/arrow index 87ac6fddaf2..93688e8c1fa 160000 --- a/contrib/arrow +++ b/contrib/arrow @@ -1 +1 @@ -Subproject commit 87ac6fddaf21d0b4ee8b8090533ff293db0da1b4 +Subproject commit 93688e8c1fa2f22d46394c548a9edbd3d2d7c62d diff --git a/contrib/simdjson b/contrib/simdjson index e3f6322af76..3fb82502f7f 160000 --- a/contrib/simdjson +++ b/contrib/simdjson @@ -1 +1 @@ -Subproject commit e3f6322af762213ff2087ce3366bf9541c7fd355 +Subproject commit 3fb82502f7f19a098006e7ff74c9b6e7c7dd4a84 diff --git a/contrib/snappy b/contrib/snappy index 3f194acb57e..156cd8939c5 160000 --- a/contrib/snappy +++ b/contrib/snappy @@ -1 +1 @@ -Subproject commit 3f194acb57e0487531c96b97af61dcbd025a78a3 +Subproject commit 156cd8939c5fba7fa68ae08db843377ecc07b4b5 diff --git a/contrib/thrift b/contrib/thrift index 010ccf0a0c7..74d6d9d3d64 160000 --- a/contrib/thrift +++ b/contrib/thrift @@ -1 +1 @@ -Subproject commit 010ccf0a0c7023fea0f6bf4e4078ebdff7e61982 +Subproject commit 74d6d9d3d6400d1672f48b4acf5bc7d1260ad96d diff --git a/dbms/src/Interpreters/MetricLog.cpp b/dbms/src/Interpreters/MetricLog.cpp index 69d9425b17e..52775ecb8ea 100644 --- a/dbms/src/Interpreters/MetricLog.cpp +++ b/dbms/src/Interpreters/MetricLog.cpp @@ -1,8 +1,11 @@ #include #include #include +<<<<<<< HEAD #include #include +======= +>>>>>>> 46a5ec5c16ed274956cc2051d0d2da213d975051 namespace DB { @@ -26,12 +29,10 @@ Block MetricLogElement::createBlock() //CurrentMetrics for (size_t i = 0, end = CurrentMetrics::end(); i < end; ++i) { - std::string name; name += "CurrentMetric_"; name += CurrentMetrics::getName(ProfileEvents::Event(i)); columns_with_type_and_name.emplace_back(std::make_shared(), name); - } return Block(columns_with_type_and_name); @@ -50,18 +51,14 @@ void MetricLogElement::appendToBlock(Block & block) const for (size_t i = 0, end = ProfileEvents::end(); i < end; ++i) { UInt64 value = ProfileEvents::global_counters[i]; - columns[iter++]->insert(value); - } //CurrentMetrics for (size_t i = 0, end = CurrentMetrics::end(); i < end; ++i) { UInt64 value = CurrentMetrics::values[i]; - columns[iter++]->insert(value); - } } diff --git a/dbms/src/Interpreters/SystemLog.cpp b/dbms/src/Interpreters/SystemLog.cpp index 6e63951d9ec..f59af169a4a 100644 --- a/dbms/src/Interpreters/SystemLog.cpp +++ b/dbms/src/Interpreters/SystemLog.cpp @@ -109,6 +109,14 @@ void SystemLogs::metricThreadFunction() } } +======= + metric_log->shutdown(); +} + +void SystemLogs::threadFunction() +{ + +>>>>>>> 46a5ec5c16ed274956cc2051d0d2da213d975051 } } From e9fcccff5997d996421649475654a46cf216c8ad Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Tue, 13 Aug 2019 17:47:19 +0300 Subject: [PATCH 0926/1165] conflict resolved --- dbms/src/Interpreters/MetricLog.cpp | 3 --- dbms/src/Interpreters/MetricLog.h | 1 + dbms/src/Interpreters/SystemLog.cpp | 9 --------- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/dbms/src/Interpreters/MetricLog.cpp b/dbms/src/Interpreters/MetricLog.cpp index 52775ecb8ea..5c526d002d6 100644 --- a/dbms/src/Interpreters/MetricLog.cpp +++ b/dbms/src/Interpreters/MetricLog.cpp @@ -1,11 +1,8 @@ #include #include #include -<<<<<<< HEAD #include #include -======= ->>>>>>> 46a5ec5c16ed274956cc2051d0d2da213d975051 namespace DB { diff --git a/dbms/src/Interpreters/MetricLog.h b/dbms/src/Interpreters/MetricLog.h index 13112d4934e..ce435b9e3cf 100644 --- a/dbms/src/Interpreters/MetricLog.h +++ b/dbms/src/Interpreters/MetricLog.h @@ -10,6 +10,7 @@ using Poco::Message; struct MetricLogElement { time_t event_time{}; + static std::string name() { return "MetricLog"; } static Block createBlock(); void appendToBlock(Block & block) const; diff --git a/dbms/src/Interpreters/SystemLog.cpp b/dbms/src/Interpreters/SystemLog.cpp index f59af169a4a..bd8a20daff1 100644 --- a/dbms/src/Interpreters/SystemLog.cpp +++ b/dbms/src/Interpreters/SystemLog.cpp @@ -109,14 +109,5 @@ void SystemLogs::metricThreadFunction() } } -======= - metric_log->shutdown(); -} - -void SystemLogs::threadFunction() -{ - ->>>>>>> 46a5ec5c16ed274956cc2051d0d2da213d975051 -} } From c8970ea6d5a298cbc3e5fb8ee149f69cbc7bfb29 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Tue, 13 Aug 2019 17:52:35 +0300 Subject: [PATCH 0927/1165] nothing --- dbms/src/Interpreters/SystemLog.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/dbms/src/Interpreters/SystemLog.cpp b/dbms/src/Interpreters/SystemLog.cpp index bd8a20daff1..8df20c4c8b5 100644 --- a/dbms/src/Interpreters/SystemLog.cpp +++ b/dbms/src/Interpreters/SystemLog.cpp @@ -38,7 +38,6 @@ std::shared_ptr createSystemLog( return std::make_shared(context, database, table, engine, flush_interval_milliseconds); } - } From 9632c4102a78d9f53749938134acf2f97fbe24f2 Mon Sep 17 00:00:00 2001 From: Vitaly Baranov Date: Tue, 13 Aug 2019 18:26:31 +0300 Subject: [PATCH 0928/1165] Change test to pass the exceeding of memory limit in ParsedJson::Iterator::Iterator when UBSan is used. --- dbms/src/Functions/FunctionsJSON.h | 2 +- dbms/tests/queries/0_stateless/00975_json_hang.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Functions/FunctionsJSON.h b/dbms/src/Functions/FunctionsJSON.h index a0aad24d0b9..0d229f8e2f3 100644 --- a/dbms/src/Functions/FunctionsJSON.h +++ b/dbms/src/Functions/FunctionsJSON.h @@ -7,6 +7,7 @@ #include "config_functions.h" #include #include +#include #include #include #include @@ -15,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/dbms/tests/queries/0_stateless/00975_json_hang.sql b/dbms/tests/queries/0_stateless/00975_json_hang.sql index d60411cb796..0618b4ba8f7 100644 --- a/dbms/tests/queries/0_stateless/00975_json_hang.sql +++ b/dbms/tests/queries/0_stateless/00975_json_hang.sql @@ -1 +1 @@ -SELECT DISTINCT JSONExtractRaw(concat('{"x":', rand() % 2 ? 'true' : 'false', '}'), 'x') AS res FROM numbers(1000000) ORDER BY res; +SELECT DISTINCT JSONExtractRaw(concat('{"x":', rand() % 2 ? 'true' : 'false', '}'), 'x') AS res FROM numbers(100000) ORDER BY res; From e227611f0133cbadbc6999f5e51b35a83d19dcf6 Mon Sep 17 00:00:00 2001 From: Alexandr Krasheninnikov Date: Tue, 13 Aug 2019 19:05:13 +0300 Subject: [PATCH 0929/1165] New function currentUser() implemented --- dbms/src/Functions/currentUser.cpp | 54 +++++++++++++++++++ .../registerFunctionsMiscellaneous.cpp | 2 + .../00990_function_current_user.reference | 3 ++ .../00990_function_current_user.sql | 4 ++ 4 files changed, 63 insertions(+) create mode 100644 dbms/src/Functions/currentUser.cpp create mode 100644 dbms/tests/queries/0_stateless/00990_function_current_user.reference create mode 100644 dbms/tests/queries/0_stateless/00990_function_current_user.sql diff --git a/dbms/src/Functions/currentUser.cpp b/dbms/src/Functions/currentUser.cpp new file mode 100644 index 00000000000..ee7c4d589a0 --- /dev/null +++ b/dbms/src/Functions/currentUser.cpp @@ -0,0 +1,54 @@ +#include +#include +#include +#include + + +namespace DB +{ + +class FunctionCurrentUser : public IFunction +{ + const String user_name; + +public: + static constexpr auto name = "currentUser"; + static FunctionPtr create(const Context & context) + { + return std::make_shared(context.getClientInfo().current_user); + } + + explicit FunctionCurrentUser(const String & user_name_) : user_name{user_name_} + { + } + + String getName() const override + { + return name; + } + size_t getNumberOfArguments() const override + { + return 0; + } + + DataTypePtr getReturnTypeImpl(const DataTypes & /*arguments*/) const override + { + return std::make_shared(); + } + + bool isDeterministic() const override { return false; } + + void executeImpl(Block & block, const ColumnNumbers &, size_t result, size_t input_rows_count) override + { + block.getByPosition(result).column = DataTypeString().createColumnConst(input_rows_count, user_name); + } +}; + + +void registerFunctionCurrentUser(FunctionFactory & factory) +{ + factory.registerFunction(); + factory.registerAlias("user", FunctionCurrentUser::name, FunctionFactory::CaseSensitive); +} + +} diff --git a/dbms/src/Functions/registerFunctionsMiscellaneous.cpp b/dbms/src/Functions/registerFunctionsMiscellaneous.cpp index 6d201d65bd3..5c86587cb84 100644 --- a/dbms/src/Functions/registerFunctionsMiscellaneous.cpp +++ b/dbms/src/Functions/registerFunctionsMiscellaneous.cpp @@ -6,6 +6,7 @@ namespace DB class FunctionFactory; void registerFunctionCurrentDatabase(FunctionFactory &); +void registerFunctionCurrentUser(FunctionFactory &); void registerFunctionHostName(FunctionFactory &); void registerFunctionVisibleWidth(FunctionFactory &); void registerFunctionToTypeName(FunctionFactory &); @@ -56,6 +57,7 @@ void registerFunctionConvertCharset(FunctionFactory &); void registerFunctionsMiscellaneous(FunctionFactory & factory) { registerFunctionCurrentDatabase(factory); + registerFunctionCurrentUser(factory); registerFunctionHostName(factory); registerFunctionVisibleWidth(factory); registerFunctionToTypeName(factory); diff --git a/dbms/tests/queries/0_stateless/00990_function_current_user.reference b/dbms/tests/queries/0_stateless/00990_function_current_user.reference new file mode 100644 index 00000000000..e8183f05f5d --- /dev/null +++ b/dbms/tests/queries/0_stateless/00990_function_current_user.reference @@ -0,0 +1,3 @@ +1 +1 +1 diff --git a/dbms/tests/queries/0_stateless/00990_function_current_user.sql b/dbms/tests/queries/0_stateless/00990_function_current_user.sql new file mode 100644 index 00000000000..c925dfd8e47 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00990_function_current_user.sql @@ -0,0 +1,4 @@ +-- since actual user name is unknown, have to perform just smoke tests +select currentUser() IS NOT NULL; +select length(currentUser()) > 0; +select currentUser() = user(); \ No newline at end of file From 4d145cb72be73617b9ebb17365863ba6b4defd9d Mon Sep 17 00:00:00 2001 From: Alexandr Krasheninnikov Date: Tue, 13 Aug 2019 19:08:12 +0300 Subject: [PATCH 0930/1165] Documentation added --- docs/en/query_language/functions/other_functions.md | 3 +++ docs/ru/query_language/functions/other_functions.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/docs/en/query_language/functions/other_functions.md b/docs/en/query_language/functions/other_functions.md index 57fa8acfee3..05961caadc8 100644 --- a/docs/en/query_language/functions/other_functions.md +++ b/docs/en/query_language/functions/other_functions.md @@ -102,6 +102,9 @@ Sleeps 'seconds' seconds on each row. You can specify an integer or a floating-p Returns the name of the current database. You can use this function in table engine parameters in a CREATE TABLE query where you need to specify the database. +## currentUser() +Returns the login of authorized user. + ## isFinite(x) Accepts Float32 and Float64 and returns UInt8 equal to 1 if the argument is not infinite and not a NaN, otherwise 0. diff --git a/docs/ru/query_language/functions/other_functions.md b/docs/ru/query_language/functions/other_functions.md index 1637c7bda93..dd4264e411f 100644 --- a/docs/ru/query_language/functions/other_functions.md +++ b/docs/ru/query_language/functions/other_functions.md @@ -97,6 +97,9 @@ SELECT visibleWidth(NULL) Возвращает имя текущей базы данных. Эта функция может использоваться в параметрах движка таблицы в запросе CREATE TABLE там, где нужно указать базу данных. +## currentUser() +Возвращает логин пользователя, от имени которого исполняется запрос. + ## isFinite(x) Принимает Float32 или Float64 и возвращает UInt8, равный 1, если аргумент не бесконечный и не NaN, иначе 0. From aab140ceff49bccbc3808ccb78f9f042bd646449 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Tue, 13 Aug 2019 19:13:08 +0300 Subject: [PATCH 0931/1165] submodules --- contrib/arrow | 2 +- contrib/simdjson | 2 +- contrib/snappy | 2 +- contrib/thrift | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/arrow b/contrib/arrow index 93688e8c1fa..87ac6fddaf2 160000 --- a/contrib/arrow +++ b/contrib/arrow @@ -1 +1 @@ -Subproject commit 93688e8c1fa2f22d46394c548a9edbd3d2d7c62d +Subproject commit 87ac6fddaf21d0b4ee8b8090533ff293db0da1b4 diff --git a/contrib/simdjson b/contrib/simdjson index 3fb82502f7f..e3f6322af76 160000 --- a/contrib/simdjson +++ b/contrib/simdjson @@ -1 +1 @@ -Subproject commit 3fb82502f7f19a098006e7ff74c9b6e7c7dd4a84 +Subproject commit e3f6322af762213ff2087ce3366bf9541c7fd355 diff --git a/contrib/snappy b/contrib/snappy index 156cd8939c5..3f194acb57e 160000 --- a/contrib/snappy +++ b/contrib/snappy @@ -1 +1 @@ -Subproject commit 156cd8939c5fba7fa68ae08db843377ecc07b4b5 +Subproject commit 3f194acb57e0487531c96b97af61dcbd025a78a3 diff --git a/contrib/thrift b/contrib/thrift index 74d6d9d3d64..010ccf0a0c7 160000 --- a/contrib/thrift +++ b/contrib/thrift @@ -1 +1 @@ -Subproject commit 74d6d9d3d6400d1672f48b4acf5bc7d1260ad96d +Subproject commit 010ccf0a0c7023fea0f6bf4e4078ebdff7e61982 From 7dba25ff9d195fa910706ed12bb6f9227a6276d7 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Tue, 13 Aug 2019 19:17:18 +0300 Subject: [PATCH 0932/1165] const --- dbms/src/Interpreters/MetricLog.cpp | 4 ++-- dbms/src/Interpreters/SystemLog.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dbms/src/Interpreters/MetricLog.cpp b/dbms/src/Interpreters/MetricLog.cpp index 5c526d002d6..088cb7cabd2 100644 --- a/dbms/src/Interpreters/MetricLog.cpp +++ b/dbms/src/Interpreters/MetricLog.cpp @@ -47,14 +47,14 @@ void MetricLogElement::appendToBlock(Block & block) const //ProfileEvents for (size_t i = 0, end = ProfileEvents::end(); i < end; ++i) { - UInt64 value = ProfileEvents::global_counters[i]; + const UInt64 value = ProfileEvents::global_counters[i]; columns[iter++]->insert(value); } //CurrentMetrics for (size_t i = 0, end = CurrentMetrics::end(); i < end; ++i) { - UInt64 value = CurrentMetrics::values[i]; + const UInt64 value = CurrentMetrics::values[i]; columns[iter++]->insert(value); } } diff --git a/dbms/src/Interpreters/SystemLog.cpp b/dbms/src/Interpreters/SystemLog.cpp index 8df20c4c8b5..6e63951d9ec 100644 --- a/dbms/src/Interpreters/SystemLog.cpp +++ b/dbms/src/Interpreters/SystemLog.cpp @@ -38,6 +38,7 @@ std::shared_ptr createSystemLog( return std::make_shared(context, database, table, engine, flush_interval_milliseconds); } + } @@ -108,5 +109,6 @@ void SystemLogs::metricThreadFunction() } } +} } From 226ef15c2ac90fded69ecb3b943cef66fe3097f0 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Tue, 13 Aug 2019 19:21:22 +0300 Subject: [PATCH 0933/1165] ZH docs build fix (#6469) * Link fix. * Fixed ZH docs build. --- docs/zh/data_types/{domain => domains}/ipv4.md | 0 docs/zh/data_types/{domain => domains}/ipv6.md | 0 docs/zh/data_types/{domain => domains}/overview.md | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename docs/zh/data_types/{domain => domains}/ipv4.md (100%) rename docs/zh/data_types/{domain => domains}/ipv6.md (100%) rename docs/zh/data_types/{domain => domains}/overview.md (100%) diff --git a/docs/zh/data_types/domain/ipv4.md b/docs/zh/data_types/domains/ipv4.md similarity index 100% rename from docs/zh/data_types/domain/ipv4.md rename to docs/zh/data_types/domains/ipv4.md diff --git a/docs/zh/data_types/domain/ipv6.md b/docs/zh/data_types/domains/ipv6.md similarity index 100% rename from docs/zh/data_types/domain/ipv6.md rename to docs/zh/data_types/domains/ipv6.md diff --git a/docs/zh/data_types/domain/overview.md b/docs/zh/data_types/domains/overview.md similarity index 100% rename from docs/zh/data_types/domain/overview.md rename to docs/zh/data_types/domains/overview.md From e07f3d9d10e58245800a3c565f454c2dc826a0b7 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Tue, 13 Aug 2019 19:47:12 +0300 Subject: [PATCH 0934/1165] refactor --- dbms/src/Interpreters/MetricLog.cpp | 42 +++++++++++++++++++++++++++++ dbms/src/Interpreters/MetricLog.h | 14 ++++++++++ dbms/src/Interpreters/SystemLog.cpp | 39 +++++---------------------- dbms/src/Interpreters/SystemLog.h | 6 ----- 4 files changed, 63 insertions(+), 38 deletions(-) diff --git a/dbms/src/Interpreters/MetricLog.cpp b/dbms/src/Interpreters/MetricLog.cpp index 088cb7cabd2..3e8bf21ad80 100644 --- a/dbms/src/Interpreters/MetricLog.cpp +++ b/dbms/src/Interpreters/MetricLog.cpp @@ -59,4 +59,46 @@ void MetricLogElement::appendToBlock(Block & block) const } } +void MetricLog::startCollectMetric(size_t collect_interval_milliseconds_) +{ + collect_interval_milliseconds = collect_interval_milliseconds_; + is_shutdown_metric_thread = false; + metric_flush_thread = ThreadFromGlobalPool([this] { metricThreadFunction(); }); +} + +void MetricLog::stopCollectMetric() +{ + bool old_val = false; + if (!is_shutdown_metric_thread.compare_exchange_strong(old_val, true)) + return; + metric_flush_thread.join(); +} + +void MetricLog::metricThreadFunction() +{ + const size_t flush_interval_milliseconds = 1000; + while (true) + { + try + { + const auto prev_timepoint = std::chrono::system_clock::now(); + + if (is_shutdown_metric_thread) + break; + + MetricLogElement elem; + elem.event_time = std::time(nullptr); + this->add(elem); + + const auto next_timepoint = prev_timepoint + std::chrono::milliseconds(flush_interval_milliseconds); + std::this_thread::sleep_until(next_timepoint); + } + catch (...) + { + tryLogCurrentException(__PRETTY_FUNCTION__); + } + + } +} + } diff --git a/dbms/src/Interpreters/MetricLog.h b/dbms/src/Interpreters/MetricLog.h index ce435b9e3cf..7c041a19d7d 100644 --- a/dbms/src/Interpreters/MetricLog.h +++ b/dbms/src/Interpreters/MetricLog.h @@ -19,6 +19,20 @@ struct MetricLogElement class MetricLog : public SystemLog { using SystemLog::SystemLog; + +public: + /// Launches a background thread to collect metrics with interval + void startCollectMetric(size_t collect_interval_milliseconds_); + + /// Stop background thread. Call before shutdown. + void stopCollectMetric(); + +private: + void metricThreadFunction(); + + ThreadFromGlobalPool metric_flush_thread; + size_t collect_interval_milliseconds; + std::atomic is_shutdown_metric_thread{false}; }; } diff --git a/dbms/src/Interpreters/SystemLog.cpp b/dbms/src/Interpreters/SystemLog.cpp index 6e63951d9ec..ce1d787562d 100644 --- a/dbms/src/Interpreters/SystemLog.cpp +++ b/dbms/src/Interpreters/SystemLog.cpp @@ -52,7 +52,12 @@ SystemLogs::SystemLogs(Context & global_context, const Poco::Util::AbstractConfi metric_log = createSystemLog(global_context, "system", "metric_log", config, "metric_log"); if (metric_log) - metric_flush_thread = ThreadFromGlobalPool([this] { metricThreadFunction(); }); + { + constexpr size_t DEFAULT_METRIC_LOG_COLLECT_INTERVAL_MILLISECONDS = 1000; + size_t collect_interval_milliseconds = config.getUInt64("metric_log.collect_interval_milliseconds", DEFAULT_METRIC_LOG_COLLECT_INTERVAL_MILLISECONDS); + metric_log->startCollectMetric(collect_interval_milliseconds); + } + part_log_database = config.getString("part_log.database", "system"); } @@ -76,39 +81,9 @@ void SystemLogs::shutdown() text_log->shutdown(); if (metric_log) { - bool old_val = false; - if (!is_shutdown_metric_thread.compare_exchange_strong(old_val, true)) - return; - metric_flush_thread.join(); + metric_log->stopCollectMetric(); metric_log->shutdown(); } } -void SystemLogs::metricThreadFunction() -{ - const size_t flush_interval_milliseconds = 1000; - while (true) - { - try - { - const auto prev_timepoint = std::chrono::system_clock::now(); - - if (is_shutdown_metric_thread) - break; - - MetricLogElement elem; - elem.event_time = std::time(nullptr); - metric_log->add(elem); - - const auto next_timepoint = prev_timepoint + std::chrono::milliseconds(flush_interval_milliseconds); - std::this_thread::sleep_until(next_timepoint); - } - catch (...) - { - tryLogCurrentException(__PRETTY_FUNCTION__); - } - - } -} - } diff --git a/dbms/src/Interpreters/SystemLog.h b/dbms/src/Interpreters/SystemLog.h index da340fab5d5..b00f77b7622 100644 --- a/dbms/src/Interpreters/SystemLog.h +++ b/dbms/src/Interpreters/SystemLog.h @@ -79,10 +79,6 @@ struct SystemLogs std::shared_ptr text_log; /// Used to log all text messages. std::shared_ptr metric_log; /// Used to log all metrics. - ThreadFromGlobalPool metric_flush_thread; - void metricThreadFunction(); - std::atomic is_shutdown_metric_thread{false}; - String part_log_database; }; @@ -121,8 +117,6 @@ public: /// Stop the background flush thread before destructor. No more data will be written. void shutdown(); - size_t getFlushInterval() { return flush_interval_milliseconds; } - protected: Context & context; const String database_name; From eed8dd713824cd710753188d790292b781eb0b52 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Tue, 13 Aug 2019 19:48:23 +0300 Subject: [PATCH 0935/1165] better --- dbms/src/Interpreters/MetricLog.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dbms/src/Interpreters/MetricLog.cpp b/dbms/src/Interpreters/MetricLog.cpp index 3e8bf21ad80..001ad1a4bd2 100644 --- a/dbms/src/Interpreters/MetricLog.cpp +++ b/dbms/src/Interpreters/MetricLog.cpp @@ -76,7 +76,6 @@ void MetricLog::stopCollectMetric() void MetricLog::metricThreadFunction() { - const size_t flush_interval_milliseconds = 1000; while (true) { try @@ -90,7 +89,7 @@ void MetricLog::metricThreadFunction() elem.event_time = std::time(nullptr); this->add(elem); - const auto next_timepoint = prev_timepoint + std::chrono::milliseconds(flush_interval_milliseconds); + const auto next_timepoint = prev_timepoint + std::chrono::milliseconds(collect_interval_milliseconds); std::this_thread::sleep_until(next_timepoint); } catch (...) From a3d4fbd07d91530d5153bc043aa8e50652ee4226 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Tue, 13 Aug 2019 20:02:17 +0300 Subject: [PATCH 0936/1165] simple test added --- .../0_stateless/00990_metric_log_table_not_empty.reference | 1 + .../queries/0_stateless/00990_metric_log_table_not_empty.sql | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00990_metric_log_table_not_empty.reference create mode 100644 dbms/tests/queries/0_stateless/00990_metric_log_table_not_empty.sql diff --git a/dbms/tests/queries/0_stateless/00990_metric_log_table_not_empty.reference b/dbms/tests/queries/0_stateless/00990_metric_log_table_not_empty.reference new file mode 100644 index 00000000000..d00491fd7e5 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00990_metric_log_table_not_empty.reference @@ -0,0 +1 @@ +1 diff --git a/dbms/tests/queries/0_stateless/00990_metric_log_table_not_empty.sql b/dbms/tests/queries/0_stateless/00990_metric_log_table_not_empty.sql new file mode 100644 index 00000000000..700312d0ba1 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00990_metric_log_table_not_empty.sql @@ -0,0 +1,5 @@ +select sleep(2) format Null; + +system flush logs; + +select count()>0 from system.metric_log \ No newline at end of file From c3e0ceecde177007381549499fc00597fc352d8e Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Tue, 13 Aug 2019 21:28:18 +0300 Subject: [PATCH 0937/1165] wait for finish calculations at underlying streams while cancelling AsynchronousBlockInputStream --- dbms/src/DataStreams/AsynchronousBlockInputStream.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/dbms/src/DataStreams/AsynchronousBlockInputStream.h b/dbms/src/DataStreams/AsynchronousBlockInputStream.h index c741d8090e9..93c695f20c9 100644 --- a/dbms/src/DataStreams/AsynchronousBlockInputStream.h +++ b/dbms/src/DataStreams/AsynchronousBlockInputStream.h @@ -80,10 +80,7 @@ public: /// Wait for some backgroud calculations to be sure, /// that after end of stream nothing is being executing. if (started) - { pool.wait(); - started = false; - } } ~AsynchronousBlockInputStream() override From 43ee50e512e92fa8b067e53ad0d3c907f98e1c69 Mon Sep 17 00:00:00 2001 From: dimarub2000 Date: Tue, 13 Aug 2019 22:12:31 +0300 Subject: [PATCH 0938/1165] QuantileExactExclusive function added. --- .../AggregateFunctionQuantile.cpp | 7 ++ .../AggregateFunctionQuantile.h | 6 +- dbms/src/AggregateFunctions/QuantileExact.h | 70 +++++++++++++++++-- 3 files changed, 78 insertions(+), 5 deletions(-) diff --git a/dbms/src/AggregateFunctions/AggregateFunctionQuantile.cpp b/dbms/src/AggregateFunctions/AggregateFunctionQuantile.cpp index d41654daee5..9d07286371c 100644 --- a/dbms/src/AggregateFunctions/AggregateFunctionQuantile.cpp +++ b/dbms/src/AggregateFunctions/AggregateFunctionQuantile.cpp @@ -24,6 +24,9 @@ template using FuncQuantilesDeterministic = A template using FuncQuantileExact = AggregateFunctionQuantile, NameQuantileExact, false, void, false>; template using FuncQuantilesExact = AggregateFunctionQuantile, NameQuantilesExact, false, void, true>; +template using FuncQuantileExactExclusive = AggregateFunctionQuantile, NameQuantileExactExclusive, false, Float64, false>; +template using FuncQuantilesExactExclusive = AggregateFunctionQuantile, NameQuantilesExactExclusive, false, Float64, true>; + template using FuncQuantileExactWeighted = AggregateFunctionQuantile, NameQuantileExactWeighted, true, void, false>; template using FuncQuantilesExactWeighted = AggregateFunctionQuantile, NameQuantilesExactWeighted, true, void, true>; @@ -92,6 +95,10 @@ void registerAggregateFunctionsQuantile(AggregateFunctionFactory & factory) factory.registerFunction(NameQuantileExact::name, createAggregateFunctionQuantile); factory.registerFunction(NameQuantilesExact::name, createAggregateFunctionQuantile); + factory.registerFunction(NameQuantileExactExclusive::name, createAggregateFunctionQuantile); + factory.registerFunction(NameQuantilesExactExclusive::name, createAggregateFunctionQuantile); + + factory.registerFunction(NameQuantileExactWeighted::name, createAggregateFunctionQuantile); factory.registerFunction(NameQuantilesExactWeighted::name, createAggregateFunctionQuantile); diff --git a/dbms/src/AggregateFunctions/AggregateFunctionQuantile.h b/dbms/src/AggregateFunctions/AggregateFunctionQuantile.h index 2e9ec914b99..4fdac6cdd53 100644 --- a/dbms/src/AggregateFunctions/AggregateFunctionQuantile.h +++ b/dbms/src/AggregateFunctions/AggregateFunctionQuantile.h @@ -199,8 +199,12 @@ struct NameQuantileDeterministic { static constexpr auto name = "quantileDetermi struct NameQuantilesDeterministic { static constexpr auto name = "quantilesDeterministic"; }; struct NameQuantileExact { static constexpr auto name = "quantileExact"; }; -struct NameQuantileExactWeighted { static constexpr auto name = "quantileExactWeighted"; }; struct NameQuantilesExact { static constexpr auto name = "quantilesExact"; }; + +struct NameQuantileExactExclusive { static constexpr auto name = "quantileExactExclusive"; }; +struct NameQuantilesExactExclusive { static constexpr auto name = "quantilesExactExclusive"; }; + +struct NameQuantileExactWeighted { static constexpr auto name = "quantileExactWeighted"; }; struct NameQuantilesExactWeighted { static constexpr auto name = "quantilesExactWeighted"; }; struct NameQuantileTiming { static constexpr auto name = "quantileTiming"; }; diff --git a/dbms/src/AggregateFunctions/QuantileExact.h b/dbms/src/AggregateFunctions/QuantileExact.h index a5b616669b9..b23a2975487 100644 --- a/dbms/src/AggregateFunctions/QuantileExact.h +++ b/dbms/src/AggregateFunctions/QuantileExact.h @@ -64,7 +64,7 @@ struct QuantileExact } /// Get the value of the `level` quantile. The level must be between 0 and 1. - Value get(Float64 level) + virtual Value get(Float64 level) { if (!array.empty()) { @@ -81,7 +81,7 @@ struct QuantileExact /// Get the `size` values of `levels` quantiles. Write `size` results starting with `result` address. /// indices - an array of index levels such that the corresponding elements will go in ascending order. - void getMany(const Float64 * levels, const size_t * indices, size_t size, Value * result) + virtual void getMany(const Float64 * levels, const size_t * indices, size_t size, Value * result) { if (!array.empty()) { @@ -108,15 +108,77 @@ struct QuantileExact } /// The same, but in the case of an empty state, NaN is returned. - Float64 getFloat(Float64) const + virtual Float64 getFloat(Float64) { throw Exception("Method getFloat is not implemented for QuantileExact", ErrorCodes::NOT_IMPLEMENTED); } - void getManyFloat(const Float64 *, const size_t *, size_t, Float64 *) const + virtual void getManyFloat(const Float64 *, const size_t *, size_t, Float64 *) { throw Exception("Method getManyFloat is not implemented for QuantileExact", ErrorCodes::NOT_IMPLEMENTED); } + + virtual ~QuantileExact() = default; +}; + +template +struct QuantileExactExclusive : public QuantileExact +{ + using QuantileExact::array; + /// Get the value of the `level` quantile. The level must be between 0 and 1. + Float64 getFloat(Float64 level) override + { + if (!array.empty()) + { + Float64 h = level * (array.size() + 1); + auto n = static_cast(h); + + if (n >= array.size()) + return array[array.size() - 1]; + else if (n < 1) + return array[0]; + + std::nth_element(array.begin(), array.begin() + n - 1, array.end()); + std::nth_element(array.begin() + n, array.begin() + n, array.end()); + + return array[n - 1] + (h - n) * (array[n] - array[n - 1]); + } + + return std::numeric_limits::quiet_NaN(); + } + + void getManyFloat(const Float64 * levels, const size_t * indices, size_t size, Float64 * result) override + { + if (!array.empty()) + { + size_t prev_n = 0; + for (size_t i = 0; i < size; ++i) + { + auto level = levels[indices[i]]; + + Float64 h = level * (array.size() + 1); + auto n = static_cast(h); + + if (n >= array.size()) + result[indices[i]] = array[array.size() - 1]; + else if (n < 1) + result[indices[i]] = array[0]; + else + { + std::nth_element(array.begin() + prev_n, array.begin() + n - 1, array.end()); + std::nth_element(array.begin() + n, array.begin() + n, array.end()); + + result[indices[i]] = array[n - 1] + (h - n) * (array[n] - array[n - 1]); + prev_n = n; + } + } + } + else + { + for (size_t i = 0; i < size; ++i) + result[i] = std::numeric_limits::quiet_NaN(); + } + } }; } From 09ecd865fc9d75c0f1e6ef05ead663ed0abc5028 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 14 Aug 2019 03:26:38 +0300 Subject: [PATCH 0939/1165] Allow to use library dictionary source with ASan. May impose troubles. --- dbms/src/Dictionaries/LibraryDictionarySource.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dbms/src/Dictionaries/LibraryDictionarySource.cpp b/dbms/src/Dictionaries/LibraryDictionarySource.cpp index b4de6506db1..2cb74b944d3 100644 --- a/dbms/src/Dictionaries/LibraryDictionarySource.cpp +++ b/dbms/src/Dictionaries/LibraryDictionarySource.cpp @@ -1,5 +1,6 @@ #include "LibraryDictionarySource.h" #include +#include #include #include #include @@ -134,7 +135,7 @@ LibraryDictionarySource::LibraryDictionarySource( ErrorCodes::FILE_DOESNT_EXIST); description.init(sample_block); library = std::make_shared(path, RTLD_LAZY -#if defined(RTLD_DEEPBIND) // Does not exists in freebsd +#if defined(RTLD_DEEPBIND) && !defined(ADDRESS_SANITIZER) // Does not exists in FreeBSD. Cannot work with Address Sanitizer. | RTLD_DEEPBIND #endif ); From 5c0c661b6e5a97bb57f9582dbee04ca33db4c021 Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Wed, 14 Aug 2019 09:02:56 +0300 Subject: [PATCH 0940/1165] Add Paris Meetup link --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index dccb75b4282..ac579d3f2a3 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ ClickHouse is an open-source column-oriented database management system that all ## Upcoming Events * [ClickHouse Meetup in Moscow](https://yandex.ru/promo/clickhouse/moscow-2019) on September 5. +* [ClickHouse Meetup in Paris](https://www.eventbrite.com/e/clickhouse-paris-meetup-2019-registration-68493270215) on October 3. * [ClickHouse Meetup in Hong Kong](https://www.meetup.com/Hong-Kong-Machine-Learning-Meetup/events/263580542/) on October 17. * [ClickHouse Meetup in Shenzhen](https://www.huodongxing.com/event/3483759917300) on October 20. * [ClickHouse Meetup in Shanghai](https://www.huodongxing.com/event/4483760336000) on October 27. From ccab7ce467c1f0fbfee1fa5f08407efdb210e491 Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Wed, 14 Aug 2019 09:05:00 +0300 Subject: [PATCH 0941/1165] Add Paris Meetup link to front page (#6485) --- website/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/index.html b/website/index.html index 017080d5647..5ab51289c92 100644 --- a/website/index.html +++ b/website/index.html @@ -94,7 +94,7 @@
    - Upcoming Meetups: Moscow on September 5, Hong Kong on October 17, Shenzhen on October 20 and Shanghai on October 27 + Upcoming Meetups: Moscow on September 5, Paris on October 3, Hong Kong on October 17, Shenzhen on October 20 and Shanghai on October 27
    From e5d32785d4a0c7e41809a69410e379987de049b8 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Wed, 14 Aug 2019 09:45:24 +0300 Subject: [PATCH 0942/1165] DOCAPI-7443: Virtual columns docs update. (#6382) --- docs/en/operations/table_engines/index.md | 68 ++++++++++++++++++++++- docs/en/operations/table_engines/kafka.md | 13 +++++ docs/en/operations/table_engines/merge.md | 24 +++----- docs/toc_en.yml | 4 +- docs/toc_fa.yml | 4 +- docs/toc_ru.yml | 4 +- docs/toc_zh.yml | 4 +- 7 files changed, 94 insertions(+), 27 deletions(-) diff --git a/docs/en/operations/table_engines/index.md b/docs/en/operations/table_engines/index.md index e370e6173bb..41680a5b3af 100644 --- a/docs/en/operations/table_engines/index.md +++ b/docs/en/operations/table_engines/index.md @@ -2,15 +2,77 @@ The table engine (type of table) determines: -- How and where data is stored, where to write it to, and where to read it from. +- How and where data is stored, where to write it to, and from where to read it. - Which queries are supported, and how. - Concurrent data access. - Use of indexes, if present. - Whether multithreaded request execution is possible. - Data replication parameters. -When reading, the engine is only required to output the requested columns, but in some cases the engine can partially process data when responding to the request. +## Engine Families -For most serious tasks, you should use engines from the `MergeTree` family. +### *MergeTree + +The most universal and functional table engines for high-load tasks. The common property of these engines is quick data insertion with subsequent data processing in the background. The `*MergeTree` engines support data replication (with [Replicated*](replication.md) versions of engines), partitioning and other features not supported in other engines. + +Engines of the family: + +- [MergTree](mergetree.md) +- [ReplacingMergeTree](replacingmergetree.md) +- [SummingMergeTree](summingmergetree.md) +- [AggregatingMergeTree](aggregatingmergetree.md) +- [CollapsingMergeTree](collapsingmergetree.md) +- [VersionedCollapsingMergeTree](versionedcollapsingmergetree.md) +- [GraphiteMergeTree](graphitemergetree.md) + +### *Log + +Lightweight [engines](log_family.md) with minimum functionality. They are the most effective in scenarios when you need to quickly write many small tables (up to about 1 million rows) and read them later as a whole. + +Engines of the family: + +- [TinyLog](tinylog.md) +- [StripeLog](stripelog.md) +- [Log](log.md) + +### Intergation engines + +Engines for communicating with other data storage and processing systems. + +Engines of the family: + +- [Kafka](kafka.md) +- [MySQL](mysql.md) +- [ODBC](odbc.md) +- [JDBC](jdbc.md) + +### Special engines + +Engines solving special tasks. + +Engines of the family: + +- [Distributed](distributed.md) +- [MaterializedView](materializedview.md) +- [Dictionary](dictionary.md) +- [Merge](merge.md) +- [File](file.md) +- [Null](null.md) +- [Set](set.md) +- [Join](join.md) +- [URL](url.md) +- [View](view.md) +- [Memory](memory.md) +- [Buffer](buffer.md) + +## Virtual columns {#table_engines-virtual_columns} + +Virtual column is an integral attribute of a table engine that is defined in the source code of the engine. + +You should not specify virtual columns in the `CREATE TABLE` query, and you cannot see them in the results of `SHOW CREATE TABLE` and `DESCRIBE TABLE` queries. Also, virtual columns are read-only, so you can't insert data into virtual columns. + +To select data from a virtual column, you must specify its name in the `SELECT` query. The `SELECT *` doesn't return values from virtual columns. + +If you create a table with a column that has the same name as one of the table virtual columns, the virtual column becomes inaccessible. Doing so is not recommended. To help avoiding conflicts virtual column names are usually prefixed with an underscore. [Original article](https://clickhouse.yandex/docs/en/operations/table_engines/) diff --git a/docs/en/operations/table_engines/kafka.md b/docs/en/operations/table_engines/kafka.md index 7bedd8f7ac9..90745ebb4cf 100644 --- a/docs/en/operations/table_engines/kafka.md +++ b/docs/en/operations/table_engines/kafka.md @@ -155,4 +155,17 @@ Similar to GraphiteMergeTree, the Kafka engine supports extended configuration u For a list of possible configuration options, see the [librdkafka configuration reference](https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md). Use the underscore (`_`) instead of a dot in the ClickHouse configuration. For example, `check.crcs=true` will be `true`. +## Virtual Columns + +- `_topic` — Kafka topic. +- `_key` — Key of the message. +- `_offset` — Offset of the message. +- `_timestamp` — Timestamp of the message. +- `_partition` — Partition of Kafka topic. + +**See Also** + +- [Virtual columns](index.md#table_engines-virtual_columns) + + [Original article](https://clickhouse.yandex/docs/en/operations/table_engines/kafka/) diff --git a/docs/en/operations/table_engines/merge.md b/docs/en/operations/table_engines/merge.md index f29075ec973..f2347d9777d 100644 --- a/docs/en/operations/table_engines/merge.md +++ b/docs/en/operations/table_engines/merge.md @@ -6,7 +6,7 @@ The `Merge` engine accepts parameters: the database name and a regular expressio Example: -``` +```sql Merge(hits, '^WatchLog') ``` @@ -26,7 +26,7 @@ Example 2: Let's say you have a old table (WatchLog_old) and decided to change partitioning without moving data to a new table (WatchLog_new) and you need to see data from both tables. -``` +```sql CREATE TABLE WatchLog_old(date Date, UserId Int64, EventType String, Cnt UInt64) ENGINE=MergeTree(date, (UserId, EventType), 8192); INSERT INTO WatchLog_old VALUES ('2018-01-01', 1, 'hit', 3); @@ -39,33 +39,25 @@ CREATE TABLE WatchLog as WatchLog_old ENGINE=Merge(currentDatabase(), '^WatchLog SELECT * FROM WatchLog - +``` +```text ┌───────date─┬─UserId─┬─EventType─┬─Cnt─┐ │ 2018-01-01 │ 1 │ hit │ 3 │ └────────────┴────────┴───────────┴─────┘ ┌───────date─┬─UserId─┬─EventType─┬─Cnt─┐ │ 2018-01-02 │ 2 │ hit │ 3 │ └────────────┴────────┴───────────┴─────┘ - ``` ## Virtual Columns -Virtual columns are columns that are provided by the table engine, regardless of the table definition. In other words, these columns are not specified in `CREATE TABLE`, but they are accessible for `SELECT`. +- `_table` — Contains the name of the table from which data was read. Type: [String](../../data_types/string.md). -Virtual columns differ from normal columns in the following ways: + You can set the constant conditions on `_table` in the `WHERE/PREWHERE` clause (for example, `WHERE _table='xyz'`). In this case the read operation is performed only for that tables where the condition on `_table` is satisfied, so the `_table` column acts as an index. -- They are not specified in table definitions. -- Data can't be added to them with `INSERT`. -- When using `INSERT` without specifying the list of columns, virtual columns are ignored. -- They are not selected when using the asterisk (`SELECT *`). -- Virtual columns are not shown in `SHOW CREATE TABLE` and `DESC TABLE` queries. +**See Also** -The `Merge` type table contains the virtual column `_table` of the type `String`. It contains the name of the table that data was read from. If any underlying table already has the column `_table`, then the virtual column is shadowed and is not accessible. - - - -If the `WHERE/PREWHERE` clause contains conditions for the `_table` column that do not depend on other table columns (as one of the conjunction elements, or as an entire expression), these conditions are used as an index. The conditions are performed on a data set of table names to read data from, and the read operation will be performed from only those tables that the condition was triggered on. +- [Virtual columns](index.md#table_engines-virtual_columns) [Original article](https://clickhouse.yandex/docs/en/operations/table_engines/merge/) diff --git a/docs/toc_en.yml b/docs/toc_en.yml index d75f81a556c..5e6854002ca 100644 --- a/docs/toc_en.yml +++ b/docs/toc_en.yml @@ -85,6 +85,8 @@ nav: - 'Integrations': - 'Kafka': 'operations/table_engines/kafka.md' - 'MySQL': 'operations/table_engines/mysql.md' + - 'JDBC': 'operations/table_engines/jdbc.md' + - 'ODBC': 'operations/table_engines/odbc.md' - 'Special': - 'Distributed': 'operations/table_engines/distributed.md' - 'External data': 'operations/table_engines/external_data.md' @@ -99,8 +101,6 @@ nav: - 'MaterializedView': 'operations/table_engines/materializedview.md' - 'Memory': 'operations/table_engines/memory.md' - 'Buffer': 'operations/table_engines/buffer.md' - - 'JDBC': 'operations/table_engines/jdbc.md' - - 'ODBC': 'operations/table_engines/odbc.md' - 'SQL Reference': - 'hidden': 'query_language/index.md' diff --git a/docs/toc_fa.yml b/docs/toc_fa.yml index 70a0f222d4d..1799093df24 100644 --- a/docs/toc_fa.yml +++ b/docs/toc_fa.yml @@ -85,6 +85,8 @@ nav: - 'Integrations': - 'Kafka': 'operations/table_engines/kafka.md' - 'MySQL': 'operations/table_engines/mysql.md' + - 'JDBC': 'operations/table_engines/jdbc.md' + - 'ODBC': 'operations/table_engines/odbc.md' - 'Special': - 'Distributed': 'operations/table_engines/distributed.md' - 'External data': 'operations/table_engines/external_data.md' @@ -99,8 +101,6 @@ nav: - 'MaterializedView': 'operations/table_engines/materializedview.md' - 'Memory': 'operations/table_engines/memory.md' - 'Buffer': 'operations/table_engines/buffer.md' - - 'JDBC': 'operations/table_engines/jdbc.md' - - 'ODBC': 'operations/table_engines/odbc.md' - 'SQL Reference': - 'hidden': 'query_language/index.md' diff --git a/docs/toc_ru.yml b/docs/toc_ru.yml index d2f463fcc85..682f171a1f3 100644 --- a/docs/toc_ru.yml +++ b/docs/toc_ru.yml @@ -86,6 +86,8 @@ nav: - 'Интеграции': - 'Kafka': 'operations/table_engines/kafka.md' - 'MySQL': 'operations/table_engines/mysql.md' + - 'JDBC': 'operations/table_engines/jdbc.md' + - 'ODBC': 'operations/table_engines/odbc.md' - 'Особые': - 'Distributed': 'operations/table_engines/distributed.md' - 'Внешние данные': 'operations/table_engines/external_data.md' @@ -100,8 +102,6 @@ nav: - 'MaterializedView': 'operations/table_engines/materializedview.md' - 'Memory': 'operations/table_engines/memory.md' - 'Buffer': 'operations/table_engines/buffer.md' - - 'JDBC': 'operations/table_engines/jdbc.md' - - 'ODBC': 'operations/table_engines/odbc.md' - 'Справка по SQL': - 'hidden': 'query_language/index.md' diff --git a/docs/toc_zh.yml b/docs/toc_zh.yml index 40b1c97d2a8..6f9abc9b36c 100644 --- a/docs/toc_zh.yml +++ b/docs/toc_zh.yml @@ -84,6 +84,8 @@ nav: - 'Integrations': - 'Kafka': 'operations/table_engines/kafka.md' - 'MySQL': 'operations/table_engines/mysql.md' + - 'JDBC': 'operations/table_engines/jdbc.md' + - 'ODBC': 'operations/table_engines/odbc.md' - 'Special': - 'Distributed': 'operations/table_engines/distributed.md' - 'External data': 'operations/table_engines/external_data.md' @@ -98,8 +100,6 @@ nav: - 'MaterializedView': 'operations/table_engines/materializedview.md' - 'Memory': 'operations/table_engines/memory.md' - 'Buffer': 'operations/table_engines/buffer.md' - - 'JDBC': 'operations/table_engines/jdbc.md' - - 'ODBC': 'operations/table_engines/odbc.md' - 'SQL语法': - 'hidden': 'query_language/index.md' From 09a67981b7655158190ffe1817eef35ef72495e9 Mon Sep 17 00:00:00 2001 From: Vxider Date: Wed, 14 Aug 2019 14:56:43 +0800 Subject: [PATCH 0943/1165] build fix --- dbms/src/Core/SettingsCommon.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Core/SettingsCommon.h b/dbms/src/Core/SettingsCommon.h index 08064096133..a2a587b7405 100644 --- a/dbms/src/Core/SettingsCommon.h +++ b/dbms/src/Core/SettingsCommon.h @@ -555,7 +555,7 @@ public: for (const auto & member : members()) { if (member.isChanged(castToDerived())) - found_changes.emplace_back(member.name.toString(), member.get_field(castToDerived())); + found_changes.push_back({member.name.toString(), member.get_field(castToDerived())}); } return found_changes; } From 6472768c07668c7749f3d18694abf22e665c6385 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Wed, 14 Aug 2019 10:58:30 +0300 Subject: [PATCH 0944/1165] DOCAPI-7090: SYSTEM DISTRIBUTED docs. EN review. RU translation. (#6262) --- docs/en/query_language/system.md | 19 ++++++++++++------- docs/ru/query_language/system.md | 15 +++++++++------ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/docs/en/query_language/system.md b/docs/en/query_language/system.md index c5f4830723f..b7797df490b 100644 --- a/docs/en/query_language/system.md +++ b/docs/en/query_language/system.md @@ -4,31 +4,36 @@ - [FLUSH DISTRIBUTED](#query_language-system-flush-distributed) - [START DISTRIBUTED SENDS](#query_language-system-start-distributed-sends) + ## Managing Distributed Tables {#query_language-system-distributed} -ClickHouse can manage [distributed](../operations/table_engines/distributed.md) tables. When a user inserts data into such table, ClickHouse creates a queue of the data which should be sent to servers of the cluster, then asynchronously sends them. You can control the processing of queue by using the requests [STOP DISTRIBUTED SENDS](#query_language-system-stop-distributed-sends), [FLUSH DISTRIBUTED](#query_language-system-flush-distributed) and [START DISTRIBUTED SENDS](#query_language-system-start-distributed-sends). Also, you can synchronously insert distributed data with the `insert_distributed_sync` setting. +ClickHouse can manage [distributed](../operations/table_engines/distributed.md) tables. When a user inserts data into these tables, ClickHouse first creates a queue of the data that should be sent to cluster nodes, then asynchronously sends it. You can manage queue processing with the [STOP DISTRIBUTED SENDS](#query_language-system-stop-distributed-sends), [FLUSH DISTRIBUTED](#query_language-system-flush-distributed), and [START DISTRIBUTED SENDS](#query_language-system-start-distributed-sends) queries. You can also synchronously insert distributed data with the `insert_distributed_sync` setting. ### STOP DISTRIBUTED SENDS {#query_language-system-stop-distributed-sends} -Disables background data distributing, when inserting data into the distributed tables. +Disables background data distribution when inserting data into distributed tables. -``` +```sql SYSTEM STOP DISTRIBUTED SENDS [db.] ``` + ### FLUSH DISTRIBUTED {#query_language-system-flush-distributed} -Forces ClickHouse to send data to the servers of the cluster in synchronous mode. If some of the servers are not available, ClickHouse throws an exception and stops query processing. When servers are back into operation, you should repeat the query. +Forces ClickHouse to send data to cluster nodes synchronously. If any nodes are unavailable, ClickHouse throws an exception and stops query execution. You can retry the query until it succeeds, which will happen when all nodes are back online. -``` +```sql SYSTEM FLUSH DISTRIBUTED [db.] ``` + ### START DISTRIBUTED SENDS {#query_language-system-start-distributed-sends} -Enables background data distributing, when inserting data into the distributed tables. +Enables background data distribution when inserting data into distributed tables. -``` +```sql SYSTEM START DISTRIBUTED SENDS [db.] ``` + +[Original article](https://clickhouse.yandex/docs/en/query_language/system/) diff --git a/docs/ru/query_language/system.md b/docs/ru/query_language/system.md index fcf6fb8eced..f35b4a39061 100644 --- a/docs/ru/query_language/system.md +++ b/docs/ru/query_language/system.md @@ -1,16 +1,16 @@ -# SYSTEM Queries {#query_language-system} +# Запросы SYSTEM {#query_language-system} - [STOP DISTRIBUTED SENDS](#query_language-system-stop-distributed-sends) - [FLUSH DISTRIBUTED](#query_language-system-flush-distributed) - [START DISTRIBUTED SENDS](#query_language-system-start-distributed-sends) -## Managing Distributed Tables {#query_language-system-distributed} +## Управление распределёнными таблицами {#query_language-system-distributed} -ClickHouse can manage [distributed](../operations/table_engines/distributed.md) tables. When a user inserts data into such table, ClickHouse creates a queue of the data which should be sent to servers of the cluster, then asynchronously sends them. You can control the processing of queue by using the requests [STOP DISTRIBUTED SENDS](#query_language-system-stop-distributed-sends), [FLUSH DISTRIBUTED](#query_language-system-flush-distributed) and [START DISTRIBUTED SENDS](#query_language-system-start-distributed-sends). +ClickHouse может оперировать [распределёнными](../operations/table_engines/distributed.md) таблицами. Когда пользователь вставляет данные в эти таблицы, ClickHouse сначала формирует очередь из данных, которые должны быть отправлены на узлы кластера, а затем асинхронно отправляет подготовленные данные. Вы пожете управлять очередью с помощью запросов [STOP DISTRIBUTED SENDS](#query_language-system-stop-distributed-sends), [START DISTRIBUTED SENDS](#query_language-system-start-distributed-sends) и [FLUSH DISTRIBUTED](#query_language-system-flush-distributed). Также есть возможность синхронно вставлять распределенные данные с помощью настройки `insert_distributed_sync`. ### STOP DISTRIBUTED SENDS {#query_language-system-stop-distributed-sends} -Disables asynchronous distribution of data between servers of the cluster. +Отключает фоновую отправку при вставке данных в распределённые таблицы. ``` SYSTEM STOP DISTRIBUTED SENDS [db.] @@ -18,7 +18,7 @@ SYSTEM STOP DISTRIBUTED SENDS [db.] ### FLUSH DISTRIBUTED {#query_language-system-flush-distributed} -Forces ClickHouse to send data to the servers of the cluster in synchronous mode. If some of the servers are not available, ClickHouse throws an exception and stops query processing. When servers back into operation, you should repeat the query. +В синхронном режиме отправляет все данные на узлы кластера. Если какие-либо узлы недоступны, ClickHouse генерирует исключение и останавливает выполнение запроса. Такой запрос можно повторять до успешного завершения, что будет означать возвращение связанности с остальными узлами кластера. ``` SYSTEM FLUSH DISTRIBUTED [db.] @@ -26,8 +26,11 @@ SYSTEM FLUSH DISTRIBUTED [db.] ### START DISTRIBUTED SENDS {#query_language-system-start-distributed-sends} -Enables asynchronous distribution of data between servers of cluster. +Включает фоновую отправку при вставке данных в распределенные таблицы. ``` SYSTEM START DISTRIBUTED SENDS [db.] ``` + +[Оригинальная статья](https://clickhouse.yandex/docs/ru/query_language/system/) + From bc4177f64cefd43c477d05dc0f92ca0c62fc4185 Mon Sep 17 00:00:00 2001 From: Alexandr Krasheninnikov Date: Wed, 14 Aug 2019 13:20:15 +0300 Subject: [PATCH 0945/1165] Make alias case-insenstitive --- dbms/src/Functions/currentUser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Functions/currentUser.cpp b/dbms/src/Functions/currentUser.cpp index ee7c4d589a0..fa8b3103be2 100644 --- a/dbms/src/Functions/currentUser.cpp +++ b/dbms/src/Functions/currentUser.cpp @@ -48,7 +48,7 @@ public: void registerFunctionCurrentUser(FunctionFactory & factory) { factory.registerFunction(); - factory.registerAlias("user", FunctionCurrentUser::name, FunctionFactory::CaseSensitive); + factory.registerAlias("user", FunctionCurrentUser::name, FunctionFactory::CaseInsensitive); } } From 6bcfe51edfd621d4239b2ffea5fba3170c6de1d0 Mon Sep 17 00:00:00 2001 From: akuzm <36882414+akuzm@users.noreply.github.com> Date: Wed, 14 Aug 2019 14:04:11 +0300 Subject: [PATCH 0946/1165] In performance test, do not read query log for queries we didn't run. (#6427) --- .../performance-test/PerformanceTest.cpp | 91 ++++++++++--------- 1 file changed, 50 insertions(+), 41 deletions(-) diff --git a/dbms/programs/performance-test/PerformanceTest.cpp b/dbms/programs/performance-test/PerformanceTest.cpp index 45e9dfa89a7..ab55cd3d6cf 100644 --- a/dbms/programs/performance-test/PerformanceTest.cpp +++ b/dbms/programs/performance-test/PerformanceTest.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include #include #include @@ -249,6 +251,54 @@ std::vector PerformanceTest::execute() runQueries(queries_with_indexes, statistics_by_run); } + + if (got_SIGINT) + { + return statistics_by_run; + } + + // Pull memory usage data from query log. The log is normally filled in + // background, so we have to flush it synchronously here to see all the + // previous queries. + { + NullBlockOutputStream null_output(Block{}); + RemoteBlockInputStream flush_log(connection, "system flush logs", + {} /* header */, context); + copyData(flush_log, null_output); + } + + for (auto & statistics : statistics_by_run) + { + if (statistics.query_id.empty()) + { + // We have statistics structs for skipped queries as well, so we + // have to filter them out. + continue; + } + + // We run some test queries several times, specifying the same query id, + // so this query to the log may return several records. Choose the + // last one, because this is when the query performance has stabilized. + RemoteBlockInputStream log_reader(connection, + "select memory_usage, query_start_time from system.query_log " + "where type = 2 and query_id = '" + statistics.query_id + "' " + "order by query_start_time desc", + {} /* header */, context); + + log_reader.readPrefix(); + Block block = log_reader.read(); + if (block.columns() == 0) + { + LOG_WARNING(log, "Query '" << statistics.query_id << "' is not found in query log."); + continue; + } + + auto column = block.getByName("memory_usage").column; + statistics.memory_usage = column->get64(0); + + log_reader.readSuffix(); + } + return statistics_by_run; } @@ -298,47 +348,6 @@ void PerformanceTest::runQueries( break; } } - - if (got_SIGINT) - { - return; - } - - // Pull memory usage data from query log. The log is normally filled in - // background, so we have to flush it synchronously here to see all the - // previous queries. - { - RemoteBlockInputStream flush_log(connection, "system flush logs", - {} /* header */, context); - flush_log.readPrefix(); - while (flush_log.read()); - flush_log.readSuffix(); - } - - for (auto & statistics : statistics_by_run) - { - RemoteBlockInputStream log_reader(connection, - "select memory_usage from system.query_log where type = 2 and query_id = '" - + statistics.query_id + "'", - {} /* header */, context); - - log_reader.readPrefix(); - Block block = log_reader.read(); - if (block.columns() == 0) - { - LOG_WARNING(log, "Query '" << statistics.query_id << "' is not found in query log."); - continue; - } - - assert(block.columns() == 1); - assert(block.getDataTypes()[0]->getName() == "UInt64"); - ColumnPtr column = block.getByPosition(0).column; - assert(column->size() == 1); - StringRef ref = column->getDataAt(0); - assert(ref.size == sizeof(UInt64)); - statistics.memory_usage = *reinterpret_cast(ref.data); - log_reader.readSuffix(); - } } From 6b6e477c76d103ba110de38c36b86b659d136935 Mon Sep 17 00:00:00 2001 From: dimarub2000 Date: Wed, 14 Aug 2019 14:13:04 +0300 Subject: [PATCH 0947/1165] Added QuantileExactInclusive function. Deleted redundant virtuals. --- .../AggregateFunctionQuantile.cpp | 5 ++ .../AggregateFunctionQuantile.h | 3 + dbms/src/AggregateFunctions/QuantileExact.h | 88 +++++++++++++++++-- 3 files changed, 87 insertions(+), 9 deletions(-) diff --git a/dbms/src/AggregateFunctions/AggregateFunctionQuantile.cpp b/dbms/src/AggregateFunctions/AggregateFunctionQuantile.cpp index 9d07286371c..e3d0cbdc289 100644 --- a/dbms/src/AggregateFunctions/AggregateFunctionQuantile.cpp +++ b/dbms/src/AggregateFunctions/AggregateFunctionQuantile.cpp @@ -27,6 +27,9 @@ template using FuncQuantilesExact = AggregateFunctionQu template using FuncQuantileExactExclusive = AggregateFunctionQuantile, NameQuantileExactExclusive, false, Float64, false>; template using FuncQuantilesExactExclusive = AggregateFunctionQuantile, NameQuantilesExactExclusive, false, Float64, true>; +template using FuncQuantileExactInclusive = AggregateFunctionQuantile, NameQuantileExactInclusive, false, Float64, false>; +template using FuncQuantilesExactInclusive = AggregateFunctionQuantile, NameQuantilesExactInclusive, false, Float64, true>; + template using FuncQuantileExactWeighted = AggregateFunctionQuantile, NameQuantileExactWeighted, true, void, false>; template using FuncQuantilesExactWeighted = AggregateFunctionQuantile, NameQuantilesExactWeighted, true, void, true>; @@ -98,6 +101,8 @@ void registerAggregateFunctionsQuantile(AggregateFunctionFactory & factory) factory.registerFunction(NameQuantileExactExclusive::name, createAggregateFunctionQuantile); factory.registerFunction(NameQuantilesExactExclusive::name, createAggregateFunctionQuantile); + factory.registerFunction(NameQuantileExactInclusive::name, createAggregateFunctionQuantile); + factory.registerFunction(NameQuantilesExactInclusive::name, createAggregateFunctionQuantile); factory.registerFunction(NameQuantileExactWeighted::name, createAggregateFunctionQuantile); factory.registerFunction(NameQuantilesExactWeighted::name, createAggregateFunctionQuantile); diff --git a/dbms/src/AggregateFunctions/AggregateFunctionQuantile.h b/dbms/src/AggregateFunctions/AggregateFunctionQuantile.h index 4fdac6cdd53..718bf419dd0 100644 --- a/dbms/src/AggregateFunctions/AggregateFunctionQuantile.h +++ b/dbms/src/AggregateFunctions/AggregateFunctionQuantile.h @@ -204,6 +204,9 @@ struct NameQuantilesExact { static constexpr auto name = "quantilesExact"; }; struct NameQuantileExactExclusive { static constexpr auto name = "quantileExactExclusive"; }; struct NameQuantilesExactExclusive { static constexpr auto name = "quantilesExactExclusive"; }; +struct NameQuantileExactInclusive { static constexpr auto name = "quantileExactInclusive"; }; +struct NameQuantilesExactInclusive { static constexpr auto name = "quantilesExactInclusive"; }; + struct NameQuantileExactWeighted { static constexpr auto name = "quantileExactWeighted"; }; struct NameQuantilesExactWeighted { static constexpr auto name = "quantilesExactWeighted"; }; diff --git a/dbms/src/AggregateFunctions/QuantileExact.h b/dbms/src/AggregateFunctions/QuantileExact.h index b23a2975487..ffa12640f8e 100644 --- a/dbms/src/AggregateFunctions/QuantileExact.h +++ b/dbms/src/AggregateFunctions/QuantileExact.h @@ -14,6 +14,7 @@ namespace DB namespace ErrorCodes { extern const int NOT_IMPLEMENTED; + extern const int BAD_ARGUMENTS; } /** Calculates quantile by collecting all values into array @@ -64,7 +65,7 @@ struct QuantileExact } /// Get the value of the `level` quantile. The level must be between 0 and 1. - virtual Value get(Float64 level) + Value get(Float64 level) { if (!array.empty()) { @@ -81,7 +82,7 @@ struct QuantileExact /// Get the `size` values of `levels` quantiles. Write `size` results starting with `result` address. /// indices - an array of index levels such that the corresponding elements will go in ascending order. - virtual void getMany(const Float64 * levels, const size_t * indices, size_t size, Value * result) + void getMany(const Float64 * levels, const size_t * indices, size_t size, Value * result) { if (!array.empty()) { @@ -121,13 +122,18 @@ struct QuantileExact virtual ~QuantileExact() = default; }; +/// QuantileExactInclusive is equivalent to Excel PERCENTILE.EXC, R-6, SAS-4, SciPy-(0,0) template struct QuantileExactExclusive : public QuantileExact { using QuantileExact::array; - /// Get the value of the `level` quantile. The level must be between 0 and 1. + + /// Get the value of the `level` quantile. The level must be between 0 and 1 excluding bounds. Float64 getFloat(Float64 level) override { + if (level == 0. || level == 1.) + throw Exception("QuantileExactExclusive cannot interpolate for the percentiles 1 and 0", ErrorCodes::BAD_ARGUMENTS); + if (!array.empty()) { Float64 h = level * (array.size() + 1); @@ -139,9 +145,73 @@ struct QuantileExactExclusive : public QuantileExact return array[0]; std::nth_element(array.begin(), array.begin() + n - 1, array.end()); - std::nth_element(array.begin() + n, array.begin() + n, array.end()); + auto nth_element = std::min_element(array.begin() + n, array.end()); - return array[n - 1] + (h - n) * (array[n] - array[n - 1]); + return array[n - 1] + (h - n) * (*nth_element - array[n - 1]); + } + + return std::numeric_limits::quiet_NaN(); + } + + void getManyFloat(const Float64 * levels, const size_t * indices, size_t size, Float64 * result) override + { + if (!array.empty()) + { + size_t prev_n = 0; + for (size_t i = 0; i < size; ++i) + { + auto level = levels[indices[i]]; + if (level == 0. || level == 1.) + throw Exception("QuantileExactExclusive cannot interpolate for the percentiles 1 and 0", ErrorCodes::BAD_ARGUMENTS); + + Float64 h = level * (array.size() + 1); + auto n = static_cast(h); + + if (n >= array.size()) + result[indices[i]] = array[array.size() - 1]; + else if (n < 1) + result[indices[i]] = array[0]; + else + { + std::nth_element(array.begin() + prev_n, array.begin() + n - 1, array.end()); + auto nth_element = std::min_element(array.begin() + n, array.end()); + + result[indices[i]] = array[n - 1] + (h - n) * (*nth_element - array[n - 1]); + prev_n = n - 1; + } + } + } + else + { + for (size_t i = 0; i < size; ++i) + result[i] = std::numeric_limits::quiet_NaN(); + } + } +}; + +/// QuantileExactInclusive is equivalent to Excel PERCENTILE and PERCENTILE.INC, R-7, SciPy-(1,1) +template +struct QuantileExactInclusive : public QuantileExact +{ + using QuantileExact::array; + + /// Get the value of the `level` quantile. The level must be between 0 and 1 including bounds. + Float64 getFloat(Float64 level) override + { + if (!array.empty()) + { + Float64 h = level * (array.size() - 1) + 1; + auto n = static_cast(h); + + if (n >= array.size()) + return array[array.size() - 1]; + else if (n < 1) + return array[0]; + + std::nth_element(array.begin(), array.begin() + n - 1, array.end()); + auto nth_element = std::min_element(array.begin() + n, array.end()); + + return array[n - 1] + (h - n) * (*nth_element - array[n - 1]); } return std::numeric_limits::quiet_NaN(); @@ -156,7 +226,7 @@ struct QuantileExactExclusive : public QuantileExact { auto level = levels[indices[i]]; - Float64 h = level * (array.size() + 1); + Float64 h = level * (array.size() - 1) + 1; auto n = static_cast(h); if (n >= array.size()) @@ -166,10 +236,10 @@ struct QuantileExactExclusive : public QuantileExact else { std::nth_element(array.begin() + prev_n, array.begin() + n - 1, array.end()); - std::nth_element(array.begin() + n, array.begin() + n, array.end()); + auto nth_element = std::min_element(array.begin() + n, array.end()); - result[indices[i]] = array[n - 1] + (h - n) * (array[n] - array[n - 1]); - prev_n = n; + result[indices[i]] = array[n - 1] + (h - n) * (*nth_element - array[n - 1]); + prev_n = n - 1; } } } From 73e208917c8a97eeeedf22a661fd1d1a0f6588b8 Mon Sep 17 00:00:00 2001 From: dimarub2000 Date: Wed, 14 Aug 2019 14:18:46 +0300 Subject: [PATCH 0948/1165] Fixed comment --- dbms/src/AggregateFunctions/QuantileExact.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dbms/src/AggregateFunctions/QuantileExact.h b/dbms/src/AggregateFunctions/QuantileExact.h index ffa12640f8e..058c433e992 100644 --- a/dbms/src/AggregateFunctions/QuantileExact.h +++ b/dbms/src/AggregateFunctions/QuantileExact.h @@ -122,7 +122,7 @@ struct QuantileExact virtual ~QuantileExact() = default; }; -/// QuantileExactInclusive is equivalent to Excel PERCENTILE.EXC, R-6, SAS-4, SciPy-(0,0) +/// QuantileExactExclusive is equivalent to Excel PERCENTILE.EXC, R-6, SAS-4, SciPy-(0,0) template struct QuantileExactExclusive : public QuantileExact { @@ -131,11 +131,11 @@ struct QuantileExactExclusive : public QuantileExact /// Get the value of the `level` quantile. The level must be between 0 and 1 excluding bounds. Float64 getFloat(Float64 level) override { - if (level == 0. || level == 1.) - throw Exception("QuantileExactExclusive cannot interpolate for the percentiles 1 and 0", ErrorCodes::BAD_ARGUMENTS); - if (!array.empty()) { + if (level == 0. || level == 1.) + throw Exception("QuantileExactExclusive cannot interpolate for the percentiles 1 and 0", ErrorCodes::BAD_ARGUMENTS); + Float64 h = level * (array.size() + 1); auto n = static_cast(h); From d9234a64c478d44c2b03bcf02c523a2f19b93485 Mon Sep 17 00:00:00 2001 From: Alexandr Krasheninnikov Date: Wed, 14 Aug 2019 15:18:11 +0300 Subject: [PATCH 0949/1165] Make function return initial user --- dbms/src/Functions/currentUser.cpp | 2 +- .../queries/0_stateless/00990_function_current_user.reference | 1 + dbms/tests/queries/0_stateless/00990_function_current_user.sql | 3 ++- docs/en/query_language/functions/other_functions.md | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/dbms/src/Functions/currentUser.cpp b/dbms/src/Functions/currentUser.cpp index fa8b3103be2..4501047fbb0 100644 --- a/dbms/src/Functions/currentUser.cpp +++ b/dbms/src/Functions/currentUser.cpp @@ -15,7 +15,7 @@ public: static constexpr auto name = "currentUser"; static FunctionPtr create(const Context & context) { - return std::make_shared(context.getClientInfo().current_user); + return std::make_shared(context.getClientInfo().initial_user); } explicit FunctionCurrentUser(const String & user_name_) : user_name{user_name_} diff --git a/dbms/tests/queries/0_stateless/00990_function_current_user.reference b/dbms/tests/queries/0_stateless/00990_function_current_user.reference index e8183f05f5d..f1f321b1ecd 100644 --- a/dbms/tests/queries/0_stateless/00990_function_current_user.reference +++ b/dbms/tests/queries/0_stateless/00990_function_current_user.reference @@ -1,3 +1,4 @@ 1 1 +1 1 1 diff --git a/dbms/tests/queries/0_stateless/00990_function_current_user.sql b/dbms/tests/queries/0_stateless/00990_function_current_user.sql index c925dfd8e47..57cd14c2b65 100644 --- a/dbms/tests/queries/0_stateless/00990_function_current_user.sql +++ b/dbms/tests/queries/0_stateless/00990_function_current_user.sql @@ -1,4 +1,5 @@ -- since actual user name is unknown, have to perform just smoke tests select currentUser() IS NOT NULL; select length(currentUser()) > 0; -select currentUser() = user(); \ No newline at end of file +select currentUser() = user(), currentUser() = USER(); +select currentUser() = initial_user from system.processes where query like '%$!@#%'; \ No newline at end of file diff --git a/docs/en/query_language/functions/other_functions.md b/docs/en/query_language/functions/other_functions.md index 05961caadc8..cc5fadcdd98 100644 --- a/docs/en/query_language/functions/other_functions.md +++ b/docs/en/query_language/functions/other_functions.md @@ -103,7 +103,7 @@ Returns the name of the current database. You can use this function in table engine parameters in a CREATE TABLE query where you need to specify the database. ## currentUser() -Returns the login of authorized user. +Returns the login of authorized user (initiator of query execution). ## isFinite(x) From d44d2d1731637cf6d259b6db147ae729ce21a7fe Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Wed, 14 Aug 2019 15:29:21 +0300 Subject: [PATCH 0950/1165] rewrite trash code in optimizeReadInOrder and disable read in order optimization with joins --- .../Interpreters/InterpreterSelectQuery.cpp | 34 +++++-------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.cpp b/dbms/src/Interpreters/InterpreterSelectQuery.cpp index e969e4fca3a..882bb44411b 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSelectQuery.cpp @@ -665,7 +665,8 @@ static UInt64 getLimitForSorting(const ASTSelectQuery & query, const Context & c } -static SortingInfoPtr optimizeReadInOrder(const MergeTreeData & merge_tree, const ASTSelectQuery & query, const Context & context) +static SortingInfoPtr optimizeReadInOrder(const MergeTreeData & merge_tree, const ASTSelectQuery & query, + const Context & context, const SyntaxAnalyzerResultPtr & syntax_result) { if (!merge_tree.hasSortingKey()) return {}; @@ -677,20 +678,12 @@ static SortingInfoPtr optimizeReadInOrder(const MergeTreeData & merge_tree, cons const auto & sorting_key_columns = merge_tree.getSortingKeyColumns(); size_t prefix_size = std::min(order_descr.size(), sorting_key_columns.size()); - auto order_by_expr = query.orderBy(); - SyntaxAnalyzerResultPtr syntax_result; - try - { - syntax_result = SyntaxAnalyzer(context).analyze(order_by_expr, merge_tree.getColumns().getAllPhysical()); - } - catch (const Exception &) - { - return {}; - } - for (size_t i = 0; i < prefix_size; ++i) { - /// Read in pk order in case of exact match with order key element + if (syntax_result->array_join_alias_to_name.count(order_descr[i].column_name)) + break; + + /// Optimize in case of exact match with order key element /// or in some simple cases when order key element is wrapped into monotonic function. int current_direction = order_descr[i].direction; if (order_descr[i].column_name == sorting_key_columns[i] && current_direction == read_direction) @@ -699,16 +692,7 @@ static SortingInfoPtr optimizeReadInOrder(const MergeTreeData & merge_tree, cons { const auto & ast = query.orderBy()->children[i]; ExpressionActionsPtr actions; - try - { - actions = ExpressionAnalyzer(ast->children.at(0), syntax_result, context).getActions(false); - } - catch (const Exception &) - { - /// Can't analyze order expression at this stage. - /// May be some actions required for order will be executed later. - break; - } + actions = ExpressionAnalyzer(ast->children.at(0), syntax_result, context).getActions(true); const auto & input_columns = actions->getRequiredColumnsWithTypes(); if (input_columns.size() != 1 || input_columns.front().name != sorting_key_columns[i]) @@ -820,10 +804,10 @@ void InterpreterSelectQuery::executeImpl(TPipeline & pipeline, const BlockInputS } SortingInfoPtr sorting_info; - if (settings.optimize_read_in_order && storage && query.orderBy() && !query.groupBy() && !query.final()) + if (settings.optimize_read_in_order && storage && query.orderBy() && !query.groupBy() && !query.final() && !query.join()) { if (const MergeTreeData * merge_tree_data = dynamic_cast(storage.get())) - sorting_info = optimizeReadInOrder(*merge_tree_data, query, context); + sorting_info = optimizeReadInOrder(*merge_tree_data, query, context, syntax_analyzer_result); } if (dry_run) From 15bbf080f36ecf1eb91bd4956639e6169ffee015 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Wed, 14 Aug 2019 15:54:41 +0300 Subject: [PATCH 0951/1165] changes after review --- dbms/programs/server/config.xml | 9 +++++++++ dbms/src/Interpreters/MetricLog.cpp | 19 ++++++++++--------- dbms/src/Interpreters/SystemLog.cpp | 3 +-- .../00990_metric_log_table_not_empty.sql | 4 ++-- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/dbms/programs/server/config.xml b/dbms/programs/server/config.xml index c09913cbd87..28901a3b897 100644 --- a/dbms/programs/server/config.xml +++ b/dbms/programs/server/config.xml @@ -329,6 +329,15 @@ text_log
    7500 + + diff --git a/docs/en/database_engines/mysql.md b/docs/en/database_engines/mysql.md index fd5417ee27d..24352c1924c 100644 --- a/docs/en/database_engines/mysql.md +++ b/docs/en/database_engines/mysql.md @@ -1,10 +1,10 @@ # MySQL -Allows to connect to some database on remote MySQL server and perform `INSERT` and `SELECT` queries with tables to exchange data between ClickHouse and MySQL. +Allows to connect to databases on a remote MySQL server and perform `INSERT` and `SELECT` queries with tables to exchange data between ClickHouse and MySQL. -The `MySQL` database engine translate queries to the MySQL server, so you can perform operations such as `SHOW TABLES` or `SHOW CREATE TABLE`. +The `MySQL` database engine translate queries to the MySQL server so you can perform operations such as `SHOW TABLES` or `SHOW CREATE TABLE`. -You cannot perform with tables the following queries: +You cannot perform the following queries: - `ATTACH`/`DETACH` - `DROP` @@ -48,7 +48,7 @@ BINARY | [FixedString](../data_types/fixedstring.md) All other MySQL data types are converted into [String](../data_types/string.md). -[Nullable](../data_types/nullable.md) data type is supported. +[Nullable](../data_types/nullable.md) is supported. ## Examples of Use @@ -120,3 +120,5 @@ SELECT * FROM mysql_db.mysql_table │ 3 │ 4 │ └────────┴───────┘ ``` + +[Original article](https://clickhouse.yandex/docs/en/database_engines/mysql/) diff --git a/docs/en/operations/table_engines/mergetree.md b/docs/en/operations/table_engines/mergetree.md index 2a099a8947d..56cc99f5653 100644 --- a/docs/en/operations/table_engines/mergetree.md +++ b/docs/en/operations/table_engines/mergetree.md @@ -28,7 +28,7 @@ Main features: ## Creating a Table {#table_engine-mergetree-creating-a-table} -``` +```sql CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] ( name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1], @@ -47,7 +47,7 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] For descriptions of request parameters, see the [request description](../../query_language/create.md). -**Query clauses** +### Query Clauses - `ENGINE` — Name and parameters of the engine. `ENGINE = MergeTree()`. The `MergeTree` engine does not have parameters. @@ -81,7 +81,7 @@ For descriptions of request parameters, see the [request description](../../quer - `merge_with_ttl_timeout` — Minimum delay in seconds before repeating a merge with TTL. Default value: 86400 (1 day). -**Example of setting the sections** +**Example of Sections Setting** ```sql ENGINE MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity=8192 @@ -107,7 +107,7 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] ) ENGINE [=] MergeTree(date-column [, sampling_expression], (primary, key), index_granularity) ``` -**MergeTree() parameters** +**MergeTree() Parameters** - `date-column` — The name of a column of the [Date](../../data_types/date.md) type. ClickHouse automatically creates partitions by month based on this column. The partition names are in the `"YYYYMM"` format. - `sampling_expression` — An expression for sampling. @@ -312,16 +312,16 @@ Reading from a table is automatically parallelized. Determines the lifetime of values. -The `TTL` clause can be set for the whole table and for each individual column. If `TTL` is set for the whole table, individual `TTL` for columns are ignored. +The `TTL` clause can be set for the whole table and for each individual column. If both `TTL` are set, ClickHouse uses that `TTL` which expires earlier. - -The table must have the column of the [Date](../../data_types/date.md) or [DateTime](../../data_types/datetime.md) data type. This date column should be used in the `TTL` clause. You can only set lifetime of the data as an interval from the date column value. +The table must have the column in the [Date](../../data_types/date.md) or [DateTime](../../data_types/datetime.md) data type. To define the lifetime of data, use operations on this time column, for example: ``` -TTL date_time + interval +TTL time_column +TTL time_column + interval ``` -You can set the `interval` by any expression, returning the value of the `DateTime` data type. For example, you can use [time interval](../../query_language/operators.md#operators-datetime) operators. +To define `interval`, use [time interval](../../query_language/operators.md#operators-datetime) operators. ``` TTL date_time + INTERVAL 1 MONTH @@ -330,20 +330,20 @@ TTL date_time + INTERVAL 15 HOUR **Column TTL** -When the values in the column expire, ClickHouse replace them with the default values for the column data type. If all the column values in the data part become expired, ClickHouse deletes this column from the data part in a filesystem. +When the values in the column expire, ClickHouse replaces them with the default values for the column data type. If all the column values in the data part expire, ClickHouse deletes this column from the data part in a filesystem. -The `TTL` clause cannot be used for key columns. +The `TTL` clause can't be used for key columns. **Table TTL** -When some data in table expires, ClickHouse deletes all the corresponding rows. +When data in a table expires, ClickHouse deletes all corresponding rows. -**Cleaning up of Data** +**Removing Data** -Data with expired TTL is removed, when ClickHouse merges data parts. +Data with an expired TTL is removed when ClickHouse merges data parts. -When ClickHouse see that some data is expired, it performs off-schedule merge. To control frequency of such merges, you can set [merge_with_ttl_timeout](#mergetree_setting-merge_with_ttl_timeout). If it is too low, many off-schedule merges consume much resources. +When ClickHouse see that data is expired, it performs an off-schedule merge. To control the frequency of such merges, you can set [merge_with_ttl_timeout](#mergetree_setting-merge_with_ttl_timeout). If the value is too low, it will perform many off-schedule merges that may consume a lot of resources. -If you perform the `SELECT` query between merges you can get the expired data. To avoid it, use the [OPTIMIZE](../../query_language/misc.md#misc_operations-optimize) query before `SELECT`. +If you perform the `SELECT` query between merges, you may get expired data. To avoid it, use the [OPTIMIZE](../../query_language/misc.md#misc_operations-optimize) query before `SELECT`. [Original article](https://clickhouse.yandex/docs/en/operations/table_engines/mergetree/) diff --git a/docs/en/query_language/create.md b/docs/en/query_language/create.md index 81d7982eb00..e40a452cfe0 100644 --- a/docs/en/query_language/create.md +++ b/docs/en/query_language/create.md @@ -10,10 +10,10 @@ CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster] [ENGINE = engine(.. - `IF NOT EXISTS` - If the `db_name` database already exists then: + If the `db_name` database already exists, then ClickHouse doesn't create a new database and: - - If clause is specified, ClickHouse doesn't create a new database and doesn't throw an exception. - - If clause is not specified, then ClickHouse doesn't create a new database and throw and exception. + - Doesn't throw an exception if clause is specified. + - Throws an exception if clause isn't specified. - `ON CLUSTER` @@ -23,7 +23,7 @@ CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster] [ENGINE = engine(.. - [MySQL](../database_engines/mysql.md) - Allows to retrieve data from the remote MySQL server. + Allows you to retrieve data from the remote MySQL server. By default, ClickHouse uses its own [database engine](../database_engines/index.md). diff --git a/docs/ru/database_engines/index.md b/docs/ru/database_engines/index.md index 3190a79017f..52aefe1bba2 100644 --- a/docs/ru/database_engines/index.md +++ b/docs/ru/database_engines/index.md @@ -1,9 +1,10 @@ -# Database Engines +# Движки баз данных -Database engines provide working with tables. +Движки баз данных обеспечивают работу с таблицами. -By default, ClickHouse uses its native database engine which provides configurable [table engines](../operations/table_engines/index.md) and [SQL dialect](../query_language/syntax.md). +По умолчанию ClickHouse использует собственный движок баз данных, который поддерживает конфигурируемые [движки таблиц](../operations/table_engines/index.md) и [диалект SQL](../query_language/syntax.md). -Also you can use the following database engines: +Также можно использовать следующие движки баз данных: - [MySQL](mysql.md) + diff --git a/docs/ru/database_engines/mysql.md b/docs/ru/database_engines/mysql.md index fd5417ee27d..acfb71d839c 100644 --- a/docs/ru/database_engines/mysql.md +++ b/docs/ru/database_engines/mysql.md @@ -1,10 +1,10 @@ # MySQL -Allows to connect to some database on remote MySQL server and perform `INSERT` and `SELECT` queries with tables to exchange data between ClickHouse and MySQL. +Позволяет подключаться к базам данных на удалённом MySQL сервере и выполнять запросы `INSERT` и `SELECT` для обмена данными между ClickHouse и MySQL. -The `MySQL` database engine translate queries to the MySQL server, so you can perform operations such as `SHOW TABLES` or `SHOW CREATE TABLE`. +Движок баз данных `MySQL` транслирует запросы при передаче на сервер MySQL, что позволяет выполнять и другие виды запросов, например `SHOW TABLES` или `SHOW CREATE TABLE`. -You cannot perform with tables the following queries: +Не поддерживаемые виды запросов: - `ATTACH`/`DETACH` - `DROP` @@ -12,48 +12,45 @@ You cannot perform with tables the following queries: - `CREATE TABLE` - `ALTER` +## Создание базы данных -## Creating a Database - -``` sql +```sql CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster] ENGINE = MySQL('host:port', 'database', 'user', 'password') ``` -**Engine Parameters** +**Параметры движка** -- `host:port` — MySQL server address. -- `database` — Remote database name. -- `user` — MySQL user. -- `password` — User password. +- `host:port` — адрес сервера MySQL. +- `database` — имя базы данных на удалённом сервере. +- `user` — пользователь MySQL. +- `password` — пароль пользователя. +## Поддержка типов данных -## Data Types Support +| MySQL | ClickHouse | +| ------ | ------------ | +| UNSIGNED TINYINT | [UInt8](../data_types/int_uint.md) | +| TINYINT | [Int8](../data_types/int_uint.md) | +| UNSIGNED SMALLINT | [UInt16](../data_types/int_uint.md) | +| SMALLINT | [Int16](../data_types/int_uint.md) | +| UNSIGNED INT, UNSIGNED MEDIUMINT | [UInt32](../data_types/int_uint.md) | +| INT, MEDIUMINT | [Int32](../data_types/int_uint.md) | +| UNSIGNED BIGINT | [UInt64](../data_types/int_uint.md) | +| BIGINT | [Int64](../data_types/int_uint.md) | +| FLOAT | [Float32](../data_types/float.md) | +| DOUBLE | [Float64](../data_types/float.md) | +| DATE | [Date](../data_types/date.md) | +| DATETIME, TIMESTAMP | [DateTime](../data_types/datetime.md) | +| BINARY | [FixedString](../data_types/fixedstring.md) | -MySQL | ClickHouse -------|------------ -UNSIGNED TINYINT | [UInt8](../data_types/int_uint.md) -TINYINT | [Int8](../data_types/int_uint.md) -UNSIGNED SMALLINT | [UInt16](../data_types/int_uint.md) -SMALLINT | [Int16](../data_types/int_uint.md) -UNSIGNED INT, UNSIGNED MEDIUMINT | [UInt32](../data_types/int_uint.md) -INT, MEDIUMINT | [Int32](../data_types/int_uint.md) -UNSIGNED BIGINT | [UInt64](../data_types/int_uint.md) -BIGINT | [Int64](../data_types/int_uint.md) -FLOAT | [Float32](../data_types/float.md) -DOUBLE | [Float64](../data_types/float.md) -DATE | [Date](../data_types/date.md) -DATETIME, TIMESTAMP | [DateTime](../data_types/datetime.md) -BINARY | [FixedString](../data_types/fixedstring.md) +Все прочие типы данных преобразуются в [String](../data_types/string.md). -All other MySQL data types are converted into [String](../data_types/string.md). +[Nullable](../data_types/nullable.md) поддержан. -[Nullable](../data_types/nullable.md) data type is supported. +## Примеры использования - -## Examples of Use - -Table in MySQL: +Таблица в MySQL: ``` mysql> USE test; @@ -77,14 +74,16 @@ mysql> select * from mysql_table; 1 row in set (0,00 sec) ``` -Database in ClickHouse, exchanging data with the MySQL server: +База данных в ClickHouse, позволяющая обмениваться данными с сервером MySQL: ```sql CREATE DATABASE mysql_db ENGINE = MySQL('localhost:3306', 'test', 'my_user', 'user_password') ``` + ```sql SHOW DATABASES ``` + ```text ┌─name─────┐ │ default │ @@ -92,31 +91,39 @@ SHOW DATABASES │ system │ └──────────┘ ``` + ```sql SHOW TABLES FROM mysql_db ``` + ```text ┌─name─────────┐ │ mysql_table │ └──────────────┘ ``` + ```sql SELECT * FROM mysql_db.mysql_table ``` + ```text ┌─int_id─┬─value─┐ │ 1 │ 2 │ └────────┴───────┘ ``` + ```sql INSERT INTO mysql_db.mysql_table VALUES (3,4) ``` + ```sql SELECT * FROM mysql_db.mysql_table ``` + ```text ┌─int_id─┬─value─┐ │ 1 │ 2 │ │ 3 │ 4 │ └────────┴───────┘ ``` + diff --git a/docs/ru/operations/table_engines/mergetree.md b/docs/ru/operations/table_engines/mergetree.md index 84ca187fd6a..d47336c2593 100644 --- a/docs/ru/operations/table_engines/mergetree.md +++ b/docs/ru/operations/table_engines/mergetree.md @@ -40,14 +40,15 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] [ORDER BY expr] [PRIMARY KEY expr] [SAMPLE BY expr] +[TTL expr] [SETTINGS name=value, ...] ``` Описание параметров запроса смотрите в [описании запроса](../../query_language/create.md). -**Секции запроса** +### Секции запроса -- `ENGINE` — Имя и параметры движка. `ENGINE = MergeTree()`. `MergeTree` не имеет параметров. +- `ENGINE` — имя и параметры движка. `ENGINE = MergeTree()`. `MergeTree` не имеет параметров. - `PARTITION BY` — [ключ партиционирования](custom_partitioning_key.md). @@ -66,22 +67,22 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] Если используется выражение для сэмплирования, то первичный ключ должен содержать его. Пример: `SAMPLE BY intHash32(UserID) ORDER BY (CounterID, EventDate, intHash32(UserID))`. -- `TTL` - выражение для задания времени хранения строк. +- `TTL` — выражение, определяющее длительность хранения строк. - Оно должно зависеть от стобца типа `Date` или `DateTime` и в качестве результата вычислять столбец типа `Date` или `DateTime`. Пример: - `TTL date + INTERVAL 1 DAY` + Должно зависеть от столбца `Date` или `DateTime` и возвращать столбец `Date` или `DateTime`. Пример:`TTL date + INTERVAL 1 DAY` - Подробнее смотрите в [TTL для стоблцов и таблиц](mergetree.md) + Дополнительные сведения смотрите в разделе [TTL для столбцов и таблиц](mergetree.md) - `SETTINGS` — дополнительные параметры, регулирующие поведение `MergeTree`: - `index_granularity` — гранулярность индекса. Число строк данных между «засечками» индекса. По умолчанию — 8192. Список всех доступных параметров можно посмотреть в [MergeTreeSettings.h](https://github.com/yandex/ClickHouse/blob/master/dbms/src/Storages/MergeTree/MergeTreeSettings.h). - `min_merge_bytes_to_use_direct_io` — минимальный объем данных, необходимый для прямого (небуферизованного) чтения/записи (direct I/O) на диск. При слиянии частей данных ClickHouse вычисляет общий объем хранения всех данных, подлежащих слиянию. Если общий объем хранения всех данных для чтения превышает `min_bytes_to_use_direct_io` байт, тогда ClickHouse использует флаг `O_DIRECT` при чтении данных с диска. Если `min_merge_bytes_to_use_direct_io = 0`, тогда прямой ввод-вывод отключен. Значение по умолчанию: `10 * 1024 * 1024 * 1024` байт. + - `merge_with_ttl_timeout` - Минимальное время в секундах для повторного выполнения слияний с TTL. По умолчанию - 86400 (1 день). **Пример задания секций** -``` +```sql ENGINE MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity=8192 ``` @@ -109,7 +110,8 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] - `date-column` — имя столбца с типом [Date](../../data_types/date.md). На основе этого столбца ClickHouse автоматически создаёт партиции по месяцам. Имена партиций имеют формат `"YYYYMM"`. - `sampling_expression` — выражение для сэмплирования. -- `(primary, key)` — первичный ключ. Тип — [Tuple()](../../data_types/tuple.md- `index_granularity` — гранулярность индекса. Число строк данных между «засечками» индекса. Для большинства задач подходит значение 8192. +- `(primary, key)` — первичный ключ. Тип — [Tuple()](../../data_types/tuple.md) +- `index_granularity` — гранулярность индекса. Число строк данных между «засечками» индекса. Для большинства задач подходит значение 8192. **Пример** @@ -118,6 +120,7 @@ MergeTree(EventDate, intHash32(UserID), (CounterID, EventDate, intHash32(UserID) ``` Движок `MergeTree` сконфигурирован таким же образом, как и в примере выше для основного способа конфигурирования движка. + ## Хранение данных @@ -298,13 +301,42 @@ INDEX b (u64 * length(str), i32 + f64 * 100, date, str) TYPE set(100) GRANULARIT Чтения из таблицы автоматически распараллеливаются. +## TTL для столбцов и таблиц {#table_engine-mergetree-ttl} -## TTL для столбцов и таблиц +Определяет время жизни значений. -Данные с истекшим TTL удаляются во время слияний. +Секция `TTL` может быть установлена как для всей таблицы, так и для каждого отдельного столбца. Если установлены оба `TTL`, то ClickHouse использует тот, что истекает раньше. -Если TTL указан для столбца, то когда он истекает, значение заменяется на значение по умолчанию. Если все значения столбца обнулены в куске, то данные этого столбца удаляются с диска в куске. Если TTL указан для таблицы, то когда он истекает, удаляется строка. +Таблица должна иметь столбец типа [Date](../../data_types/date.md) или [DateTime](../../data_types/datetime.md). Для установки времени жизни данных, следует использовать операцию со столбцом с временем, например: -Когда истекает TTL для какого-нибудь значения или строки в куске, назначается внеочередное слияние. Чтобы контролировать частоту слияний с TTL, вы можете задать настройку `merge_with_ttl_timeout`. Если ее значение слишком мало, то будет происходить слишком много внеочередных слияний и мало обычных, вследствие чего может ухудшиться производительность. +``` +TTL time_column +TTL time_column + interval +``` + +Чтобы задать `interval`, используйте операторы [интервала времени](../../query_language/operators.md#operators-datetime). + +``` +TTL date_time + INTERVAL 1 MONTH +TTL date_time + INTERVAL 15 HOUR +``` + +**TTL столбца** + +Когда срок действия значений в столбце истечет, ClickHouse заменит их значениями по умолчанию для типа данных столбца. Если срок действия всех значений столбцов в части данных истек, ClickHouse удаляет столбец из куска данных в файловой системе. + +Секцию `TTL` нельзя использовать для ключевых столбцов. + +**TTL таблицы** + +Когда некоторые данные в таблице устаревают, ClickHouse удаляет все соответствующие строки. + +**Удаление данных** + +Данные с истекшим TTL удаляются, когда ClickHouse мёржит куски данных. + +Когда ClickHouse видит, что некоторые данные устарели, он выполняет внеплановые мёржи. Для управление частотой подобных мёржей, можно задать настройку [merge_with_ttl_timeout](#mergetree_setting-merge_with_ttl_timeout). Если её значение слишком низкое, придется выполнять много внеплановых мёржей, которые могут начать потреблять значительную долю ресурсов сервера. + +Если вы выполните запрос `SELECT` между слияниями вы можете получить устаревшие данные. Чтобы избежать этого используйте запрос [OPTIMIZE](../../query_language/misc.md#misc_operations-optimize) перед `SELECT`. [Оригинальная статья](https://clickhouse.yandex/docs/ru/operations/table_engines/mergetree/) diff --git a/docs/ru/query_language/create.md b/docs/ru/query_language/create.md index be75bb9ce51..ebbef603390 100644 --- a/docs/ru/query_language/create.md +++ b/docs/ru/query_language/create.md @@ -1,13 +1,30 @@ -## CREATE DATABASE +## CREATE DATABASE {#query_language-create-database} -Создание базы данных db\_name. +Создает базу данных. ```sql -CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster] +CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster] [ENGINE = engine(...)] ``` -`База данных` - это просто директория для таблиц. -Если написано `IF NOT EXISTS`, то запрос не будет возвращать ошибку, если база данных уже существует. +### Секции + +- `IF NOT EXISTS` + + Если база данных с именем `db_name` уже существует, то ClickHouse не создаёт базу данных и: + - Не генерирует исключение, если секция указана. + - Генерирует исключение, если секция не указана. + +- `ON CLUSTER` + + ClickHouse создаёт базу данных `db_name` на всех серверах указанного кластера. + +- `ENGINE` + + - [MySQL](../database_engines/mysql.md) + + Позволяет получать данные с удаленного сервера MySQL. + + По умолчанию ClickHouse использует собственный [движок баз данных](../database_engines/index.md). ## CREATE TABLE {#create-table-query} @@ -48,7 +65,7 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name ENGINE = engine AS SELECT ... Во всех случаях, если указано `IF NOT EXISTS`, то запрос не будет возвращать ошибку, если таблица уже существует. В этом случае, запрос будет ничего не делать. -После секции `ENGINE` в запросе могут использоваться и другие секции в зависимости от движка. Подробную документацию по созданию таблиц смотрите в описаниях [движков](../operations/table_engines/index.md#table_engines). +После секции `ENGINE` в запросе могут использоваться и другие секции в зависимости от движка. Подробную документацию по созданию таблиц смотрите в описаниях [движков таблиц](../operations/table_engines/index.md#table_engines). ### Значения по умолчанию {#create-default-values} @@ -88,11 +105,7 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name ENGINE = engine AS SELECT ... ### Выражение для TTL -Может быть указано только для таблиц семейства MergeTree. Выражение для указания времени хранения значений. Оно должно зависеть от стобца типа `Date` или `DateTime` и в качестве результата вычислять столбец типа `Date` или `DateTime`. Пример: - `TTL date + INTERVAL 1 DAY` - -Нельзя указывать TTL для ключевых столбцов. Подробнее смотрите в [TTL для стоблцов и таблиц](../operations/table_engines/mergetree.md) - +Определяет время хранения значений. Может быть указано только для таблиц семейства MergeTree. Подробнее смотрите в [TTL для столбцов и таблиц](../operations/table_engines/mergetree.md#table_engine-mergetree-ttl). ## Форматы сжатия для колонок diff --git a/docs/ru/query_language/operators.md b/docs/ru/query_language/operators.md index a493e555af7..de38bb5b193 100644 --- a/docs/ru/query_language/operators.md +++ b/docs/ru/query_language/operators.md @@ -65,13 +65,13 @@ `a GLOBAL NOT IN ...` - функция `globalNotIn(a, b)` -## Оператор для работы с датами и временем +## Оператор для работы с датами и временем {#operators-datetime} ``` sql EXTRACT(part FROM date); ``` -Позволяет извлечь отдельные части из переданной даты. Например, можно получить месяц из даты, или минуты из времени. +Позволяет извлечь отдельные части из переданной даты. Например, можно получить месяц из даты, или минуты из времени. В параметре `part` указывается, какой фрагмент даты нужно получить. Доступные значения: @@ -99,8 +99,8 @@ SELECT EXTRACT(YEAR FROM toDate('2017-06-15')); ``` sql CREATE TABLE test.Orders ( - OrderId UInt64, - OrderName String, + OrderId UInt64, + OrderName String, OrderDate DateTime ) ENGINE = Log; @@ -110,11 +110,11 @@ ENGINE = Log; INSERT INTO test.Orders VALUES (1, 'Jarlsberg Cheese', toDateTime('2008-10-11 13:23:44')); ``` ``` sql -SELECT - toYear(OrderDate) AS OrderYear, - toMonth(OrderDate) AS OrderMonth, - toDayOfMonth(OrderDate) AS OrderDay, - toHour(OrderDate) AS OrderHour, +SELECT + toYear(OrderDate) AS OrderYear, + toMonth(OrderDate) AS OrderMonth, + toDayOfMonth(OrderDate) AS OrderDay, + toHour(OrderDate) AS OrderHour, toMinute(OrderDate) AS OrderMinute, toSecond(OrderDate) AS OrderSecond FROM test.Orders; From 047a14a1893910b37b0fe287d012a715abd84f7a Mon Sep 17 00:00:00 2001 From: chertus Date: Wed, 14 Aug 2019 19:53:30 +0300 Subject: [PATCH 0972/1165] one more minor refactoring --- dbms/src/Interpreters/ActionsVisitor.h | 10 ++++++---- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 4 ++-- dbms/src/Interpreters/ExpressionAnalyzer.h | 2 +- dbms/src/Interpreters/GlobalSubqueriesVisitor.h | 1 - 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/dbms/src/Interpreters/ActionsVisitor.h b/dbms/src/Interpreters/ActionsVisitor.h index 9841c8e9df8..4d03f758f61 100644 --- a/dbms/src/Interpreters/ActionsVisitor.h +++ b/dbms/src/Interpreters/ActionsVisitor.h @@ -54,7 +54,6 @@ struct ScopeStack /// Collect ExpressionAction from AST. Returns PreparedSets and SubqueriesForSets too. -/// After AST is visited source ExpressionActions should be updated with popActionsLevel() method. class ActionsVisitor { public: @@ -63,9 +62,11 @@ public: PreparedSets & prepared_sets_, SubqueriesForSets & subqueries_for_sets_, bool no_subqueries_, bool only_consts_, bool no_storage_or_local_, std::ostream * ostr_ = nullptr); - void visit(const ASTPtr & ast); - - ExpressionActionsPtr popActionsLevel() { return actions_stack.popLevel(); } + void visit(const ASTPtr & ast, ExpressionActionsPtr & actions) + { + visit(ast); + actions = actions_stack.popLevel(); + } private: const Context & context; @@ -81,6 +82,7 @@ private: std::ostream * ostr; ScopeStack actions_stack; + void visit(const ASTPtr & ast); SetPtr makeSet(const ASTFunction * node, const Block & sample_block); }; diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index 1990c427020..2a96a58c4f2 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -320,8 +321,7 @@ void ExpressionAnalyzer::getRootActions(const ASTPtr & ast, bool no_subqueries, ActionsVisitor actions_visitor(context, settings.size_limits_for_set, subquery_depth, sourceColumns(), actions, prepared_sets, subqueries_for_sets, no_subqueries, only_consts, !isRemoteStorage(), log.stream()); - actions_visitor.visit(ast); - actions = actions_visitor.popActionsLevel(); + actions_visitor.visit(ast, actions); } diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.h b/dbms/src/Interpreters/ExpressionAnalyzer.h index d40b1c219b5..2e70662f196 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.h +++ b/dbms/src/Interpreters/ExpressionAnalyzer.h @@ -2,9 +2,9 @@ #include #include -#include #include #include +#include #include #include diff --git a/dbms/src/Interpreters/GlobalSubqueriesVisitor.h b/dbms/src/Interpreters/GlobalSubqueriesVisitor.h index 1622c27f62f..583ec026af0 100644 --- a/dbms/src/Interpreters/GlobalSubqueriesVisitor.h +++ b/dbms/src/Interpreters/GlobalSubqueriesVisitor.h @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include From e83482b51220991c95060d3df44d8938a5f9afc8 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Wed, 14 Aug 2019 20:21:45 +0300 Subject: [PATCH 0973/1165] metric_log.xml --- dbms/programs/server/config.d/metric_log.xml | 8 ++++++++ dbms/programs/server/config.xml | 1 + 2 files changed, 9 insertions(+) create mode 100644 dbms/programs/server/config.d/metric_log.xml diff --git a/dbms/programs/server/config.d/metric_log.xml b/dbms/programs/server/config.d/metric_log.xml new file mode 100644 index 00000000000..0ca9f162416 --- /dev/null +++ b/dbms/programs/server/config.d/metric_log.xml @@ -0,0 +1,8 @@ + + + system + metric_log
    + 7500 + 1000 +
    +
    diff --git a/dbms/programs/server/config.xml b/dbms/programs/server/config.xml index 28901a3b897..44b3c25c19d 100644 --- a/dbms/programs/server/config.xml +++ b/dbms/programs/server/config.xml @@ -329,6 +329,7 @@ text_log
    7500 + --> diff --git a/docs/en/query_language/agg_functions/reference.md b/docs/en/query_language/agg_functions/reference.md index 350803f5aef..3e3e1e2cc01 100644 --- a/docs/en/query_language/agg_functions/reference.md +++ b/docs/en/query_language/agg_functions/reference.md @@ -650,7 +650,7 @@ The function takes a variable number of parameters. Parameters can be `Tuple`, ` - [uniqHLL12](#agg_function-uniqhll12) -## groupArray(x), groupArray(max_size)(x) +## groupArray(x), groupArray(max_size)(x) {#agg_function-grouparray} Creates an array of argument values. Values can be added to the array in any (indeterminate) order. From b1d1a23318758c74bb7a883bf39022db584474b5 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Thu, 15 Aug 2019 13:10:59 +0300 Subject: [PATCH 0986/1165] DOCAPI-7431: Formatted queries docs (#6490) --- docs/en/interfaces/cli.md | 25 +++++++++++++++++++++++++ docs/en/interfaces/http.md | 9 +++++++++ 2 files changed, 34 insertions(+) diff --git a/docs/en/interfaces/cli.md b/docs/en/interfaces/cli.md index 09c8baed5f5..9f9448f27c8 100644 --- a/docs/en/interfaces/cli.md +++ b/docs/en/interfaces/cli.md @@ -65,6 +65,31 @@ You can cancel a long query by pressing Ctrl+C. However, you will still need to The command-line client allows passing external data (external temporary tables) for querying. For more information, see the section "External data for query processing". +### Queries with Parameters {#cli-queries-with-parameters} + +You can create a query with parameters, and pass values for these parameters with the parameters of the client app. For example: + +```bash +clickhouse-client --param_parName="[1, 2]" -q "SELECT * FROM table WHERE a = {parName:Array(UInt16)}" +``` + +#### Syntax of a Query {#cli-queries-with-parameters-syntax} + +Format a query by the standard method. Values that you want to put into the query from the app parameters place in braces and format as follows: + +``` +{:} +``` + +- `name` — Identifier of a placeholder that should be used in app parameter as `--param_name = value`. +- `data type` — A data type of app parameter value. For example, data structure like `(integer, ('string', integer))` can have a data type `Tuple(UInt8, Tuple(String, UInt8))` (also you can use another [integer](../data_types/int_uint.md) types). + +#### Example + +```bash +clickhouse-client --param_tuple_in_tuple="(10, ('dt', 10))" -q "SELECT * FROM table WHERE val = {tuple_in_tuple:Tuple(UInt8, Tuple(String, UInt8))}" +``` + ## Configuring {#interfaces_cli_configuration} You can pass parameters to `clickhouse-client` (all parameters have a default value) using: diff --git a/docs/en/interfaces/http.md b/docs/en/interfaces/http.md index 37da364942c..ef32b101b71 100644 --- a/docs/en/interfaces/http.md +++ b/docs/en/interfaces/http.md @@ -244,5 +244,14 @@ curl -sS 'http://localhost:8123/?max_result_bytes=4000000&buffer_size=3000000&wa Use buffering to avoid situations where a query processing error occurred after the response code and HTTP headers were sent to the client. In this situation, an error message is written at the end of the response body, and on the client side, the error can only be detected at the parsing stage. +### Queries with Parameters {#cli-queries-with-parameters} + +You can create a query with parameters, and pass values for these parameters with the parameters of the HTTP request. For more information, see [CLI Formatted Queries](cli.md#cli-queries-with-parameters). + +### Example + +```bash +curl -sS "
    ?param_id=2¶m_phrase=test" -d "SELECT * FROM table WHERE int_column = {id:UInt8} and string_column = {phrase:String}" +``` [Original article](https://clickhouse.yandex/docs/en/interfaces/http_interface/) From 6ef3b5f9c758962f6175405da46170ed5555c83a Mon Sep 17 00:00:00 2001 From: CurtizJ Date: Thu, 15 Aug 2019 13:15:04 +0300 Subject: [PATCH 0987/1165] fix usage of global syntax_result in optimizeReadInOrder --- dbms/src/Interpreters/InterpreterSelectQuery.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.cpp b/dbms/src/Interpreters/InterpreterSelectQuery.cpp index 9a6c15f87f6..6786f64795d 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSelectQuery.cpp @@ -666,7 +666,7 @@ static UInt64 getLimitForSorting(const ASTSelectQuery & query, const Context & c static SortingInfoPtr optimizeReadInOrder(const MergeTreeData & merge_tree, const ASTSelectQuery & query, - const Context & context, const SyntaxAnalyzerResultPtr & syntax_result) + const Context & context, const SyntaxAnalyzerResultPtr & global_syntax_result) { if (!merge_tree.hasSortingKey()) return {}; @@ -680,7 +680,7 @@ static SortingInfoPtr optimizeReadInOrder(const MergeTreeData & merge_tree, cons for (size_t i = 0; i < prefix_size; ++i) { - if (syntax_result->array_join_result_to_source.count(order_descr[i].column_name)) + if (global_syntax_result->array_join_result_to_source.count(order_descr[i].column_name)) break; /// Optimize in case of exact match with order key element @@ -690,9 +690,9 @@ static SortingInfoPtr optimizeReadInOrder(const MergeTreeData & merge_tree, cons prefix_order_descr.push_back(order_descr[i]); else { - const auto & ast = query.orderBy()->children[i]; - ExpressionActionsPtr actions; - actions = ExpressionAnalyzer(ast->children.at(0), syntax_result, context).getActions(true); + auto ast = query.orderBy()->children[i]->children.at(0); + auto syntax_result = SyntaxAnalyzer(context).analyze(ast, global_syntax_result->required_source_columns); + auto actions = ExpressionAnalyzer(ast, syntax_result, context).getActions(true); const auto & input_columns = actions->getRequiredColumnsWithTypes(); if (input_columns.size() != 1 || input_columns.front().name != sorting_key_columns[i]) From e2171a038b56cca3504ed42870e58698550dbc08 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 15 Aug 2019 14:10:33 +0300 Subject: [PATCH 0988/1165] Temporarily disabled 00963_temporary_live_view_watch_live_timeout. --- ..._temporary_live_view_watch_live_timeout.py | 49 ------------------- 1 file changed, 49 deletions(-) delete mode 100755 dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py diff --git a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py deleted file mode 100755 index df627c84e49..00000000000 --- a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python -import os -import sys -import signal - -CURDIR = os.path.dirname(os.path.realpath(__file__)) -sys.path.insert(0, os.path.join(CURDIR, 'helpers')) - -from client import client, prompt, end_of_block - -log = None -# uncomment the line below for debugging -#log=sys.stdout - -with client(name='client1>', log=log) as client1, client(name='client2>', log=log) as client2: - client1.expect(prompt) - client2.expect(prompt) - - client1.send('DROP TABLE IF EXISTS test.lv') - client1.expect(prompt) - client1.send('DROP TABLE IF EXISTS test.mt') - client1.expect(prompt) - client1.send('SET temporary_live_view_timeout=1') - client1.expect(prompt) - client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') - client1.expect(prompt) - client1.send('CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') - client1.expect(prompt) - client1.send('WATCH test.lv') - client1.expect(r'0.*1' + end_of_block) - client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') - client2.expect(prompt) - client1.expect(r'6.*2' + end_of_block) - client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') - client2.expect(prompt) - client1.expect(r'21.*3' + end_of_block) - # send Ctrl-C - client1.send('\x03', eol='') - match = client1.expect('(%s)|([#\$] )' % prompt) - if match.groups()[1]: - client1.send(client1.command) - client1.expect(prompt) - client1.send('SELECT sleep(1)') - client1.expect(prompt) - client1.send('DROP TABLE test.lv') - client1.expect('Table test.lv doesn\'t exist') - client1.expect(prompt) - client1.send('DROP TABLE test.mt') - client1.expect(prompt) From 67f6129284a12b207f9debf720ae6de462573d1a Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 15 Aug 2019 14:18:41 +0300 Subject: [PATCH 0989/1165] Temporarily disabled 00963_temporary_live_view_watch_live_timeout. --- ...y_live_view_watch_live_timeout.py.disabled | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100755 dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py.disabled diff --git a/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py.disabled b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py.disabled new file mode 100755 index 00000000000..df627c84e49 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00963_temporary_live_view_watch_live_timeout.py.disabled @@ -0,0 +1,49 @@ +#!/usr/bin/env python +import os +import sys +import signal + +CURDIR = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(CURDIR, 'helpers')) + +from client import client, prompt, end_of_block + +log = None +# uncomment the line below for debugging +#log=sys.stdout + +with client(name='client1>', log=log) as client1, client(name='client2>', log=log) as client2: + client1.expect(prompt) + client2.expect(prompt) + + client1.send('DROP TABLE IF EXISTS test.lv') + client1.expect(prompt) + client1.send('DROP TABLE IF EXISTS test.mt') + client1.expect(prompt) + client1.send('SET temporary_live_view_timeout=1') + client1.expect(prompt) + client1.send('CREATE TABLE test.mt (a Int32) Engine=MergeTree order by tuple()') + client1.expect(prompt) + client1.send('CREATE TEMPORARY LIVE VIEW test.lv AS SELECT sum(a) FROM test.mt') + client1.expect(prompt) + client1.send('WATCH test.lv') + client1.expect(r'0.*1' + end_of_block) + client2.send('INSERT INTO test.mt VALUES (1),(2),(3)') + client2.expect(prompt) + client1.expect(r'6.*2' + end_of_block) + client2.send('INSERT INTO test.mt VALUES (4),(5),(6)') + client2.expect(prompt) + client1.expect(r'21.*3' + end_of_block) + # send Ctrl-C + client1.send('\x03', eol='') + match = client1.expect('(%s)|([#\$] )' % prompt) + if match.groups()[1]: + client1.send(client1.command) + client1.expect(prompt) + client1.send('SELECT sleep(1)') + client1.expect(prompt) + client1.send('DROP TABLE test.lv') + client1.expect('Table test.lv doesn\'t exist') + client1.expect(prompt) + client1.send('DROP TABLE test.mt') + client1.expect(prompt) From 1b500ade459d51845fa881f250ddd58d07b8cfe8 Mon Sep 17 00:00:00 2001 From: chertus Date: Thu, 15 Aug 2019 14:22:19 +0300 Subject: [PATCH 0990/1165] remove duplicated include --- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index 86cf8cd0d68..eaba3d568e3 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -56,7 +56,6 @@ #include #include -#include #include #include #include From 994f9f3cc6f21beacf0e0f643daf62cd0beda5af Mon Sep 17 00:00:00 2001 From: chertus Date: Thu, 15 Aug 2019 16:54:59 +0300 Subject: [PATCH 0991/1165] unify ActionsVisitor: rewrite as InDepthNodeVisitor --- dbms/src/Interpreters/ActionsVisitor.cpp | 551 ++++++++++--------- dbms/src/Interpreters/ActionsVisitor.h | 80 ++- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 7 +- 3 files changed, 339 insertions(+), 299 deletions(-) diff --git a/dbms/src/Interpreters/ActionsVisitor.cpp b/dbms/src/Interpreters/ActionsVisitor.cpp index 523343a288e..7c6f97d5ed5 100644 --- a/dbms/src/Interpreters/ActionsVisitor.cpp +++ b/dbms/src/Interpreters/ActionsVisitor.cpp @@ -1,3 +1,5 @@ +#include + #include #include @@ -19,8 +21,6 @@ #include #include -#include -#include #include #include #include @@ -228,346 +228,351 @@ const Block & ScopeStack::getSampleBlock() const return stack.back().actions->getSampleBlock(); } - -ActionsVisitor::ActionsVisitor( - const Context & context_, SizeLimits set_size_limit_, size_t subquery_depth_, - const NamesAndTypesList & source_columns_, const ExpressionActionsPtr & actions, - PreparedSets & prepared_sets_, SubqueriesForSets & subqueries_for_sets_, - bool no_subqueries_, bool only_consts_, bool no_storage_or_local_, std::ostream * ostr_) -: context(context_), - set_size_limit(set_size_limit_), - subquery_depth(subquery_depth_), - source_columns(source_columns_), - prepared_sets(prepared_sets_), - subqueries_for_sets(subqueries_for_sets_), - no_subqueries(no_subqueries_), - only_consts(only_consts_), - no_storage_or_local(no_storage_or_local_), - visit_depth(0), - ostr(ostr_), - actions_stack(actions, context) +struct CachedColumnName { + String cached; + + const String & get(const ASTPtr & ast) + { + if (cached.empty()) + cached = ast->getColumnName(); + return cached; + } +}; + +bool ActionsMatcher::needChildVisit(const ASTPtr & node, const ASTPtr & child) +{ + /// Visit children themself + if (node->as() || + node->as() || + node->as()) + return false; + + /// Do not go to FROM, JOIN, UNION. + if (child->as() || + child->as()) + return false; + + return true; } -void ActionsVisitor::visit(const ASTPtr & ast) +void ActionsMatcher::visit(const ASTPtr & ast, Data & data) { - DumpASTNode dump(*ast, ostr, visit_depth, "getActions"); + if (const auto * identifier = ast->as()) + visit(*identifier, ast, data); + else if (const auto * node = ast->as()) + visit(*node, ast, data); + else if (const auto * literal = ast->as()) + visit(*literal, ast, data); +} - String ast_column_name; - auto getColumnName = [&ast, &ast_column_name]() +void ActionsMatcher::visit(const ASTIdentifier & identifier, const ASTPtr & ast, Data & data) +{ + CachedColumnName column_name; + + if (!data.only_consts && !data.actions_stack.getSampleBlock().has(column_name.get(ast))) { - if (ast_column_name.empty()) - ast_column_name = ast->getColumnName(); + /// The requested column is not in the block. + /// If such a column exists in the table, then the user probably forgot to surround it with an aggregate function or add it to GROUP BY. - return ast_column_name; - }; + bool found = false; + for (const auto & column_name_type : data.source_columns) + if (column_name_type.name == column_name.get(ast)) + found = true; - /// If the result of the calculation already exists in the block. - if ((ast->as() || ast->as()) && actions_stack.getSampleBlock().has(getColumnName())) + if (found) + throw Exception("Column " + column_name.get(ast) + " is not under aggregate function and not in GROUP BY.", + ErrorCodes::NOT_AN_AGGREGATE); + + /// Special check for WITH statement alias. Add alias action to be able to use this alias. + if (identifier.prefer_alias_to_column_name && !identifier.alias.empty()) + data.actions_stack.addAction(ExpressionAction::addAliases({{identifier.name, identifier.alias}})); + } +} + +void ActionsMatcher::visit(const ASTFunction & node, const ASTPtr & ast, Data & data) +{ + CachedColumnName column_name; + + if (data.hasColumn(column_name.get(ast))) return; - if (const auto * identifier = ast->as()) + if (node.name == "lambda") + throw Exception("Unexpected lambda expression", ErrorCodes::UNEXPECTED_EXPRESSION); + + /// Function arrayJoin. + if (node.name == "arrayJoin") { - if (!only_consts && !actions_stack.getSampleBlock().has(getColumnName())) + if (node.arguments->children.size() != 1) + throw Exception("arrayJoin requires exactly 1 argument", ErrorCodes::TYPE_MISMATCH); + + ASTPtr arg = node.arguments->children.at(0); + visit(arg, data); + if (!data.only_consts) { - /// The requested column is not in the block. - /// If such a column exists in the table, then the user probably forgot to surround it with an aggregate function or add it to GROUP BY. - - bool found = false; - for (const auto & column_name_type : source_columns) - if (column_name_type.name == getColumnName()) - found = true; - - if (found) - throw Exception("Column " + getColumnName() + " is not under aggregate function and not in GROUP BY.", - ErrorCodes::NOT_AN_AGGREGATE); - - /// Special check for WITH statement alias. Add alias action to be able to use this alias. - if (identifier->prefer_alias_to_column_name && !identifier->alias.empty()) - actions_stack.addAction(ExpressionAction::addAliases({{identifier->name, identifier->alias}})); + String result_name = column_name.get(ast); + data.actions_stack.addAction(ExpressionAction::copyColumn(arg->getColumnName(), result_name)); + NameSet joined_columns; + joined_columns.insert(result_name); + data.actions_stack.addAction(ExpressionAction::arrayJoin(joined_columns, false, data.context)); } + + return; } - else if (const auto * node = ast->as()) + + SetPtr prepared_set; + if (functionIsInOrGlobalInOperator(node.name)) { - if (node->name == "lambda") - throw Exception("Unexpected lambda expression", ErrorCodes::UNEXPECTED_EXPRESSION); + /// Let's find the type of the first argument (then getActionsImpl will be called again and will not affect anything). + visit(node.arguments->children.at(0), data); - /// Function arrayJoin. - if (node->name == "arrayJoin") + if (!data.no_subqueries) { - if (node->arguments->children.size() != 1) - throw Exception("arrayJoin requires exactly 1 argument", ErrorCodes::TYPE_MISMATCH); - - ASTPtr arg = node->arguments->children.at(0); - visit(arg); - if (!only_consts) + /// Transform tuple or subquery into a set. + prepared_set = makeSet(node, data); + } + else + { + if (!data.only_consts) { - String result_name = getColumnName(); - actions_stack.addAction(ExpressionAction::copyColumn(arg->getColumnName(), result_name)); - NameSet joined_columns; - joined_columns.insert(result_name); - actions_stack.addAction(ExpressionAction::arrayJoin(joined_columns, false, context)); - } + /// We are in the part of the tree that we are not going to compute. You just need to define types. + /// Do not subquery and create sets. We treat "IN" as "ignoreExceptNull" function. + data.actions_stack.addAction(ExpressionAction::applyFunction( + FunctionFactory::instance().get("ignoreExceptNull", data.context), + { node.arguments->children.at(0)->getColumnName() }, + column_name.get(ast))); + } return; } + } - SetPtr prepared_set; - if (functionIsInOrGlobalInOperator(node->name)) + /// A special function `indexHint`. Everything that is inside it is not calculated + /// (and is used only for index analysis, see KeyCondition). + if (node.name == "indexHint") + { + data.actions_stack.addAction(ExpressionAction::addColumn(ColumnWithTypeAndName( + ColumnConst::create(ColumnUInt8::create(1, 1), 1), std::make_shared(), + column_name.get(ast)))); + return; + } + + if (AggregateFunctionFactory::instance().isAggregateFunctionName(node.name)) + return; + + /// Context object that we pass to function should live during query. + const Context & function_context = data.context.hasQueryContext() + ? data.context.getQueryContext() + : data.context; + + FunctionBuilderPtr function_builder; + try + { + function_builder = FunctionFactory::instance().get(node.name, function_context); + } + catch (DB::Exception & e) + { + auto hints = AggregateFunctionFactory::instance().getHints(node.name); + if (!hints.empty()) + e.addMessage("Or unknown aggregate function " + node.name + ". Maybe you meant: " + toString(hints)); + e.rethrow(); + } + + Names argument_names; + DataTypes argument_types; + bool arguments_present = true; + + /// If the function has an argument-lambda expression, you need to determine its type before the recursive call. + bool has_lambda_arguments = false; + + for (size_t arg = 0; arg < node.arguments->children.size(); ++arg) + { + auto & child = node.arguments->children[arg]; + auto child_column_name = child->getColumnName(); + + const auto * lambda = child->as(); + if (lambda && lambda->name == "lambda") { - /// Let's find the type of the first argument (then getActionsImpl will be called again and will not affect anything). - visit(node->arguments->children.at(0)); + /// If the argument is a lambda expression, just remember its approximate type. + if (lambda->arguments->children.size() != 2) + throw Exception("lambda requires two arguments", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); - if (!no_subqueries) + const auto * lambda_args_tuple = lambda->arguments->children.at(0)->as(); + + if (!lambda_args_tuple || lambda_args_tuple->name != "tuple") + throw Exception("First argument of lambda must be a tuple", ErrorCodes::TYPE_MISMATCH); + + has_lambda_arguments = true; + argument_types.emplace_back(std::make_shared(DataTypes(lambda_args_tuple->arguments->children.size()))); + /// Select the name in the next cycle. + argument_names.emplace_back(); + } + else if (functionIsInOrGlobalInOperator(node.name) && arg == 1 && prepared_set) + { + ColumnWithTypeAndName column; + column.type = std::make_shared(); + + /// If the argument is a set given by an enumeration of values (so, the set was already built), give it a unique name, + /// so that sets with the same literal representation do not fuse together (they can have different types). + if (!prepared_set->empty()) + column.name = getUniqueName(data.actions_stack.getSampleBlock(), "__set"); + else + column.name = child_column_name; + + if (!data.actions_stack.getSampleBlock().has(column.name)) { - /// Transform tuple or subquery into a set. - prepared_set = makeSet(node, actions_stack.getSampleBlock()); + column.column = ColumnSet::create(1, prepared_set); + + data.actions_stack.addAction(ExpressionAction::addColumn(column)); + } + + argument_types.push_back(column.type); + argument_names.push_back(column.name); + } + else + { + /// If the argument is not a lambda expression, call it recursively and find out its type. + visit(child, data); + std::string name = child_column_name; + if (data.actions_stack.getSampleBlock().has(name)) + { + argument_types.push_back(data.actions_stack.getSampleBlock().getByName(name).type); + argument_names.push_back(name); } else { - if (!only_consts) - { - /// We are in the part of the tree that we are not going to compute. You just need to define types. - /// Do not subquery and create sets. We treat "IN" as "ignoreExceptNull" function. - - actions_stack.addAction(ExpressionAction::applyFunction( - FunctionFactory::instance().get("ignoreExceptNull", context), - { node->arguments->children.at(0)->getColumnName() }, - getColumnName())); - } - return; + if (data.only_consts) + arguments_present = false; + else + throw Exception("Unknown identifier: " + name, ErrorCodes::UNKNOWN_IDENTIFIER); } } + } - /// A special function `indexHint`. Everything that is inside it is not calculated - /// (and is used only for index analysis, see KeyCondition). - if (node->name == "indexHint") + if (data.only_consts && !arguments_present) + return; + + if (has_lambda_arguments && !data.only_consts) + { + function_builder->getLambdaArgumentTypes(argument_types); + + /// Call recursively for lambda expressions. + for (size_t i = 0; i < node.arguments->children.size(); ++i) { - actions_stack.addAction(ExpressionAction::addColumn(ColumnWithTypeAndName( - ColumnConst::create(ColumnUInt8::create(1, 1), 1), std::make_shared(), - getColumnName()))); - return; - } - - if (AggregateFunctionFactory::instance().isAggregateFunctionName(node->name)) - return; - - /// Context object that we pass to function should live during query. - const Context & function_context = context.hasQueryContext() - ? context.getQueryContext() - : context; - - FunctionBuilderPtr function_builder; - try - { - function_builder = FunctionFactory::instance().get(node->name, function_context); - } - catch (DB::Exception & e) - { - auto hints = AggregateFunctionFactory::instance().getHints(node->name); - if (!hints.empty()) - e.addMessage("Or unknown aggregate function " + node->name + ". Maybe you meant: " + toString(hints)); - e.rethrow(); - } - - Names argument_names; - DataTypes argument_types; - bool arguments_present = true; - - /// If the function has an argument-lambda expression, you need to determine its type before the recursive call. - bool has_lambda_arguments = false; - - for (size_t arg = 0; arg < node->arguments->children.size(); ++arg) - { - auto & child = node->arguments->children[arg]; - auto child_column_name = child->getColumnName(); + ASTPtr child = node.arguments->children[i]; const auto * lambda = child->as(); if (lambda && lambda->name == "lambda") { - /// If the argument is a lambda expression, just remember its approximate type. - if (lambda->arguments->children.size() != 2) - throw Exception("lambda requires two arguments", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); - + const DataTypeFunction * lambda_type = typeid_cast(argument_types[i].get()); const auto * lambda_args_tuple = lambda->arguments->children.at(0)->as(); + const ASTs & lambda_arg_asts = lambda_args_tuple->arguments->children; + NamesAndTypesList lambda_arguments; - if (!lambda_args_tuple || lambda_args_tuple->name != "tuple") - throw Exception("First argument of lambda must be a tuple", ErrorCodes::TYPE_MISMATCH); - - has_lambda_arguments = true; - argument_types.emplace_back(std::make_shared(DataTypes(lambda_args_tuple->arguments->children.size()))); - /// Select the name in the next cycle. - argument_names.emplace_back(); - } - else if (functionIsInOrGlobalInOperator(node->name) && arg == 1 && prepared_set) - { - ColumnWithTypeAndName column; - column.type = std::make_shared(); - - /// If the argument is a set given by an enumeration of values (so, the set was already built), give it a unique name, - /// so that sets with the same literal representation do not fuse together (they can have different types). - if (!prepared_set->empty()) - column.name = getUniqueName(actions_stack.getSampleBlock(), "__set"); - else - column.name = child_column_name; - - if (!actions_stack.getSampleBlock().has(column.name)) + for (size_t j = 0; j < lambda_arg_asts.size(); ++j) { - column.column = ColumnSet::create(1, prepared_set); + auto opt_arg_name = tryGetIdentifierName(lambda_arg_asts[j]); + if (!opt_arg_name) + throw Exception("lambda argument declarations must be identifiers", ErrorCodes::TYPE_MISMATCH); - actions_stack.addAction(ExpressionAction::addColumn(column)); + lambda_arguments.emplace_back(*opt_arg_name, lambda_type->getArgumentTypes()[j]); } - argument_types.push_back(column.type); - argument_names.push_back(column.name); + data.actions_stack.pushLevel(lambda_arguments); + visit(lambda->arguments->children.at(1), data); + ExpressionActionsPtr lambda_actions = data.actions_stack.popLevel(); + + String result_name = lambda->arguments->children.at(1)->getColumnName(); + lambda_actions->finalize(Names(1, result_name)); + DataTypePtr result_type = lambda_actions->getSampleBlock().getByName(result_name).type; + + Names captured; + Names required = lambda_actions->getRequiredColumns(); + for (const auto & required_arg : required) + if (findColumn(required_arg, lambda_arguments) == lambda_arguments.end()) + captured.push_back(required_arg); + + /// We can not name `getColumnName()`, + /// because it does not uniquely define the expression (the types of arguments can be different). + String lambda_name = getUniqueName(data.actions_stack.getSampleBlock(), "__lambda"); + + auto function_capture = std::make_shared( + lambda_actions, captured, lambda_arguments, result_type, result_name); + data.actions_stack.addAction(ExpressionAction::applyFunction(function_capture, captured, lambda_name)); + + argument_types[i] = std::make_shared(lambda_type->getArgumentTypes(), result_type); + argument_names[i] = lambda_name; } - else - { - /// If the argument is not a lambda expression, call it recursively and find out its type. - visit(child); - std::string name = child_column_name; - if (actions_stack.getSampleBlock().has(name)) - { - argument_types.push_back(actions_stack.getSampleBlock().getByName(name).type); - argument_names.push_back(name); - } - else - { - if (only_consts) - arguments_present = false; - else - throw Exception("Unknown identifier: " + name, ErrorCodes::UNKNOWN_IDENTIFIER); - } - } - } - - if (only_consts && !arguments_present) - return; - - if (has_lambda_arguments && !only_consts) - { - function_builder->getLambdaArgumentTypes(argument_types); - - /// Call recursively for lambda expressions. - for (size_t i = 0; i < node->arguments->children.size(); ++i) - { - ASTPtr child = node->arguments->children[i]; - - const auto * lambda = child->as(); - if (lambda && lambda->name == "lambda") - { - const DataTypeFunction * lambda_type = typeid_cast(argument_types[i].get()); - const auto * lambda_args_tuple = lambda->arguments->children.at(0)->as(); - const ASTs & lambda_arg_asts = lambda_args_tuple->arguments->children; - NamesAndTypesList lambda_arguments; - - for (size_t j = 0; j < lambda_arg_asts.size(); ++j) - { - auto opt_arg_name = tryGetIdentifierName(lambda_arg_asts[j]); - if (!opt_arg_name) - throw Exception("lambda argument declarations must be identifiers", ErrorCodes::TYPE_MISMATCH); - - lambda_arguments.emplace_back(*opt_arg_name, lambda_type->getArgumentTypes()[j]); - } - - actions_stack.pushLevel(lambda_arguments); - visit(lambda->arguments->children.at(1)); - ExpressionActionsPtr lambda_actions = actions_stack.popLevel(); - - String result_name = lambda->arguments->children.at(1)->getColumnName(); - lambda_actions->finalize(Names(1, result_name)); - DataTypePtr result_type = lambda_actions->getSampleBlock().getByName(result_name).type; - - Names captured; - Names required = lambda_actions->getRequiredColumns(); - for (const auto & required_arg : required) - if (findColumn(required_arg, lambda_arguments) == lambda_arguments.end()) - captured.push_back(required_arg); - - /// We can not name `getColumnName()`, - /// because it does not uniquely define the expression (the types of arguments can be different). - String lambda_name = getUniqueName(actions_stack.getSampleBlock(), "__lambda"); - - auto function_capture = std::make_shared( - lambda_actions, captured, lambda_arguments, result_type, result_name); - actions_stack.addAction(ExpressionAction::applyFunction(function_capture, captured, lambda_name)); - - argument_types[i] = std::make_shared(lambda_type->getArgumentTypes(), result_type); - argument_names[i] = lambda_name; - } - } - } - - if (only_consts) - { - for (const auto & argument_name : argument_names) - { - if (!actions_stack.getSampleBlock().has(argument_name)) - { - arguments_present = false; - break; - } - } - } - - if (arguments_present) - { - actions_stack.addAction( - ExpressionAction::applyFunction(function_builder, argument_names, getColumnName())); } } - else if (const auto * literal = ast->as()) - { - DataTypePtr type = applyVisitor(FieldToDataType(), literal->value); - ColumnWithTypeAndName column; - column.column = type->createColumnConst(1, convertFieldToType(literal->value, *type)); - column.type = type; - column.name = getColumnName(); - - actions_stack.addAction(ExpressionAction::addColumn(column)); - } - else + if (data.only_consts) { - for (auto & child : ast->children) + for (const auto & argument_name : argument_names) { - /// Do not go to FROM, JOIN, UNION. - if (!child->as() && !child->as()) - visit(child); + if (!data.actions_stack.getSampleBlock().has(argument_name)) + { + arguments_present = false; + break; + } } } + + if (arguments_present) + { + data.actions_stack.addAction( + ExpressionAction::applyFunction(function_builder, argument_names, column_name.get(ast))); + } } -SetPtr ActionsVisitor::makeSet(const ASTFunction * node, const Block & sample_block) +void ActionsMatcher::visit(const ASTLiteral & literal, const ASTPtr & ast, Data & data) +{ + CachedColumnName column_name; + + if (data.hasColumn(column_name.get(ast))) + return; + + DataTypePtr type = applyVisitor(FieldToDataType(), literal.value); + + ColumnWithTypeAndName column; + column.column = type->createColumnConst(1, convertFieldToType(literal.value, *type)); + column.type = type; + column.name = column_name.get(ast); + + data.actions_stack.addAction(ExpressionAction::addColumn(column)); +} + +SetPtr ActionsMatcher::makeSet(const ASTFunction & node, Data & data) { /** You need to convert the right argument to a set. * This can be a table name, a value, a value enumeration, or a subquery. * The enumeration of values is parsed as a function `tuple`. */ - const IAST & args = *node->arguments; + const IAST & args = *node.arguments; const ASTPtr & arg = args.children.at(1); + const Block & sample_block = data.actions_stack.getSampleBlock(); /// If the subquery or table name for SELECT. const auto * identifier = arg->as(); if (arg->as() || identifier) { auto set_key = PreparedSetKey::forSubquery(*arg); - if (prepared_sets.count(set_key)) - return prepared_sets.at(set_key); + if (data.prepared_sets.count(set_key)) + return data.prepared_sets.at(set_key); /// A special case is if the name of the table is specified on the right side of the IN statement, /// and the table has the type Set (a previously prepared set). if (identifier) { DatabaseAndTableWithAlias database_table(*identifier); - StoragePtr table = context.tryGetTable(database_table.database, database_table.table); + StoragePtr table = data.context.tryGetTable(database_table.database, database_table.table); if (table) { StorageSet * storage_set = dynamic_cast(table.get()); if (storage_set) { - prepared_sets[set_key] = storage_set->getSet(); + data.prepared_sets[set_key] = storage_set->getSet(); return storage_set->getSet(); } } @@ -576,25 +581,25 @@ SetPtr ActionsVisitor::makeSet(const ASTFunction * node, const Block & sample_bl /// We get the stream of blocks for the subquery. Create Set and put it in place of the subquery. String set_id = arg->getColumnName(); - SubqueryForSet & subquery_for_set = subqueries_for_sets[set_id]; + SubqueryForSet & subquery_for_set = data.subqueries_for_sets[set_id]; /// If you already created a Set with the same subquery / table. if (subquery_for_set.set) { - prepared_sets[set_key] = subquery_for_set.set; + data.prepared_sets[set_key] = subquery_for_set.set; return subquery_for_set.set; } - SetPtr set = std::make_shared(set_size_limit, false); + SetPtr set = std::make_shared(data.set_size_limit, false); /** The following happens for GLOBAL INs: * - in the addExternalStorage function, the IN (SELECT ...) subquery is replaced with IN _data1, * in the subquery_for_set object, this subquery is set as source and the temporary table _data1 as the table. * - this function shows the expression IN_data1. */ - if (!subquery_for_set.source && no_storage_or_local) + if (!subquery_for_set.source && data.no_storage_or_local) { - auto interpreter = interpretSubquery(arg, context, subquery_depth, {}); + auto interpreter = interpretSubquery(arg, data.context, data.subquery_depth, {}); subquery_for_set.source = std::make_shared( interpreter->getSampleBlock(), [interpreter]() mutable { return interpreter->execute().in; }); @@ -627,13 +632,13 @@ SetPtr ActionsVisitor::makeSet(const ASTFunction * node, const Block & sample_bl } subquery_for_set.set = set; - prepared_sets[set_key] = set; + data.prepared_sets[set_key] = set; return set; } else { /// An explicit enumeration of values in parentheses. - return makeExplicitSet(node, sample_block, false, context, set_size_limit, prepared_sets); + return makeExplicitSet(&node, sample_block, false, data.context, data.set_size_limit, data.prepared_sets); } } diff --git a/dbms/src/Interpreters/ActionsVisitor.h b/dbms/src/Interpreters/ActionsVisitor.h index 4d03f758f61..963dd9f8675 100644 --- a/dbms/src/Interpreters/ActionsVisitor.h +++ b/dbms/src/Interpreters/ActionsVisitor.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace DB @@ -52,38 +53,71 @@ struct ScopeStack const Block & getSampleBlock() const; }; +class ASTIdentifier; +class ASTFunction; +class ASTLiteral; /// Collect ExpressionAction from AST. Returns PreparedSets and SubqueriesForSets too. -class ActionsVisitor +class ActionsMatcher { public: - ActionsVisitor(const Context & context_, SizeLimits set_size_limit_, size_t subquery_depth_, - const NamesAndTypesList & source_columns_, const ExpressionActionsPtr & actions, - PreparedSets & prepared_sets_, SubqueriesForSets & subqueries_for_sets_, - bool no_subqueries_, bool only_consts_, bool no_storage_or_local_, std::ostream * ostr_ = nullptr); + using Visitor = ConstInDepthNodeVisitor; - void visit(const ASTPtr & ast, ExpressionActionsPtr & actions) + struct Data { - visit(ast); - actions = actions_stack.popLevel(); - } + const Context & context; + SizeLimits set_size_limit; + size_t subquery_depth; + const NamesAndTypesList & source_columns; + PreparedSets & prepared_sets; + SubqueriesForSets & subqueries_for_sets; + bool no_subqueries; + bool only_consts; + bool no_storage_or_local; + size_t visit_depth; + ScopeStack actions_stack; + + Data(const Context & context_, SizeLimits set_size_limit_, size_t subquery_depth_, + const NamesAndTypesList & source_columns_, const ExpressionActionsPtr & actions, + PreparedSets & prepared_sets_, SubqueriesForSets & subqueries_for_sets_, + bool no_subqueries_, bool only_consts_, bool no_storage_or_local_) + : context(context_), + set_size_limit(set_size_limit_), + subquery_depth(subquery_depth_), + source_columns(source_columns_), + prepared_sets(prepared_sets_), + subqueries_for_sets(subqueries_for_sets_), + no_subqueries(no_subqueries_), + only_consts(only_consts_), + no_storage_or_local(no_storage_or_local_), + visit_depth(0), + actions_stack(actions, context) + {} + + void updateActions(ExpressionActionsPtr & actions) + { + actions = actions_stack.popLevel(); + } + + /// Does result of the calculation already exists in the block. + bool hasColumn(const String & columnName) const + { + return actions_stack.getSampleBlock().has(columnName); + } + }; + + static void visit(const ASTPtr & ast, Data & data); + static bool needChildVisit(const ASTPtr & node, const ASTPtr & child); private: - const Context & context; - SizeLimits set_size_limit; - size_t subquery_depth; - const NamesAndTypesList & source_columns; - PreparedSets & prepared_sets; - SubqueriesForSets & subqueries_for_sets; - const bool no_subqueries; - const bool only_consts; - const bool no_storage_or_local; - mutable size_t visit_depth; - std::ostream * ostr; - ScopeStack actions_stack; - void visit(const ASTPtr & ast); - SetPtr makeSet(const ASTFunction * node, const Block & sample_block); + static void visit(const ASTIdentifier & identifier, const ASTPtr & ast, Data & data); + static void visit(const ASTFunction & node, const ASTPtr & ast, Data & data); + static void visit(const ASTLiteral & literal, const ASTPtr & ast, Data & data); + + static SetPtr makeSet(const ASTFunction & node, Data & data); }; +using ActionsVisitor = ActionsMatcher::Visitor; + } diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index eaba3d568e3..2132259ecaa 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -315,10 +315,11 @@ void SelectQueryExpressionAnalyzer::makeSetsForIndex(const ASTPtr & node) void ExpressionAnalyzer::getRootActions(const ASTPtr & ast, bool no_subqueries, ExpressionActionsPtr & actions, bool only_consts) { LogAST log; - ActionsVisitor actions_visitor(context, settings.size_limits_for_set, subquery_depth, + ActionsVisitor::Data visitor_data(context, settings.size_limits_for_set, subquery_depth, sourceColumns(), actions, prepared_sets, subqueries_for_sets, - no_subqueries, only_consts, !isRemoteStorage(), log.stream()); - actions_visitor.visit(ast, actions); + no_subqueries, only_consts, !isRemoteStorage()); + ActionsVisitor(visitor_data, log.stream()).visit(ast); + visitor_data.updateActions(actions); } From 24e5b95b98de432f0cdb828546a825bf37c7cd66 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 15 Aug 2019 17:00:36 +0300 Subject: [PATCH 0992/1165] Fix test_external_dictionaries for non root user. --- dbms/tests/integration/helpers/cluster.py | 2 +- .../test_external_dictionaries/external_sources.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dbms/tests/integration/helpers/cluster.py b/dbms/tests/integration/helpers/cluster.py index bd3ecb9ae9c..1288aaa23f2 100644 --- a/dbms/tests/integration/helpers/cluster.py +++ b/dbms/tests/integration/helpers/cluster.py @@ -562,7 +562,7 @@ class ClickHouseInstance: with open(local_path, 'r') as fdata: data = fdata.read() encoded_data = base64.b64encode(data) - self.exec_in_container(["bash", "-c", "echo {} | base64 --decode > {}".format(encoded_data, dest_path)]) + self.exec_in_container(["bash", "-c", "echo {} | base64 --decode > {}".format(encoded_data, dest_path)], user='root') def get_process_pid(self, process_name): output = self.exec_in_container(["bash", "-c", "ps ax | grep '{}' | grep -v 'grep' | grep -v 'bash -c' | awk '{{print $1}}'".format(process_name)]) diff --git a/dbms/tests/integration/test_external_dictionaries/external_sources.py b/dbms/tests/integration/test_external_dictionaries/external_sources.py index 71dc05ca78c..7ff24b4b28c 100644 --- a/dbms/tests/integration/test_external_dictionaries/external_sources.py +++ b/dbms/tests/integration/test_external_dictionaries/external_sources.py @@ -246,7 +246,7 @@ class SourceFile(ExternalSource): def prepare(self, structure, table_name, cluster): self.node = cluster.instances[self.docker_hostname] path = "/" + table_name + ".tsv" - self.node.exec_in_container(["bash", "-c", "touch {}".format(path)]) + self.node.exec_in_container(["bash", "-c", "touch {}".format(path)], user="root") self.ordered_names = structure.get_ordered_names() self.prepared = True @@ -260,7 +260,7 @@ class SourceFile(ExternalSource): sorted_row.append(str(row.data[name])) str_data = '\t'.join(sorted_row) - self.node.exec_in_container(["bash", "-c", "echo \"{row}\" >> {fname}".format(row=str_data, fname=path)]) + self.node.exec_in_container(["bash", "-c", "echo \"{row}\" >> {fname}".format(row=str_data, fname=path)], user="root") def compatible_with_layout(self, layout): return 'cache' not in layout.name @@ -286,7 +286,7 @@ class _SourceExecutableBase(ExternalSource): def prepare(self, structure, table_name, cluster): self.node = cluster.instances[self.docker_hostname] path = "/" + table_name + ".tsv" - self.node.exec_in_container(["bash", "-c", "touch {}".format(path)]) + self.node.exec_in_container(["bash", "-c", "touch {}".format(path)], user="root") self.ordered_names = structure.get_ordered_names() self.prepared = True @@ -300,7 +300,7 @@ class _SourceExecutableBase(ExternalSource): sorted_row.append(str(row.data[name])) str_data = '\t'.join(sorted_row) - self.node.exec_in_container(["bash", "-c", "echo \"{row}\" >> {fname}".format(row=str_data, fname=path)]) + self.node.exec_in_container(["bash", "-c", "echo \"{row}\" >> {fname}".format(row=str_data, fname=path)], user='root') class SourceExecutableCache(_SourceExecutableBase): @@ -337,7 +337,7 @@ class SourceHTTPBase(ExternalSource): def prepare(self, structure, table_name, cluster): self.node = cluster.instances[self.docker_hostname] path = "/" + table_name + ".tsv" - self.node.exec_in_container(["bash", "-c", "touch {}".format(path)]) + self.node.exec_in_container(["bash", "-c", "touch {}".format(path)], user='root') script_dir = os.path.dirname(os.path.realpath(__file__)) self.node.copy_file_to_container(os.path.join(script_dir, './http_server.py'), '/http_server.py') @@ -361,7 +361,7 @@ class SourceHTTPBase(ExternalSource): sorted_row.append(str(row.data[name])) str_data = '\t'.join(sorted_row) - self.node.exec_in_container(["bash", "-c", "echo \"{row}\" >> {fname}".format(row=str_data, fname=path)]) + self.node.exec_in_container(["bash", "-c", "echo \"{row}\" >> {fname}".format(row=str_data, fname=path)], user='root') class SourceHTTP(SourceHTTPBase): From c52a34fd15bc834ab40c8ef91ee281a89d58e2b3 Mon Sep 17 00:00:00 2001 From: Ivan Lezhankin Date: Thu, 15 Aug 2019 16:49:49 +0300 Subject: [PATCH 0993/1165] Add test for multiple mat. views --- .../integration/test_storage_kafka/test.py | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/dbms/tests/integration/test_storage_kafka/test.py b/dbms/tests/integration/test_storage_kafka/test.py index c47f68bf673..09b13d884f6 100644 --- a/dbms/tests/integration/test_storage_kafka/test.py +++ b/dbms/tests/integration/test_storage_kafka/test.py @@ -325,6 +325,54 @@ def test_kafka_materialized_view(kafka_cluster): kafka_check_result(result, True) +@pytest.mark.timeout(60) +def test_kafka_many_materialized_views(kafka_cluster): + instance.query(''' + DROP TABLE IF EXISTS test.view1; + DROP TABLE IF EXISTS test.view2; + DROP TABLE IF EXISTS test.consumer1; + DROP TABLE IF EXISTS test.consumer2; + CREATE TABLE test.kafka (key UInt64, value UInt64) + ENGINE = Kafka + SETTINGS kafka_broker_list = 'kafka1:19092', + kafka_topic_list = 'mmv', + kafka_group_name = 'mmv', + kafka_format = 'JSONEachRow', + kafka_row_delimiter = '\\n'; + CREATE TABLE test.view1 (key UInt64, value UInt64) + ENGINE = MergeTree() + ORDER BY key; + CREATE TABLE test.view2 (key UInt64, value UInt64) + ENGINE = MergeTree() + ORDER BY key; + CREATE MATERIALIZED VIEW test.consumer1 TO test.view1 AS + SELECT * FROM test.kafka; + CREATE MATERIALIZED VIEW test.consumer2 TO test.view2 AS + SELECT * FROM test.kafka; + ''') + + messages = [] + for i in range(50): + messages.append(json.dumps({'key': i, 'value': i})) + kafka_produce('mmv', messages) + + while True: + result1 = instance.query('SELECT * FROM test.view1') + result2 = instance.query('SELECT * FROM test.view2') + if kafka_check_result(result1) and kafka_check_result(result2): + break + + instance.query(''' + DROP TABLE test.consumer1; + DROP TABLE test.consumer2; + DROP TABLE test.view1; + DROP TABLE test.view2; + ''') + + kafka_check_result(result1, True) + kafka_check_result(result2, True) + + @pytest.mark.timeout(300) def test_kafka_flush_on_big_message(kafka_cluster): # Create batchs of messages of size ~100Kb From e895251bc67330299f53b8fa42222726098fcbf5 Mon Sep 17 00:00:00 2001 From: chertus Date: Thu, 15 Aug 2019 17:22:33 +0300 Subject: [PATCH 0994/1165] minor changes --- dbms/src/Interpreters/ActionsVisitor.cpp | 39 ++++++++++++------------ dbms/src/Interpreters/ActionsVisitor.h | 10 ++++++ 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/dbms/src/Interpreters/ActionsVisitor.cpp b/dbms/src/Interpreters/ActionsVisitor.cpp index 7c6f97d5ed5..c519d75b812 100644 --- a/dbms/src/Interpreters/ActionsVisitor.cpp +++ b/dbms/src/Interpreters/ActionsVisitor.cpp @@ -269,8 +269,10 @@ void ActionsMatcher::visit(const ASTPtr & ast, Data & data) void ActionsMatcher::visit(const ASTIdentifier & identifier, const ASTPtr & ast, Data & data) { CachedColumnName column_name; + if (data.hasColumn(column_name.get(ast))) + return; - if (!data.only_consts && !data.actions_stack.getSampleBlock().has(column_name.get(ast))) + if (!data.only_consts) { /// The requested column is not in the block. /// If such a column exists in the table, then the user probably forgot to surround it with an aggregate function or add it to GROUP BY. @@ -286,14 +288,13 @@ void ActionsMatcher::visit(const ASTIdentifier & identifier, const ASTPtr & ast, /// Special check for WITH statement alias. Add alias action to be able to use this alias. if (identifier.prefer_alias_to_column_name && !identifier.alias.empty()) - data.actions_stack.addAction(ExpressionAction::addAliases({{identifier.name, identifier.alias}})); + data.addAction(ExpressionAction::addAliases({{identifier.name, identifier.alias}})); } } void ActionsMatcher::visit(const ASTFunction & node, const ASTPtr & ast, Data & data) { CachedColumnName column_name; - if (data.hasColumn(column_name.get(ast))) return; @@ -311,10 +312,10 @@ void ActionsMatcher::visit(const ASTFunction & node, const ASTPtr & ast, Data & if (!data.only_consts) { String result_name = column_name.get(ast); - data.actions_stack.addAction(ExpressionAction::copyColumn(arg->getColumnName(), result_name)); + data.addAction(ExpressionAction::copyColumn(arg->getColumnName(), result_name)); NameSet joined_columns; joined_columns.insert(result_name); - data.actions_stack.addAction(ExpressionAction::arrayJoin(joined_columns, false, data.context)); + data.addAction(ExpressionAction::arrayJoin(joined_columns, false, data.context)); } return; @@ -338,7 +339,7 @@ void ActionsMatcher::visit(const ASTFunction & node, const ASTPtr & ast, Data & /// We are in the part of the tree that we are not going to compute. You just need to define types. /// Do not subquery and create sets. We treat "IN" as "ignoreExceptNull" function. - data.actions_stack.addAction(ExpressionAction::applyFunction( + data.addAction(ExpressionAction::applyFunction( FunctionFactory::instance().get("ignoreExceptNull", data.context), { node.arguments->children.at(0)->getColumnName() }, column_name.get(ast))); @@ -351,7 +352,7 @@ void ActionsMatcher::visit(const ASTFunction & node, const ASTPtr & ast, Data & /// (and is used only for index analysis, see KeyCondition). if (node.name == "indexHint") { - data.actions_stack.addAction(ExpressionAction::addColumn(ColumnWithTypeAndName( + data.addAction(ExpressionAction::addColumn(ColumnWithTypeAndName( ColumnConst::create(ColumnUInt8::create(1, 1), 1), std::make_shared(), column_name.get(ast)))); return; @@ -415,15 +416,15 @@ void ActionsMatcher::visit(const ASTFunction & node, const ASTPtr & ast, Data & /// If the argument is a set given by an enumeration of values (so, the set was already built), give it a unique name, /// so that sets with the same literal representation do not fuse together (they can have different types). if (!prepared_set->empty()) - column.name = getUniqueName(data.actions_stack.getSampleBlock(), "__set"); + column.name = getUniqueName(data.getSampleBlock(), "__set"); else column.name = child_column_name; - if (!data.actions_stack.getSampleBlock().has(column.name)) + if (!data.hasColumn(column.name)) { column.column = ColumnSet::create(1, prepared_set); - data.actions_stack.addAction(ExpressionAction::addColumn(column)); + data.addAction(ExpressionAction::addColumn(column)); } argument_types.push_back(column.type); @@ -434,9 +435,9 @@ void ActionsMatcher::visit(const ASTFunction & node, const ASTPtr & ast, Data & /// If the argument is not a lambda expression, call it recursively and find out its type. visit(child, data); std::string name = child_column_name; - if (data.actions_stack.getSampleBlock().has(name)) + if (data.hasColumn(name)) { - argument_types.push_back(data.actions_stack.getSampleBlock().getByName(name).type); + argument_types.push_back(data.getSampleBlock().getByName(name).type); argument_names.push_back(name); } else @@ -494,11 +495,11 @@ void ActionsMatcher::visit(const ASTFunction & node, const ASTPtr & ast, Data & /// We can not name `getColumnName()`, /// because it does not uniquely define the expression (the types of arguments can be different). - String lambda_name = getUniqueName(data.actions_stack.getSampleBlock(), "__lambda"); + String lambda_name = getUniqueName(data.getSampleBlock(), "__lambda"); auto function_capture = std::make_shared( lambda_actions, captured, lambda_arguments, result_type, result_name); - data.actions_stack.addAction(ExpressionAction::applyFunction(function_capture, captured, lambda_name)); + data.addAction(ExpressionAction::applyFunction(function_capture, captured, lambda_name)); argument_types[i] = std::make_shared(lambda_type->getArgumentTypes(), result_type); argument_names[i] = lambda_name; @@ -510,7 +511,7 @@ void ActionsMatcher::visit(const ASTFunction & node, const ASTPtr & ast, Data & { for (const auto & argument_name : argument_names) { - if (!data.actions_stack.getSampleBlock().has(argument_name)) + if (!data.hasColumn(argument_name)) { arguments_present = false; break; @@ -520,15 +521,13 @@ void ActionsMatcher::visit(const ASTFunction & node, const ASTPtr & ast, Data & if (arguments_present) { - data.actions_stack.addAction( - ExpressionAction::applyFunction(function_builder, argument_names, column_name.get(ast))); + data.addAction(ExpressionAction::applyFunction(function_builder, argument_names, column_name.get(ast))); } } void ActionsMatcher::visit(const ASTLiteral & literal, const ASTPtr & ast, Data & data) { CachedColumnName column_name; - if (data.hasColumn(column_name.get(ast))) return; @@ -539,7 +538,7 @@ void ActionsMatcher::visit(const ASTLiteral & literal, const ASTPtr & ast, Data column.type = type; column.name = column_name.get(ast); - data.actions_stack.addAction(ExpressionAction::addColumn(column)); + data.addAction(ExpressionAction::addColumn(column)); } SetPtr ActionsMatcher::makeSet(const ASTFunction & node, Data & data) @@ -550,7 +549,7 @@ SetPtr ActionsMatcher::makeSet(const ASTFunction & node, Data & data) */ const IAST & args = *node.arguments; const ASTPtr & arg = args.children.at(1); - const Block & sample_block = data.actions_stack.getSampleBlock(); + const Block & sample_block = data.getSampleBlock(); /// If the subquery or table name for SELECT. const auto * identifier = arg->as(); diff --git a/dbms/src/Interpreters/ActionsVisitor.h b/dbms/src/Interpreters/ActionsVisitor.h index 963dd9f8675..def72c7ad1c 100644 --- a/dbms/src/Interpreters/ActionsVisitor.h +++ b/dbms/src/Interpreters/ActionsVisitor.h @@ -99,6 +99,16 @@ public: actions = actions_stack.popLevel(); } + void addAction(const ExpressionAction & action) + { + actions_stack.addAction(action); + } + + const Block & getSampleBlock() const + { + return actions_stack.getSampleBlock(); + } + /// Does result of the calculation already exists in the block. bool hasColumn(const String & columnName) const { From 854da3b6a241951638cf442f1d08f0b27efc24b0 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Thu, 15 Aug 2019 19:09:43 +0300 Subject: [PATCH 0995/1165] ms column added --- dbms/src/Interpreters/MetricLog.cpp | 17 ++++++++++++++++- dbms/src/Interpreters/MetricLog.h | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/dbms/src/Interpreters/MetricLog.cpp b/dbms/src/Interpreters/MetricLog.cpp index c1423a5c11c..03cf820a2ee 100644 --- a/dbms/src/Interpreters/MetricLog.cpp +++ b/dbms/src/Interpreters/MetricLog.cpp @@ -13,6 +13,7 @@ Block MetricLogElement::createBlock() columns_with_type_and_name.emplace_back(std::make_shared(), "event_date"); columns_with_type_and_name.emplace_back(std::make_shared(), "event_time"); + columns_with_type_and_name.emplace_back(std::make_shared(), "milliseconds"); //ProfileEvents for (size_t i = 0, end = ProfileEvents::end(); i < end; ++i) @@ -43,6 +44,7 @@ void MetricLogElement::appendToBlock(Block & block) const columns[iter++]->insert(DateLUT::instance().toDayNum(event_time)); columns[iter++]->insert(event_time); + columns[iter++]->insert(milliseconds); //ProfileEvents for (size_t i = 0, end = ProfileEvents::end(); i < end; ++i) @@ -74,6 +76,16 @@ void MetricLog::stopCollectMetric() metric_flush_thread.join(); } +inline UInt64 time_in_milliseconds(std::chrono::time_point timepoint) +{ + return std::chrono::duration_cast(timepoint.time_since_epoch()).count(); +} + +inline UInt64 time_in_seconds(std::chrono::time_point timepoint) +{ + return std::chrono::duration_cast(timepoint.time_since_epoch()).count(); +} + void MetricLog::metricThreadFunction() { auto desired_timepoint = std::chrono::system_clock::now(); @@ -88,9 +100,12 @@ void MetricLog::metricThreadFunction() MetricLogElement elem; elem.event_time = std::chrono::system_clock::to_time_t(prev_timepoint); + elem.milliseconds = time_in_milliseconds(prev_timepoint) - time_in_seconds(prev_timepoint) * 1000; this->add(elem); - desired_timepoint = prev_timepoint + std::chrono::milliseconds(collect_interval_milliseconds); + while (desired_timepoint <= std::chrono::system_clock::now()) + desired_timepoint += std::chrono::milliseconds(collect_interval_milliseconds); + std::this_thread::sleep_until(desired_timepoint); } catch (...) diff --git a/dbms/src/Interpreters/MetricLog.h b/dbms/src/Interpreters/MetricLog.h index 7c041a19d7d..032700600f1 100644 --- a/dbms/src/Interpreters/MetricLog.h +++ b/dbms/src/Interpreters/MetricLog.h @@ -10,6 +10,7 @@ using Poco::Message; struct MetricLogElement { time_t event_time{}; + UInt64 milliseconds{}; static std::string name() { return "MetricLog"; } static Block createBlock(); From 2cfbd1e194b46df0ce07567c2eb9f87411577c04 Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Thu, 15 Aug 2019 19:39:18 +0300 Subject: [PATCH 0996/1165] reused prev_timepoint --- dbms/src/Interpreters/MetricLog.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dbms/src/Interpreters/MetricLog.cpp b/dbms/src/Interpreters/MetricLog.cpp index 03cf820a2ee..00d486c8788 100644 --- a/dbms/src/Interpreters/MetricLog.cpp +++ b/dbms/src/Interpreters/MetricLog.cpp @@ -93,19 +93,18 @@ void MetricLog::metricThreadFunction() { try { - const auto prev_timepoint = desired_timepoint; - if (is_shutdown_metric_thread) break; MetricLogElement elem; + const auto prev_timepoint = std::chrono::system_clock::now(); elem.event_time = std::chrono::system_clock::to_time_t(prev_timepoint); elem.milliseconds = time_in_milliseconds(prev_timepoint) - time_in_seconds(prev_timepoint) * 1000; + this->add(elem); while (desired_timepoint <= std::chrono::system_clock::now()) desired_timepoint += std::chrono::milliseconds(collect_interval_milliseconds); - std::this_thread::sleep_until(desired_timepoint); } catch (...) From 053f0ee78d863654e23d5709d2a582808728744a Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Thu, 15 Aug 2019 20:46:35 +0300 Subject: [PATCH 0997/1165] fix compilation --- dbms/src/Interpreters/MutationsInterpreter.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dbms/src/Interpreters/MutationsInterpreter.cpp b/dbms/src/Interpreters/MutationsInterpreter.cpp index dff891607a5..160d0bc8023 100644 --- a/dbms/src/Interpreters/MutationsInterpreter.cpp +++ b/dbms/src/Interpreters/MutationsInterpreter.cpp @@ -199,8 +199,7 @@ void MutationsInterpreter::prepare(bool dry_run) { auto query = index->expr->clone(); auto syntax_result = SyntaxAnalyzer(context).analyze(query, all_columns); - ExpressionAnalyzer analyzer(query, syntax_result, context); - const auto required_columns = analyzer.getRequiredSourceColumns(); + const auto required_columns = syntax_result->requiredSourceColumns(); for (const String & dependency : required_columns) { @@ -283,8 +282,7 @@ void MutationsInterpreter::prepare(bool dry_run) auto query = (*it)->expr->clone(); auto syntax_result = SyntaxAnalyzer(context).analyze(query, all_columns); - ExpressionAnalyzer analyzer(query, syntax_result, context); - const auto required_columns = analyzer.getRequiredSourceColumns(); + const auto required_columns = syntax_result->requiredSourceColumns(); affected_indices_columns.insert(std::cbegin(required_columns), std::cend(required_columns)); } else From f59fa67050cd5407789824626826837e3cb6b107 Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Thu, 15 Aug 2019 21:46:16 +0300 Subject: [PATCH 0998/1165] added type checks for set index functions --- dbms/src/Functions/bitBoolMaskAnd.cpp | 6 ++++++ dbms/src/Functions/bitBoolMaskOr.cpp | 6 ++++++ dbms/src/Functions/bitSwapLastTwo.cpp | 6 ++++++ dbms/src/Functions/bitWrapperFunc.cpp | 8 +++++++- 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/dbms/src/Functions/bitBoolMaskAnd.cpp b/dbms/src/Functions/bitBoolMaskAnd.cpp index f7cf7efa25f..02e681b59b8 100644 --- a/dbms/src/Functions/bitBoolMaskAnd.cpp +++ b/dbms/src/Functions/bitBoolMaskAnd.cpp @@ -4,6 +4,10 @@ namespace DB { + namespace ErrorCodes + { + extern const int BAD_CAST; + } /// Working with UInt8: last bit = can be true, previous = can be false (Like dbms/src/Storages/MergeTree/BoolMask.h). /// This function provides "AND" operation for BoolMasks. @@ -17,6 +21,8 @@ namespace DB template static inline Result apply(A left, B right) { + if constexpr (!std::is_same_v || !std::is_same_v) + throw DB::Exception("Only UInt8 type is supported by __bitBoolMaskAnd.", ErrorCodes::BAD_CAST); return static_cast( ((static_cast(left) & static_cast(right)) & 1) | ((((static_cast(left) >> 1) | (static_cast(right) >> 1)) & 1) << 1)); diff --git a/dbms/src/Functions/bitBoolMaskOr.cpp b/dbms/src/Functions/bitBoolMaskOr.cpp index 0c34b8e5bdb..d1261f4fe14 100644 --- a/dbms/src/Functions/bitBoolMaskOr.cpp +++ b/dbms/src/Functions/bitBoolMaskOr.cpp @@ -4,6 +4,10 @@ namespace DB { + namespace ErrorCodes + { + extern const int BAD_CAST; + } /// Working with UInt8: last bit = can be true, previous = can be false (Like dbms/src/Storages/MergeTree/BoolMask.h). /// This function provides "OR" operation for BoolMasks. @@ -17,6 +21,8 @@ namespace DB template static inline Result apply(A left, B right) { + if constexpr (!std::is_same_v || !std::is_same_v) + throw DB::Exception("Only UInt8 type is supported by __bitBoolMaskOr.", ErrorCodes::BAD_CAST); return static_cast( ((static_cast(left) | static_cast(right)) & 1) | ((((static_cast(left) >> 1) & (static_cast(right) >> 1)) & 1) << 1)); diff --git a/dbms/src/Functions/bitSwapLastTwo.cpp b/dbms/src/Functions/bitSwapLastTwo.cpp index 4a3b0cd304a..7b3f92a0724 100644 --- a/dbms/src/Functions/bitSwapLastTwo.cpp +++ b/dbms/src/Functions/bitSwapLastTwo.cpp @@ -4,6 +4,10 @@ namespace DB { + namespace ErrorCodes + { + extern const int BAD_CAST; + } /// Working with UInt8: last bit = can be true, previous = can be false (Like dbms/src/Storages/MergeTree/BoolMask.h). /// This function provides "NOT" operation for BoolMasks by swapping last two bits ("can be true" <-> "can be false"). @@ -14,6 +18,8 @@ namespace DB static inline ResultType NO_SANITIZE_UNDEFINED apply(A a) { + if constexpr (!std::is_same_v) + throw DB::Exception("Only UInt8 type is supported by __bitSwapLastTwo.", ErrorCodes::BAD_CAST); return static_cast( ((static_cast(a) & 1) << 1) | ((static_cast(a) >> 1) & 1)); } diff --git a/dbms/src/Functions/bitWrapperFunc.cpp b/dbms/src/Functions/bitWrapperFunc.cpp index b9e37838875..c8951de66d1 100644 --- a/dbms/src/Functions/bitWrapperFunc.cpp +++ b/dbms/src/Functions/bitWrapperFunc.cpp @@ -4,6 +4,10 @@ namespace DB { + namespace ErrorCodes + { + extern const int BAD_CAST; + } /// Working with UInt8: last bit = can be true, previous = can be false (Like dbms/src/Storages/MergeTree/BoolMask.h). /// This function wraps bool atomic functions @@ -15,7 +19,9 @@ namespace DB static inline ResultType NO_SANITIZE_UNDEFINED apply(A a) { - return a == static_cast(0) ? static_cast(0b10) : static_cast(0b1); + if constexpr (!std::is_integral_v) + throw DB::Exception("It's a bug! Only integer types are supported by __bitWrapperFunc.", ErrorCodes::BAD_CAST); + return a == 0 ? static_cast(0b10) : static_cast(0b1); } #if USE_EMBEDDED_COMPILER From a051009d2896780942e10014021822faf0859107 Mon Sep 17 00:00:00 2001 From: Nikita Vasilev Date: Thu, 15 Aug 2019 21:48:48 +0300 Subject: [PATCH 0999/1165] add it's a bug mes --- dbms/src/Functions/bitBoolMaskAnd.cpp | 2 +- dbms/src/Functions/bitBoolMaskOr.cpp | 2 +- dbms/src/Functions/bitSwapLastTwo.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dbms/src/Functions/bitBoolMaskAnd.cpp b/dbms/src/Functions/bitBoolMaskAnd.cpp index 02e681b59b8..eaa1a2a3343 100644 --- a/dbms/src/Functions/bitBoolMaskAnd.cpp +++ b/dbms/src/Functions/bitBoolMaskAnd.cpp @@ -22,7 +22,7 @@ namespace DB static inline Result apply(A left, B right) { if constexpr (!std::is_same_v || !std::is_same_v) - throw DB::Exception("Only UInt8 type is supported by __bitBoolMaskAnd.", ErrorCodes::BAD_CAST); + throw DB::Exception("It's a bug! Only UInt8 type is supported by __bitBoolMaskAnd.", ErrorCodes::BAD_CAST); return static_cast( ((static_cast(left) & static_cast(right)) & 1) | ((((static_cast(left) >> 1) | (static_cast(right) >> 1)) & 1) << 1)); diff --git a/dbms/src/Functions/bitBoolMaskOr.cpp b/dbms/src/Functions/bitBoolMaskOr.cpp index d1261f4fe14..903c3582375 100644 --- a/dbms/src/Functions/bitBoolMaskOr.cpp +++ b/dbms/src/Functions/bitBoolMaskOr.cpp @@ -22,7 +22,7 @@ namespace DB static inline Result apply(A left, B right) { if constexpr (!std::is_same_v || !std::is_same_v) - throw DB::Exception("Only UInt8 type is supported by __bitBoolMaskOr.", ErrorCodes::BAD_CAST); + throw DB::Exception("It's a bug! Only UInt8 type is supported by __bitBoolMaskOr.", ErrorCodes::BAD_CAST); return static_cast( ((static_cast(left) | static_cast(right)) & 1) | ((((static_cast(left) >> 1) & (static_cast(right) >> 1)) & 1) << 1)); diff --git a/dbms/src/Functions/bitSwapLastTwo.cpp b/dbms/src/Functions/bitSwapLastTwo.cpp index 7b3f92a0724..22b7b889d8b 100644 --- a/dbms/src/Functions/bitSwapLastTwo.cpp +++ b/dbms/src/Functions/bitSwapLastTwo.cpp @@ -19,7 +19,7 @@ namespace DB static inline ResultType NO_SANITIZE_UNDEFINED apply(A a) { if constexpr (!std::is_same_v) - throw DB::Exception("Only UInt8 type is supported by __bitSwapLastTwo.", ErrorCodes::BAD_CAST); + throw DB::Exception("It's a bug! Only UInt8 type is supported by __bitSwapLastTwo.", ErrorCodes::BAD_CAST); return static_cast( ((static_cast(a) & 1) << 1) | ((static_cast(a) >> 1) & 1)); } From 2ef878d7ceeb93c8e6c77dcff822561e7927c28d Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 15 Aug 2019 22:31:43 +0300 Subject: [PATCH 1000/1165] Add alwaysReturnsConstant for IFunctionBase. Set alwaysReturnsConstant=true for ignore. --- dbms/src/Functions/IFunction.h | 3 +++ dbms/src/Functions/ignore.cpp | 2 ++ dbms/src/Interpreters/ExpressionActions.cpp | 11 +++++++++-- dbms/src/Interpreters/ExpressionActions.h | 1 + 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/dbms/src/Functions/IFunction.h b/dbms/src/Functions/IFunction.h index 287e7a84170..e5c24b98cec 100644 --- a/dbms/src/Functions/IFunction.h +++ b/dbms/src/Functions/IFunction.h @@ -159,6 +159,8 @@ public: */ virtual bool isSuitableForConstantFolding() const { return true; } + virtual bool alwaysReturnsConstant() const { return false; } + /** Function is called "injective" if it returns different result for different values of arguments. * Example: hex, negate, tuple... * @@ -456,6 +458,7 @@ public: } bool isSuitableForConstantFolding() const override { return function->isSuitableForConstantFolding(); } + bool alwaysReturnsConstant() const override { return function->alwaysReturnsConstant(); } bool isInjective(const Block & sample_block) override { return function->isInjective(sample_block); } diff --git a/dbms/src/Functions/ignore.cpp b/dbms/src/Functions/ignore.cpp index 73aaea9f3ca..c3ed34ac994 100644 --- a/dbms/src/Functions/ignore.cpp +++ b/dbms/src/Functions/ignore.cpp @@ -42,6 +42,8 @@ public: { block.getByPosition(result).column = DataTypeUInt8().createColumnConst(input_rows_count, 0u); } + + bool alwaysReturnsConstant() const override { return true; } }; diff --git a/dbms/src/Interpreters/ExpressionActions.cpp b/dbms/src/Interpreters/ExpressionActions.cpp index 475e6e3cbf0..4d8da6b28b4 100644 --- a/dbms/src/Interpreters/ExpressionActions.cpp +++ b/dbms/src/Interpreters/ExpressionActions.cpp @@ -204,7 +204,12 @@ void ExpressionAction::prepare(Block & sample_block, const Settings & settings) } size_t result_position = sample_block.columns(); - sample_block.insert({nullptr, result_type, result_name}); + + ColumnPtr const_col; + if (function_base->alwaysReturnsConstant()) + const_col = result_type->createColumnConstWithDefaultValue(0); + + sample_block.insert({const_col, result_type, result_name}); function = function_base->prepare(sample_block, arguments, result_position); if (auto * prepared_function = dynamic_cast(function.get())) @@ -235,6 +240,8 @@ void ExpressionAction::prepare(Block & sample_block, const Settings & settings) if (col.column->empty()) col.column = col.column->cloneResized(1); + + is_suitable_for_constant_folding = true; } } @@ -956,7 +963,7 @@ void ExpressionActions::finalize(const Names & output_columns) /** If the function is a constant expression, then replace the action by adding a column-constant - result. * That is, we perform constant folding. */ - if (action.type == ExpressionAction::APPLY_FUNCTION && sample_block.has(out)) + if (action.type == ExpressionAction::APPLY_FUNCTION && action.is_suitable_for_constant_folding && sample_block.has(out)) { auto & result = sample_block.getByName(out); if (result.column) diff --git a/dbms/src/Interpreters/ExpressionActions.h b/dbms/src/Interpreters/ExpressionActions.h index 984ecf124be..48162188b6c 100644 --- a/dbms/src/Interpreters/ExpressionActions.h +++ b/dbms/src/Interpreters/ExpressionActions.h @@ -97,6 +97,7 @@ public: PreparedFunctionPtr function; Names argument_names; bool is_function_compiled = false; + bool is_suitable_for_constant_folding = false; /// For ARRAY_JOIN NameSet array_joined_columns; From 25c882e3cc2e8aae7b0fd1aab5b8e4ec36871537 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Fri, 16 Aug 2019 00:22:54 +0300 Subject: [PATCH 1001/1165] fixed unbundled build --- dbms/src/Core/MySQLProtocol.h | 6 ++++-- dbms/src/Interpreters/UsersManager.cpp | 28 ++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/dbms/src/Core/MySQLProtocol.h b/dbms/src/Core/MySQLProtocol.h index 7e29dc9676d..029d7ded18a 100644 --- a/dbms/src/Core/MySQLProtocol.h +++ b/dbms/src/Core/MySQLProtocol.h @@ -23,7 +23,6 @@ #include #include #include -#include /// Implementation of MySQL wire protocol. /// Works only on little-endian architecture. @@ -943,7 +942,10 @@ private: class Sha256Password : public IPlugin { public: - Sha256Password(RSA & public_key, RSA & private_key, Logger * log) : public_key(public_key), private_key(private_key), log(log) + Sha256Password(RSA & public_key_, RSA & private_key_, Logger * log_) + : public_key(public_key_) + , private_key(private_key_) + , log(log_) { /** Native authentication sent 20 bytes + '\0' character = 21 bytes. * This plugin must do the same to stay consistent with historical behavior if it is set to operate as a default plugin. [1] diff --git a/dbms/src/Interpreters/UsersManager.cpp b/dbms/src/Interpreters/UsersManager.cpp index 6d1f7152b9e..123d4bd8704 100644 --- a/dbms/src/Interpreters/UsersManager.cpp +++ b/dbms/src/Interpreters/UsersManager.cpp @@ -8,9 +8,11 @@ #include #include #include -#include #include #include +#if USE_SSL +# include +#endif namespace DB @@ -69,10 +71,28 @@ UserPtr UsersManager::authorizeAndGetUser( if (!it->second->password_sha256_hex.empty()) { - Poco::SHA2Engine engine; - engine.update(password); - if (Poco::SHA2Engine::digestToHex(engine.digest()) != it->second->password_sha256_hex) +#if USE_SSL + unsigned char hash[32]; + + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, reinterpret_cast(password.data()), password.size()); + SHA256_Final(hash, &ctx); + + String hash_hex; + { + WriteBufferFromString buf(hash_hex); + HexWriteBuffer hex_buf(buf); + hex_buf.write(reinterpret_cast(hash), sizeof(hash)); + } + + Poco::toLowerInPlace(hash_hex); + + if (hash_hex != it->second->password_sha256_hex) on_wrong_password(); +#else + throw DB::Exception("SHA256 passwords support is disabled, because ClickHouse was built without SSL library", DB::ErrorCodes::SUPPORT_IS_DISABLED); +#endif } else if (!it->second->password_double_sha1_hex.empty()) { From b28861147268910e6c8777d40496c31fac28a81b Mon Sep 17 00:00:00 2001 From: Yuriy Date: Fri, 16 Aug 2019 00:54:53 +0300 Subject: [PATCH 1002/1165] static linking of sha256_password in mariadb-connector-c --- .../linux_x86_64/libmariadb/ma_client_plugin.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/contrib/mariadb-connector-c-cmake/linux_x86_64/libmariadb/ma_client_plugin.c b/contrib/mariadb-connector-c-cmake/linux_x86_64/libmariadb/ma_client_plugin.c index b7fdcdbcb85..fefba7944ef 100644 --- a/contrib/mariadb-connector-c-cmake/linux_x86_64/libmariadb/ma_client_plugin.c +++ b/contrib/mariadb-connector-c-cmake/linux_x86_64/libmariadb/ma_client_plugin.c @@ -76,17 +76,18 @@ struct st_client_plugin_int *plugin_list[MYSQL_CLIENT_MAX_PLUGINS + MARIADB_CLIE static pthread_mutex_t LOCK_load_client_plugin; #endif - extern struct st_mysql_client_plugin mysql_native_password_client_plugin; - extern struct st_mysql_client_plugin mysql_old_password_client_plugin; - extern struct st_mysql_client_plugin pvio_socket_client_plugin; +extern struct st_mysql_client_plugin mysql_native_password_client_plugin; +extern struct st_mysql_client_plugin mysql_old_password_client_plugin; +extern struct st_mysql_client_plugin pvio_socket_client_plugin; +extern struct st_mysql_client_plugin sha256_password_client_plugin; struct st_mysql_client_plugin *mysql_client_builtins[]= { - (struct st_mysql_client_plugin *)&mysql_native_password_client_plugin, - (struct st_mysql_client_plugin *)&mysql_old_password_client_plugin, - (struct st_mysql_client_plugin *)&pvio_socket_client_plugin, - + (struct st_mysql_client_plugin *)&mysql_native_password_client_plugin, + (struct st_mysql_client_plugin *)&mysql_old_password_client_plugin, + (struct st_mysql_client_plugin *)&pvio_socket_client_plugin, + (struct st_mysql_client_plugin *)&sha256_password_client_plugin, 0 }; From c08d01cfb4305cab5afcc1eb39973753d1216008 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Fri, 16 Aug 2019 02:03:58 +0300 Subject: [PATCH 1003/1165] linking caching_sha2_password plugin statically --- contrib/mariadb-connector-c | 2 +- .../linux_x86_64/libmariadb/ma_client_plugin.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/contrib/mariadb-connector-c b/contrib/mariadb-connector-c index d85d0e98999..c6503d3acc8 160000 --- a/contrib/mariadb-connector-c +++ b/contrib/mariadb-connector-c @@ -1 +1 @@ -Subproject commit d85d0e98999cd9e28ceb66645999b4a9ce85370e +Subproject commit c6503d3acc85ca1a7f5e7e38b605d7c9410aac1e diff --git a/contrib/mariadb-connector-c-cmake/linux_x86_64/libmariadb/ma_client_plugin.c b/contrib/mariadb-connector-c-cmake/linux_x86_64/libmariadb/ma_client_plugin.c index fefba7944ef..434a4b3f4c3 100644 --- a/contrib/mariadb-connector-c-cmake/linux_x86_64/libmariadb/ma_client_plugin.c +++ b/contrib/mariadb-connector-c-cmake/linux_x86_64/libmariadb/ma_client_plugin.c @@ -80,6 +80,7 @@ extern struct st_mysql_client_plugin mysql_native_password_client_plugin; extern struct st_mysql_client_plugin mysql_old_password_client_plugin; extern struct st_mysql_client_plugin pvio_socket_client_plugin; extern struct st_mysql_client_plugin sha256_password_client_plugin; +extern struct st_mysql_client_plugin caching_sha2_password_client_plugin; struct st_mysql_client_plugin *mysql_client_builtins[]= @@ -88,6 +89,7 @@ struct st_mysql_client_plugin *mysql_client_builtins[]= (struct st_mysql_client_plugin *)&mysql_old_password_client_plugin, (struct st_mysql_client_plugin *)&pvio_socket_client_plugin, (struct st_mysql_client_plugin *)&sha256_password_client_plugin, + (struct st_mysql_client_plugin *)&caching_sha2_password_client_plugin, 0 }; From cf9b41549d4e390ed8fdef75ab024d9102255b28 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 16 Aug 2019 02:35:54 +0300 Subject: [PATCH 1004/1165] MetricLog: code cleanups; comments --- dbms/src/Interpreters/MetricLog.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/dbms/src/Interpreters/MetricLog.cpp b/dbms/src/Interpreters/MetricLog.cpp index 00d486c8788..b17813ba401 100644 --- a/dbms/src/Interpreters/MetricLog.cpp +++ b/dbms/src/Interpreters/MetricLog.cpp @@ -89,29 +89,28 @@ inline UInt64 time_in_seconds(std::chrono::time_point void MetricLog::metricThreadFunction() { auto desired_timepoint = std::chrono::system_clock::now(); - while (true) + while (!is_shutdown_metric_thread) { try { - if (is_shutdown_metric_thread) - break; - MetricLogElement elem; - const auto prev_timepoint = std::chrono::system_clock::now(); - elem.event_time = std::chrono::system_clock::to_time_t(prev_timepoint); - elem.milliseconds = time_in_milliseconds(prev_timepoint) - time_in_seconds(prev_timepoint) * 1000; + const auto current_time = std::chrono::system_clock::now(); + elem.event_time = std::chrono::system_clock::to_time_t(current_time); + elem.milliseconds = time_in_milliseconds(current_time) - time_in_seconds(current_time) * 1000; this->add(elem); - while (desired_timepoint <= std::chrono::system_clock::now()) + /// We will record current time into table but align it to regular time intervals to avoid time drift. + /// We may drop some time points if the server is overloaded and recording took too much time. + while (desired_timepoint <= current_time) desired_timepoint += std::chrono::milliseconds(collect_interval_milliseconds); + std::this_thread::sleep_until(desired_timepoint); } catch (...) { tryLogCurrentException(__PRETTY_FUNCTION__); } - } } From b66719725f17238ee817f6d292e95116c0591a00 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 16 Aug 2019 03:49:33 +0300 Subject: [PATCH 1005/1165] Fix race condition in system.parts vs. ALTER --- dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp | 2 ++ dbms/src/Storages/System/StorageSystemParts.cpp | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp index f64bdcc9740..0b208a13b59 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp @@ -409,6 +409,8 @@ void MergeTreeDataPart::remove() const #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-variable" #endif + std::shared_lock lock(columns_lock); + for (const auto & [file, _] : checksums.files) { String path_to_remove = to + "/" + file; diff --git a/dbms/src/Storages/System/StorageSystemParts.cpp b/dbms/src/Storages/System/StorageSystemParts.cpp index 65d17f096c3..58fe57c2739 100644 --- a/dbms/src/Storages/System/StorageSystemParts.cpp +++ b/dbms/src/Storages/System/StorageSystemParts.cpp @@ -114,7 +114,11 @@ void StorageSystemParts::processNextStorage(MutableColumns & columns_, const Sto columns_[i++]->insert(part->stateString()); MinimalisticDataPartChecksums helper; - helper.computeTotalChecksums(part->checksums); + { + /// TODO MergeTreeDataPart structure is too error-prone. + std::shared_lock lock(part->columns_lock); + helper.computeTotalChecksums(part->checksums); + } auto checksum = helper.hash_of_all_files; columns_[i++]->insert(getHexUIntLowercase(checksum.first) + getHexUIntLowercase(checksum.second)); From d8efa5a842562e655d88f39a3b5a29d4043eb8c2 Mon Sep 17 00:00:00 2001 From: Yuriy Date: Fri, 16 Aug 2019 03:59:59 +0300 Subject: [PATCH 1006/1165] added missing caching_sha2_pw.c --- contrib/mariadb-connector-c-cmake/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/mariadb-connector-c-cmake/CMakeLists.txt b/contrib/mariadb-connector-c-cmake/CMakeLists.txt index a0582d89685..b8d27d144d3 100644 --- a/contrib/mariadb-connector-c-cmake/CMakeLists.txt +++ b/contrib/mariadb-connector-c-cmake/CMakeLists.txt @@ -42,6 +42,7 @@ ${MARIADB_CLIENT_SOURCE_DIR}/plugins/auth/mariadb_cleartext.c ${MARIADB_CLIENT_SOURCE_DIR}/plugins/auth/my_auth.c ${MARIADB_CLIENT_SOURCE_DIR}/plugins/auth/old_password.c ${MARIADB_CLIENT_SOURCE_DIR}/plugins/auth/sha256_pw.c +${MARIADB_CLIENT_SOURCE_DIR}/plugins/auth/caching_sha2_pw.c #${MARIADB_CLIENT_SOURCE_DIR}/plugins/auth/sspi_client.c #${MARIADB_CLIENT_SOURCE_DIR}/plugins/auth/sspi_errmsg.c ${MARIADB_CLIENT_SOURCE_DIR}/plugins/connection/aurora.c From ab827ca6f3344ec1fc24f832414492cadbf8b52c Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 16 Aug 2019 04:28:09 +0300 Subject: [PATCH 1007/1165] Added failing test --- ...0991_system_parts_race_condition.reference | 0 .../00991_system_parts_race_condition.sh | 71 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00991_system_parts_race_condition.reference create mode 100755 dbms/tests/queries/0_stateless/00991_system_parts_race_condition.sh diff --git a/dbms/tests/queries/0_stateless/00991_system_parts_race_condition.reference b/dbms/tests/queries/0_stateless/00991_system_parts_race_condition.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dbms/tests/queries/0_stateless/00991_system_parts_race_condition.sh b/dbms/tests/queries/0_stateless/00991_system_parts_race_condition.sh new file mode 100755 index 00000000000..66c1af8f447 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00991_system_parts_race_condition.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash + +CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +. $CURDIR/../shell_config.sh + +set -e + +$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS alter_table" +$CLICKHOUSE_CLIENT -q "CREATE TABLE alter_table (a UInt8, b Int16, c Float32, d String, e Array(UInt8), f Nullable(UUID), g Tuple(UInt8, UInt16)) ENGINE = MergeTree ORDER BY a PARTITION BY b % 10 SETTINGS old_parts_lifetime = 1" + +function thread1() +{ + while true; do $CLICKHOUSE_CLIENT --query "SELECT * FROM system.parts FORMAT Null"; done +} + +function thread2() +{ + while true; do $CLICKHOUSE_CLIENT -n --query "ALTER TABLE alter_table ADD COLUMN h String; ALTER TABLE alter_table MODIFY COLUMN h UInt64; ALTER TABLE alter_table DROP COLUMN h;"; done +} + +function thread3() +{ + while true; do $CLICKHOUSE_CLIENT -q "INSERT INTO alter_table SELECT rand(1), rand(2), 1 / rand(3), toString(rand(4)), [rand(5), rand(6)], rand(7) % 2 ? NULL : generateUUIDv4(), (rand(8), rand(9)) FROM numbers(100000)"; done +} + +function thread4() +{ + while true; do $CLICKHOUSE_CLIENT -q "OPTIMIZE TABLE alter_table FINAL"; done +} + +function thread5() +{ + while true; do $CLICKHOUSE_CLIENT -q "ALTER TABLE alter_table DELETE WHERE rand() % 2 = 1"; done +} + +# https://stackoverflow.com/questions/9954794/execute-a-shell-function-with-timeout +export -f thread1; +export -f thread2; +export -f thread3; +export -f thread4; +export -f thread5; + +TIMEOUT=30 + +timeout $TIMEOUT bash -c thread1 2> /dev/null & +timeout $TIMEOUT bash -c thread2 2> /dev/null & +timeout $TIMEOUT bash -c thread3 2> /dev/null & +timeout $TIMEOUT bash -c thread4 2> /dev/null & +timeout $TIMEOUT bash -c thread5 2> /dev/null & + +timeout $TIMEOUT bash -c thread1 2> /dev/null & +timeout $TIMEOUT bash -c thread2 2> /dev/null & +timeout $TIMEOUT bash -c thread3 2> /dev/null & +timeout $TIMEOUT bash -c thread4 2> /dev/null & +timeout $TIMEOUT bash -c thread5 2> /dev/null & + +timeout $TIMEOUT bash -c thread1 2> /dev/null & +timeout $TIMEOUT bash -c thread2 2> /dev/null & +timeout $TIMEOUT bash -c thread3 2> /dev/null & +timeout $TIMEOUT bash -c thread4 2> /dev/null & +timeout $TIMEOUT bash -c thread5 2> /dev/null & + +timeout $TIMEOUT bash -c thread1 2> /dev/null & +timeout $TIMEOUT bash -c thread2 2> /dev/null & +timeout $TIMEOUT bash -c thread3 2> /dev/null & +timeout $TIMEOUT bash -c thread4 2> /dev/null & +timeout $TIMEOUT bash -c thread5 2> /dev/null & + +wait + +$CLICKHOUSE_CLIENT -q "DROP TABLE alter_table" From 8d3ede98e2d3420d7ae90e921bde82e7a0570bd8 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 16 Aug 2019 05:21:01 +0300 Subject: [PATCH 1008/1165] Added another test --- ...m_parts_race_condition_zookeeper.reference | 0 ...2_system_parts_race_condition_zookeeper.sh | 73 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00992_system_parts_race_condition_zookeeper.reference create mode 100755 dbms/tests/queries/0_stateless/00992_system_parts_race_condition_zookeeper.sh diff --git a/dbms/tests/queries/0_stateless/00992_system_parts_race_condition_zookeeper.reference b/dbms/tests/queries/0_stateless/00992_system_parts_race_condition_zookeeper.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/dbms/tests/queries/0_stateless/00992_system_parts_race_condition_zookeeper.sh b/dbms/tests/queries/0_stateless/00992_system_parts_race_condition_zookeeper.sh new file mode 100755 index 00000000000..83c74b3363a --- /dev/null +++ b/dbms/tests/queries/0_stateless/00992_system_parts_race_condition_zookeeper.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +. $CURDIR/../shell_config.sh + +set -e + +$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS alter_table" +$CLICKHOUSE_CLIENT -q "DROP TABLE IF EXISTS alter_table2" +$CLICKHOUSE_CLIENT -q "CREATE TABLE alter_table (a UInt8, b Int16, c Float32, d String, e Array(UInt8), f Nullable(UUID), g Tuple(UInt8, UInt16)) ENGINE = ReplicatedMergeTree('/clickhouse/tables/alter_table', 'r1') ORDER BY a PARTITION BY b % 10 SETTINGS old_parts_lifetime = 1" +$CLICKHOUSE_CLIENT -q "CREATE TABLE alter_table2 (a UInt8, b Int16, c Float32, d String, e Array(UInt8), f Nullable(UUID), g Tuple(UInt8, UInt16)) ENGINE = ReplicatedMergeTree('/clickhouse/tables/alter_table', 'r2') ORDER BY a PARTITION BY b % 10 SETTINGS old_parts_lifetime = 1" + +function thread1() +{ + while true; do $CLICKHOUSE_CLIENT --query "SELECT * FROM system.parts FORMAT Null"; done +} + +function thread2() +{ + while true; do $CLICKHOUSE_CLIENT -n --query "ALTER TABLE alter_table ADD COLUMN h String; ALTER TABLE alter_table MODIFY COLUMN h UInt64; ALTER TABLE alter_table DROP COLUMN h;"; done +} + +function thread3() +{ + while true; do $CLICKHOUSE_CLIENT -q "INSERT INTO alter_table SELECT rand(1), rand(2), 1 / rand(3), toString(rand(4)), [rand(5), rand(6)], rand(7) % 2 ? NULL : generateUUIDv4(), (rand(8), rand(9)) FROM numbers(100000)"; done +} + +function thread4() +{ + while true; do $CLICKHOUSE_CLIENT -q "OPTIMIZE TABLE alter_table FINAL"; done +} + +function thread5() +{ + while true; do $CLICKHOUSE_CLIENT -q "ALTER TABLE alter_table DELETE WHERE rand() % 2 = 1"; done +} + +# https://stackoverflow.com/questions/9954794/execute-a-shell-function-with-timeout +export -f thread1; +export -f thread2; +export -f thread3; +export -f thread4; +export -f thread5; + +TIMEOUT=10 + +timeout $TIMEOUT bash -c thread1 2> /dev/null & +timeout $TIMEOUT bash -c thread2 2> /dev/null & +timeout $TIMEOUT bash -c thread3 2> /dev/null & +timeout $TIMEOUT bash -c thread4 2> /dev/null & +timeout $TIMEOUT bash -c thread5 2> /dev/null & + +timeout $TIMEOUT bash -c thread1 2> /dev/null & +timeout $TIMEOUT bash -c thread2 2> /dev/null & +timeout $TIMEOUT bash -c thread3 2> /dev/null & +timeout $TIMEOUT bash -c thread4 2> /dev/null & +timeout $TIMEOUT bash -c thread5 2> /dev/null & + +timeout $TIMEOUT bash -c thread1 2> /dev/null & +timeout $TIMEOUT bash -c thread2 2> /dev/null & +timeout $TIMEOUT bash -c thread3 2> /dev/null & +timeout $TIMEOUT bash -c thread4 2> /dev/null & +timeout $TIMEOUT bash -c thread5 2> /dev/null & + +timeout $TIMEOUT bash -c thread1 2> /dev/null & +timeout $TIMEOUT bash -c thread2 2> /dev/null & +timeout $TIMEOUT bash -c thread3 2> /dev/null & +timeout $TIMEOUT bash -c thread4 2> /dev/null & +timeout $TIMEOUT bash -c thread5 2> /dev/null & + +wait + +$CLICKHOUSE_CLIENT -q "DROP TABLE alter_table" From b808f2e2e8dca86c534b52c435b5f5a6f76362d2 Mon Sep 17 00:00:00 2001 From: alesapin Date: Fri, 16 Aug 2019 11:19:13 +0300 Subject: [PATCH 1009/1165] Add metric log --- dbms/tests/config/metric_log.xml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 dbms/tests/config/metric_log.xml diff --git a/dbms/tests/config/metric_log.xml b/dbms/tests/config/metric_log.xml new file mode 100644 index 00000000000..0ca9f162416 --- /dev/null +++ b/dbms/tests/config/metric_log.xml @@ -0,0 +1,8 @@ + + + system + metric_log
    + 7500 + 1000 +
    +
    From d8a5d6b602efc907428667ac91ed20c3397d2147 Mon Sep 17 00:00:00 2001 From: BayoNet Date: Fri, 16 Aug 2019 12:36:25 +0300 Subject: [PATCH 1010/1165] DOCAPI-7991: Upate of *Log engines docs. --- .../en/operations/table_engines/log_family.md | 20 ++++++++----------- docs/en/operations/table_engines/tinylog.md | 18 ++++------------- 2 files changed, 12 insertions(+), 26 deletions(-) diff --git a/docs/en/operations/table_engines/log_family.md b/docs/en/operations/table_engines/log_family.md index ae9e30d3728..bc55f5ccce4 100644 --- a/docs/en/operations/table_engines/log_family.md +++ b/docs/en/operations/table_engines/log_family.md @@ -1,6 +1,6 @@ # Log Engine Family -These engines were developed for scenarios when you need to write many tables with the small amount of data (less than 1 million rows). +These engines were developed for scenarios when you need to quickly write many small tables (up to about 1 million rows) and read them later as a whole. Engines of the family: @@ -14,6 +14,10 @@ Engines: - Store data on a disk. - Append data to the end of file when writing. +- Support locs for concurrent data access. + + During `INSERT` query the table is locked, and other queries for reading and writing data both wait for unlocking. If there are no writing data queries, any number of reading data queries can be performed concurrently. + - Do not support [mutation](../../query_language/alter.md#alter-mutations) operations. - Do not support indexes. @@ -23,20 +27,12 @@ Engines: You can get a table with corrupted data if something breaks the write operation, for example, abnormal server shutdown. + ## Differences -The `Log` and `StripeLog` engines support: +The `TinyLog` engine is the simplest in the family and provides the poorest functionality and lowest efficiency. The `TinyLog` engine does not support a parallel reading of data. It reads the data slower than other engines of the family that have parallel reading, and it uses almost as many descriptors as the `Log` engine because it stores each column in a separate file. Use it in simple low-load scenarios. -- Locks for concurrent data access. +The `Log` and `StripeLog` engines support parallel reading of data. When reading data ClickHouse uses multiple threads. Each thread processes separated data block. The `Log` engine uses the separate file for each column of the table. The `StripeLog` stores all the data in one file. Thus the `StripeLog` engine uses fewer descriptors in the operating system, but the `Log` engine provides a more efficient reading of the data. - During `INSERT` query the table is locked, and other queries for reading and writing data both wait for unlocking. If there are no writing data queries, any number of reading data queries can be performed concurrently. - -- Parallel reading of data. - - When reading data ClickHouse uses multiple threads. Each thread processes separated data block. - -The `Log` engine uses the separate file for each column of the table. The `StripeLog` stores all the data in one file. Thus the `StripeLog` engine uses fewer descriptors in the operating system, but the `Log` engine provides a more efficient reading of the data. - -The `TinyLog` engine is the simplest in the family and provides the poorest functionality and lowest efficiency. The `TinyLog` engine does not support a parallel reading and concurrent access and stores each column in a separate file. It reads the data slower than both other engines with parallel reading, and it uses almost as many descriptors as the `Log` engine. You can use it in simple low-load scenarios. [Original article](https://clickhouse.yandex/docs/en/operations/table_engines/log_family/) diff --git a/docs/en/operations/table_engines/tinylog.md b/docs/en/operations/table_engines/tinylog.md index 563912d92f1..fe4913118e9 100644 --- a/docs/en/operations/table_engines/tinylog.md +++ b/docs/en/operations/table_engines/tinylog.md @@ -1,22 +1,12 @@ # TinyLog -Engine belongs to the family of log engines. See the common properties of log engines and their differences in the [Log Engine Family](log_family.md) article. +Engine belongs to the family of log engines. See [Log Engine Family](log_family.md) for common properties of log engines and for their differences. -The simplest table engine, which stores data on a disk. -Each column is stored in a separate compressed file. -When writing, data is appended to the end of files. +The typical way using this table engine is write-once method: firstly write the data one time, then read it as many times as needed. For example, you can use `TinyLog`-type tables for intermediary data that is processed in small batches. -Concurrent data access is not restricted in any way: +Queries are executed in a single stream. In other words, this engine is intended for relatively small tables (recommended up to about 1,000,000 rows). It makes sense to use this table engine if you have many small tables, since it is simpler than the [Log](log.md) engine (fewer files need to be opened). -- If you are simultaneously reading from a table and writing to it in a different query, the read operation will complete with an error. -- If you are writing to a table in multiple queries simultaneously, the data will be broken. +The situation when you have a large number of small tables guarantees poor productivity, but may already be used when working with another DBMS, and you may find it easier to switch to using `TinyLog`-type tables. -The typical way to use this table is write-once: first just write the data one time, then read it as many times as needed. -Queries are executed in a single stream. In other words, this engine is intended for relatively small tables (recommended up to 1,000,000 rows). -It makes sense to use this table engine if you have many small tables, since it is simpler than the Log engine (fewer files need to be opened). -The situation when you have a large number of small tables guarantees poor productivity, but may already be used when working with another DBMS, and you may find it easier to switch to using TinyLog types of tables. -**Indexes are not supported.** - -In Yandex.Metrica, TinyLog tables are used for intermediary data that is processed in small batches. [Original article](https://clickhouse.yandex/docs/en/operations/table_engines/tinylog/) From 08021fe125fbad24625dd5412004fc39772fc34c Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 16 Aug 2019 12:38:12 +0300 Subject: [PATCH 1011/1165] Add alwaysReturnsConstant for IFunctionBase. --- dbms/src/Interpreters/ExpressionActions.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/dbms/src/Interpreters/ExpressionActions.cpp b/dbms/src/Interpreters/ExpressionActions.cpp index 4d8da6b28b4..487959bd063 100644 --- a/dbms/src/Interpreters/ExpressionActions.cpp +++ b/dbms/src/Interpreters/ExpressionActions.cpp @@ -204,12 +204,7 @@ void ExpressionAction::prepare(Block & sample_block, const Settings & settings) } size_t result_position = sample_block.columns(); - - ColumnPtr const_col; - if (function_base->alwaysReturnsConstant()) - const_col = result_type->createColumnConstWithDefaultValue(0); - - sample_block.insert({const_col, result_type, result_name}); + sample_block.insert({nullptr, result_type, result_name}); function = function_base->prepare(sample_block, arguments, result_position); if (auto * prepared_function = dynamic_cast(function.get())) @@ -963,7 +958,7 @@ void ExpressionActions::finalize(const Names & output_columns) /** If the function is a constant expression, then replace the action by adding a column-constant - result. * That is, we perform constant folding. */ - if (action.type == ExpressionAction::APPLY_FUNCTION && action.is_suitable_for_constant_folding && sample_block.has(out)) + if (action.type == ExpressionAction::APPLY_FUNCTION && sample_block.has(out)) { auto & result = sample_block.getByName(out); if (result.column) @@ -1089,6 +1084,18 @@ void ExpressionActions::finalize(const Names & output_columns) actions.swap(new_actions); + for (auto & action : new_actions) + { + if (action.type == ExpressionAction::APPLY_FUNCTION + && action.function_base->alwaysReturnsConstant() + && sample_block.has(action.result_name)) + { + auto & result = sample_block.getByName(action.result_name); + if (!result.column) + result.column = result.type->createColumnConstWithDefaultValue(0); + } + } + /* std::cerr << "\n"; for (const auto & action : actions) std::cerr << action.toString() << "\n"; From 0eb1a931b434abae192a6dfebf18e3d11ea6e2b3 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 16 Aug 2019 13:29:33 +0300 Subject: [PATCH 1012/1165] Add alwaysReturnsConstant for IFunctionBase. --- dbms/src/Interpreters/ExpressionActions.cpp | 34 ++++++++++----------- dbms/src/Interpreters/ExpressionActions.h | 5 +-- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/dbms/src/Interpreters/ExpressionActions.cpp b/dbms/src/Interpreters/ExpressionActions.cpp index 487959bd063..dc312b30ef1 100644 --- a/dbms/src/Interpreters/ExpressionActions.cpp +++ b/dbms/src/Interpreters/ExpressionActions.cpp @@ -178,7 +178,7 @@ ExpressionAction ExpressionAction::ordinaryJoin( } -void ExpressionAction::prepare(Block & sample_block, const Settings & settings) +void ExpressionAction::prepare(Block & sample_block, const Settings & settings, NameSet & names_not_for_constant_folding) { // std::cerr << "preparing: " << toString() << std::endl; @@ -193,6 +193,7 @@ void ExpressionAction::prepare(Block & sample_block, const Settings & settings) throw Exception("Column '" + result_name + "' already exists", ErrorCodes::DUPLICATE_COLUMN); bool all_const = true; + bool all_suitable_for_constant_folding = true; ColumnNumbers arguments(argument_names.size()); for (size_t i = 0; i < argument_names.size(); ++i) @@ -201,10 +202,18 @@ void ExpressionAction::prepare(Block & sample_block, const Settings & settings) ColumnPtr col = sample_block.safeGetByPosition(arguments[i]).column; if (!col || !isColumnConst(*col)) all_const = false; + + if (names_not_for_constant_folding.count(argument_names[i])) + all_suitable_for_constant_folding = false; } size_t result_position = sample_block.columns(); - sample_block.insert({nullptr, result_type, result_name}); + + ColumnPtr const_col; + if (function_base->alwaysReturnsConstant()) + const_col = result_type->createColumnConstWithDefaultValue(1); + + sample_block.insert({const_col, result_type, result_name}); function = function_base->prepare(sample_block, arguments, result_position); if (auto * prepared_function = dynamic_cast(function.get())) @@ -217,7 +226,7 @@ void ExpressionAction::prepare(Block & sample_block, const Settings & settings) /// If all arguments are constants, and function is suitable to be executed in 'prepare' stage - execute function. /// But if we compile expressions compiled version of this function maybe placed in cache, /// so we don't want to unfold non deterministic functions - if (all_const && function_base->isSuitableForConstantFolding() && (!compile_expressions || function_base->isDeterministic())) + if (all_const && (!compile_expressions || function_base->isDeterministic())) { function->execute(sample_block, arguments, result_position, sample_block.rows(), true); @@ -236,7 +245,8 @@ void ExpressionAction::prepare(Block & sample_block, const Settings & settings) if (col.column->empty()) col.column = col.column->cloneResized(1); - is_suitable_for_constant_folding = true; + if (!all_suitable_for_constant_folding || !function_base->isSuitableForConstantFolding()) + names_not_for_constant_folding.insert(result_name); } } @@ -729,7 +739,7 @@ void ExpressionActions::addImpl(ExpressionAction action, Names & new_names) for (const auto & name_with_alias : action.projection) new_names.emplace_back(name_with_alias.second); - action.prepare(sample_block, settings); + action.prepare(sample_block, settings, names_not_for_constant_folding); actions.push_back(action); } @@ -961,7 +971,7 @@ void ExpressionActions::finalize(const Names & output_columns) if (action.type == ExpressionAction::APPLY_FUNCTION && sample_block.has(out)) { auto & result = sample_block.getByName(out); - if (result.column) + if (result.column && names_not_for_constant_folding.count(result.name) == 0) { action.type = ExpressionAction::ADD_COLUMN; action.result_type = result.type; @@ -1084,18 +1094,6 @@ void ExpressionActions::finalize(const Names & output_columns) actions.swap(new_actions); - for (auto & action : new_actions) - { - if (action.type == ExpressionAction::APPLY_FUNCTION - && action.function_base->alwaysReturnsConstant() - && sample_block.has(action.result_name)) - { - auto & result = sample_block.getByName(action.result_name); - if (!result.column) - result.column = result.type->createColumnConstWithDefaultValue(0); - } - } - /* std::cerr << "\n"; for (const auto & action : actions) std::cerr << action.toString() << "\n"; diff --git a/dbms/src/Interpreters/ExpressionActions.h b/dbms/src/Interpreters/ExpressionActions.h index 48162188b6c..8b959235cc5 100644 --- a/dbms/src/Interpreters/ExpressionActions.h +++ b/dbms/src/Interpreters/ExpressionActions.h @@ -97,7 +97,6 @@ public: PreparedFunctionPtr function; Names argument_names; bool is_function_compiled = false; - bool is_suitable_for_constant_folding = false; /// For ARRAY_JOIN NameSet array_joined_columns; @@ -145,7 +144,7 @@ public: private: friend class ExpressionActions; - void prepare(Block & sample_block, const Settings & settings); + void prepare(Block & sample_block, const Settings & settings, NameSet & names_not_for_constant_folding); void execute(Block & block, bool dry_run) const; void executeOnTotals(Block & block) const; }; @@ -269,6 +268,8 @@ private: Actions actions; /// The example of result (output) block. Block sample_block; + /// Columns which can't be used for constant folding. + NameSet names_not_for_constant_folding; Settings settings; #if USE_EMBEDDED_COMPILER From 670c8a3e50223bc1c23c027d5ab1a6f9092920d1 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 16 Aug 2019 13:41:17 +0300 Subject: [PATCH 1013/1165] Add alwaysReturnsConstant for IFunctionBase. --- dbms/src/Interpreters/ExpressionActions.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/dbms/src/Interpreters/ExpressionActions.cpp b/dbms/src/Interpreters/ExpressionActions.cpp index dc312b30ef1..6636fed488c 100644 --- a/dbms/src/Interpreters/ExpressionActions.cpp +++ b/dbms/src/Interpreters/ExpressionActions.cpp @@ -208,12 +208,7 @@ void ExpressionAction::prepare(Block & sample_block, const Settings & settings, } size_t result_position = sample_block.columns(); - - ColumnPtr const_col; - if (function_base->alwaysReturnsConstant()) - const_col = result_type->createColumnConstWithDefaultValue(1); - - sample_block.insert({const_col, result_type, result_name}); + sample_block.insert({nullptr, result_type, result_name}); function = function_base->prepare(sample_block, arguments, result_position); if (auto * prepared_function = dynamic_cast(function.get())) @@ -250,6 +245,13 @@ void ExpressionAction::prepare(Block & sample_block, const Settings & settings, } } + auto & res = sample_block.getByPosition(result_position); + if (!res.column && function_base->alwaysReturnsConstant()) + { + res.column = result_type->createColumnConstWithDefaultValue(1); + names_not_for_constant_folding.insert(result_name); + } + break; } From 688cc4976a028a013dbba8800767b5240061ee1c Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 16 Aug 2019 14:03:23 +0300 Subject: [PATCH 1014/1165] Moved NOTICE to dbms/src --- NOTICE | 41 ----------------------------------------- dbms/src/NOTICE | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 41 deletions(-) delete mode 100644 NOTICE create mode 100644 dbms/src/NOTICE diff --git a/NOTICE b/NOTICE deleted file mode 100644 index 59c6923e66a..00000000000 --- a/NOTICE +++ /dev/null @@ -1,41 +0,0 @@ --- -The following notice shall be applied to the files listed below. - -Some modifications Copyright (c) 2018 BlackBerry Limited - -Licensed 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. - -dbms/src/Common/ErrorCodes.cpp -dbms/src/Common/UInt128.h -dbms/src/Core/Block.h -dbms/src/Core/Defines.h -dbms/src/Core/Settings.h -dbms/src/DataStreams/PushingToViewsBlockOutputStream.cpp -dbms/src/DataStreams/PushingToViewsBlockOutputStream.h -dbms/src/DataStreams/copyData.cpp -dbms/src/Databases/DatabasesCommon.cpp -dbms/src/IO/WriteBufferValidUTF8.cpp -dbms/src/Interpreters/InterpreterAlterQuery.cpp -dbms/src/Interpreters/InterpreterCreateQuery.cpp -dbms/src/Interpreters/InterpreterFactory.cpp -dbms/src/Parsers/ASTAlterQuery.cpp -dbms/src/Parsers/ASTAlterQuery.h -dbms/src/Parsers/ASTCreateQuery.cpp -dbms/src/Parsers/ASTCreateQuery.h -dbms/src/Parsers/ParserAlterQuery.cpp -dbms/src/Parsers/ParserAlterQuery.h -dbms/src/Parsers/ParserCreateQuery.cpp -dbms/src/Parsers/ParserCreateQuery.h -dbms/src/Parsers/ParserQueryWithOutput.cpp -dbms/src/Storages/IStorage.h -dbms/src/Storages/StorageFactory.cpp -dbms/src/Storages/registerStorages.cpp --- diff --git a/dbms/src/NOTICE b/dbms/src/NOTICE new file mode 100644 index 00000000000..d0d3efe3f8e --- /dev/null +++ b/dbms/src/NOTICE @@ -0,0 +1,41 @@ +-- +The following notice shall be applied to the files listed below. + +Some modifications Copyright (c) 2018 BlackBerry Limited + +Licensed 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. + +Common/ErrorCodes.cpp +Common/UInt128.h +Core/Block.h +Core/Defines.h +Core/Settings.h +DataStreams/PushingToViewsBlockOutputStream.cpp +DataStreams/PushingToViewsBlockOutputStream.h +DataStreams/copyData.cpp +Databases/DatabasesCommon.cpp +IO/WriteBufferValidUTF8.cpp +Interpreters/InterpreterAlterQuery.cpp +Interpreters/InterpreterCreateQuery.cpp +Interpreters/InterpreterFactory.cpp +Parsers/ASTAlterQuery.cpp +Parsers/ASTAlterQuery.h +Parsers/ASTCreateQuery.cpp +Parsers/ASTCreateQuery.h +Parsers/ParserAlterQuery.cpp +Parsers/ParserAlterQuery.h +Parsers/ParserCreateQuery.cpp +Parsers/ParserCreateQuery.h +Parsers/ParserQueryWithOutput.cpp +Storages/IStorage.h +Storages/StorageFactory.cpp +Storages/registerStorages.cpp +-- From 69ed5279b50ec16163fc3f9fa85b06bea478bafa Mon Sep 17 00:00:00 2001 From: Vitaly Baranov Date: Fri, 16 Aug 2019 15:48:48 +0300 Subject: [PATCH 1015/1165] Get rid of dynamic allocation in ParsedJson::Iterator. --- contrib/simdjson | 2 +- dbms/tests/queries/0_stateless/00975_json_hang.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/simdjson b/contrib/simdjson index 9dfab9d9a4c..e9be643db5c 160000 --- a/contrib/simdjson +++ b/contrib/simdjson @@ -1 +1 @@ -Subproject commit 9dfab9d9a4c111690a101ea0a7506a2b2f3fa414 +Subproject commit e9be643db5cf1c29a69bc80ee72d220124a9c50e diff --git a/dbms/tests/queries/0_stateless/00975_json_hang.sql b/dbms/tests/queries/0_stateless/00975_json_hang.sql index 0618b4ba8f7..d60411cb796 100644 --- a/dbms/tests/queries/0_stateless/00975_json_hang.sql +++ b/dbms/tests/queries/0_stateless/00975_json_hang.sql @@ -1 +1 @@ -SELECT DISTINCT JSONExtractRaw(concat('{"x":', rand() % 2 ? 'true' : 'false', '}'), 'x') AS res FROM numbers(100000) ORDER BY res; +SELECT DISTINCT JSONExtractRaw(concat('{"x":', rand() % 2 ? 'true' : 'false', '}'), 'x') AS res FROM numbers(1000000) ORDER BY res; From 29f4f83c39e1915491ac8d9ee5d9dec1b77808e9 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 16 Aug 2019 15:54:50 +0300 Subject: [PATCH 1016/1165] Fix build. --- dbms/src/Interpreters/InterpreterSelectQuery.cpp | 2 +- dbms/src/Interpreters/InterpreterSelectQuery.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.cpp b/dbms/src/Interpreters/InterpreterSelectQuery.cpp index 7d0ddaef9a8..37e895331ab 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.cpp +++ b/dbms/src/Interpreters/InterpreterSelectQuery.cpp @@ -479,7 +479,7 @@ Block InterpreterSelectQuery::getSampleBlockImpl() InterpreterSelectQuery::AnalysisResult InterpreterSelectQuery::analyzeExpressions( const ASTSelectQuery & query, - ExpressionAnalyzer & query_analyzer, + SelectQueryExpressionAnalyzer & query_analyzer, QueryProcessingStage::Enum from_stage, QueryProcessingStage::Enum to_stage, const Context & context, diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.h b/dbms/src/Interpreters/InterpreterSelectQuery.h index 466f806f8ff..fc3e46dd345 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.h +++ b/dbms/src/Interpreters/InterpreterSelectQuery.h @@ -175,7 +175,7 @@ private: static AnalysisResult analyzeExpressions( const ASTSelectQuery & query, - ExpressionAnalyzer & query_analyzer, + SelectQueryExpressionAnalyzer & query_analyzer, QueryProcessingStage::Enum from_stage, QueryProcessingStage::Enum to_stage, const Context & context, From da6925f74fd742f91632ae0531104071a8097cc0 Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Fri, 16 Aug 2019 16:22:26 +0300 Subject: [PATCH 1017/1165] [website] take upcoming meetups from README.md (#6520) --- website/index.html | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/website/index.html b/website/index.html index 5ab51289c92..f2ef2f698f0 100644 --- a/website/index.html +++ b/website/index.html @@ -94,7 +94,6 @@
    - Upcoming Meetups: Moscow on September 5, Paris on October 3, Hong Kong on October 17, Shenzhen on October 20 and Shanghai on October 27
    @@ -495,6 +494,38 @@ clickhouse-client