Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion dbms/src/Columns/ColumnAggregateFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class ColumnAggregateFunction final : public COWPtrHelper<IColumn, ColumnAggrega
{}

public:
~ColumnAggregateFunction();
~ColumnAggregateFunction() override;

void set(const AggregateFunctionPtr & func_) { func = func_; }

Expand Down Expand Up @@ -328,6 +328,8 @@ class ColumnAggregateFunction final : public COWPtrHelper<IColumn, ColumnAggrega

void getPermutation(bool reverse, size_t limit, int nan_direction_hint, Permutation & res) const override;

size_t capacity() const override { return data.capacity(); }

/** More efficient manipulation methods */
Container & getData() { return data; }

Expand Down
14 changes: 11 additions & 3 deletions dbms/src/Columns/ColumnArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -620,11 +620,19 @@ struct Less
} // namespace


void ColumnArray::reserve(size_t n)
void ColumnArray::reserveWithStrategy(size_t n, ReserveStrategy strategy)
{
getOffsets().reserve(n);
switch (strategy)
{
case ReserveStrategy::Default:
getOffsets().reserve(n);
break;
case ReserveStrategy::ScaleFactor1_5:
getOffsets().reserve(n / 2 * 3);
break;
}
/// The average size of arrays is not taken into account here. Or it is considered to be no more than 1.
getData().reserve(n);
getData().reserveWithStrategy(n, strategy);
}

void ColumnArray::reserveAlign(size_t n, size_t alignment)
Expand Down
3 changes: 2 additions & 1 deletion dbms/src/Columns/ColumnArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,8 @@ class ColumnArray final : public COWPtrHelper<IColumn, ColumnArray>
ColumnPtr permute(const Permutation & perm, size_t limit) const override;
int compareAt(size_t n, size_t m, const IColumn & rhs_, int nan_direction_hint) const override;
void getPermutation(bool reverse, size_t limit, int nan_direction_hint, Permutation & res) const override;
void reserve(size_t n) override;
size_t capacity() const override { return data->capacity(); }
void reserveWithStrategy(size_t n, ReserveStrategy strategy) override;
void reserveAlign(size_t n, size_t alignment) override;
size_t byteSize() const override;
size_t byteSize(size_t offset, size_t limit) const override;
Expand Down
2 changes: 2 additions & 0 deletions dbms/src/Columns/ColumnConst.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ class ColumnConst final : public COWPtrHelper<IColumn, ColumnConst>
ColumnPtr permute(const Permutation & perm, size_t limit) const override;
void getPermutation(bool reverse, size_t limit, int nan_direction_hint, Permutation & res) const override;

size_t capacity() const override { return data->capacity(); }

size_t byteSize() const override { return data->byteSize() + sizeof(s); }

size_t byteSize(size_t /*offset*/, size_t /*limit*/) const override { return byteSize(); }
Expand Down
14 changes: 14 additions & 0 deletions dbms/src/Columns/ColumnDecimal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,20 @@ MutableColumnPtr ColumnDecimal<T>::cloneResized(size_t size) const
return res;
}

template <typename T>
void ColumnDecimal<T>::reserveWithStrategy(size_t n, IColumn::ReserveStrategy strategy)
{
switch (strategy)
{
case IColumn::ReserveStrategy::Default:
data.reserve(n);
break;
case IColumn::ReserveStrategy::ScaleFactor1_5:
data.reserve_exact(n / 2 * 3);
break;
}
}

template <typename T>
void ColumnDecimal<T>::insertData(const char * src [[maybe_unused]], size_t /*length*/)
{
Expand Down
5 changes: 3 additions & 2 deletions dbms/src/Columns/ColumnDecimal.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,9 @@ class ColumnDecimal final : public COWPtrHelper<ColumnVectorHelper, ColumnDecima
size_t byteSize() const override { return data.size() * sizeof(data[0]); }
size_t byteSize(size_t /*offset*/, size_t limit) const override { return limit * sizeof(data[0]); }
size_t allocatedBytes() const override { return data.allocated_bytes(); }
//void protect() override { data.protect(); }
void reserve(size_t n) override { data.reserve(n); }

size_t capacity() const override { return data.capacity(); }
void reserveWithStrategy(size_t n, IColumn::ReserveStrategy strategy) override;
void reserveAlign(size_t n, size_t alignment) override { data.reserve(n, alignment); }

void insertFrom(const IColumn & src, size_t n) override
Expand Down
13 changes: 13 additions & 0 deletions dbms/src/Columns/ColumnFixedString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,19 @@ void ColumnFixedString::gather(ColumnGathererStream & gatherer)
gatherer.gather(*this);
}

void ColumnFixedString::reserveWithStrategy(size_t size, IColumn::ReserveStrategy strategy)
{
switch (strategy)
{
case ReserveStrategy::Default:
chars.reserve(n * size);
break;
case ReserveStrategy::ScaleFactor1_5:
chars.reserve_exact(n / 2 * 3 * size);
break;
}
}

void ColumnFixedString::getExtremes(Field & min, Field & max) const
{
min = String();
Expand Down
4 changes: 3 additions & 1 deletion dbms/src/Columns/ColumnFixedString.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ class ColumnFixedString final : public COWPtrHelper<IColumn, ColumnFixedString>

void getPermutation(bool reverse, size_t limit, int nan_direction_hint, Permutation & res) const override;

size_t capacity() const override { return chars.capacity() / n; }

void insertRangeFrom(const IColumn & src, size_t start, size_t length) override;

ColumnPtr filter(const IColumn::Filter & filt, ssize_t result_size_hint) const override;
Expand Down Expand Up @@ -223,7 +225,7 @@ class ColumnFixedString final : public COWPtrHelper<IColumn, ColumnFixedString>

void gather(ColumnGathererStream & gatherer_stream) override;

void reserve(size_t size) override { chars.reserve(n * size); }
void reserveWithStrategy(size_t size, IColumn::ReserveStrategy strategy) override;
void reserveAlign(size_t size, size_t alignment) override { chars.reserve(n * size, alignment); }

void getExtremes(Field & min, Field & max) const override;
Expand Down
3 changes: 3 additions & 0 deletions dbms/src/Columns/ColumnFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,9 @@ class ColumnFunction final : public COWPtrHelper<IColumn, ColumnFunction>
throw Exception("getPermutation is not implemented for " + getName(), ErrorCodes::NOT_IMPLEMENTED);
}

// A fake capacity for ColumnFunction, as it does not hold data in the same way as other columns.
size_t capacity() const override { return 0; }

void gather(ColumnGathererStream &) override
{
throw Exception("Method gather is not supported for " + getName(), ErrorCodes::NOT_IMPLEMENTED);
Expand Down
5 changes: 4 additions & 1 deletion dbms/src/Columns/ColumnNothing.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ class ColumnNothing final : public COWPtrHelper<IColumnDummy, ColumnNothing>

public:
const char * getFamilyName() const override { return "Nothing"; }
MutableColumnPtr cloneDummy(size_t s) const override { return ColumnNothing::create(s); };
MutableColumnPtr cloneDummy(size_t s) const override { return ColumnNothing::create(s); }

bool canBeInsideNullable() const override { return true; }

// ColumnNothing does not hold any data, so capacity is 0.
size_t capacity() const override { return 1; }
};

} // namespace DB
19 changes: 16 additions & 3 deletions dbms/src/Columns/ColumnNullable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -632,10 +632,23 @@ void ColumnNullable::gather(ColumnGathererStream & gatherer)
gatherer.gather(*this);
}

void ColumnNullable::reserve(size_t n)
size_t ColumnNullable::capacity() const
{
getNestedColumn().reserve(n);
getNullMapData().reserve(n);
return getNestedColumn().capacity();
}

void ColumnNullable::reserveWithStrategy(size_t n, IColumn::ReserveStrategy strategy)
{
getNestedColumn().reserveWithStrategy(n, strategy);
switch (strategy)
{
case ReserveStrategy::Default:
getNullMapData().reserve(n);
break;
case ReserveStrategy::ScaleFactor1_5:
getNullMapData().reserve_exact(n / 2 * 3);
break;
}
}

void ColumnNullable::reserveAlign(size_t n, size_t alignment)
Expand Down
3 changes: 2 additions & 1 deletion dbms/src/Columns/ColumnNullable.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ class ColumnNullable final : public COWPtrHelper<IColumn, ColumnNullable>
Permutation & res) const override;
void adjustPermutationWithNullDirection(bool reverse, size_t limit, int null_direction_hint, Permutation & res)
const;
void reserve(size_t n) override;
size_t capacity() const override;
void reserveWithStrategy(size_t n, IColumn::ReserveStrategy strategy) override;
void reserveAlign(size_t n, size_t alignment) override;
void reserveWithTotalMemoryHint(size_t n, Int64 total_memory_hint) override;
void reserveAlignWithTotalMemoryHint(size_t n, Int64 total_memory_hint, size_t alignment) override;
Expand Down
3 changes: 3 additions & 0 deletions dbms/src/Columns/ColumnSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class ColumnSet final : public COWPtrHelper<IColumnDummy, ColumnSet>

ConstSetPtr getData() const { return data; }

// A fake capacity for ColumnSet, as it does not hold data in the same way as other columns.
size_t capacity() const override { return 1; }

private:
ConstSetPtr data;
};
Expand Down
21 changes: 18 additions & 3 deletions dbms/src/Columns/ColumnString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,11 +288,26 @@ void ColumnString::gather(ColumnGathererStream & gatherer)
gatherer.gather(*this);
}

size_t ColumnString::capacity() const
{
return chars.capacity() / APPROX_STRING_SIZE; // Approximate capacity based on average string size.
}

void ColumnString::reserve(size_t n)
void ColumnString::reserveWithStrategy(size_t n, IColumn::ReserveStrategy strategy)
{
offsets.reserve(n);
chars.reserve(n * APPROX_STRING_SIZE);
switch (strategy)
{
case IColumn::ReserveStrategy::Default:
offsets.reserve(n);
chars.reserve(n * APPROX_STRING_SIZE);
break;
case IColumn::ReserveStrategy::ScaleFactor1_5:
// offsets.reserve_exact(n / 2 * 3);
// chars.reserve_exact(n * APPROX_STRING_SIZE / 2 * 3);
offsets.resize(n / 2 * 3);
chars.resize(n / 2 * APPROX_STRING_SIZE * 3);
break;
}
}

void ColumnString::reserveAlign(size_t n, size_t alignment)
Expand Down
4 changes: 3 additions & 1 deletion dbms/src/Columns/ColumnString.h
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,9 @@ class ColumnString final : public COWPtrHelper<IColumn, ColumnString>

void gather(ColumnGathererStream & gatherer_stream) override;

void reserve(size_t n) override;
size_t capacity() const override;

void reserveWithStrategy(size_t n, IColumn::ReserveStrategy strategy) override;
void reserveAlign(size_t n, size_t alignment) override;

void reserveWithTotalMemoryHint(size_t n, Int64 total_memory_hint) override;
Expand Down
11 changes: 9 additions & 2 deletions dbms/src/Columns/ColumnTuple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,11 +421,18 @@ void ColumnTuple::gather(ColumnGathererStream & gatherer)
gatherer.gather(*this);
}

void ColumnTuple::reserve(size_t n)
size_t ColumnTuple::capacity() const
{
return columns.empty() ? 0 : columns[0]->capacity();
}

void ColumnTuple::reserveWithStrategy(size_t n, IColumn::ReserveStrategy strategy)
{
const size_t tuple_size = columns.size();
for (size_t i = 0; i < tuple_size; ++i)
getColumn(i).reserve(n);
{
getColumn(i).reserveWithStrategy(n, strategy);
}
}

void ColumnTuple::reserveAlign(size_t n, size_t alignment)
Expand Down
3 changes: 2 additions & 1 deletion dbms/src/Columns/ColumnTuple.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ class ColumnTuple final : public COWPtrHelper<IColumn, ColumnTuple>
int compareAt(size_t n, size_t m, const IColumn & rhs, int nan_direction_hint) const override;
void getExtremes(Field & min, Field & max) const override;
void getPermutation(bool reverse, size_t limit, int nan_direction_hint, Permutation & res) const override;
void reserve(size_t n) override;
size_t capacity() const override;
void reserveWithStrategy(size_t n, IColumn::ReserveStrategy strategy) override;
void reserveAlign(size_t n, size_t alignment) override;
size_t byteSize() const override;
size_t byteSize(size_t offset, size_t limit) const override;
Expand Down
14 changes: 13 additions & 1 deletion dbms/src/Columns/ColumnVector.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,19 @@ class ColumnVector final : public COWPtrHelper<ColumnVectorHelper, ColumnVector<

void getPermutation(bool reverse, size_t limit, int nan_direction_hint, IColumn::Permutation & res) const override;

void reserve(size_t n) override { data.reserve(n); }
size_t capacity() const override { return data.capacity(); }
void reserveWithStrategy(size_t n, IColumn::ReserveStrategy strategy) override
{
switch (strategy)
{
case IColumn::ReserveStrategy::Default:
data.reserve(n);
break;
case IColumn::ReserveStrategy::ScaleFactor1_5:
data.reserve_exact(n / 2 * 3);
break;
}
}
void reserveAlign(size_t n, size_t alignment) override { data.reserve(n, alignment); }

const char * getFamilyName() const override;
Expand Down
21 changes: 18 additions & 3 deletions dbms/src/Columns/IColumn.h
Original file line number Diff line number Diff line change
Expand Up @@ -507,16 +507,31 @@ class IColumn : public COWPtr<IColumn>
virtual void gather(ColumnGathererStream & gatherer_stream) = 0;

/** Computes minimum and maximum element of the column.
* In addition to numeric types, the funtion is completely implemented for Date and DateTime.
* For strings and arrays function should retrurn default value.
* In addition to numeric types, the function is completely implemented for Date and DateTime.
* For strings and arrays function should return default value.
* (except for constant columns; they should return value of the constant).
* If column is empty function should return default value.
*/
virtual void getExtremes(Field & min, Field & max) const = 0;

/// Returns the number of elements that this column can hold without reallocating.
virtual size_t capacity() const = 0;

enum class ReserveStrategy
{
// Use the default behavior of PODArray, which doubles the capacity each time.
Default,
// Use the strategy that reserves memory for 1.5 times the requested size.
ScaleFactor1_5,
};

/// Reserves memory for specified amount of elements. If reservation isn't possible, does nothing.
/// It affects performance only (not correctness).
virtual void reserve(size_t /*n*/) {}
void reserve(size_t n) { reserveWithStrategy(n, ReserveStrategy::Default); }

/// Reserves memory for specified amount of elements with strategy.
/// If reservation isn't possible, does nothing. It affects performance only (not correctness).
virtual void reserveWithStrategy(size_t /*n*/, ReserveStrategy /*strategy*/) {}

/// Reserves aligned memory for specified amount of elements. If reservation isn't possible, does nothing.
/// It affects performance only (not correctness).
Expand Down
1 change: 1 addition & 0 deletions dbms/src/Columns/IColumnDummy.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class IColumnDummy : public IColumn
virtual MutableColumnPtr cloneDummy(size_t s_) const = 0;

MutableColumnPtr cloneResized(size_t s_) const override { return cloneDummy(s_); }
size_t capacity() const override { return s; }
size_t size() const override { return s; }
void insertDefault() override { ++s; }

Expand Down
1 change: 0 additions & 1 deletion dbms/src/Common/CurrentMetrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include <stddef.h>

#include <atomic>
#include <cstdint>
#include <utility>

/** Allows to count number of simultaneously happening processes or current value of some metric.
Expand Down
30 changes: 30 additions & 0 deletions dbms/src/Common/PODArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,37 @@

namespace DB
{
namespace ErrorCodes
{
extern const int CANNOT_ALLOCATE_MEMORY;
}

/// Used for left padding of PODArray when empty
const char EmptyPODArray[EmptyPODArraySize]{};

namespace PODArrayDetails
{

ALWAYS_INLINE size_t byte_size(size_t num_elements, size_t element_size)
{
size_t amount;
if (__builtin_mul_overflow(num_elements, element_size, &amount))
throw Exception(
ErrorCodes::CANNOT_ALLOCATE_MEMORY,
"Amount of memory requested to allocate is more than allowed");
return amount;
}

ALWAYS_INLINE size_t
minimum_memory_for_elements(size_t num_elements, size_t element_size, size_t pad_left, size_t pad_right)
{
size_t amount;
if (__builtin_add_overflow(byte_size(num_elements, element_size), pad_left + pad_right, &amount))
throw Exception(
ErrorCodes::CANNOT_ALLOCATE_MEMORY,
"Amount of memory requested to allocate is more than allowed");
return amount;
}

} // namespace PODArrayDetails
} // namespace DB
Loading