mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
Overcome gcc limitation
This commit is contained in:
parent
e8c29bf15f
commit
06e79e914c
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/unaligned.h>
|
||||
|
||||
#include <Common/typeid_cast.h>
|
||||
#include <Common/assert_cast.h>
|
||||
|
||||
@ -34,7 +36,7 @@ namespace DB
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
struct __attribute__((__packed__)) AggregateFunctionUniqUpToData
|
||||
struct AggregateFunctionUniqUpToData
|
||||
{
|
||||
/** If count == threshold + 1 - this means that it is "overflowed" (values greater than threshold).
|
||||
* In this case (for example, after calling the merge function), the `data` array does not necessarily contain the initialized values
|
||||
@ -42,7 +44,17 @@ struct __attribute__((__packed__)) AggregateFunctionUniqUpToData
|
||||
* then set count to `threshold + 1`, and values from another state are not copied.
|
||||
*/
|
||||
UInt8 count = 0;
|
||||
T data[0];
|
||||
char data_ptr[0];
|
||||
|
||||
T load(size_t i) const
|
||||
{
|
||||
return unalignedLoad<T>(data_ptr + i * sizeof(T));
|
||||
}
|
||||
|
||||
void store(size_t i, const T & x)
|
||||
{
|
||||
unalignedStore<T>(data_ptr + i * sizeof(T), x);
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
@ -59,12 +71,12 @@ struct __attribute__((__packed__)) AggregateFunctionUniqUpToData
|
||||
|
||||
/// Linear search for the matching element.
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
if (data[i] == x)
|
||||
if (load(i) == x)
|
||||
return;
|
||||
|
||||
/// Did not find the matching element. If there is room for one more element, insert it.
|
||||
if (count < threshold)
|
||||
data[count] = x;
|
||||
store(count, x);
|
||||
|
||||
/// After increasing count, the state may be overflowed.
|
||||
++count;
|
||||
@ -83,7 +95,7 @@ struct __attribute__((__packed__)) AggregateFunctionUniqUpToData
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < rhs.count; ++i)
|
||||
insert(rhs.data[i], threshold);
|
||||
insert(rhs.load(i), threshold);
|
||||
}
|
||||
|
||||
void write(WriteBuffer & wb, UInt8 threshold) const
|
||||
@ -92,7 +104,7 @@ struct __attribute__((__packed__)) AggregateFunctionUniqUpToData
|
||||
|
||||
/// Write values only if the state is not overflowed. Otherwise, they are not needed, and only the fact that the state is overflowed is important.
|
||||
if (count <= threshold)
|
||||
wb.write(reinterpret_cast<const char *>(data), count * sizeof(data[0]));
|
||||
wb.write(data_ptr, count * sizeof(T));
|
||||
}
|
||||
|
||||
void read(ReadBuffer & rb, UInt8 threshold)
|
||||
@ -100,7 +112,7 @@ struct __attribute__((__packed__)) AggregateFunctionUniqUpToData
|
||||
readBinary(count, rb);
|
||||
|
||||
if (count <= threshold)
|
||||
rb.read(reinterpret_cast<char *>(data), count * sizeof(data[0]));
|
||||
rb.read(data_ptr, count * sizeof(T));
|
||||
}
|
||||
|
||||
/// ALWAYS_INLINE is required to have better code layout for uniqUpTo function
|
||||
|
Loading…
Reference in New Issue
Block a user