MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / getItemsByTwoKeyColumnsImpl

Method getItemsByTwoKeyColumnsImpl

src/Dictionaries/IPAddressDictionary.cpp:702–780  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

700
701template <typename AttributeType, typename ValueSetter, typename DefaultValueExtractor>
702void IPAddressDictionary::getItemsByTwoKeyColumnsImpl(
703 const Attribute & attribute,
704 const Columns & key_columns,
705 ValueSetter && set_value,
706 DefaultValueExtractor & default_value_extractor) const
707{
708 const auto & first_column = key_columns.front();
709 const size_t rows = first_column->size();
710 auto & vec = std::get<ContainerType<AttributeType>>(attribute.maps);
711
712 if (const auto * ipv4_col = std::get_if<IPv4Container>(&ip_column))
713 {
714 const auto * key_ip_column_ptr = typeid_cast<const ColumnVector<UInt32> *>(&*key_columns.front());
715 if (key_ip_column_ptr == nullptr)
716 throw Exception(ErrorCodes::TYPE_MISMATCH, "Expected a UInt32 IP column");
717
718 const auto & key_mask_column = assert_cast<const ColumnVector<UInt8> &>(*key_columns.back());
719
720 auto comp_v4 = [&](size_t elem, const IPv4Subnet & target)
721 {
722 UInt32 addr = (*ipv4_col)[elem];
723 if (addr == target.addr)
724 return mask_column[elem] < target.prefix;
725 return addr < target.addr;
726 };
727
728 for (const auto i : collections::range(0, rows))
729 {
730 UInt32 addr = key_ip_column_ptr->getElement(i);
731 UInt8 mask = key_mask_column.getElement(i);
732
733 auto range = collections::range(0, row_idx.size());
734 auto found_it = std::lower_bound(range.begin(), range.end(), IPv4Subnet{addr, mask}, comp_v4);
735
736 if (likely(found_it != range.end() &&
737 (*ipv4_col)[*found_it] == addr &&
738 mask_column[*found_it] == mask))
739 {
740 set_value(i, vec[row_idx[*found_it]]);
741 }
742 else
743 set_value(i, default_value_extractor[i]);
744 }
745 return;
746 }
747
748 const auto * key_ip_column_ptr = typeid_cast<const ColumnFixedString *>(&*key_columns.front());
749 if (key_ip_column_ptr == nullptr || key_ip_column_ptr->getN() != IPV6_BINARY_LENGTH)
750 throw Exception(ErrorCodes::TYPE_MISMATCH, "Expected a FixedString(16) IP column");
751
752 const auto & key_mask_column = assert_cast<const ColumnVector<UInt8> &>(*key_columns.back());
753
754 const auto * ipv6_col = std::get_if<IPv6Container>(&ip_column);
755 auto comp_v6 = [&](size_t i, const IPv6Subnet & target)
756 {
757 auto cmpres = memcmp16(getIPv6FromOffset(*ipv6_col, i), target.addr);
758 if (cmpres == 0)
759 return mask_column[i] < target.prefix;

Callers

nothing calls this directly

Calls 13

rangeFunction · 0.85
memcmp16Function · 0.85
memequal16Function · 0.85
ExceptionClass · 0.50
frontMethod · 0.45
sizeMethod · 0.45
backMethod · 0.45
getElementMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
getNMethod · 0.45
getDataAtMethod · 0.45

Tested by

no test coverage detected