| /** @file |
| |
| A brief file description |
| |
| @section license License |
| |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you 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. |
| */ |
| |
| #include <time.h> |
| #include <stdint.h> |
| #include <iostream> |
| #include <utility> |
| #include <vector> |
| #include <map> |
| #include <sys/time.h> |
| using namespace std; |
| |
| static int windowSize=200;//ms |
| static int totalDuration=2000;//seconds |
| static int lowerCutOff=300; |
| static int higherCutOff=1000; |
| |
| class FailureInfo |
| { |
| public: |
| |
| FailureInfo() |
| { |
| gettimeofday(&_start,NULL); |
| _totalSlot=totalDuration/windowSize;//INtegral multiple |
| _marker=0; |
| for(int i=0;i<_totalSlot;i++) |
| _passFail.push_back(make_pair(0,0)); |
| |
| _avgOverWindow=0; |
| _windowPassed=0; |
| }; |
| |
| ~FailureInfo() |
| { |
| } |
| |
| //Whenever the window time expires u start filling the count |
| //by taking a mod |
| //so what u get is over a window of 200 ms and 10 rounds |
| //the no of failures |
| //Introduce a variable which will be a function of |
| //failure and which will lead to points in graph |
| //according to which the probability of serving the |
| // data from cache or contacting the origin server |
| // will be decided |
| std::vector <std::pair < double,double > > _passFail; |
| |
| int _marker; |
| |
| int _totalSlot; |
| |
| struct timeval _start; |
| |
| double _avgOverWindow; |
| |
| int _windowPassed; |
| |
| }; |
| |
| |
| typedef std::map<std::string,class FailureInfo*> FailureData; |
| |
| void registerSuccFail(string URL,FailureData& data,bool isSuccess) |
| { |
| struct timeval currTime,result,startTime; |
| int marker; |
| FailureData::iterator it; |
| it=data.find(URL); |
| vector < pair < double , double > > & passFail=it->second->_passFail; |
| marker=it->second->_marker; |
| |
| |
| startTime=it->second->_start; |
| |
| gettimeofday(&currTime,NULL); |
| |
| timersub(&currTime,&startTime,&result); |
| |
| |
| |
| if( ( result.tv_sec*1000000+result.tv_usec ) > (windowSize*1000) ) |
| { |
| marker=++marker%it->second->_totalSlot; |
| if(marker==it->second->_totalSlot-1) |
| { |
| ++it->second->_windowPassed; |
| double avg=0; |
| for(int i=0;i<it->second->_totalSlot;i++) |
| { |
| if(passFail[i].first >0) |
| { |
| avg+=passFail[i].first/(passFail[i].first+passFail[i].second); |
| } |
| } |
| it->second->_avgOverWindow+=avg/it->second->_windowPassed; |
| } |
| it->second->_marker=marker; |
| gettimeofday(&it->second->_start,NULL); |
| } |
| |
| |
| if(isSuccess) |
| { |
| passFail[marker].second++; |
| } |
| |
| else |
| { |
| passFail[marker].first++; |
| } |
| } |
| |
| |
| bool isAttemptReq(string URL,FailureData& data) |
| { |
| FailureData::iterator it; |
| it=data.find(URL); |
| if(it != data.end()) |
| { |
| double avg=0; |
| vector < pair < double , double > > & passFail=it->second->_passFail; |
| |
| for(int i=0;i<it->second->_totalSlot;i++) |
| { |
| //cout<<"Failure:"<<passFail[i].first<< "Total"<< (passFail[i].first+passFail[i].second )<<endl; |
| if(passFail[i].first >0) |
| { |
| avg+=passFail[i].first/(passFail[i].first+passFail[i].second); |
| //cout<<"Prob of faillure:"<<passFail[i].first/(passFail[i].first+passFail[i].second)<<endl; |
| } |
| } |
| |
| if(avg) |
| { |
| avg=avg/it->second->_totalSlot; |
| double prob; |
| |
| |
| if(avg*1000<lowerCutOff) |
| { |
| prob=avg; |
| } |
| |
| |
| else |
| { |
| double mapFactor=( ( (avg*1000-lowerCutOff)*(avg*1000-lowerCutOff) ) / ( higherCutOff-lowerCutOff ) )+lowerCutOff; |
| prob=mapFactor/1000; |
| cout<<prob<<endl; |
| } |
| |
| if(prob==1) |
| { |
| prob=it->second->_avgOverWindow; |
| cout<<"Average"<<prob<<endl; |
| } |
| |
| int decision=rand()%100; |
| |
| |
| if(decision<prob*100) |
| return false; |
| |
| return true; |
| } |
| return true; |
| |
| } |
| else |
| { |
| FailureInfo* info=new FailureInfo(); |
| data[URL]=info; |
| return true; |
| } |
| } |
| |
| |
| const std::string fetchURL="www.example.com"; |
| int main(int argc,char**argv) |
| { |
| //Simulate the scenario |
| FailureData data; |
| int noOfAttempt=0,noOfExcept=0; |
| |
| int count=atoi(argv[1]); |
| while(count--) |
| { |
| int decision=rand()%100; |
| |
| if(isAttemptReq(fetchURL,data)) |
| { |
| noOfAttempt++; |
| if(decision>=atoi(argv[2]) && 0) |
| registerSuccFail(fetchURL,data,true); |
| |
| else |
| registerSuccFail(fetchURL,data,false); |
| } |
| else |
| noOfExcept++; |
| |
| } |
| |
| cout<<" SERVED FROM ATTEMPT "<<noOfAttempt<<" TOTAL "<<atoi(argv[1])<<endl; |
| cout<<" SERVED FROM EXCEPT "<<noOfExcept<<" TOTAL "<<atoi(argv[1])<<endl; |
| |
| } |