// for debugging - may be unused void SetOperator::printTupleMap(const char* nonce, TupleMap &tuples) { printf("Printing TupleMap (%s): ", nonce); for (TupleMap::const_iterator mapIt = tuples.begin(); mapIt != tuples.end(); ++mapIt) { TableTuple tuple = mapIt->first; printf("%s, ", tuple.debugNoHeader().c_str()); } printf("\n"); fflush(stdout); }
void ExceptIntersectSetOperator::intersectTupleMaps(TupleMap& map_a, TupleMap& map_b) { TupleMap::iterator it_a = map_a.begin(); while(it_a != map_a.end()) { TupleMap::iterator it_b = map_b.find(it_a->first); if (it_b == map_b.end()) { it_a = map_a.erase(it_a); } else { it_a->second = std::min(it_a->second, it_b->second); ++it_a; } } }
void ExceptIntersectSetOperator::collectTuples(Table& input_table, TupleMap& tuple_map) { TableIterator iterator = input_table.iterator(); TableTuple tuple(input_table.schema()); while (iterator.next(tuple)) { TupleMap::iterator mapIt = tuple_map.find(tuple); if (mapIt == tuple_map.end()) { tuple_map.insert(std::make_pair(tuple, 1)); } else if (m_is_all) { ++mapIt->second; } } }
bool ExceptIntersectSetOperator::processTuples() { // Map to keep candidate tuples. The key is the tuple itself // The value - tuple's repeat count in the final table. TupleMap tuples; assert( ! m_input_tables.empty()); size_t ii = m_input_tablerefs.size(); while (ii--) { m_input_tables[ii] = m_input_tablerefs[ii].getTable(); } if ( ! m_is_except) { // For intersect we want to start with the smallest table std::vector<Table*>::iterator minTableIt = std::min_element(m_input_tables.begin(), m_input_tables.end(), TableSizeLess()); std::swap(m_input_tables[0], *minTableIt); } // Collect all tuples from the first set Table* input_table = m_input_tables[0]; collectTuples(*input_table, tuples); // // For each remaining input table, collect its tuple into a separate map // and substract/intersect it from/with the first one // TupleMap next_tuples; for (size_t ctr = 1, cnt = m_input_tables.size(); ctr < cnt; ctr++) { next_tuples.clear(); input_table = m_input_tables[ctr]; assert(input_table); collectTuples(*input_table, next_tuples); if (m_is_except) { exceptTupleMaps(tuples, next_tuples); } else { intersectTupleMaps(tuples, next_tuples); } } // Insert remaining tuples to the output table for (TupleMap::const_iterator mapIt = tuples.begin(); mapIt != tuples.end(); ++mapIt) { TableTuple tuple = mapIt->first; for (size_t i = 0; i < mapIt->second; ++i) { m_output_table->insertTempTuple(tuple); } } return true; }
void ExceptIntersectSetOperator::exceptTupleMaps(TupleMap& map_a, TupleMap& map_b) { TupleMap::iterator it_a = map_a.begin(); while(it_a != map_a.end()) { TupleMap::iterator it_b = map_b.find(it_a->first); if (it_b != map_b.end()) { if (it_a->second > it_b->second) { it_a->second -= it_b->second; } else { it_a = map_a.erase(it_a); continue; } } ++it_a; } }
bool ExceptIntersectSetOperator::processTuplesDo() { // Map to keep candidate tuples. The key is the tuple itself // The value - tuple's repeat count in the final table. TupleMap tuples; // Collect all tuples from the first set assert(!m_input_tables.empty()); Table* input_table = m_input_tables[0]; collectTuples(*input_table, tuples); // // For each remaining input table, collect its tuple into a separate map // and substract/intersect it from/with the first one // TupleMap next_tuples; for (size_t ctr = 1, cnt = m_input_tables.size(); ctr < cnt; ctr++) { next_tuples.clear(); Table* input_table = m_input_tables[ctr]; assert(input_table); collectTuples(*input_table, next_tuples); if (m_is_except) { exceptTupleMaps(tuples, next_tuples); } else { intersectTupleMaps(tuples, next_tuples); } } // Insert remaining tuples to our ouput table for (TupleMap::const_iterator mapIt = tuples.begin(); mapIt != tuples.end(); ++mapIt) { TableTuple tuple = mapIt->first; for (size_t i = 0; i < mapIt->second; ++i) { if (!m_output_table->insertTuple(tuple)) { VOLT_ERROR("Failed to insert tuple from input table '%s' into" " output table '%s'", m_input_tables[0]->name().c_str(), m_output_table->name().c_str()); return false; } } } return true; }