void SequentialHeapMerger::copyValues(const std::vector<c_atable_ptr_t > &input_tables, size_t source_column_index, atable_ptr_t &merged_table, size_t destination_column_index, std::vector<std::vector<value_id_t> > &value_id_mapping, bool useValid, const std::vector<bool>& valid) { ValueId value_id; // copy all value ids to the new doc vector // and apply value id mapping size_t merged_table_row = 0; // Only apply the mapping if we have one, for non-dict columns, we // just copy the "value_ids". We use almost identical source code // here to avoid the additional branch in the inner loop. Not pretty // but it works. if (value_id_mapping.size() > 0) { size_t part_counter = 0; for (size_t table = 0; table < input_tables.size(); table++) { for (size_t row = 0; row < input_tables[table]->size(); row++) { if (!useValid || (useValid && valid[part_counter + row])) { value_id.valueId = input_tables[table]->getValueId(source_column_index, row).valueId; value_id.valueId = value_id_mapping[table][value_id.valueId]; // translate value id to new dict merged_table->setValueId(destination_column_index, merged_table_row, value_id); merged_table_row++; } } part_counter += input_tables[table]->size(); } } else { // No dict columns size_t part_counter = 0; for (size_t table = 0; table < input_tables.size(); table++) { for (size_t row = 0; row < input_tables[table]->size(); row++) { if (!useValid || (useValid && valid[part_counter + row])) { value_id.valueId = input_tables[table]->getValueId(source_column_index, row).valueId; merged_table->setValueId(destination_column_index, merged_table_row, value_id); merged_table_row++; } } part_counter += input_tables[table]->size(); } } }
value_type operator() () { auto d = std::dynamic_pointer_cast<OrderPreservingDictionary<R>>(_dict); size_t tabSize = _main->size(); size_t start = _main->size() - _delta->size(); for(size_t row = start; row < tabSize; ++row) { _main->setValueId(_dstCol, row, ValueId{d->getValueIdForValue(_delta->getValue<R>(_col, row-start)), 0}); } }
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); } }