00001 #ifndef Impala_Util_RangeIterator_h 00002 #define Impala_Util_RangeIterator_h 00003 00004 #include "Util/Iterable.h" 00005 00006 namespace Impala 00007 { 00008 namespace Util 00009 { 00010 00011 class RangeIterator 00012 { 00013 public: 00014 RangeIterator() 00015 { 00016 mDone = false; 00017 } 00018 00019 Iterable* GetIterable(const std::string& name) 00020 { 00021 for(int i=0 ; i<mRanges.size() ; i++) 00022 if(mRanges[i]->GetName() == name) 00023 return mRanges[i]; 00024 return 0; 00025 } 00026 00027 int GetTotalIterations() 00028 { 00029 int total = 1; 00030 for(int i=0 ; i<mRanges.size() ; i++) 00031 total *= mRanges[i]->GetSteps(); 00032 return total; 00033 } 00034 00035 int GetIteration() 00036 { 00037 return mCurrentIteration; 00038 } 00039 00040 void AddRange(const std::string& name, const std::string& range) 00041 { 00042 Util::Iterable* param = Util::ParseRangeDefinition(name, range); 00043 if(param == 0) 00044 return; 00045 00046 for(int i=0 ; i<mRanges.size() ; i++) 00047 if(mRanges[i]->GetName() == name) 00048 { 00049 delete mRanges[i]; 00050 mRanges[i] = param; 00051 return; 00052 } 00053 mRanges.push_back(param); 00054 } 00055 00060 void SetIteration(int iteration) 00061 { 00062 if(iteration >= GetTotalIterations()) 00063 ILOG_ERROR("argument too big"); 00064 00065 mDone = false; 00066 00067 for(int i=0 ; i<mRanges.size() ; i++) 00068 { 00069 Util::Iterable* curr = mRanges[i]; 00070 int range = curr->GetSteps(); 00071 if(range > 0) 00072 { 00073 curr->SetIteration(iteration % range); 00074 iteration /= range; 00075 } 00076 } 00077 } 00078 00079 void GetParameters(PropertySet* properties) 00080 { 00081 for(int i=0 ; i<mRanges.size() ; i++) 00082 properties->Add(mRanges[i]->GetName(), mRanges[i]->GetValue()); 00083 } 00084 00085 void Next() 00086 { 00087 int i; 00088 for(i=0 ; i<mRanges.size() ; i++) 00089 { 00090 Util::Iterable* curr = mRanges[i]; 00091 curr->Next(); 00092 if(curr->Done()) 00093 curr->SetIteration(0); 00094 else 00095 break; 00096 } 00097 if(i==mRanges.size()) 00098 mDone = true; 00099 } 00100 00101 bool IsDone() 00102 { 00103 return mDone; 00104 } 00105 00106 private: 00107 void InitialiseDistribution(int thisCpu, int nrCpus) 00108 { 00109 // for each loop (parameter range) assign a number of cpus and continue with the loop that contains this cpu. 00110 mCurrentIteration = (GetTotalIterations() * thisCpu) / nrCpus; 00111 mLastIteration = ((GetTotalIterations() * (thisCpu+1)) / nrCpus) - 1; 00112 } 00113 00114 int mCurrentIteration; 00115 int mLastIteration; 00116 bool mDone; 00117 00118 std::vector<Iterable*> mRanges; 00119 ILOG_VAR_DEC; 00120 }; 00121 00122 ILOG_VAR_INIT(RangeIterator, Impala.Util); 00123 00124 std::ostream& operator<<(std::ostream& os, RangeIterator& ri) 00125 { 00126 PropertySet ps; 00127 ri.GetParameters(&ps); 00128 ps.Print(os); 00129 return os; 00130 } 00131 00132 }//namespace Util 00133 }//namespace Impala 00134 00135 #endif 00136