1 Star 0 Fork 393

kuoyihp/workflow

forked from 搜狗开源/workflow 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
WFAlgoTaskFactory.inl 16.23 KB
一键复制 编辑 原始数据 按行查看 历史
xiehan 提交于 1年前 . Update WFAlgoTaskFactory.inl
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
/*
Copyright (c) 2019 Sogou, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Author: Xie Han (xiehan@sogou-inc.com)
*/
#include <stdlib.h>
#include <random>
#include <algorithm>
#include <vector>
#include <functional>
#include <utility>
#include "Workflow.h"
#include "WFGlobal.h"
/********** Classes without CMP **********/
template<typename T>
class __WFSortTask : public WFSortTask<T>
{
protected:
virtual void execute()
{
std::sort(this->input.first, this->input.last);
this->output.first = this->input.first;
this->output.last = this->input.last;
}
public:
__WFSortTask(ExecQueue *queue, Executor *executor,
T *first, T *last,
sort_callback_t<T>&& cb) :
WFSortTask<T>(queue, executor, std::move(cb))
{
this->input.first = first;
this->input.last = last;
this->output.first = NULL;
this->output.last = NULL;
}
};
template<typename T>
class __WFMergeTask : public WFMergeTask<T>
{
protected:
virtual void execute();
public:
__WFMergeTask(ExecQueue *queue, Executor *executor,
T *first1, T *last1, T *first2, T *last2, T *d_first,
merge_callback_t<T>&& cb) :
WFMergeTask<T>(queue, executor, std::move(cb))
{
this->input.first1 = first1;
this->input.last1 = last1;
this->input.first2 = first2;
this->input.last2 = last2;
this->input.d_first = d_first;
this->output.first = NULL;
this->output.last = NULL;
}
};
template<typename T>
void __WFMergeTask<T>::execute()
{
auto *input = &this->input;
auto *output = &this->output;
if (input->first1 == input->d_first && input->last1 == input->first2)
{
std::inplace_merge(input->first1, input->first2, input->last2);
output->last = input->last2;
}
else if (input->first2 == input->d_first && input->last2 == input->first1)
{
std::inplace_merge(input->first2, input->first1, input->last1);
output->last = input->last1;
}
else
{
output->last = std::merge(input->first1, input->last1,
input->first2, input->last2,
input->d_first);
}
output->first = input->d_first;
}
template<typename T>
class __WFParSortTask : public __WFSortTask<T>
{
public:
virtual void dispatch();
protected:
virtual SubTask *done()
{
if (this->flag)
return series_of(this)->pop();
return this->WFSortTask<T>::done();
}
virtual void execute();
protected:
int depth;
int flag;
public:
__WFParSortTask(ExecQueue *queue, Executor *executor,
T *first, T *last, int depth,
sort_callback_t<T>&& cb) :
__WFSortTask<T>(queue, executor, first, last, std::move(cb))
{
this->depth = depth;
this->flag = 0;
}
};
template<typename T>
void __WFParSortTask<T>::dispatch()
{
size_t n = this->input.last - this->input.first;
if (!this->flag && this->depth < 7 && n >= 32)
{
SeriesWork *series = series_of(this);
T *middle = this->input.first + n / 2;
auto *task1 =
new __WFParSortTask<T>(this->queue, this->executor,
this->input.first, middle,
this->depth + 1,
nullptr);
auto *task2 =
new __WFParSortTask<T>(this->queue, this->executor,
middle, this->input.last,
this->depth + 1,
nullptr);
SeriesWork *sub_series[2] = {
Workflow::create_series_work(task1, nullptr),
Workflow::create_series_work(task2, nullptr)
};
ParallelWork *parallel =
Workflow::create_parallel_work(sub_series, 2, nullptr);
series->push_front(this);
series->push_front(parallel);
this->flag = 1;
this->subtask_done();
}
else
this->__WFSortTask<T>::dispatch();
}
template<typename T>
void __WFParSortTask<T>::execute()
{
if (this->flag)
{
size_t n = this->input.last - this->input.first;
T *middle = this->input.first + n / 2;
std::inplace_merge(this->input.first, middle, this->input.last);
this->output.first = this->input.first;
this->output.last = this->input.last;
this->flag = 0;
}
else
this->__WFSortTask<T>::execute();
}
/********** Classes with CMP **********/
template<typename T, class CMP>
class __WFSortTaskCmp : public __WFSortTask<T>
{
protected:
virtual void execute()
{
std::sort(this->input.first, this->input.last,
std::move(this->compare));
this->output.first = this->input.first;
this->output.last = this->input.last;
}
protected:
CMP compare;
public:
__WFSortTaskCmp(ExecQueue *queue, Executor *executor,
T *first, T *last, CMP&& cmp,
sort_callback_t<T>&& cb) :
__WFSortTask<T>(queue, executor, first, last, std::move(cb)),
compare(std::move(cmp))
{
}
};
template<typename T, class CMP>
class __WFMergeTaskCmp : public __WFMergeTask<T>
{
protected:
virtual void execute();
protected:
CMP compare;
public:
__WFMergeTaskCmp(ExecQueue *queue, Executor *executor,
T *first1, T *last1, T *first2, T *last2,
T *d_first, CMP&& cmp,
merge_callback_t<T>&& cb) :
__WFMergeTask<T>(queue, executor, first1, last1, first2, last2, d_first,
std::move(cb)),
compare(std::move(cmp))
{
}
};
template<typename T, class CMP>
void __WFMergeTaskCmp<T, CMP>::execute()
{
auto *input = &this->input;
auto *output = &this->output;
if (input->first1 == input->d_first && input->last1 == input->first2)
{
std::inplace_merge(input->first1, input->first2, input->last2,
std::move(this->compare));
output->last = input->last2;
}
else if (input->first2 == input->d_first && input->last2 == input->first1)
{
std::inplace_merge(input->first2, input->first1, input->last1,
std::move(this->compare));
output->last = input->last1;
}
else
{
output->last = std::merge(input->first1, input->last1,
input->first2, input->last2,
input->d_first,
std::move(this->compare));
}
output->first = input->d_first;
}
template<typename T, class CMP>
class __WFParSortTaskCmp : public __WFSortTaskCmp<T, CMP>
{
public:
virtual void dispatch();
protected:
virtual SubTask *done()
{
if (this->flag)
return series_of(this)->pop();
return this->WFSortTask<T>::done();
}
virtual void execute();
protected:
int depth;
int flag;
public:
__WFParSortTaskCmp(ExecQueue *queue, Executor *executor,
T *first, T *last, CMP cmp, int depth,
sort_callback_t<T>&& cb) :
__WFSortTaskCmp<T, CMP>(queue, executor, first, last, std::move(cmp),
std::move(cb))
{
this->depth = depth;
this->flag = 0;
}
};
template<typename T, class CMP>
void __WFParSortTaskCmp<T, CMP>::dispatch()
{
size_t n = this->input.last - this->input.first;
if (!this->flag && this->depth < 7 && n >= 32)
{
SeriesWork *series = series_of(this);
T *middle = this->input.first + n / 2;
auto *task1 =
new __WFParSortTaskCmp<T, CMP>(this->queue, this->executor,
this->input.first, middle,
this->compare, this->depth + 1,
nullptr);
auto *task2 =
new __WFParSortTaskCmp<T, CMP>(this->queue, this->executor,
middle, this->input.last,
this->compare, this->depth + 1,
nullptr);
SeriesWork *sub_series[2] = {
Workflow::create_series_work(task1, nullptr),
Workflow::create_series_work(task2, nullptr)
};
ParallelWork *parallel =
Workflow::create_parallel_work(sub_series, 2, nullptr);
series->push_front(this);
series->push_front(parallel);
this->flag = 1;
this->subtask_done();
}
else
this->__WFSortTaskCmp<T, CMP>::dispatch();
}
template<typename T, class CMP>
void __WFParSortTaskCmp<T, CMP>::execute()
{
if (this->flag)
{
size_t n = this->input.last - this->input.first;
T *middle = this->input.first + n / 2;
std::inplace_merge(this->input.first, middle, this->input.last,
std::move(this->compare));
this->output.first = this->input.first;
this->output.last = this->input.last;
this->flag = 0;
}
else
this->__WFSortTaskCmp<T, CMP>::execute();
}
/********** Factory functions without CMP **********/
template<typename T, class CB>
WFSortTask<T> *WFAlgoTaskFactory::create_sort_task(const std::string& name,
T *first, T *last,
CB callback)
{
return new __WFSortTask<T>(WFGlobal::get_exec_queue(name),
WFGlobal::get_compute_executor(),
first, last,
std::move(callback));
}
template<typename T, class CB>
WFMergeTask<T> *WFAlgoTaskFactory::create_merge_task(const std::string& name,
T *first1, T *last1,
T *first2, T *last2,
T *d_first,
CB callback)
{
return new __WFMergeTask<T>(WFGlobal::get_exec_queue(name),
WFGlobal::get_compute_executor(),
first1, last1, first2, last2, d_first,
std::move(callback));
}
template<typename T, class CB>
WFSortTask<T> *WFAlgoTaskFactory::create_psort_task(const std::string& name,
T *first, T *last,
CB callback)
{
return new __WFParSortTask<T>(WFGlobal::get_exec_queue(name),
WFGlobal::get_compute_executor(),
first, last, 0,
std::move(callback));
}
/********** Factory functions with CMP **********/
template<typename T, class CMP, class CB>
WFSortTask<T> *WFAlgoTaskFactory::create_sort_task(const std::string& name,
T *first, T *last,
CMP compare,
CB callback)
{
return new __WFSortTaskCmp<T, CMP>(WFGlobal::get_exec_queue(name),
WFGlobal::get_compute_executor(),
first, last, std::move(compare),
std::move(callback));
}
template<typename T, class CMP, class CB>
WFMergeTask<T> *WFAlgoTaskFactory::create_merge_task(const std::string& name,
T *first1, T *last1,
T *first2, T *last2,
T *d_first,
CMP compare,
CB callback)
{
return new __WFMergeTaskCmp<T, CMP>(WFGlobal::get_exec_queue(name),
WFGlobal::get_compute_executor(),
first1, last1, first2, last2,
d_first, std::move(compare),
std::move(callback));
}
template<typename T, class CMP, class CB>
WFSortTask<T> *WFAlgoTaskFactory::create_psort_task(const std::string& name,
T *first, T *last,
CMP compare,
CB callback)
{
return new __WFParSortTaskCmp<T, CMP>(WFGlobal::get_exec_queue(name),
WFGlobal::get_compute_executor(),
first, last, std::move(compare), 0,
std::move(callback));
}
/****************** Shuffle ******************/
template<typename T>
class __WFShuffleTask : public WFShuffleTask<T>
{
protected:
virtual void execute()
{
std::shuffle(this->input.first, this->input.last,
std::mt19937_64(random()));
this->output.first = this->input.first;
this->output.last = this->input.last;
}
public:
__WFShuffleTask(ExecQueue *queue, Executor *executor,
T *first, T *last,
shuffle_callback_t<T>&& cb) :
WFShuffleTask<T>(queue, executor, std::move(cb))
{
this->input.first = first;
this->input.last = last;
this->output.first = NULL;
this->output.last = NULL;
}
};
template<typename T, class URBG>
class __WFShuffleTaskGen : public __WFShuffleTask<T>
{
protected:
virtual void execute()
{
std::shuffle(this->input.first, this->input.last,
std::move(this->generator));
this->output.first = this->input.first;
this->output.last = this->input.last;
}
protected:
URBG generator;
public:
__WFShuffleTaskGen(ExecQueue *queue, Executor *executor,
T *first, T *last, URBG&& gen,
shuffle_callback_t<T>&& cb) :
__WFShuffleTask<T>(queue, executor, std::move(cb)),
generator(std::move(gen))
{
}
};
template<typename T, class CB>
WFShuffleTask<T> *WFAlgoTaskFactory::create_shuffle_task(const std::string& name,
T *first, T *last,
CB callback)
{
return new __WFShuffleTask<T>(WFGlobal::get_exec_queue(name),
WFGlobal::get_compute_executor(),
first, last,
std::move(callback));
}
template<typename T, class URBG, class CB>
WFShuffleTask<T> *WFAlgoTaskFactory::create_shuffle_task(const std::string& name,
T *first, T *last,
URBG generator,
CB callback)
{
return new __WFShuffleTaskGen<T, URBG>(WFGlobal::get_exec_queue(name),
WFGlobal::get_compute_executor(),
first, last, std::move(generator),
std::move(callback));
}
/****************** Remove ******************/
template<typename T>
class __WFRemoveTask : public WFRemoveTask<T>
{
protected:
virtual void execute()
{
this->output.last = std::remove(this->input.first, this->input.last,
this->input.value);
this->output.first = this->input.first;
}
public:
__WFRemoveTask(ExecQueue *queue, Executor *executor,
T *first, T *last, T&& value,
remove_callback_t<T>&& cb) :
WFRemoveTask<T>(queue, executor, std::move(cb))
{
this->input.first = first;
this->input.last = last;
this->input.value = std::move(value);
this->output.first = NULL;
this->output.last = NULL;
}
};
template<typename T, class CB>
WFRemoveTask<T> *WFAlgoTaskFactory::create_remove_task(const std::string& name,
T *first, T *last,
T value,
CB callback)
{
return new __WFRemoveTask<T>(WFGlobal::get_exec_queue(name),
WFGlobal::get_compute_executor(),
first, last, std::move(value),
std::move(callback));
}
/****************** Unique ******************/
template<typename T>
class __WFUniqueTask : public WFUniqueTask<T>
{
protected:
virtual void execute()
{
this->output.last = std::unique(this->input.first, this->input.last);
this->output.first = this->input.first;
}
public:
__WFUniqueTask(ExecQueue *queue, Executor *executor,
T *first, T *last,
unique_callback_t<T>&& cb) :
WFUniqueTask<T>(queue, executor, std::move(cb))
{
this->input.first = first;
this->input.last = last;
this->output.first = NULL;
this->output.last = NULL;
}
};
template<typename T, class CB>
WFUniqueTask<T> *WFAlgoTaskFactory::create_unique_task(const std::string& name,
T *first, T *last,
CB callback)
{
return new __WFUniqueTask<T>(WFGlobal::get_exec_queue(name),
WFGlobal::get_compute_executor(),
first, last,
std::move(callback));
}
/****************** Reverse ******************/
template<typename T>
class __WFReverseTask : public WFReverseTask<T>
{
protected:
virtual void execute()
{
std::reverse(this->input.first, this->input.last);
this->output.first = this->input.first;
this->output.last = this->input.last;
}
public:
__WFReverseTask(ExecQueue *queue, Executor *executor,
T *first, T *last,
reverse_callback_t<T>&& cb) :
WFReverseTask<T>(queue, executor, std::move(cb))
{
this->input.first = first;
this->input.last = last;
this->output.first = NULL;
this->output.last = NULL;
}
};
template<typename T, class CB>
WFReverseTask<T> *WFAlgoTaskFactory::create_reverse_task(const std::string& name,
T *first, T *last,
CB callback)
{
return new __WFReverseTask<T>(WFGlobal::get_exec_queue(name),
WFGlobal::get_compute_executor(),
first, last,
std::move(callback));
}
/****************** Rotate ******************/
template<typename T>
class __WFRotateTask : public WFRotateTask<T>
{
protected:
virtual void execute()
{
std::rotate(this->input.first, this->input.middle, this->input.last);
this->output.first = this->input.first;
this->output.last = this->input.last;
}
public:
__WFRotateTask(ExecQueue *queue, Executor *executor,
T *first, T* middle, T *last,
rotate_callback_t<T>&& cb) :
WFRotateTask<T>(queue, executor, std::move(cb))
{
this->input.first = first;
this->input.middle = middle;
this->input.last = last;
this->output.first = NULL;
this->output.last = NULL;
}
};
template<typename T, class CB>
WFRotateTask<T> *WFAlgoTaskFactory::create_rotate_task(const std::string& name,
T *first, T *middle, T *last,
CB callback)
{
return new __WFRotateTask<T>(WFGlobal::get_exec_queue(name),
WFGlobal::get_compute_executor(),
first, middle, last,
std::move(callback));
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/qizhendong_admin/workflow.git
git@gitee.com:qizhendong_admin/workflow.git
qizhendong_admin
workflow
workflow
master

搜索帮助