void SequentialHeapMerger::mergeValues(const std::vector<c_atable_ptr_t > &input_tables, size_t source_column_index, atable_ptr_t merged_table, size_t destination_column_index, value_id_mapping_t &value_id_mapping, bool useValid, const std::vector<bool>& valid) { std::vector<AbstractTable::SharedDictionaryPtr > value_id_maps; AbstractTable::SharedDictionaryPtr new_dict; // shortcut for dicts value_id_maps.reserve(input_tables.size()); for (size_t table = 0; table < input_tables.size(); table++) { if (!types::isCompatible(merged_table->metadataAt(destination_column_index).getType(), input_tables[table]->metadataAt(source_column_index).getType())) { throw std::runtime_error("Dictionary types don't match"); } auto dict = std::dynamic_pointer_cast<BaseDictionary<T>>(input_tables[table]->dictionaryAt(source_column_index)); value_id_maps.push_back(dict); } // Create new BaseDictionary - shrink when merge finished? new_dict = createNewDict<T>(input_tables, value_id_maps, value_id_mapping, source_column_index, useValid, valid); // set new value id map for column merged_table->setDictionaryAt(new_dict, destination_column_index); }
void SimpleStoreMerger::mergeValues(const std::vector<c_atable_ptr_t > &input_tables, atable_ptr_t merged_table, const column_mapping_t &column_mapping, const uint64_t newSize, bool useValid, const std::vector<bool>& valid) { if (useValid) throw std::runtime_error("SimpleStoreMerger does not support valid vectors"); if(input_tables.size() != 2) throw std::runtime_error("SimpleStoreMerger does not support more than two tables"); auto delta = std::dynamic_pointer_cast<const RawTable>(input_tables[1]); auto main = input_tables[0]; // Prepare type handling MergeDictFunctor fun; type_switch<hyrise_basic_types> ts; std::vector<MergeDictFunctor::result> mergedDictionaries(column_mapping.size()); // Extract unique values for delta for(const auto& kv : column_mapping) { const auto& col = kv.first; const auto& dst = kv.second; fun.prepare(main, delta, col); auto result = ts(main->typeOfColumn(col), fun); merged_table->setDictionaryAt(result.dict, dst); mergedDictionaries[col] = result; } // Update the values of the new Table merged_table->resize(newSize); size_t tabSize = main->size(); for(size_t row=0; row < tabSize; ++row) { for( const auto& kv : column_mapping) { const auto& col = kv.first; const auto& dst = kv.second; merged_table->setValueId(dst, row, ValueId{mergedDictionaries[col].mapping[main->getValueId(col, row).valueId], 0}); } } // Map the values for the values in the uncompressed delta MapValueForValueId map; for( const auto& kv : column_mapping) { const auto& col = kv.first; const auto& dst = kv.second; map.prepare(merged_table, dst, mergedDictionaries[col].dict, col, delta); ts(merged_table->typeOfColumn(dst), map); } }
void SequentialHeapMerger::mergeValues(const std::vector<c_atable_ptr_t > &input_tables, atable_ptr_t merged_table, const column_mapping_t &column_mapping, const uint64_t newSize, bool useValid, const std::vector<bool>& valid) { //if (input_tables.size () != 2) // throw std::runtime_error("Merging more than 2 tables is not supported with this merger..."); std::vector<value_id_mapping_t> mappingPerAtrtibute(input_tables[0]->columnCount()); for (const auto & kv: column_mapping) { const auto &source = kv.first; const auto &destination = kv.second; switch (merged_table->metadataAt(destination).getType()) { case IntegerType: case IntegerTypeDelta: case IntegerTypeDeltaConcurrent: mergeValues<hyrise_int_t>(input_tables, source, merged_table, destination, mappingPerAtrtibute[source], useValid, valid); break; case FloatType: case FloatTypeDelta: case FloatTypeDeltaConcurrent: mergeValues<hyrise_float_t>(input_tables, source, merged_table, destination, mappingPerAtrtibute[source], useValid, valid); break; case StringType: case StringTypeDelta: case StringTypeDeltaConcurrent: mergeValues<hyrise_string_t>(input_tables, source, merged_table, destination, mappingPerAtrtibute[source], useValid, valid); break; case IntegerNoDictType: case FloatNoDictType: merged_table->setDictionaryAt(makeDictionary(merged_table->typeOfColumn(destination)), destination); default: break; } } merged_table->resize(newSize); // Only after the dictionaries are merged copy the values for (const auto & kv: column_mapping) { const auto &source = kv.first; const auto &destination = kv.second; // copy the actual values and apply mapping copyValues(input_tables, source, merged_table, destination, mappingPerAtrtibute[source], useValid, valid); } }