void Spread::StartSpread() { double remainTime;// 剩余扩散时间 int oldLoad; struct timeval now1,now2; struct timespec timeout;// pthread_cond_timedwait pthread_mutex_lock(&mMutex); oldLoad = mSpreadNode.currentLoad; remainTime = mSpreadNode.fileLength * oldLoad * 1.0 / mSpreadNode.diskBand; //复制开始时间 mSpreadNode.startTime = getRelativeTime(); while(remainTime > 0) { oldLoad = mSpreadNode.currentLoad;// 睡眠前记录当前负载 gettimeofday(&now1, NULL); RemainTime(remainTime, timeout, now1); int ret = pthread_cond_timedwait(&mCond, &mMutex, &timeout); if (ETIMEDOUT == ret) { remainTime = 0.0; break; } else if (ret != 0) { LOG_INFO("pthread_cond_timedwait error,exit."); exit(1); } gettimeofday(&now2, NULL); double timeslips = getTimeSlips(&now2, &now1); remainTime -= timeslips; if(remainTime < 0) break; remainTime = remainTime * mSpreadNode.currentLoad / oldLoad; } // 复制结束时间 mSpreadNode.endTime = getRelativeTime(); mSpreadNode.isFinished = true; pthread_mutex_unlock(&mMutex); }
int LFRUManager::duplicateMethod(unsigned int serverId) { unsigned int needSpreadFile; double minWeight, curWeight; minWeight = 1000000.0; string logStr = "server[" + numToString(serverId) + "] is overload"; serverLog.writeSystemLog(logStr); //get the file need to spread struct timeval callTime; gettimeofday(&callTime, NULL); ostringstream logStream; for (unsigned int i = 0; i < LFRUFileList.size(); i++) { if (LFRUFileList[i]->serverId != serverId) continue; logStream<<"for server "<<serverId<<",file "<<LFRUFileList[i]->fileId<<endl; logStream<<"\tcallTime:"<<callTime.tv_sec<<":"<<callTime.tv_usec<<" "; logStream<<"t0:"<<t0.tv_sec<<":"<<t0.tv_usec<<" "; logStream<<"vtime:"<<LFRUFileList[i]->vtime.tv_sec<<":"<< LFRUFileList[i]->vtime.tv_usec<<" "; logStream<<"count:"<<LFRUFileList[i]->count<<" "; double fk = getTimeSlips(&callTime, &t0) / (double(LFRUFileList[i]->count * 1000000.0)); double rk = getTimeSlips(&callTime, &(LFRUFileList[i]->vtime)) / 1000000.0; curWeight = period - getTimeSlips(&callTime, &t0) / 1000000.0; curWeight = curWeight * rk / (double) period; curWeight += getTimeSlips(&callTime, &t0) * fk / (1000000.0 * period); logStream<<"Fk:"<<fk<<",rk:"<<rk<<",weight : "<<curWeight<<" "; //logStr = "in server[" + numToString(serverId) + "],the count of file " + //numToString(DWFileList[i]->fileId) + " is " + numToString(curCount); //serverLog.writeResourceLog(logStr); if (minWeight > curWeight) { minWeight = curWeight; needSpreadFile = LFRUFileList[i]->fileId; } logStream<<" minWeight = "<<minWeight<<",need spread file ="<<needSpreadFile<<endl; } serverLog.writeResourceLog(logStream.str()); logStr = "server[" + numToString(serverId) + "] chose file[" + numToString(needSpreadFile) + "] to spread"; serverLog.writeResourceLog(logStr); //choose the machine that have the minLoad and don't have the file vector<unsigned int > containList; getServerList(needSpreadFile, containList); vector<unsigned int> noList; noList.clear(); for (unsigned int i = 0; i < subServerNum; i++) { bool isContain = false; for (unsigned int j = 0; j < containList.size(); j++) { if (containList[j] == i) { isContain = true; break; } } if (isContain == false) { noList.push_back(i); } } int targetServer = lb->getMinLoadServer(noList); if (targetServer < 0) { logStr = "no server to duplicate"; serverLog.writeResourceLog(logStr); return -1; } logStr = "the spread target server is server[" + numToString(targetServer) + "]"; serverLog.writeResourceLog(logStr); //should have some transport time lb->addFileToSubServer(needSpreadFile, targetServer); addNewServer(needSpreadFile, targetServer); LFRUFileInfo *fileInfo = new LFRUFileInfo(needSpreadFile, targetServer); if (fileInfo != NULL) LFRUFileList.push_back(fileInfo); lb->printFileList(); return 0; }