Skip to content

Commit 0472da2

Browse files
authored
Merge pull request #257 from den818/MapView
Some improvement ColumnMap
2 parents d2e56ae + 209d3ea commit 0472da2

File tree

4 files changed

+87
-15
lines changed

4 files changed

+87
-15
lines changed

clickhouse/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ INSTALL(FILES base/input.h DESTINATION include/clickhouse/base/)
102102
INSTALL(FILES base/open_telemetry.h DESTINATION include/clickhouse/base/)
103103
INSTALL(FILES base/output.h DESTINATION include/clickhouse/base/)
104104
INSTALL(FILES base/platform.h DESTINATION include/clickhouse/base/)
105+
INSTALL(FILES base/projected_iterator.h DESTINATION include/clickhouse/base/)
105106
INSTALL(FILES base/singleton.h DESTINATION include/clickhouse/base/)
106107
INSTALL(FILES base/socket.h DESTINATION include/clickhouse/base/)
107108
INSTALL(FILES base/string_utils.h DESTINATION include/clickhouse/base/)

clickhouse/base/projected_iterator.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#pragma once
2+
3+
#include <iterator>
4+
#include <type_traits>
5+
#include <utility>
6+
7+
namespace clickhouse {
8+
9+
template <typename UnaryFunction, typename Iterator, typename Reference = decltype(std::declval<UnaryFunction>()(std::declval<Iterator>())),
10+
typename Value = std::decay_t<Reference>>
11+
class ProjectedIterator {
12+
public:
13+
using value_type = Value;
14+
using reference = Reference;
15+
using pointer = Reference;
16+
using difference_type = typename std::iterator_traits<Iterator>::difference_type;
17+
using iterator_category = typename std::iterator_traits<Iterator>::iterator_category;
18+
19+
ProjectedIterator() = default;
20+
21+
inline ProjectedIterator(Iterator const& iterator, UnaryFunction functor)
22+
: iterator_(iterator)
23+
, functor_(std::move(functor)) {
24+
}
25+
26+
inline UnaryFunction functor() const { return functor; }
27+
28+
inline Iterator const& base() const { return iterator_; }
29+
30+
inline reference operator*() const { return functor_(iterator_); }
31+
32+
inline ProjectedIterator& operator++() {
33+
++iterator_;
34+
return *this;
35+
}
36+
37+
inline ProjectedIterator& operator--() {
38+
--iterator_;
39+
return *this;
40+
}
41+
42+
inline bool operator==(const ProjectedIterator& other) const {
43+
return this->iterator_ == other.iterator_;
44+
}
45+
46+
inline bool operator!=(const ProjectedIterator& other) const {
47+
return !(*this == other);
48+
}
49+
50+
private:
51+
Iterator iterator_;
52+
UnaryFunction functor_;
53+
};
54+
55+
} // namespace clickhouse

clickhouse/columns/array.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ class ColumnArrayT : public ColumnArray {
167167
const size_t size_;
168168
size_t index_;
169169
public:
170+
Iterator() = default;
171+
170172
Iterator(std::shared_ptr<NestedColumnType> typed_nested_data, size_t offset, size_t size, size_t index)
171173
: typed_nested_data_(typed_nested_data)
172174
, offset_(offset)
@@ -270,7 +272,7 @@ class ColumnArrayT : public ColumnArray {
270272
size_t counter = 0;
271273

272274
while (begin != end) {
273-
nested_data.Append(*begin);
275+
nested_data.Append(std::move(*begin));
274276
++begin;
275277
++counter;
276278
}

clickhouse/columns/map.h

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
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

911
namespace 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

Comments
 (0)