Skip to content

Commit e4cc9a1

Browse files
authored
Merge pull request #176 from Enmk/optimize_array_slice
Optimized ColumnArray::Slice
2 parents c15e7fe + 64b8f92 commit e4cc9a1

File tree

2 files changed

+19
-10
lines changed

2 files changed

+19
-10
lines changed

clickhouse/columns/array.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "array.h"
22
#include "numeric.h"
3+
34
#include <stdexcept>
45

56
namespace clickhouse {
@@ -45,10 +46,9 @@ ColumnRef ColumnArray::Slice(size_t begin, size_t size) const {
4546
if (size && begin + size > Size())
4647
throw ValidationError("Slice indexes are out of bounds");
4748

48-
auto result = std::make_shared<ColumnArray>(data_->CloneEmpty());
49-
for (size_t i = 0; i < size; i++) {
50-
result->AppendAsColumn(GetAsColumn(begin + i));
51-
}
49+
auto result = std::make_shared<ColumnArray>(data_->Slice(GetOffset(begin), GetOffset(begin + size) - GetOffset(begin)));
50+
for (size_t i = 0; i < size; i++)
51+
result->AddOffset(GetSize(begin + i));
5252

5353
return result;
5454
}

ut/column_array_ut.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ TEST(ColumnArray, Slice) {
134134
}
135135

136136
TEST(ColumnArray, Slice_2D) {
137+
// Verify that ColumnArray::Slice on 2D Array produces a 2D Array of proper type, size and contents.
138+
// Also check that slices can be of any size.
137139
const std::vector<std::vector<std::vector<uint64_t>>> values = {
138140
{{1u, 2u}, {3u}},
139141
{{4u}, {5u, 6u, 7u}, {8u, 9u}, {}},
@@ -143,13 +145,20 @@ TEST(ColumnArray, Slice_2D) {
143145
};
144146

145147
std::shared_ptr<ColumnArray> untyped_array = Create2DArray<ColumnUInt64>(values);
146-
147148
for (size_t i = 0; i < values.size() - 1; ++i) {
148-
auto slice = untyped_array->Slice(i, 1)->AsStrict<ColumnArray>();
149-
EXPECT_EQ(1u, slice->Size());
150-
151-
for (size_t j = 0; j < values[i].size(); ++j) {
152-
EXPECT_TRUE(CompareRecursive(values[i][j], *slice->GetAsColumnTyped<ColumnArray>(0)->GetAsColumnTyped<ColumnUInt64>(j)));
149+
for (size_t slice_size = 0; slice_size < values.size() - i; ++slice_size) {
150+
auto slice = untyped_array->Slice(i, slice_size)->AsStrict<ColumnArray>();
151+
EXPECT_EQ(slice_size, slice->Size());
152+
153+
for (size_t slice_row = 0; slice_row < slice_size; ++slice_row) {
154+
SCOPED_TRACE(::testing::Message() << "i: " << i << " slice_size:" << slice_size << " row:" << slice_row);
155+
auto val = slice->GetAsColumnTyped<ColumnArray>(slice_row);
156+
ASSERT_EQ(values[i + slice_row].size(), val->Size());
157+
158+
for (size_t j = 0; j < values[i + slice_row].size(); ++j) {
159+
ASSERT_TRUE(CompareRecursive(values[i + slice_row][j], *val->GetAsColumnTyped<ColumnUInt64>(j)));
160+
}
161+
}
153162
}
154163
}
155164
}

0 commit comments

Comments
 (0)