00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 #ifndef AMINO_FOREACH_H
00022 #define AMINO_FOREACH_H
00023 
00024 #include <algorithm>
00025 
00026 #include <amino/thread.h>
00027 #include <amino/ftask.h>
00028 
00029 namespace amino{
00030     template<typename iteratorT, typename FuncT, typename Executor>
00031         void for_each(Executor& exec, iteratorT begin, iteratorT end, FuncT func){
00032             int procCount = getProcessNum();
00033             for_each(exec, procCount, begin, end, func);
00034         }
00035 
00036     template<typename iteratorT, typename FuncT>
00037         class CallStdForEach:public Runnable{
00038             private:
00039                 iteratorT f_begin, f_end;
00040                 FuncT* f_func;
00041             public:
00042                 CallStdForEach(){}
00043 
00044                 void setup(iteratorT begin, iteratorT end, FuncT& func){
00045                     f_begin = begin;
00046                     f_end = end;
00047                     f_func = &func;
00048                 }
00049 
00050                 void * run(){
00051                     std::for_each(f_begin, f_end, *f_func);
00052                     return NULL;
00053                 }
00054         };
00055 
00056     template<typename iteratorT, typename FuncT, typename Executor>
00057         void for_each(Executor& exec, int divNum, iteratorT begin, iteratorT end, FuncT func){
00058             int len = end-begin;
00059             int step = len/divNum;
00060             if(step==0) {
00061                 step=1;
00062                 divNum = len;
00063             }
00064 
00065             typedef CallStdForEach<iteratorT, FuncT> Caller;
00066             Caller * pCallers = new Caller[divNum];
00067             FutureTask ** pFTasks = new FutureTask*[divNum];
00068 
00069             for(int i=0;i<divNum-1;i++){
00070                 pCallers[i].setup(begin+i*step, begin+(i+1)*step, func);
00071                 pFTasks[i] = new FutureTask(pCallers+i);
00072                 exec.execute(pFTasks[i]);
00073             }
00074 
00075             pCallers[divNum-1].setup(begin+(divNum-1)*step, end, func);
00076             pFTasks[divNum-1] = new FutureTask(pCallers+(divNum-1));
00077 
00078             exec.execute(pFTasks[divNum-1]);
00079 
00080             for(int i=0;i<divNum;i++){
00081                 pFTasks[i]->get();
00082                         delete pFTasks[i];
00083             }
00084             delete[] pFTasks;
00085             delete[] pCallers;
00086         }
00087 };
00088 
00089 #endif