#pragma once #include #include #include #include #include // TODO include this last because of a broken roaring header. See the comment inside. #include namespace DB { /// Counts bitmap operation on numbers. template class AggregateFunctionBitmap final : public IAggregateFunctionDataHelper> { public: AggregateFunctionBitmap(const DataTypePtr & type) : IAggregateFunctionDataHelper>({type}, {}) { } String getName() const override { return Data::name(); } DataTypePtr getReturnType() const override { return std::make_shared>(); } bool allocatesMemoryInArena() const override { return false; } void add(AggregateDataPtr __restrict place, const IColumn ** columns, size_t row_num, Arena *) const override { this->data(place).rbs.add(assert_cast &>(*columns[0]).getData()[row_num]); } void merge(AggregateDataPtr __restrict place, ConstAggregateDataPtr rhs, Arena *) const override { this->data(place).rbs.merge(this->data(rhs).rbs); } void serialize(ConstAggregateDataPtr __restrict place, WriteBuffer & buf, std::optional /* version */) const override { this->data(place).rbs.write(buf); } void deserialize(AggregateDataPtr __restrict place, ReadBuffer & buf, std::optional /* version */, Arena *) const override { this->data(place).rbs.read(buf); } void insertResultInto(AggregateDataPtr __restrict place, IColumn & to, Arena *) const override { assert_cast &>(to).getData().push_back(this->data(place).rbs.size()); } }; /// This aggregate function takes the states of AggregateFunctionBitmap as its argument. template class AggregateFunctionBitmapL2 final : public IAggregateFunctionDataHelper> { private: static constexpr auto STATE_VERSION_1_MIN_REVISION = 54455; public: AggregateFunctionBitmapL2(const DataTypePtr & type) : IAggregateFunctionDataHelper>({type}, {}) { } String getName() const override { return Policy::name; } DataTypePtr getReturnType() const override { return std::make_shared>(); } bool allocatesMemoryInArena() const override { return false; } DataTypePtr getStateType() const override { return this->argument_types.at(0); } void add(AggregateDataPtr __restrict place, const IColumn ** columns, size_t row_num, Arena *) const override { Data & data_lhs = this->data(place); const Data & data_rhs = this->data(assert_cast(*columns[0]).getData()[row_num]); if (!data_lhs.init) { data_lhs.init = true; data_lhs.rbs.merge(data_rhs.rbs); } else { Policy::apply(data_lhs, data_rhs); } } void merge(AggregateDataPtr __restrict place, ConstAggregateDataPtr rhs, Arena *) const override { Data & data_lhs = this->data(place); const Data & data_rhs = this->data(rhs); if (!data_rhs.init) return; if (!data_lhs.init) { data_lhs.init = true; data_lhs.rbs.merge(data_rhs.rbs); } else { Policy::apply(data_lhs, data_rhs); } } bool isVersioned() const override { return true; } size_t getDefaultVersion() const override { return 1; } size_t getVersionFromRevision(size_t revision) const override { if (revision >= STATE_VERSION_1_MIN_REVISION) return 1; else return 0; } void serialize(ConstAggregateDataPtr __restrict place, WriteBuffer & buf, std::optional version) const override { if (!version) version = getDefaultVersion(); if (*version >= 1) DB::writeBoolText(this->data(place).init, buf); this->data(place).rbs.write(buf); } void deserialize(AggregateDataPtr __restrict place, ReadBuffer & buf, std::optional version, Arena *) const override { if (!version) version = getDefaultVersion(); if (*version >= 1) DB::readBoolText(this->data(place).init, buf); this->data(place).rbs.read(buf); } void insertResultInto(AggregateDataPtr __restrict place, IColumn & to, Arena *) const override { assert_cast &>(to).getData().push_back(this->data(place).rbs.size()); } }; template class BitmapAndPolicy { public: static constexpr auto name = "groupBitmapAnd"; static void apply(Data & lhs, const Data & rhs) { lhs.rbs.rb_and(rhs.rbs); } }; template class BitmapOrPolicy { public: static constexpr auto name = "groupBitmapOr"; static void apply(Data & lhs, const Data & rhs) { lhs.rbs.rb_or(rhs.rbs); } }; template class BitmapXorPolicy { public: static constexpr auto name = "groupBitmapXor"; static void apply(Data & lhs, const Data & rhs) { lhs.rbs.rb_xor(rhs.rbs); } }; template using AggregateFunctionBitmapL2And = AggregateFunctionBitmapL2>; template using AggregateFunctionBitmapL2Or = AggregateFunctionBitmapL2>; template using AggregateFunctionBitmapL2Xor = AggregateFunctionBitmapL2>; }