11#pragma once
22
3+ #include " ../base/projected_iterator.h"
34#include " array.h"
45#include " column.h"
56#include " tuple.h"
67
8+ #include < functional>
79#include < map>
810
911namespace clickhouse {
@@ -122,6 +124,8 @@ class ColumnMapT : public ColumnMap {
122124 typename ArrayColumnType::ArrayValueView::Iterator data_iterator_;
123125
124126 public:
127+ Iterator () = default ;
128+
125129 Iterator (typename ArrayColumnType::ArrayValueView::Iterator data_iterator)
126130 : data_iterator_(data_iterator) {}
127131
@@ -187,13 +191,19 @@ class ColumnMapT : public ColumnMap {
187191 if (size () != other.size ()) {
188192 return false ;
189193 }
190- using Vector = std::vector<std::pair<Key, Value>>;
191- Vector l (begin (), end ());
192- Vector r (other.begin (), other.end ());
193- auto comp = [](const auto & l, const auto & r) { return l.frist < r.first ; };
194- std::sort (l.begin (), l.end (), comp);
195- std::sort (r.begin (), r.end (), comp);
196- return std::equal (l.begin (), l.end (), r.begin (), r.end ());
194+ const auto make_index = [](const auto & data) {
195+ std::vector<size_t > result{data.Size ()};
196+ std::generate (result.begin (), result.end (), [i = 0 ] () mutable {return i++;});
197+ std::sort (result.begin (), result.end (), [&data](size_t l, size_t r) {return data[l] < data[r];});
198+ return result;
199+ };
200+ const auto index = make_index (data_);
201+ for (const auto & val : other.data_ ) {
202+ if (!std::binary_search (index.begin (), index.end (), val,
203+ [&data = data_](const auto & l, size_t r) {return l < data[r];})) {
204+ return false ;
205+ }
206+ }
197207 return true ;
198208 }
199209
@@ -214,13 +224,17 @@ class ColumnMapT : public ColumnMap {
214224
215225 template <typename T>
216226 inline void Append (const T& value) {
217- // TODO Refuse to copy.
218- std::vector<std::tuple<typename T::key_type, typename T::mapped_type>> container;
219- container.reserve (value.size ());
220- for (const auto & i : value) {
221- container.emplace_back (i.first , i.second );
222- }
223- typed_data_->Append (container.begin (), container.end ());
227+ using BaseIter = decltype (value.begin ());
228+ using KeyOfT = decltype (std::declval<BaseIter>()->first );
229+ using ValOfT = decltype (std::declval<BaseIter>()->second );
230+ using Functor = std::function<std::tuple<KeyOfT, ValOfT>(const BaseIter&)>;
231+ using Iterator = ProjectedIterator<Functor, BaseIter>;
232+
233+ Functor functor = [](const BaseIter& i) {
234+ return std::make_tuple (std::cref (i->first ), std::cref (i->second ));
235+ };
236+
237+ typed_data_->Append (Iterator{value.begin (), functor}, Iterator{value.end (), functor});
224238 }
225239
226240 static auto Wrap (ColumnMap&& col) {
0 commit comments