From fe826427bedcf32b354bd8ae9e27271dfe6d256f Mon Sep 17 00:00:00 2001 From: rtcote Date: Tue, 19 Sep 2023 17:13:54 -0600 Subject: [PATCH 1/8] Add reserve, capacity, & SwapElements methods to numeric columns --- clickhouse/columns/column.h | 6 ++++++ clickhouse/columns/numeric.cpp | 16 ++++++++++++++++ clickhouse/columns/numeric.h | 8 ++++++++ 3 files changed, 30 insertions(+) diff --git a/clickhouse/columns/column.h b/clickhouse/columns/column.h index b54cbdee..9f0cc01d 100644 --- a/clickhouse/columns/column.h +++ b/clickhouse/columns/column.h @@ -80,6 +80,12 @@ class Column : public std::enable_shared_from_this { /// Returns count of rows in the column. virtual size_t Size() const = 0; + /// Increase the capacity of the column + virtual void Reserve([[maybe_unused]]size_t new_cap) {} + + /// Returns the capacity of the column + virtual size_t Capacity() const { return 0; } + /// Makes slice of the current column. virtual ColumnRef Slice(size_t begin, size_t len) const = 0; diff --git a/clickhouse/columns/numeric.cpp b/clickhouse/columns/numeric.cpp index 81d6c721..a1563112 100644 --- a/clickhouse/columns/numeric.cpp +++ b/clickhouse/columns/numeric.cpp @@ -38,6 +38,12 @@ void ColumnVector::Erase(size_t pos, size_t count) { data_.erase(data_.begin() + begin, data_.begin() + last); } +template +void ColumnVector::SwapElements(size_t pos1, size_t pos2) { + auto data_it = data_.begin(); + std::iter_swap(data_it + pos1, data_it + pos2); +} + template void ColumnVector::Clear() { data_.clear(); @@ -72,6 +78,16 @@ size_t ColumnVector::Size() const { return data_.size(); } +template +void ColumnVector::Reserve(size_t new_cap) { + data_.reserve(new_cap); +} + +template +size_t ColumnVector::Capacity() const { + return data_.capacity(); +} + template ColumnRef ColumnVector::Slice(size_t begin, size_t len) const { return std::make_shared>(SliceVector(data_, begin, len)); diff --git a/clickhouse/columns/numeric.h b/clickhouse/columns/numeric.h index dcc344bb..c1bc324f 100644 --- a/clickhouse/columns/numeric.h +++ b/clickhouse/columns/numeric.h @@ -30,6 +30,8 @@ class ColumnVector : public Column { void Erase(size_t pos, size_t count = 1); + void SwapElements(size_t pos1, size_t pos2); + public: /// Appends content of given column to the end of current one. void Append(ColumnRef column) override; @@ -46,6 +48,12 @@ class ColumnVector : public Column { /// Returns count of rows in the column. size_t Size() const override; + /// Increase the capacity of the column + void Reserve(size_t new_cap) override; + + /// Returns the capacity of the column + size_t Capacity() const override; + /// Makes slice of the current column. ColumnRef Slice(size_t begin, size_t len) const override; ColumnRef CloneEmpty() const override; From 27e712622f2b4f110fc400165554f6097f23d0b0 Mon Sep 17 00:00:00 2001 From: rtcote Date: Wed, 20 Sep 2023 12:10:38 -0600 Subject: [PATCH 2/8] Added GenericColumnTest.Capacity & ColumnsCase.NumericSwap tests --- clickhouse/columns/column.h | 6 +++--- ut/Column_ut.cpp | 41 +++++++++++++++++++++++++++++++++++++ ut/columns_ut.cpp | 13 ++++++++++++ 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/clickhouse/columns/column.h b/clickhouse/columns/column.h index 9f0cc01d..190fdf8e 100644 --- a/clickhouse/columns/column.h +++ b/clickhouse/columns/column.h @@ -80,11 +80,11 @@ class Column : public std::enable_shared_from_this { /// Returns count of rows in the column. virtual size_t Size() const = 0; - /// Increase the capacity of the column + /// Increase the capacity of the column (currently only supported by numeric types at this time) virtual void Reserve([[maybe_unused]]size_t new_cap) {} - /// Returns the capacity of the column - virtual size_t Capacity() const { return 0; } + /// Returns the capacity of the column (currently only supported by numeric types at this time) + virtual size_t Capacity() const { return Size(); } /// Makes slice of the current column. virtual ColumnRef Slice(size_t begin, size_t len) const = 0; diff --git a/ut/Column_ut.cpp b/ut/Column_ut.cpp index ace1f79d..073af1b6 100644 --- a/ut/Column_ut.cpp +++ b/ut/Column_ut.cpp @@ -305,6 +305,47 @@ TYPED_TEST(GenericColumnTest, Clear) { EXPECT_EQ(0u, column->Size()); } +// Check if ColumnType is numeric +template +inline bool isNumericColumnType([[maybe_unused]]const ColumnType& col) { + if constexpr (std::is_same_v) { + return true; + } else if constexpr (std::is_same_v) { + return true; + } else if constexpr (std::is_same_v) { + return true; + } else if constexpr (std::is_same_v) { + return true; + } else if constexpr (std::is_same_v) { + return true; + } else if constexpr (std::is_same_v) { + return true; + } else if constexpr (std::is_same_v) { + return true; + } else if constexpr (std::is_same_v) { + return true; + } else if constexpr (std::is_same_v) { + return true; + } else if constexpr (std::is_same_v) { + return true; + } else { + return false; + } +} + +TYPED_TEST(GenericColumnTest, Capacity) { + auto [column, values] = this->MakeColumnWithValues(100); + EXPECT_EQ(values.size(), column->Size()); + + column->Reserve(200); + + if (isNumericColumnType(*column)) { + EXPECT_EQ(200u, column->Capacity()); + } else { + EXPECT_EQ(100u, column->Capacity()); + } +} + TYPED_TEST(GenericColumnTest, Swap) { auto [column_A, values] = this->MakeColumnWithValues(100); auto column_B = this->MakeColumn(); diff --git a/ut/columns_ut.cpp b/ut/columns_ut.cpp index ce477554..246db445 100644 --- a/ut/columns_ut.cpp +++ b/ut/columns_ut.cpp @@ -58,6 +58,19 @@ TEST(ColumnsCase, NumericSlice) { ASSERT_EQ(sub->At(2), 13u); } +TEST(ColumnsCase, NumericSwap) { + auto col = std::make_shared(MakeNumbers()); + + ASSERT_EQ(col->Size(), 11u); + ASSERT_EQ(col->At(3), 7u); + ASSERT_EQ(col->At(10), 31u); + + col->SwapElements(3, 10); + + ASSERT_EQ(col->Size(), 11u); + ASSERT_EQ(col->At(3), 31u); + ASSERT_EQ(col->At(10), 7u); +} TEST(ColumnsCase, FixedStringInit) { const auto column_data = MakeFixedStrings(3); From a1625094591c000898c7c4ff4776bd527179d964 Mon Sep 17 00:00:00 2001 From: rtcote Date: Thu, 21 Sep 2023 11:45:41 -0600 Subject: [PATCH 3/8] Add new methods for date types --- clickhouse/columns/column.h | 4 +- clickhouse/columns/date.cpp | 80 ++++++++++ clickhouse/columns/date.h | 68 +++++++++ clickhouse/columns/decimal.cpp | 38 +++++ clickhouse/columns/decimal.h | 18 +++ clickhouse/columns/numeric.cpp | 10 ++ clickhouse/columns/numeric.h | 9 ++ ut/Column_ut.cpp | 18 ++- ut/columns_ut.cpp | 260 +++++++++++++++++++++++++++++++++ 9 files changed, 500 insertions(+), 5 deletions(-) diff --git a/clickhouse/columns/column.h b/clickhouse/columns/column.h index 190fdf8e..efca1b2e 100644 --- a/clickhouse/columns/column.h +++ b/clickhouse/columns/column.h @@ -80,10 +80,10 @@ class Column : public std::enable_shared_from_this { /// Returns count of rows in the column. virtual size_t Size() const = 0; - /// Increase the capacity of the column (currently only supported by numeric types at this time) + /// Increase the capacity of the column (currently only supported by numeric/date types at this time) virtual void Reserve([[maybe_unused]]size_t new_cap) {} - /// Returns the capacity of the column (currently only supported by numeric types at this time) + /// Returns the capacity of the column (currently only supported by numeric/date types at this time) virtual size_t Capacity() const { return Size(); } /// Makes slice of the current column. diff --git a/clickhouse/columns/date.cpp b/clickhouse/columns/date.cpp index f4d08cb4..0cedf288 100644 --- a/clickhouse/columns/date.cpp +++ b/clickhouse/columns/date.cpp @@ -31,6 +31,18 @@ uint16_t ColumnDate::RawAt(size_t n) const { return data_->At(n); } +void ColumnDate::SwapElements(size_t pos1, size_t pos2) { + data_->SwapElements(pos1, pos2); +} + +bool ColumnDate::CompareElementsGT(size_t pos1, size_t pos2) const { + return data_->CompareElementsGT(pos1, pos2); +} + +bool ColumnDate::CompareElementsLT(size_t pos1, size_t pos2) const { + return data_->CompareElementsLT(pos1, pos2); +} + void ColumnDate::Append(ColumnRef column) { if (auto col = column->As()) { data_->Append(col->data_); @@ -49,6 +61,14 @@ size_t ColumnDate::Size() const { return data_->Size(); } +void ColumnDate::Reserve(size_t new_cap) { + data_->Reserve(new_cap); +} + +size_t ColumnDate::Capacity() const { + return data_->Capacity(); +} + ColumnRef ColumnDate::Slice(size_t begin, size_t len) const { auto col = data_->Slice(begin, len)->As(); auto result = std::make_shared(); @@ -106,6 +126,18 @@ int32_t ColumnDate32::RawAt(size_t n) const { return data_->At(n); } +void ColumnDate32::SwapElements(size_t pos1, size_t pos2) { + data_->SwapElements(pos1, pos2); +} + +bool ColumnDate32::CompareElementsGT(size_t pos1, size_t pos2) const { + return data_->CompareElementsGT(pos1, pos2); +} + +bool ColumnDate32::CompareElementsLT(size_t pos1, size_t pos2) const { + return data_->CompareElementsLT(pos1, pos2); +} + bool ColumnDate32::LoadBody(InputStream* input, size_t rows) { return data_->LoadBody(input, rows); } @@ -118,6 +150,14 @@ size_t ColumnDate32::Size() const { return data_->Size(); } +void ColumnDate32::Reserve(size_t new_cap) { + data_->Reserve(new_cap); +} + +size_t ColumnDate32::Capacity() const { + return data_->Capacity(); +} + ColumnRef ColumnDate32::Slice(size_t begin, size_t len) const { auto col = data_->Slice(begin, len)->As(); auto result = std::make_shared(); @@ -164,6 +204,18 @@ std::string ColumnDateTime::Timezone() const { return type_->As()->Timezone(); } +void ColumnDateTime::SwapElements(size_t pos1, size_t pos2) { + data_->SwapElements(pos1, pos2); +} + +bool ColumnDateTime::CompareElementsGT(size_t pos1, size_t pos2) const { + return data_->CompareElementsGT(pos1, pos2); +} + +bool ColumnDateTime::CompareElementsLT(size_t pos1, size_t pos2) const { + return data_->CompareElementsLT(pos1, pos2); +} + void ColumnDateTime::Append(ColumnRef column) { if (auto col = column->As()) { data_->Append(col->data_); @@ -182,6 +234,14 @@ size_t ColumnDateTime::Size() const { return data_->Size(); } +void ColumnDateTime::Reserve(size_t new_cap) { + data_->Reserve(new_cap); +} + +size_t ColumnDateTime::Capacity() const { + return data_->Capacity(); +} + void ColumnDateTime::Clear() { data_->Clear(); } @@ -237,6 +297,18 @@ Int64 ColumnDateTime64::At(size_t n) const { return static_cast(data_->At(n)); } +void ColumnDateTime64::SwapElements(size_t pos1, size_t pos2) { + data_->SwapElements(pos1, pos2); +} + +bool ColumnDateTime64::CompareElementsGT(size_t pos1, size_t pos2) const { + return data_->CompareElementsGT(pos1, pos2); +} + +bool ColumnDateTime64::CompareElementsLT(size_t pos1, size_t pos2) const { + return data_->CompareElementsLT(pos1, pos2); +} + std::string ColumnDateTime64::Timezone() const { return type_->As()->Timezone(); } @@ -263,6 +335,14 @@ size_t ColumnDateTime64::Size() const { return data_->Size(); } +void ColumnDateTime64::Reserve(size_t new_cap) { + data_->Reserve(new_cap); +} + +size_t ColumnDateTime64::Capacity() const { + return data_->Capacity(); +} + ItemView ColumnDateTime64::GetItem(size_t index) const { return ItemView(Type::DateTime64, data_->GetItem(index)); } diff --git a/clickhouse/columns/date.h b/clickhouse/columns/date.h index 9b170001..9158d888 100644 --- a/clickhouse/columns/date.h +++ b/clickhouse/columns/date.h @@ -27,6 +27,17 @@ class ColumnDate : public Column { void AppendRaw(uint16_t value); uint16_t RawAt(size_t n) const; + /// Swap two Elements/rows in the column + void SwapElements(size_t pos1, size_t pos2); + + /// Test if the value at position 1 is greater than the value at position 2 + /// No range checking is performed for performance + bool CompareElementsGT(size_t pos1, size_t pos2) const; + + /// Test if the value at position 1 is less than the value at position 2 + /// No range checking is performed for performance + bool CompareElementsLT(size_t pos1, size_t pos2) const; + /// Appends content of given column to the end of current one. void Append(ColumnRef column) override; @@ -42,6 +53,12 @@ class ColumnDate : public Column { /// Returns count of rows in the column. size_t Size() const override; + /// Increase the capacity of the column + void Reserve(size_t new_cap) override; + + /// Returns the capacity of the column + size_t Capacity() const override; + /// Makes slice of the current column. ColumnRef Slice(size_t begin, size_t len) const override; ColumnRef CloneEmpty() const override; @@ -77,6 +94,17 @@ class ColumnDate32 : public Column { void AppendRaw(int32_t value); int32_t RawAt(size_t n) const; + /// Swap two Elements/rows in the column + void SwapElements(size_t pos1, size_t pos2); + + /// Test if the value at position 1 is greater than the value at position 2 + /// No range checking is performed for performance + bool CompareElementsGT(size_t pos1, size_t pos2) const; + + /// Test if the value at position 1 is less than the value at position 2 + /// No range checking is performed for performance + bool CompareElementsLT(size_t pos1, size_t pos2) const; + /// Loads column data from input stream. bool LoadBody(InputStream* input, size_t rows) override; @@ -89,6 +117,12 @@ class ColumnDate32 : public Column { /// Returns count of rows in the column. size_t Size() const override; + /// Increase the capacity of the column + void Reserve(size_t new_cap) override; + + /// Returns the capacity of the column + size_t Capacity() const override; + /// Makes slice of the current column. ColumnRef Slice(size_t begin, size_t len) const override; ColumnRef CloneEmpty() const override; @@ -119,6 +153,17 @@ class ColumnDateTime : public Column { /// Timezone associated with a data column. std::string Timezone() const; + /// Swap two Elements/rows in the column + void SwapElements(size_t pos1, size_t pos2); + + /// Test if the value at position 1 is greater than the value at position 2 + /// No range checking is performed for performance + bool CompareElementsGT(size_t pos1, size_t pos2) const; + + /// Test if the value at position 1 is less than the value at position 2 + /// No range checking is performed for performance + bool CompareElementsLT(size_t pos1, size_t pos2) const; + public: /// Appends content of given column to the end of current one. void Append(ColumnRef column) override; @@ -135,6 +180,12 @@ class ColumnDateTime : public Column { /// Returns count of rows in the column. size_t Size() const override; + /// Increase the capacity of the column + void Reserve(size_t new_cap) override; + + /// Returns the capacity of the column + size_t Capacity() const override; + /// Makes slice of the current column. ColumnRef Slice(size_t begin, size_t len) const override; ColumnRef CloneEmpty() const override; @@ -169,6 +220,17 @@ class ColumnDateTime64 : public Column { /// Timezone associated with a data column. std::string Timezone() const; + /// Swap two Elements/rows in the column + void SwapElements(size_t pos1, size_t pos2); + + /// Test if the value at position 1 is greater than the value at position 2 + /// No range checking is performed for performance + bool CompareElementsGT(size_t pos1, size_t pos2) const; + + /// Test if the value at position 1 is less than the value at position 2 + /// No range checking is performed for performance + bool CompareElementsLT(size_t pos1, size_t pos2) const; + public: /// Appends content of given column to the end of current one. void Append(ColumnRef column) override; @@ -185,6 +247,12 @@ class ColumnDateTime64 : public Column { /// Returns count of rows in the column. size_t Size() const override; + /// Increase the capacity of the column + void Reserve(size_t new_cap) override; + + /// Returns the capacity of the column + size_t Capacity() const override; + /// Makes slice of the current column. ColumnRef Slice(size_t begin, size_t len) const override; ColumnRef CloneEmpty() const override; diff --git a/clickhouse/columns/decimal.cpp b/clickhouse/columns/decimal.cpp index d44dc0c0..a9fd350f 100644 --- a/clickhouse/columns/decimal.cpp +++ b/clickhouse/columns/decimal.cpp @@ -205,6 +205,36 @@ void ColumnDecimal::SaveBody(OutputStream* output) { data_->SaveBody(output); } +void ColumnDecimal::SwapElements(size_t pos1, size_t pos2) { + if (data_->Type()->GetCode() == Type::Int32) { + data_->As()->SwapElements(pos1, pos2); + } else if (data_->Type()->GetCode() == Type::Int64) { + data_->As()->SwapElements(pos1, pos2); + } else { + data_->As()->SwapElements(pos1, pos2); + } +} + +bool ColumnDecimal::CompareElementsGT(size_t pos1, size_t pos2) const { + if (data_->Type()->GetCode() == Type::Int32) { + return data_->As()->CompareElementsGT(pos1, pos2); + } else if (data_->Type()->GetCode() == Type::Int64) { + return data_->As()->CompareElementsGT(pos1, pos2); + } else { + return data_->As()->CompareElementsGT(pos1, pos2); + } +} + +bool ColumnDecimal::CompareElementsLT(size_t pos1, size_t pos2) const { + if (data_->Type()->GetCode() == Type::Int32) { + return data_->As()->CompareElementsLT(pos1, pos2); + } else if (data_->Type()->GetCode() == Type::Int64) { + return data_->As()->CompareElementsLT(pos1, pos2); + } else { + return data_->As()->CompareElementsLT(pos1, pos2); + } +} + void ColumnDecimal::Clear() { data_->Clear(); } @@ -213,6 +243,14 @@ size_t ColumnDecimal::Size() const { return data_->Size(); } +void ColumnDecimal::Reserve(size_t new_cap) { + data_->Reserve(new_cap); +} + +size_t ColumnDecimal::Capacity() const { + return data_->Capacity(); +} + ColumnRef ColumnDecimal::Slice(size_t begin, size_t len) const { // coundn't use std::make_shared since this c-tor is private return ColumnRef{new ColumnDecimal(type_, data_->Slice(begin, len))}; diff --git a/clickhouse/columns/decimal.h b/clickhouse/columns/decimal.h index 4b09553a..e6641659 100644 --- a/clickhouse/columns/decimal.h +++ b/clickhouse/columns/decimal.h @@ -20,12 +20,30 @@ class ColumnDecimal : public Column { Int128 At(size_t i) const; inline auto operator[](size_t i) const { return At(i); } + /// Swap two Elements/rows in the column + void SwapElements(size_t pos1, size_t pos2); + + /// Test if the value at position 1 is greater than the value at position 2 + /// No range checking is performed for performance + bool CompareElementsGT(size_t pos1, size_t pos2) const; + + /// Test if the value at position 1 is less than the value at position 2 + /// No range checking is performed for performance + bool CompareElementsLT(size_t pos1, size_t pos2) const; + public: void Append(ColumnRef column) override; bool LoadBody(InputStream* input, size_t rows) override; void SaveBody(OutputStream* output) override; void Clear() override; size_t Size() const override; + + /// Increase the capacity of the column + void Reserve(size_t new_cap) override; + + /// Returns the capacity of the column + size_t Capacity() const override; + ColumnRef Slice(size_t begin, size_t len) const override; ColumnRef CloneEmpty() const override; void Swap(Column& other) override; diff --git a/clickhouse/columns/numeric.cpp b/clickhouse/columns/numeric.cpp index a1563112..27676d9c 100644 --- a/clickhouse/columns/numeric.cpp +++ b/clickhouse/columns/numeric.cpp @@ -44,6 +44,16 @@ void ColumnVector::SwapElements(size_t pos1, size_t pos2) { std::iter_swap(data_it + pos1, data_it + pos2); } +template +bool ColumnVector::CompareElementsGT(size_t pos1, size_t pos2) const { + return data_[pos1] > data_[pos2]; +} + +template +bool ColumnVector::CompareElementsLT(size_t pos1, size_t pos2) const { + return data_[pos1] < data_[pos2]; +} + template void ColumnVector::Clear() { data_.clear(); diff --git a/clickhouse/columns/numeric.h b/clickhouse/columns/numeric.h index c1bc324f..4e9137f1 100644 --- a/clickhouse/columns/numeric.h +++ b/clickhouse/columns/numeric.h @@ -30,8 +30,17 @@ class ColumnVector : public Column { void Erase(size_t pos, size_t count = 1); + /// Swap two Elements/rows in the column void SwapElements(size_t pos1, size_t pos2); + /// Test if the value at position 1 is greater than the value at position 2 + /// No range checking is performed for performance + bool CompareElementsGT(size_t pos1, size_t pos2) const; + + /// Test if the value at position 1 is less than the value at position 2 + /// No range checking is performed for performance + bool CompareElementsLT(size_t pos1, size_t pos2) const; + public: /// Appends content of given column to the end of current one. void Append(ColumnRef column) override; diff --git a/ut/Column_ut.cpp b/ut/Column_ut.cpp index 073af1b6..2d93727b 100644 --- a/ut/Column_ut.cpp +++ b/ut/Column_ut.cpp @@ -305,9 +305,9 @@ TYPED_TEST(GenericColumnTest, Clear) { EXPECT_EQ(0u, column->Size()); } -// Check if ColumnType is numeric +// Check if ColumnType supports Capacity/Reserve methods template -inline bool isNumericColumnType([[maybe_unused]]const ColumnType& col) { +inline bool supportsCapacity([[maybe_unused]]const ColumnType& col) { if constexpr (std::is_same_v) { return true; } else if constexpr (std::is_same_v) { @@ -324,10 +324,22 @@ inline bool isNumericColumnType([[maybe_unused]]const ColumnType& col) { return true; } else if constexpr (std::is_same_v) { return true; + } else if constexpr (std::is_same_v) { + return true; } else if constexpr (std::is_same_v) { return true; } else if constexpr (std::is_same_v) { return true; + } else if constexpr (std::is_same_v) { + return true; + } else if constexpr (std::is_same_v) { + return true; + } else if constexpr (std::is_same_v) { + return true; + } else if constexpr (std::is_same_v) { + return true; + } else if constexpr (std::is_same_v) { + return true; } else { return false; } @@ -339,7 +351,7 @@ TYPED_TEST(GenericColumnTest, Capacity) { column->Reserve(200); - if (isNumericColumnType(*column)) { + if (supportsCapacity(*column)) { EXPECT_EQ(200u, column->Capacity()); } else { EXPECT_EQ(100u, column->Capacity()); diff --git a/ut/columns_ut.cpp b/ut/columns_ut.cpp index 246db445..9b140aef 100644 --- a/ut/columns_ut.cpp +++ b/ut/columns_ut.cpp @@ -72,6 +72,21 @@ TEST(ColumnsCase, NumericSwap) { ASSERT_EQ(col->At(10), 7u); } +TEST(ColumnsCase, NumericCompare) { + auto col = std::make_shared(MakeNumbers()); + + ASSERT_EQ(col->Size(), 11u); + ASSERT_EQ(col->At(3), 7u); + ASSERT_EQ(col->At(10), 31u); + + ASSERT_TRUE(col->CompareElementsLT( 3, 10)); + ASSERT_TRUE(col->CompareElementsGT(10, 3)); + + ASSERT_EQ(col->Size(), 11u); + ASSERT_EQ(col->At(3), 7u); + ASSERT_EQ(col->At(10), 31u); +} + TEST(ColumnsCase, FixedStringInit) { const auto column_data = MakeFixedStrings(3); auto col = std::make_shared(3, column_data); @@ -369,6 +384,251 @@ TEST(ColumnsCase, Date2038) { ASSERT_EQ(largeDate, col1->At(0)); } +TEST(ColumnsCase, DateSwap) { + auto col = std::make_shared(); + + col->AppendRaw(1u); + col->AppendRaw(1234u); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->RawAt(0), 1u); + ASSERT_EQ(col->RawAt(1), 1234u); + + col->SwapElements(0, 1); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->RawAt(0), 1234u); + ASSERT_EQ(col->RawAt(1), 1u); +} + +TEST(ColumnsCase, Date32Swap) { + auto col = std::make_shared(); + + col->AppendRaw(1); + col->AppendRaw(1234); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->RawAt(0), 1); + ASSERT_EQ(col->RawAt(1), 1234); + + col->SwapElements(0, 1); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->RawAt(0), 1234); + ASSERT_EQ(col->RawAt(1), 1); +} + +TEST(ColumnsCase, DateTimeSwap) { + auto col = std::make_shared(); + + col->Append(1u); + col->Append(1234u); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1u); + ASSERT_EQ(col->At(1), 1234u); + + col->SwapElements(0, 1); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1234u); + ASSERT_EQ(col->At(1), 1u); +} + +TEST(ColumnsCase, DateTime64Swap) { + auto col = std::make_shared(6ul); + + col->Append(1u); + col->Append(1234u); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1u); + ASSERT_EQ(col->At(1), 1234u); + + col->SwapElements(0, 1); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1234u); + ASSERT_EQ(col->At(1), 1u); +} + +TEST(ColumnsCase, Decimal32Swap) { + auto col = std::make_shared(9, 0); + + col->Append(1); + col->Append(1234); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1); + ASSERT_EQ(col->At(1), 1234); + + col->SwapElements(0, 1); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1234); + ASSERT_EQ(col->At(1), 1); +} + +TEST(ColumnsCase, Decimal64Swap) { + auto col = std::make_shared(18, 0); + + col->Append(1); + col->Append(1234); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1); + ASSERT_EQ(col->At(1), 1234); + + col->SwapElements(0, 1); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1234); + ASSERT_EQ(col->At(1), 1); +} + +TEST(ColumnsCase, Decimal128Swap) { + auto col = std::make_shared(38, 0); + + col->Append(1); + col->Append(1234); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1); + ASSERT_EQ(col->At(1), 1234); + + col->SwapElements(0, 1); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1234); + ASSERT_EQ(col->At(1), 1); +} + +TEST(ColumnsCase, DateCompare) { + auto col = std::make_shared(); + + col->AppendRaw(1u); + col->AppendRaw(1234u); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->RawAt(0), 1u); + ASSERT_EQ(col->RawAt(1), 1234u); + + ASSERT_TRUE(col->CompareElementsLT(0, 1)); + ASSERT_TRUE(col->CompareElementsGT(1, 0)); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->RawAt(0), 1u); + ASSERT_EQ(col->RawAt(1), 1234u); +} + +TEST(ColumnsCase, Date32Compare) { + auto col = std::make_shared(); + + col->AppendRaw(1); + col->AppendRaw(1234); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->RawAt(0), 1); + ASSERT_EQ(col->RawAt(1), 1234); + + ASSERT_TRUE(col->CompareElementsLT(0, 1)); + ASSERT_TRUE(col->CompareElementsGT(1, 0)); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->RawAt(0), 1); + ASSERT_EQ(col->RawAt(1), 1234); +} + +TEST(ColumnsCase, DateTimeCompare) { + auto col = std::make_shared(); + + col->Append(1u); + col->Append(1234u); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1u); + ASSERT_EQ(col->At(1), 1234u); + + ASSERT_TRUE(col->CompareElementsLT(0, 1)); + ASSERT_TRUE(col->CompareElementsGT(1, 0)); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1u); + ASSERT_EQ(col->At(1), 1234u); +} + +TEST(ColumnsCase, DateTime64Compare) { + auto col = std::make_shared(6ul); + + col->Append(1u); + col->Append(1234u); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1u); + ASSERT_EQ(col->At(1), 1234u); + + ASSERT_TRUE(col->CompareElementsLT(0, 1)); + ASSERT_TRUE(col->CompareElementsGT(1, 0)); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1u); + ASSERT_EQ(col->At(1), 1234u); +} + +TEST(ColumnsCase, Decimal32Compare) { + auto col = std::make_shared(9, 0); + + col->Append(1); + col->Append(1234); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1); + ASSERT_EQ(col->At(1), 1234); + + ASSERT_TRUE(col->CompareElementsLT(0, 1)); + ASSERT_TRUE(col->CompareElementsGT(1, 0)); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1); + ASSERT_EQ(col->At(1), 1234); +} + +TEST(ColumnsCase, Decimal64Compare) { + auto col = std::make_shared(18, 0); + + col->Append(1); + col->Append(1234); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1); + ASSERT_EQ(col->At(1), 1234); + + ASSERT_TRUE(col->CompareElementsLT(0, 1)); + ASSERT_TRUE(col->CompareElementsGT(1, 0)); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1); + ASSERT_EQ(col->At(1), 1234); +} + +TEST(ColumnsCase, Decimal128Compare) { + auto col = std::make_shared(38, 0); + + col->Append(1); + col->Append(1234); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1); + ASSERT_EQ(col->At(1), 1234); + + ASSERT_TRUE(col->CompareElementsLT(0, 1)); + ASSERT_TRUE(col->CompareElementsGT(1, 0)); + + ASSERT_EQ(col->Size(), 2u); + ASSERT_EQ(col->At(0), 1); + ASSERT_EQ(col->At(1), 1234); +} + TEST(ColumnsCase, EnumTest) { std::vector enum_items = {{"Hi", 1}, {"Hello", 2}}; From 5948eb68ef1c5006dcd53b269f8a4776d18567bb Mon Sep 17 00:00:00 2001 From: rtcote Date: Wed, 27 Sep 2023 08:00:46 -0600 Subject: [PATCH 4/8] Add AppendRaw to ColumnDateTime --- clickhouse/columns/date.cpp | 4 ++++ clickhouse/columns/date.h | 3 +++ ut/columns_ut.cpp | 4 ++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/clickhouse/columns/date.cpp b/clickhouse/columns/date.cpp index 0cedf288..9bd3c5bb 100644 --- a/clickhouse/columns/date.cpp +++ b/clickhouse/columns/date.cpp @@ -200,6 +200,10 @@ std::time_t ColumnDateTime::At(size_t n) const { return data_->At(n); } +void ColumnDateTime::AppendRaw(uint32_t value) { + data_->Append(value); +} + std::string ColumnDateTime::Timezone() const { return type_->As()->Timezone(); } diff --git a/clickhouse/columns/date.h b/clickhouse/columns/date.h index 9158d888..ece7b71b 100644 --- a/clickhouse/columns/date.h +++ b/clickhouse/columns/date.h @@ -150,6 +150,9 @@ class ColumnDateTime : public Column { std::time_t At(size_t n) const; inline std::time_t operator [] (size_t n) const { return At(n); } + /// Append raw as UNIX epoch seconds in uint32 + void AppendRaw(uint32_t value); + /// Timezone associated with a data column. std::string Timezone() const; diff --git a/ut/columns_ut.cpp b/ut/columns_ut.cpp index 9b140aef..4221e0c8 100644 --- a/ut/columns_ut.cpp +++ b/ut/columns_ut.cpp @@ -421,8 +421,8 @@ TEST(ColumnsCase, Date32Swap) { TEST(ColumnsCase, DateTimeSwap) { auto col = std::make_shared(); - col->Append(1u); - col->Append(1234u); + col->AppendRaw(1u); + col->AppendRaw(1234u); ASSERT_EQ(col->Size(), 2u); ASSERT_EQ(col->At(0), 1u); From 873107d18e0c3d83def3021b39a8a37fafa13770 Mon Sep 17 00:00:00 2001 From: rtcote Date: Tue, 3 Oct 2023 22:42:39 -0600 Subject: [PATCH 5/8] Review changes --- clickhouse/columns/column.h | 6 - clickhouse/columns/date.cpp | 104 +++------- clickhouse/columns/date.h | 81 ++------ clickhouse/columns/decimal.cpp | 38 ---- clickhouse/columns/decimal.h | 17 -- clickhouse/columns/numeric.cpp | 23 +-- clickhouse/columns/numeric.h | 20 +- ut/Column_ut.cpp | 53 ----- ut/columns_ut.cpp | 364 ++++++++------------------------- 9 files changed, 152 insertions(+), 554 deletions(-) diff --git a/clickhouse/columns/column.h b/clickhouse/columns/column.h index efca1b2e..b54cbdee 100644 --- a/clickhouse/columns/column.h +++ b/clickhouse/columns/column.h @@ -80,12 +80,6 @@ class Column : public std::enable_shared_from_this { /// Returns count of rows in the column. virtual size_t Size() const = 0; - /// Increase the capacity of the column (currently only supported by numeric/date types at this time) - virtual void Reserve([[maybe_unused]]size_t new_cap) {} - - /// Returns the capacity of the column (currently only supported by numeric/date types at this time) - virtual size_t Capacity() const { return Size(); } - /// Makes slice of the current column. virtual ColumnRef Slice(size_t begin, size_t len) const = 0; diff --git a/clickhouse/columns/date.cpp b/clickhouse/columns/date.cpp index 9bd3c5bb..b93386c8 100644 --- a/clickhouse/columns/date.cpp +++ b/clickhouse/columns/date.cpp @@ -31,22 +31,22 @@ uint16_t ColumnDate::RawAt(size_t n) const { return data_->At(n); } -void ColumnDate::SwapElements(size_t pos1, size_t pos2) { - data_->SwapElements(pos1, pos2); +void ColumnDate::Append(ColumnRef column) { + if (auto col = column->As()) { + data_->Append(col->data_); + } } -bool ColumnDate::CompareElementsGT(size_t pos1, size_t pos2) const { - return data_->CompareElementsGT(pos1, pos2); +std::vector &ColumnDate::GetRawVector() { + return data_->GetRawVector(); } -bool ColumnDate::CompareElementsLT(size_t pos1, size_t pos2) const { - return data_->CompareElementsLT(pos1, pos2); +void ColumnDate::Reserve(size_t new_cap) { + data_->Reserve(new_cap); } -void ColumnDate::Append(ColumnRef column) { - if (auto col = column->As()) { - data_->Append(col->data_); - } +size_t ColumnDate::Capacity() const { + return data_->Capacity(); } bool ColumnDate::LoadBody(InputStream* input, size_t rows) { @@ -61,14 +61,6 @@ size_t ColumnDate::Size() const { return data_->Size(); } -void ColumnDate::Reserve(size_t new_cap) { - data_->Reserve(new_cap); -} - -size_t ColumnDate::Capacity() const { - return data_->Capacity(); -} - ColumnRef ColumnDate::Slice(size_t begin, size_t len) const { auto col = data_->Slice(begin, len)->As(); auto result = std::make_shared(); @@ -118,24 +110,24 @@ void ColumnDate32::Append(ColumnRef column) { } } -void ColumnDate32::AppendRaw(int32_t value) { - data_->Append(value); +std::vector & ColumnDate32::GetRawVector() { + return data_->GetRawVector(); } -int32_t ColumnDate32::RawAt(size_t n) const { - return data_->At(n); +void ColumnDate32::Reserve(size_t new_cap) { + data_->Reserve(new_cap); } -void ColumnDate32::SwapElements(size_t pos1, size_t pos2) { - data_->SwapElements(pos1, pos2); +size_t ColumnDate32::Capacity() const { + return data_->Capacity(); } -bool ColumnDate32::CompareElementsGT(size_t pos1, size_t pos2) const { - return data_->CompareElementsGT(pos1, pos2); +void ColumnDate32::AppendRaw(int32_t value) { + data_->Append(value); } -bool ColumnDate32::CompareElementsLT(size_t pos1, size_t pos2) const { - return data_->CompareElementsLT(pos1, pos2); +int32_t ColumnDate32::RawAt(size_t n) const { + return data_->At(n); } bool ColumnDate32::LoadBody(InputStream* input, size_t rows) { @@ -150,14 +142,6 @@ size_t ColumnDate32::Size() const { return data_->Size(); } -void ColumnDate32::Reserve(size_t new_cap) { - data_->Reserve(new_cap); -} - -size_t ColumnDate32::Capacity() const { - return data_->Capacity(); -} - ColumnRef ColumnDate32::Slice(size_t begin, size_t len) const { auto col = data_->Slice(begin, len)->As(); auto result = std::make_shared(); @@ -208,22 +192,22 @@ std::string ColumnDateTime::Timezone() const { return type_->As()->Timezone(); } -void ColumnDateTime::SwapElements(size_t pos1, size_t pos2) { - data_->SwapElements(pos1, pos2); +void ColumnDateTime::Append(ColumnRef column) { + if (auto col = column->As()) { + data_->Append(col->data_); + } } -bool ColumnDateTime::CompareElementsGT(size_t pos1, size_t pos2) const { - return data_->CompareElementsGT(pos1, pos2); +std::vector & ColumnDateTime::GetRawVector() { + return data_->GetRawVector(); } -bool ColumnDateTime::CompareElementsLT(size_t pos1, size_t pos2) const { - return data_->CompareElementsLT(pos1, pos2); +void ColumnDateTime::Reserve(size_t new_cap) { + data_->Reserve(new_cap); } -void ColumnDateTime::Append(ColumnRef column) { - if (auto col = column->As()) { - data_->Append(col->data_); - } +size_t ColumnDateTime::Capacity() const { + return data_->Capacity(); } bool ColumnDateTime::LoadBody(InputStream* input, size_t rows) { @@ -238,14 +222,6 @@ size_t ColumnDateTime::Size() const { return data_->Size(); } -void ColumnDateTime::Reserve(size_t new_cap) { - data_->Reserve(new_cap); -} - -size_t ColumnDateTime::Capacity() const { - return data_->Capacity(); -} - void ColumnDateTime::Clear() { data_->Clear(); } @@ -301,18 +277,6 @@ Int64 ColumnDateTime64::At(size_t n) const { return static_cast(data_->At(n)); } -void ColumnDateTime64::SwapElements(size_t pos1, size_t pos2) { - data_->SwapElements(pos1, pos2); -} - -bool ColumnDateTime64::CompareElementsGT(size_t pos1, size_t pos2) const { - return data_->CompareElementsGT(pos1, pos2); -} - -bool ColumnDateTime64::CompareElementsLT(size_t pos1, size_t pos2) const { - return data_->CompareElementsLT(pos1, pos2); -} - std::string ColumnDateTime64::Timezone() const { return type_->As()->Timezone(); } @@ -339,14 +303,6 @@ size_t ColumnDateTime64::Size() const { return data_->Size(); } -void ColumnDateTime64::Reserve(size_t new_cap) { - data_->Reserve(new_cap); -} - -size_t ColumnDateTime64::Capacity() const { - return data_->Capacity(); -} - ItemView ColumnDateTime64::GetItem(size_t index) const { return ItemView(Type::DateTime64, data_->GetItem(index)); } diff --git a/clickhouse/columns/date.h b/clickhouse/columns/date.h index ece7b71b..a17cf26b 100644 --- a/clickhouse/columns/date.h +++ b/clickhouse/columns/date.h @@ -27,19 +27,17 @@ class ColumnDate : public Column { void AppendRaw(uint16_t value); uint16_t RawAt(size_t n) const; - /// Swap two Elements/rows in the column - void SwapElements(size_t pos1, size_t pos2); + /// Appends content of given column to the end of current one. + void Append(ColumnRef column) override; - /// Test if the value at position 1 is greater than the value at position 2 - /// No range checking is performed for performance - bool CompareElementsGT(size_t pos1, size_t pos2) const; + /// Get Raw Vector Contents + std::vector & GetRawVector(); - /// Test if the value at position 1 is less than the value at position 2 - /// No range checking is performed for performance - bool CompareElementsLT(size_t pos1, size_t pos2) const; + /// Increase the capacity of the column + void Reserve(size_t new_cap); - /// Appends content of given column to the end of current one. - void Append(ColumnRef column) override; + /// Returns the capacity of the column + size_t Capacity() const; /// Loads column data from input stream. bool LoadBody(InputStream* input, size_t rows) override; @@ -53,12 +51,6 @@ class ColumnDate : public Column { /// Returns count of rows in the column. size_t Size() const override; - /// Increase the capacity of the column - void Reserve(size_t new_cap) override; - - /// Returns the capacity of the column - size_t Capacity() const override; - /// Makes slice of the current column. ColumnRef Slice(size_t begin, size_t len) const override; ColumnRef CloneEmpty() const override; @@ -94,16 +86,14 @@ class ColumnDate32 : public Column { void AppendRaw(int32_t value); int32_t RawAt(size_t n) const; - /// Swap two Elements/rows in the column - void SwapElements(size_t pos1, size_t pos2); + /// Get Raw Vector Contents + std::vector & GetRawVector(); - /// Test if the value at position 1 is greater than the value at position 2 - /// No range checking is performed for performance - bool CompareElementsGT(size_t pos1, size_t pos2) const; + /// Increase the capacity of the column + void Reserve(size_t new_cap); - /// Test if the value at position 1 is less than the value at position 2 - /// No range checking is performed for performance - bool CompareElementsLT(size_t pos1, size_t pos2) const; + /// Returns the capacity of the column + size_t Capacity() const; /// Loads column data from input stream. bool LoadBody(InputStream* input, size_t rows) override; @@ -117,12 +107,6 @@ class ColumnDate32 : public Column { /// Returns count of rows in the column. size_t Size() const override; - /// Increase the capacity of the column - void Reserve(size_t new_cap) override; - - /// Returns the capacity of the column - size_t Capacity() const override; - /// Makes slice of the current column. ColumnRef Slice(size_t begin, size_t len) const override; ColumnRef CloneEmpty() const override; @@ -156,16 +140,14 @@ class ColumnDateTime : public Column { /// Timezone associated with a data column. std::string Timezone() const; - /// Swap two Elements/rows in the column - void SwapElements(size_t pos1, size_t pos2); + /// Get Raw Vector Contents + std::vector & GetRawVector(); - /// Test if the value at position 1 is greater than the value at position 2 - /// No range checking is performed for performance - bool CompareElementsGT(size_t pos1, size_t pos2) const; + /// Increase the capacity of the column + void Reserve(size_t new_cap); - /// Test if the value at position 1 is less than the value at position 2 - /// No range checking is performed for performance - bool CompareElementsLT(size_t pos1, size_t pos2) const; + /// Returns the capacity of the column + size_t Capacity() const; public: /// Appends content of given column to the end of current one. @@ -183,12 +165,6 @@ class ColumnDateTime : public Column { /// Returns count of rows in the column. size_t Size() const override; - /// Increase the capacity of the column - void Reserve(size_t new_cap) override; - - /// Returns the capacity of the column - size_t Capacity() const override; - /// Makes slice of the current column. ColumnRef Slice(size_t begin, size_t len) const override; ColumnRef CloneEmpty() const override; @@ -223,17 +199,6 @@ class ColumnDateTime64 : public Column { /// Timezone associated with a data column. std::string Timezone() const; - /// Swap two Elements/rows in the column - void SwapElements(size_t pos1, size_t pos2); - - /// Test if the value at position 1 is greater than the value at position 2 - /// No range checking is performed for performance - bool CompareElementsGT(size_t pos1, size_t pos2) const; - - /// Test if the value at position 1 is less than the value at position 2 - /// No range checking is performed for performance - bool CompareElementsLT(size_t pos1, size_t pos2) const; - public: /// Appends content of given column to the end of current one. void Append(ColumnRef column) override; @@ -250,12 +215,6 @@ class ColumnDateTime64 : public Column { /// Returns count of rows in the column. size_t Size() const override; - /// Increase the capacity of the column - void Reserve(size_t new_cap) override; - - /// Returns the capacity of the column - size_t Capacity() const override; - /// Makes slice of the current column. ColumnRef Slice(size_t begin, size_t len) const override; ColumnRef CloneEmpty() const override; diff --git a/clickhouse/columns/decimal.cpp b/clickhouse/columns/decimal.cpp index a9fd350f..d44dc0c0 100644 --- a/clickhouse/columns/decimal.cpp +++ b/clickhouse/columns/decimal.cpp @@ -205,36 +205,6 @@ void ColumnDecimal::SaveBody(OutputStream* output) { data_->SaveBody(output); } -void ColumnDecimal::SwapElements(size_t pos1, size_t pos2) { - if (data_->Type()->GetCode() == Type::Int32) { - data_->As()->SwapElements(pos1, pos2); - } else if (data_->Type()->GetCode() == Type::Int64) { - data_->As()->SwapElements(pos1, pos2); - } else { - data_->As()->SwapElements(pos1, pos2); - } -} - -bool ColumnDecimal::CompareElementsGT(size_t pos1, size_t pos2) const { - if (data_->Type()->GetCode() == Type::Int32) { - return data_->As()->CompareElementsGT(pos1, pos2); - } else if (data_->Type()->GetCode() == Type::Int64) { - return data_->As()->CompareElementsGT(pos1, pos2); - } else { - return data_->As()->CompareElementsGT(pos1, pos2); - } -} - -bool ColumnDecimal::CompareElementsLT(size_t pos1, size_t pos2) const { - if (data_->Type()->GetCode() == Type::Int32) { - return data_->As()->CompareElementsLT(pos1, pos2); - } else if (data_->Type()->GetCode() == Type::Int64) { - return data_->As()->CompareElementsLT(pos1, pos2); - } else { - return data_->As()->CompareElementsLT(pos1, pos2); - } -} - void ColumnDecimal::Clear() { data_->Clear(); } @@ -243,14 +213,6 @@ size_t ColumnDecimal::Size() const { return data_->Size(); } -void ColumnDecimal::Reserve(size_t new_cap) { - data_->Reserve(new_cap); -} - -size_t ColumnDecimal::Capacity() const { - return data_->Capacity(); -} - ColumnRef ColumnDecimal::Slice(size_t begin, size_t len) const { // coundn't use std::make_shared since this c-tor is private return ColumnRef{new ColumnDecimal(type_, data_->Slice(begin, len))}; diff --git a/clickhouse/columns/decimal.h b/clickhouse/columns/decimal.h index e6641659..a6c86377 100644 --- a/clickhouse/columns/decimal.h +++ b/clickhouse/columns/decimal.h @@ -20,17 +20,6 @@ class ColumnDecimal : public Column { Int128 At(size_t i) const; inline auto operator[](size_t i) const { return At(i); } - /// Swap two Elements/rows in the column - void SwapElements(size_t pos1, size_t pos2); - - /// Test if the value at position 1 is greater than the value at position 2 - /// No range checking is performed for performance - bool CompareElementsGT(size_t pos1, size_t pos2) const; - - /// Test if the value at position 1 is less than the value at position 2 - /// No range checking is performed for performance - bool CompareElementsLT(size_t pos1, size_t pos2) const; - public: void Append(ColumnRef column) override; bool LoadBody(InputStream* input, size_t rows) override; @@ -38,12 +27,6 @@ class ColumnDecimal : public Column { void Clear() override; size_t Size() const override; - /// Increase the capacity of the column - void Reserve(size_t new_cap) override; - - /// Returns the capacity of the column - size_t Capacity() const override; - ColumnRef Slice(size_t begin, size_t len) const override; ColumnRef CloneEmpty() const override; void Swap(Column& other) override; diff --git a/clickhouse/columns/numeric.cpp b/clickhouse/columns/numeric.cpp index 27676d9c..57a32dd0 100644 --- a/clickhouse/columns/numeric.cpp +++ b/clickhouse/columns/numeric.cpp @@ -39,19 +39,18 @@ void ColumnVector::Erase(size_t pos, size_t count) { } template -void ColumnVector::SwapElements(size_t pos1, size_t pos2) { - auto data_it = data_.begin(); - std::iter_swap(data_it + pos1, data_it + pos2); +std::vector & ColumnVector::GetRawVector() { + return data_; } template -bool ColumnVector::CompareElementsGT(size_t pos1, size_t pos2) const { - return data_[pos1] > data_[pos2]; +void ColumnVector::Reserve(size_t new_cap) { + data_.reserve(new_cap); } template -bool ColumnVector::CompareElementsLT(size_t pos1, size_t pos2) const { - return data_[pos1] < data_[pos2]; +size_t ColumnVector::Capacity() const { + return data_.capacity(); } template @@ -88,16 +87,6 @@ size_t ColumnVector::Size() const { return data_.size(); } -template -void ColumnVector::Reserve(size_t new_cap) { - data_.reserve(new_cap); -} - -template -size_t ColumnVector::Capacity() const { - return data_.capacity(); -} - template ColumnRef ColumnVector::Slice(size_t begin, size_t len) const { return std::make_shared>(SliceVector(data_, begin, len)); diff --git a/clickhouse/columns/numeric.h b/clickhouse/columns/numeric.h index 4e9137f1..d3523614 100644 --- a/clickhouse/columns/numeric.h +++ b/clickhouse/columns/numeric.h @@ -30,16 +30,14 @@ class ColumnVector : public Column { void Erase(size_t pos, size_t count = 1); - /// Swap two Elements/rows in the column - void SwapElements(size_t pos1, size_t pos2); + /// Get Raw Vector Contents + std::vector & GetRawVector(); - /// Test if the value at position 1 is greater than the value at position 2 - /// No range checking is performed for performance - bool CompareElementsGT(size_t pos1, size_t pos2) const; + /// Increase the capacity of the column + void Reserve(size_t new_cap); - /// Test if the value at position 1 is less than the value at position 2 - /// No range checking is performed for performance - bool CompareElementsLT(size_t pos1, size_t pos2) const; + /// Returns the capacity of the column + size_t Capacity() const; public: /// Appends content of given column to the end of current one. @@ -57,12 +55,6 @@ class ColumnVector : public Column { /// Returns count of rows in the column. size_t Size() const override; - /// Increase the capacity of the column - void Reserve(size_t new_cap) override; - - /// Returns the capacity of the column - size_t Capacity() const override; - /// Makes slice of the current column. ColumnRef Slice(size_t begin, size_t len) const override; ColumnRef CloneEmpty() const override; diff --git a/ut/Column_ut.cpp b/ut/Column_ut.cpp index 2d93727b..ace1f79d 100644 --- a/ut/Column_ut.cpp +++ b/ut/Column_ut.cpp @@ -305,59 +305,6 @@ TYPED_TEST(GenericColumnTest, Clear) { EXPECT_EQ(0u, column->Size()); } -// Check if ColumnType supports Capacity/Reserve methods -template -inline bool supportsCapacity([[maybe_unused]]const ColumnType& col) { - if constexpr (std::is_same_v) { - return true; - } else if constexpr (std::is_same_v) { - return true; - } else if constexpr (std::is_same_v) { - return true; - } else if constexpr (std::is_same_v) { - return true; - } else if constexpr (std::is_same_v) { - return true; - } else if constexpr (std::is_same_v) { - return true; - } else if constexpr (std::is_same_v) { - return true; - } else if constexpr (std::is_same_v) { - return true; - } else if constexpr (std::is_same_v) { - return true; - } else if constexpr (std::is_same_v) { - return true; - } else if constexpr (std::is_same_v) { - return true; - } else if constexpr (std::is_same_v) { - return true; - } else if constexpr (std::is_same_v) { - return true; - } else if constexpr (std::is_same_v) { - return true; - } else if constexpr (std::is_same_v) { - return true; - } else if constexpr (std::is_same_v) { - return true; - } else { - return false; - } -} - -TYPED_TEST(GenericColumnTest, Capacity) { - auto [column, values] = this->MakeColumnWithValues(100); - EXPECT_EQ(values.size(), column->Size()); - - column->Reserve(200); - - if (supportsCapacity(*column)) { - EXPECT_EQ(200u, column->Capacity()); - } else { - EXPECT_EQ(100u, column->Capacity()); - } -} - TYPED_TEST(GenericColumnTest, Swap) { auto [column_A, values] = this->MakeColumnWithValues(100); auto column_B = this->MakeColumn(); diff --git a/ut/columns_ut.cpp b/ut/columns_ut.cpp index 4221e0c8..44f66b06 100644 --- a/ut/columns_ut.cpp +++ b/ut/columns_ut.cpp @@ -58,35 +58,6 @@ TEST(ColumnsCase, NumericSlice) { ASSERT_EQ(sub->At(2), 13u); } -TEST(ColumnsCase, NumericSwap) { - auto col = std::make_shared(MakeNumbers()); - - ASSERT_EQ(col->Size(), 11u); - ASSERT_EQ(col->At(3), 7u); - ASSERT_EQ(col->At(10), 31u); - - col->SwapElements(3, 10); - - ASSERT_EQ(col->Size(), 11u); - ASSERT_EQ(col->At(3), 31u); - ASSERT_EQ(col->At(10), 7u); -} - -TEST(ColumnsCase, NumericCompare) { - auto col = std::make_shared(MakeNumbers()); - - ASSERT_EQ(col->Size(), 11u); - ASSERT_EQ(col->At(3), 7u); - ASSERT_EQ(col->At(10), 31u); - - ASSERT_TRUE(col->CompareElementsLT( 3, 10)); - ASSERT_TRUE(col->CompareElementsGT(10, 3)); - - ASSERT_EQ(col->Size(), 11u); - ASSERT_EQ(col->At(3), 7u); - ASSERT_EQ(col->At(10), 31u); -} - TEST(ColumnsCase, FixedStringInit) { const auto column_data = MakeFixedStrings(3); auto col = std::make_shared(3, column_data); @@ -384,251 +355,6 @@ TEST(ColumnsCase, Date2038) { ASSERT_EQ(largeDate, col1->At(0)); } -TEST(ColumnsCase, DateSwap) { - auto col = std::make_shared(); - - col->AppendRaw(1u); - col->AppendRaw(1234u); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->RawAt(0), 1u); - ASSERT_EQ(col->RawAt(1), 1234u); - - col->SwapElements(0, 1); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->RawAt(0), 1234u); - ASSERT_EQ(col->RawAt(1), 1u); -} - -TEST(ColumnsCase, Date32Swap) { - auto col = std::make_shared(); - - col->AppendRaw(1); - col->AppendRaw(1234); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->RawAt(0), 1); - ASSERT_EQ(col->RawAt(1), 1234); - - col->SwapElements(0, 1); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->RawAt(0), 1234); - ASSERT_EQ(col->RawAt(1), 1); -} - -TEST(ColumnsCase, DateTimeSwap) { - auto col = std::make_shared(); - - col->AppendRaw(1u); - col->AppendRaw(1234u); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1u); - ASSERT_EQ(col->At(1), 1234u); - - col->SwapElements(0, 1); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1234u); - ASSERT_EQ(col->At(1), 1u); -} - -TEST(ColumnsCase, DateTime64Swap) { - auto col = std::make_shared(6ul); - - col->Append(1u); - col->Append(1234u); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1u); - ASSERT_EQ(col->At(1), 1234u); - - col->SwapElements(0, 1); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1234u); - ASSERT_EQ(col->At(1), 1u); -} - -TEST(ColumnsCase, Decimal32Swap) { - auto col = std::make_shared(9, 0); - - col->Append(1); - col->Append(1234); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1); - ASSERT_EQ(col->At(1), 1234); - - col->SwapElements(0, 1); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1234); - ASSERT_EQ(col->At(1), 1); -} - -TEST(ColumnsCase, Decimal64Swap) { - auto col = std::make_shared(18, 0); - - col->Append(1); - col->Append(1234); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1); - ASSERT_EQ(col->At(1), 1234); - - col->SwapElements(0, 1); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1234); - ASSERT_EQ(col->At(1), 1); -} - -TEST(ColumnsCase, Decimal128Swap) { - auto col = std::make_shared(38, 0); - - col->Append(1); - col->Append(1234); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1); - ASSERT_EQ(col->At(1), 1234); - - col->SwapElements(0, 1); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1234); - ASSERT_EQ(col->At(1), 1); -} - -TEST(ColumnsCase, DateCompare) { - auto col = std::make_shared(); - - col->AppendRaw(1u); - col->AppendRaw(1234u); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->RawAt(0), 1u); - ASSERT_EQ(col->RawAt(1), 1234u); - - ASSERT_TRUE(col->CompareElementsLT(0, 1)); - ASSERT_TRUE(col->CompareElementsGT(1, 0)); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->RawAt(0), 1u); - ASSERT_EQ(col->RawAt(1), 1234u); -} - -TEST(ColumnsCase, Date32Compare) { - auto col = std::make_shared(); - - col->AppendRaw(1); - col->AppendRaw(1234); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->RawAt(0), 1); - ASSERT_EQ(col->RawAt(1), 1234); - - ASSERT_TRUE(col->CompareElementsLT(0, 1)); - ASSERT_TRUE(col->CompareElementsGT(1, 0)); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->RawAt(0), 1); - ASSERT_EQ(col->RawAt(1), 1234); -} - -TEST(ColumnsCase, DateTimeCompare) { - auto col = std::make_shared(); - - col->Append(1u); - col->Append(1234u); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1u); - ASSERT_EQ(col->At(1), 1234u); - - ASSERT_TRUE(col->CompareElementsLT(0, 1)); - ASSERT_TRUE(col->CompareElementsGT(1, 0)); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1u); - ASSERT_EQ(col->At(1), 1234u); -} - -TEST(ColumnsCase, DateTime64Compare) { - auto col = std::make_shared(6ul); - - col->Append(1u); - col->Append(1234u); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1u); - ASSERT_EQ(col->At(1), 1234u); - - ASSERT_TRUE(col->CompareElementsLT(0, 1)); - ASSERT_TRUE(col->CompareElementsGT(1, 0)); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1u); - ASSERT_EQ(col->At(1), 1234u); -} - -TEST(ColumnsCase, Decimal32Compare) { - auto col = std::make_shared(9, 0); - - col->Append(1); - col->Append(1234); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1); - ASSERT_EQ(col->At(1), 1234); - - ASSERT_TRUE(col->CompareElementsLT(0, 1)); - ASSERT_TRUE(col->CompareElementsGT(1, 0)); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1); - ASSERT_EQ(col->At(1), 1234); -} - -TEST(ColumnsCase, Decimal64Compare) { - auto col = std::make_shared(18, 0); - - col->Append(1); - col->Append(1234); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1); - ASSERT_EQ(col->At(1), 1234); - - ASSERT_TRUE(col->CompareElementsLT(0, 1)); - ASSERT_TRUE(col->CompareElementsGT(1, 0)); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1); - ASSERT_EQ(col->At(1), 1234); -} - -TEST(ColumnsCase, Decimal128Compare) { - auto col = std::make_shared(38, 0); - - col->Append(1); - col->Append(1234); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1); - ASSERT_EQ(col->At(1), 1234); - - ASSERT_TRUE(col->CompareElementsLT(0, 1)); - ASSERT_TRUE(col->CompareElementsGT(1, 0)); - - ASSERT_EQ(col->Size(), 2u); - ASSERT_EQ(col->At(0), 1); - ASSERT_EQ(col->At(1), 1234); -} - TEST(ColumnsCase, EnumTest) { std::vector enum_items = {{"Hi", 1}, {"Hello", 2}}; @@ -1189,3 +915,93 @@ TEST(ColumnsCase, ColumnMapT_Wrap) { EXPECT_EQ("123", map_view.At(1)); EXPECT_EQ("abc", map_view.At(2)); } + +TEST(ColumnsCase, ReservedAndCapacity) { + std::vector> columns; + + #define RaC_TEST_CASE(test_id_in, column_type) \ + case test_id_in: { \ + columns.push_back(std::make_shared()); \ + auto column = std::static_pointer_cast(columns[test_id_in]); \ + column->Reserve(100u); \ + ASSERT_EQ(column->Capacity(), 100u); \ + ASSERT_EQ(columns[test_id_in]->Size(), 0u); \ + break; \ + } + + for (uint rac_test_id = 0; rac_test_id < 14; ++rac_test_id) { + switch (rac_test_id) { + RaC_TEST_CASE( 0, ColumnUInt8); + RaC_TEST_CASE( 1, ColumnUInt16); + RaC_TEST_CASE( 2, ColumnUInt32); + RaC_TEST_CASE( 3, ColumnUInt64); + RaC_TEST_CASE( 4, ColumnInt8); + RaC_TEST_CASE( 5, ColumnInt16); + RaC_TEST_CASE( 6, ColumnInt32); + RaC_TEST_CASE( 7, ColumnInt64); + RaC_TEST_CASE( 8, ColumnInt128); + RaC_TEST_CASE( 9, ColumnFloat32); + RaC_TEST_CASE(10, ColumnFloat64); + RaC_TEST_CASE(11, ColumnDate); + RaC_TEST_CASE(12, ColumnDate32); + RaC_TEST_CASE(13, ColumnDateTime); + default: { + EXPECT_NE(0, 0); + break; + } + } + } +} + +TEST(ColumnsCase, RawVector) { + std::vector> columns; + + #define RV_TEST_CASE(test_id_in, column_type) \ + case test_id_in: { \ + columns.push_back(std::make_shared()); \ + auto column = std::static_pointer_cast(columns[test_id_in]); \ + column->Append(10u); \ + column->Append(20u); \ + ASSERT_EQ(columns[test_id_in]->Size(), 2u); \ + auto column_v = column->GetRawVector(); \ + ASSERT_EQ(static_cast(column_v[0]), 10u); \ + ASSERT_EQ(static_cast(column_v[1]), 20u); \ + break; \ + } + + #define RV_TEST_CASE_D(test_id_in, column_type) \ + case test_id_in: { \ + columns.push_back(std::make_shared()); \ + auto column = std::static_pointer_cast(columns[test_id_in]); \ + column->AppendRaw(10u); \ + column->AppendRaw(20u); \ + ASSERT_EQ(columns[test_id_in]->Size(), 2u); \ + auto column_v = column->GetRawVector(); \ + ASSERT_EQ(static_cast(column_v[0]), 10u); \ + ASSERT_EQ(static_cast(column_v[1]), 20u); \ + break; \ + } + + for (uint rv_test_id = 0; rv_test_id < 14; ++rv_test_id) { + switch (rv_test_id) { + RV_TEST_CASE( 0, ColumnUInt8); + RV_TEST_CASE( 1, ColumnUInt16); + RV_TEST_CASE( 2, ColumnUInt32); + RV_TEST_CASE( 3, ColumnUInt64); + RV_TEST_CASE( 4, ColumnInt8); + RV_TEST_CASE( 5, ColumnInt16); + RV_TEST_CASE( 6, ColumnInt32); + RV_TEST_CASE( 7, ColumnInt64); + RV_TEST_CASE( 8, ColumnInt128); + RV_TEST_CASE( 9, ColumnFloat32); + RV_TEST_CASE( 10, ColumnFloat64); + RV_TEST_CASE_D( 11, ColumnDate); + RV_TEST_CASE_D( 12, ColumnDate32); + RV_TEST_CASE_D( 13, ColumnDateTime); + default: { + EXPECT_NE(0, 0); + break; + } + } + } +} From 64e1454061177f55cbc8d385f407b64a7ec03a19 Mon Sep 17 00:00:00 2001 From: rtcote Date: Tue, 3 Oct 2023 22:46:00 -0600 Subject: [PATCH 6/8] Review changes without extra whitespace --- clickhouse/columns/decimal.h | 1 - ut/columns_ut.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/clickhouse/columns/decimal.h b/clickhouse/columns/decimal.h index a6c86377..4b09553a 100644 --- a/clickhouse/columns/decimal.h +++ b/clickhouse/columns/decimal.h @@ -26,7 +26,6 @@ class ColumnDecimal : public Column { void SaveBody(OutputStream* output) override; void Clear() override; size_t Size() const override; - ColumnRef Slice(size_t begin, size_t len) const override; ColumnRef CloneEmpty() const override; void Swap(Column& other) override; diff --git a/ut/columns_ut.cpp b/ut/columns_ut.cpp index 44f66b06..ad56dad3 100644 --- a/ut/columns_ut.cpp +++ b/ut/columns_ut.cpp @@ -58,6 +58,7 @@ TEST(ColumnsCase, NumericSlice) { ASSERT_EQ(sub->At(2), 13u); } + TEST(ColumnsCase, FixedStringInit) { const auto column_data = MakeFixedStrings(3); auto col = std::make_shared(3, column_data); From 8e1db8d4ba70133424671879233a60b6e5fa6415 Mon Sep 17 00:00:00 2001 From: rtcote Date: Wed, 4 Oct 2023 20:17:00 -0600 Subject: [PATCH 7/8] Replace uint with uint8_t in unittest --- ut/columns_ut.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ut/columns_ut.cpp b/ut/columns_ut.cpp index ad56dad3..b2304774 100644 --- a/ut/columns_ut.cpp +++ b/ut/columns_ut.cpp @@ -930,7 +930,7 @@ TEST(ColumnsCase, ReservedAndCapacity) { break; \ } - for (uint rac_test_id = 0; rac_test_id < 14; ++rac_test_id) { + for (uint8_t rac_test_id = 0; rac_test_id < 14; ++rac_test_id) { switch (rac_test_id) { RaC_TEST_CASE( 0, ColumnUInt8); RaC_TEST_CASE( 1, ColumnUInt16); @@ -983,7 +983,7 @@ TEST(ColumnsCase, RawVector) { break; \ } - for (uint rv_test_id = 0; rv_test_id < 14; ++rv_test_id) { + for (uint8_t rv_test_id = 0; rv_test_id < 14; ++rv_test_id) { switch (rv_test_id) { RV_TEST_CASE( 0, ColumnUInt8); RV_TEST_CASE( 1, ColumnUInt16); From 979bb9f2a8b47fb0e3c4609e68d3bc635fff6c5c Mon Sep 17 00:00:00 2001 From: rtcote Date: Thu, 5 Oct 2023 16:46:10 -0600 Subject: [PATCH 8/8] Replace uint with uint32_t in unittest --- ut/columns_ut.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ut/columns_ut.cpp b/ut/columns_ut.cpp index b2304774..fb0d4147 100644 --- a/ut/columns_ut.cpp +++ b/ut/columns_ut.cpp @@ -965,8 +965,8 @@ TEST(ColumnsCase, RawVector) { column->Append(20u); \ ASSERT_EQ(columns[test_id_in]->Size(), 2u); \ auto column_v = column->GetRawVector(); \ - ASSERT_EQ(static_cast(column_v[0]), 10u); \ - ASSERT_EQ(static_cast(column_v[1]), 20u); \ + ASSERT_EQ(static_cast(column_v[0]), 10u); \ + ASSERT_EQ(static_cast(column_v[1]), 20u); \ break; \ } @@ -978,8 +978,8 @@ TEST(ColumnsCase, RawVector) { column->AppendRaw(20u); \ ASSERT_EQ(columns[test_id_in]->Size(), 2u); \ auto column_v = column->GetRawVector(); \ - ASSERT_EQ(static_cast(column_v[0]), 10u); \ - ASSERT_EQ(static_cast(column_v[1]), 20u); \ + ASSERT_EQ(static_cast(column_v[0]), 10u); \ + ASSERT_EQ(static_cast(column_v[1]), 20u); \ break; \ }