ClickHouse 學習中,如果有問題,請在下方討論。
為了比較快的了解聚合函數的相關架構,我們選擇比較簡單的聚合函數。常見比較簡單的聚合函數有max/min/sum/average等,我們拿sum為例.
例如: 我們有個SQL 語句 select sum(a) from table; 如果看做是一個簡單的求和問題,那么我們就會遍歷所有輸入的數據,並進行求和計算。 類似
偽碼:
long Sum(data){
let sum = 0;
//遍歷列中的數據,並進行計算。
for (auto _data: data)
sum += _data;
return sum;
}
那么在AggregateFunctionSum是如何實現這種抽象的呢. 帶着這個疑問,我們找到AggregateFunctionSum.h 文件.
這個類模板 繼承沖擊力比較強,需要做一下作者在這類繼承關系上的思路。
/// Counts the sum of the numbers. template <typename T, typename TResult, typename Data, AggregateFunctionSumType Type> class AggregateFunctionSum final : public IAggregateFunctionDataHelper<Data, AggregateFunctionSum<T, TResult, Data, Type>>
以下是推斷邏輯:
某個聚合函數的實際組成是由 函數 + 數據構成 (這里是繼承關系)。
1. 這里類比 AggregateFunctionSum : IAggregateFunctionDataHelpler(從類名稱上,繼承了Function和 Data的信息,后面會繼續進行分解)
2. IAggregateFunctionDataHelper 本模板類中定義的Data相關的 成員及成員函數,除去Data相關的就是 IAggregateFunctionHelper 的模板類。
3. IAggregateFunctionHelper 是個Function的Helper類模板,類模板參數中的Derived中應該是一個Function. (AggregateFunctionSum<T,TResult,Data,Type>).
4. IAggregateFunctionHelper 應該在繼承IAggregateFunction的所有成員后,還需要加入一些增強(Helper)的成員。 這里我們看到的是 addFree ,靜態方法,因為畢竟IAggregateFunctionHelpler是個Interface(因為其沒有實現IAggregateFunction里面所有的pure virtual function,所以不能實例化)。其中也override了一些IAggregateFunction的一些 pure virtual function. addFree方法 的確是可以通過 static_cast<const Derived &>(*that).add(place, columns, row_column, arena).
5.通過Debug,我們可以看到,一般聚合函數的調用是在這里進行的。(Aggregator.cpp).
/** Create an aggregate function with a numeric type in the template parameter, depending on the type of the argument. */ template <template <typename> class AggregateFunctionTemplate, typename... TArgs> static IAggregateFunction * createWithNumericType(const IDataType & argument_type, TArgs && ... args)
---未完待續
#include <iostream>
using namespace std;
class Base{
protected:
static void f(){cout << "invoke static f method" << endl;}
};
class Derived: public Base{
public:
using func_type = void (*)();
void derivedFunc(){
this->f();
//為函數指針賦值 使用&和不使用&結果竟然是一樣的。語法兼容性有點強。
func_type x = &f;
func_type y = f;
y();
x();
}
};
int main(){
Derived d;
d.derivedFunc();
}
---結果
➜ C++Basic ./accessStaticMethodViaThisPointer
函數指針 賦值 還是太靈活。
invoke static f method
invoke static f method
invoke static f method
