1139823Simp/* 21541Srgrimes * Copyright 2010, Haiku. 31541Srgrimes * Distributed under the terms of the MIT License. 41541Srgrimes * 51541Srgrimes * Authors: 61541Srgrimes * Clemens Zeidler <haiku@clemens-zeidler.de> 71541Srgrimes */ 81541Srgrimes 91541Srgrimes#include "CatchUpManager.h" 101541Srgrimes 111541Srgrimes#include <vector> 121541Srgrimes 131541Srgrimes#include <Debug.h> 141541Srgrimes#include <Query.h> 151541Srgrimes 161541Srgrimes#include "IndexServer.h" 171541Srgrimes 181541Srgrimes 191541Srgrimesconst uint32 kCatchUp = '&CaU'; 201541Srgrimesconst uint32 kCatchUpDone = '&CUD'; 211541Srgrimes 221541Srgrimesconst bigtime_t kSecond = 1000000; 231541Srgrimes 241541Srgrimes 251541SrgrimesCatchUpAnalyser::CatchUpAnalyser(const BVolume& volume, time_t start, 261541Srgrimes time_t end, BHandler* manager) 271541Srgrimes : 281541Srgrimes AnalyserDispatcher("CatchUpAnalyser"), 291541Srgrimes fVolume(volume), 301541Srgrimes fStart(start), 311541Srgrimes fEnd(end), 3222521Sdyson fCatchUpManager(manager) 3350477Speter{ 341541Srgrimes 351541Srgrimes} 3683651Speter 3783651Speter 3822521Sdysonvoid 39214048SrmacklemCatchUpAnalyser::MessageReceived(BMessage *message) 40214048Srmacklem{ 41214048Srmacklem switch (message->what) { 42214048Srmacklem case kCatchUp: 43184588Sdfr _CatchUp(); 44184588Sdfr break; 45184588Sdfr 46184588Sdfr default: 47184588Sdfr BLooper::MessageReceived(message); 481541Srgrimes } 491541Srgrimes} 501541Srgrimes 511541Srgrimes 521541Srgrimesvoid 531541SrgrimesCatchUpAnalyser::StartAnalysing() 54214048Srmacklem{ 551541Srgrimes PostMessage(kCatchUp); 56122698Salfred Run(); 579336Sdfr} 581541Srgrimes 591541Srgrimes 601541Srgrimesvoid 6128270SwollmanCatchUpAnalyser::AnalyseEntry(const entry_ref& ref) 621541Srgrimes{ 631541Srgrimes for (int i = 0; i < fFileAnalyserList.CountItems(); i++) { 641541Srgrimes FileAnalyser* analyser = fFileAnalyserList.ItemAt(i); 659336Sdfr const analyser_settings& settings = analyser->CachedSettings(); 661541Srgrimes if (settings.syncPosition / kSecond >= fStart 67147280Sgreen && settings.watchingStart / kSecond <= fEnd) 6836176Speter analyser->AnalyseEntry(ref); 6936176Speter } 7036176Speter} 7136176Speter 729336Sdfr 7360938Sjakevoid 7419449SdfrCatchUpAnalyser::_CatchUp() 7519449Sdfr{ 7619449Sdfr STRACE("_CatchUp start %i, end %i\n", (int)fStart, (int)fEnd); 7736473Speter for (int i = 0; i < fFileAnalyserList.CountItems(); i++) 78122953Salfred STRACE("- Analyser %s\n", fFileAnalyserList.ItemAt(i)->Name().String()); 79131691Salfred 80131691Salfred BQuery query; 81184588Sdfr query.SetVolume(&fVolume); 82184588Sdfr query.PushAttr("last_modified"); 83184588Sdfr query.PushInt32(fStart); 84184588Sdfr query.PushOp(B_GE); 85184588Sdfr query.PushAttr("last_modified"); 86230547Sjhb query.PushInt32(fEnd); 87202767Srmacklem query.PushOp(B_LE); 88122698Salfred query.PushOp(B_AND); 89122698Salfred 90122698Salfred query.Fetch(); 91122698Salfred 92122698Salfred std::vector<entry_ref> entryList; 93122698Salfred entry_ref ref; 941541Srgrimes while (query.GetNextRef(&ref) == B_OK) 951541Srgrimes entryList.push_back(ref); 96214048Srmacklem 97214048Srmacklem printf("CatchUpAnalyser:: entryList.size() %i\n", (int)entryList.size()); 98214048Srmacklem 99214048Srmacklem if (entryList.size() == 0) 100214048Srmacklem return; 101214048Srmacklem 102214048Srmacklem for (uint32 i = 0; i < entryList.size(); i++) { 103214048Srmacklem if (Stopped()) 104216931Srmacklem return; 105214048Srmacklem if (i % 100 == 0) 10655206Speter printf("Catch up: %i/%i\n", (int)i,(int)entryList.size()); 1071541Srgrimes AnalyseEntry(entryList[i]); 1081541Srgrimes } 1091541Srgrimes LastEntry(); 1101541Srgrimes 11119449Sdfr _WriteSyncSatus(fEnd * kSecond); 112131691Salfred printf("Catched up.\n"); 113131691Salfred 11455206Speter BMessenger managerMessenger(fCatchUpManager); 1151541Srgrimes BMessage msg(kCatchUpDone); 116131691Salfred msg.AddPointer("Analyser", this); 117131691Salfred managerMessenger.SendMessage(&msg); 1182175Spaul} 119131691Salfred 120230547Sjhb 121230547Sjhbvoid 122230547SjhbCatchUpAnalyser::_WriteSyncSatus(bigtime_t syncTime) 123230547Sjhb{ 124202767Srmacklem for (int i = 0; i < fFileAnalyserList.CountItems(); i++) { 125202767Srmacklem AnalyserSettings* settings = fFileAnalyserList.ItemAt(i)->Settings(); 126202767Srmacklem ASSERT(settings); 127202767Srmacklem settings->SetSyncPosition(syncTime); 128131691Salfred settings->WriteSettings(); 129131691Salfred } 130131691Salfred 131} 132 133 134CatchUpManager::CatchUpManager(const BVolume& volume) 135 : 136 fVolume(volume) 137{ 138 139} 140 141 142CatchUpManager::~CatchUpManager() 143{ 144 Stop(); 145 146 for (int i = 0; i < fFileAnalyserQueue.CountItems(); i++) 147 delete fFileAnalyserQueue.ItemAt(i); 148} 149 150 151void 152CatchUpManager::MessageReceived(BMessage *message) 153{ 154 CatchUpAnalyser* analyser; 155 switch (message->what) { 156 case kCatchUpDone: 157 message->GetPointer("Analyser", &analyser); 158 fCatchUpAnalyserList.RemoveItem(analyser); 159 analyser->PostMessage(B_QUIT_REQUESTED); 160 break; 161 162 default: 163 BHandler::MessageReceived(message); 164 } 165} 166 167 168bool 169CatchUpManager::AddAnalyser(const FileAnalyser* analyserOrg) 170{ 171 IndexServer* server = (IndexServer*)be_app; 172 FileAnalyser* analyser = server->CreateFileAnalyser(analyserOrg->Name(), 173 fVolume); 174 if (!analyser) 175 return false; 176 ASSERT(analyserOrg->Settings()); 177 analyser->SetSettings(analyserOrg->Settings()); 178 179 bool status = fFileAnalyserQueue.AddItem(analyser); 180 if (!status) 181 delete analyser; 182 return status; 183} 184 185 186void 187CatchUpManager::RemoveAnalyser(const BString& name) 188{ 189 for (int i = 0; i < fFileAnalyserQueue.CountItems(); i++) { 190 FileAnalyser* analyser = fFileAnalyserQueue.ItemAt(i); 191 if (analyser->Name() == name) { 192 fFileAnalyserQueue.RemoveItem(analyser); 193 delete analyser; 194 } 195 } 196 197 for (int i = 0; i < fCatchUpAnalyserList.CountItems(); i++) 198 fCatchUpAnalyserList.ItemAt(i)->RemoveAnalyser(name); 199} 200 201 202bool 203CatchUpManager::CatchUp() 204{ 205 STRACE("CatchUpManager::CatchUp()\n"); 206 bigtime_t startBig = real_time_clock_usecs(); 207 bigtime_t endBig = 0; 208 for (int i = 0; i < fFileAnalyserQueue.CountItems(); i++) { 209 FileAnalyser* analyser = fFileAnalyserQueue.ItemAt(i); 210 analyser->UpdateSettingsCache(); 211 const analyser_settings& settings = analyser->CachedSettings(); 212 STRACE("%s, %i, %i\n", analyser->Name().String(), 213 (int)settings.syncPosition, (int)settings.watchingStart); 214 if (settings.syncPosition < startBig) 215 startBig = settings.syncPosition; 216 if (settings.watchingStart > endBig) 217 endBig = settings.watchingStart; 218 } 219 220 CatchUpAnalyser* catchUpAnalyser = new CatchUpAnalyser(fVolume, 221 startBig / kSecond, endBig / kSecond, this); 222 if (!catchUpAnalyser) 223 return false; 224 if (!fCatchUpAnalyserList.AddItem(catchUpAnalyser)) { 225 delete catchUpAnalyser; 226 return false; 227 } 228 229 for (int i = 0; i < fFileAnalyserQueue.CountItems(); i++) { 230 FileAnalyser* analyser = fFileAnalyserQueue.ItemAt(i); 231 // if AddAnalyser fails at least don't leak 232 if (!catchUpAnalyser->AddAnalyser(analyser)) 233 delete analyser; 234 235 } 236 fFileAnalyserQueue.MakeEmpty(); 237 238 catchUpAnalyser->StartAnalysing(); 239 return true; 240} 241 242 243void 244CatchUpManager::Stop() 245{ 246 for (int i = 0; i < fCatchUpAnalyserList.CountItems(); i++) { 247 CatchUpAnalyser* catchUpAnalyser = fCatchUpAnalyserList.ItemAt(i); 248 catchUpAnalyser->Stop(); 249 catchUpAnalyser->PostMessage(B_QUIT_REQUESTED); 250 } 251 fCatchUpAnalyserList.MakeEmpty(); 252} 253