コードベースで順番に説明していく。
ユーザーは、QueryWork クラスを継承したクラスを作り、そこに DB 処理を記述する。
class MyWork: public QueryWork
{
int32_t result_value;
virtual void work(Connection conn, void* pData) {
Statement stmt = conn->createStatement();
ResultSet rs = stmt->executeQuery("select * from tbl");
rs->next();
rs->getInt32(1, &result_value);
}
}
select を行い、結果を result_value メンバ変数にセットしている。この並列フレームワークでは、同一の Connection に対して同時に実行されることはない。 同期を気にせずに DBI の操作を記述することができる。
アプリケーションでは、QueryParallelizer オブジェクトを一つ用意し、 そこに Work オブジェクトをどんどん登録していく形になる。
bool start(size_t n,
Driver d,
const char* host,
const char* port,
const char* db,
const char* user,
const char* pass);
Driver d = GetPgsqlDriver(); QueryParallelizer par = new QueryParallelizer(); par.start(5, d, ...);
終了には、stop() と join() 関数を使う。
join() は完了を待つ。 join() 前に stop() を呼んでおくこと。
Work の登録には QueryParallelizer の addWork() を使う。 いくつかの登録方法があり、それぞれ結果の受け取り方が異なる。
bool addWork(QueryWork* w, void* data, bool autodelete);
である。data は Work の work() 関数で受け取るパラメータである。
autodelete は、このワークオブジェクトをフレームワークが delete するかどうかを指示する真偽値である。真ならば work 呼び出し後に delete される。
bool addWork(QueryWork* w, void* data, t_callback cb, void* cbdata);
である。data は Work の work() 関数で受け取るパラメータである。
typedef void(*t_callback)(QueryWork* w, void* cbdata, bool* autodelete);
となっている。addWork の cbdata がそのままコールバック関数に渡される。コールバック関数にはもう一つ、autodelete がある。 これは out 引数で、フレームワークが Work オブジェクトを delete して欲しい場合に真にセットする。
void MyCallback(QoeryWork* _w, void* cbdata) {
MyWork* w = static_cast< MyWork* >(_w);
printf("result: %d\n", w->result_value);
delete w;
*cbdata = false;
}
int main() {
par.addWork(new MyWork(), NULL, &MyCallback, NULL);
}
typedef nine::concurrent::Future< ResourceWork* > FutureResourceWork;
FutureResourceWork addWork(ResourceWork* w, void* data);
FutureResourceWork は、ResourceWork* を受け渡しする Future クラスである。使い方は Futureクラスの説明を参照のこと。
FutureResultWork f = par.addWork(new MyWork(), NULL);
ResourceWork* _w = f->get();
MyWork* w = static_cast< MyWork* >(_w);
printf("result: %d\n", w->result_value);
f->release();