1
1
#pragma once
2
2
3
+ #include " ../base/projected_iterator.h"
3
4
#include " array.h"
4
5
#include " column.h"
5
6
#include " tuple.h"
6
7
8
+ #include < functional>
7
9
#include < map>
8
10
9
11
namespace clickhouse {
@@ -122,6 +124,8 @@ class ColumnMapT : public ColumnMap {
122
124
typename ArrayColumnType::ArrayValueView::Iterator data_iterator_;
123
125
124
126
public:
127
+ Iterator () = default ;
128
+
125
129
Iterator (typename ArrayColumnType::ArrayValueView::Iterator data_iterator)
126
130
: data_iterator_(data_iterator) {}
127
131
@@ -187,13 +191,19 @@ class ColumnMapT : public ColumnMap {
187
191
if (size () != other.size ()) {
188
192
return false ;
189
193
}
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
+ }
197
207
return true ;
198
208
}
199
209
@@ -214,13 +224,17 @@ class ColumnMapT : public ColumnMap {
214
224
215
225
template <typename T>
216
226
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});
224
238
}
225
239
226
240
static auto Wrap (ColumnMap&& col) {
0 commit comments