1 /* 2 * Copyright 2010, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Clemens Zeidler <haiku@clemens-zeidler.de> 7 */ 8 9 #include "CatchUpManager.h" 10 11 #include <vector> 12 13 #include <Debug.h> 14 #include <Query.h> 15 16 #include "IndexServer.h" 17 18 19 const uint32 kCatchUp = '&CaU'; 20 const uint32 kCatchUpDone = '&CUD'; 21 22 const bigtime_t kSecond = 1000000; 23 24 25 CatchUpAnalyser::CatchUpAnalyser(const BVolume& volume, time_t start, 26 time_t end, BHandler* manager) 27 : 28 AnalyserDispatcher("CatchUpAnalyser"), 29 fVolume(volume), 30 fStart(start), 31 fEnd(end), 32 fCatchUpManager(manager) 33 { 34 35 } 36 37 38 void 39 CatchUpAnalyser::MessageReceived(BMessage *message) 40 { 41 switch (message->what) { 42 case kCatchUp: 43 _CatchUp(); 44 break; 45 46 default: 47 BLooper::MessageReceived(message); 48 } 49 } 50 51 52 void 53 CatchUpAnalyser::StartAnalysing() 54 { 55 PostMessage(kCatchUp); 56 Run(); 57 } 58 59 60 void 61 CatchUpAnalyser::AnalyseEntry(const entry_ref& ref) 62 { 63 for (int i = 0; i < fFileAnalyserList.CountItems(); i++) { 64 FileAnalyser* analyser = fFileAnalyserList.ItemAt(i); 65 const analyser_settings& settings = analyser->CachedSettings(); 66 if (settings.syncPosition / kSecond >= fStart 67 && settings.watchingStart / kSecond <= fEnd) 68 analyser->AnalyseEntry(ref); 69 } 70 } 71 72 73 void 74 CatchUpAnalyser::_CatchUp() 75 { 76 STRACE("_CatchUp start %i, end %i\n", (int)fStart, (int)fEnd); 77 for (int i = 0; i < fFileAnalyserList.CountItems(); i++) 78 STRACE("- Analyser %s\n", fFileAnalyserList.ItemAt(i)->Name().String()); 79 80 BQuery query; 81 query.SetVolume(&fVolume); 82 query.PushAttr("last_modified"); 83 query.PushInt32(fStart); 84 query.PushOp(B_GE); 85 query.PushAttr("last_modified"); 86 query.PushInt32(fEnd); 87 query.PushOp(B_LE); 88 query.PushOp(B_AND); 89 90 query.Fetch(); 91 92 std::vector<entry_ref> entryList; 93 entry_ref ref; 94 while (query.GetNextRef(&ref) == B_OK) 95 entryList.push_back(ref); 96 97 printf("CatchUpAnalyser:: entryList.size() %i\n", (int)entryList.size()); 98 99 if (entryList.size() == 0) 100 return; 101 102 for (uint32 i = 0; i < entryList.size(); i++) { 103 if (Stopped()) 104 return; 105 if (i % 100 == 0) 106 printf("Catch up: %i/%i\n", (int)i,(int)entryList.size()); 107 AnalyseEntry(entryList[i]); 108 } 109 LastEntry(); 110 111 _WriteSyncSatus(fEnd * kSecond); 112 printf("Catched up.\n"); 113 114 BMessenger managerMessenger(fCatchUpManager); 115 BMessage msg(kCatchUpDone); 116 msg.AddPointer("Analyser", this); 117 managerMessenger.SendMessage(&msg); 118 } 119 120 121 void 122 CatchUpAnalyser::_WriteSyncSatus(bigtime_t syncTime) 123 { 124 for (int i = 0; i < fFileAnalyserList.CountItems(); i++) { 125 AnalyserSettings* settings = fFileAnalyserList.ItemAt(i)->Settings(); 126 ASSERT(settings); 127 settings->SetSyncPosition(syncTime); 128 settings->WriteSettings(); 129 } 130 131 } 132 133 134 CatchUpManager::CatchUpManager(const BVolume& volume) 135 : 136 fVolume(volume) 137 { 138 139 } 140 141 142 CatchUpManager::~CatchUpManager() 143 { 144 Stop(); 145 146 for (int i = 0; i < fFileAnalyserQueue.CountItems(); i++) 147 delete fFileAnalyserQueue.ItemAt(i); 148 } 149 150 151 void 152 CatchUpManager::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 168 bool 169 CatchUpManager::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 186 void 187 CatchUpManager::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 202 bool 203 CatchUpManager::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 243 void 244 CatchUpManager::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