uint32 reindex(dtree_node_t *node, uint32 *next_id) { node->node_id = (*next_id)++; if (!IS_LEAF(node)) { return reindex(node->y, next_id) + reindex(node->n, next_id) + 1; } else { return 1; } }
void BasicGroupBigraph::groupProteinsBy(const Array<Set> & groups) { // remake the list of names and then remake the graph with them collapsed groupProtNames = Array<Array<string> > (groups.size()); originalN = Array<Counter> (groups.size()); int k; for (k=0; k<groups.size(); k++) { groupProtNames[k] = proteinsToPSMs.names[ groups[k] ]; // all possible sets of proteins can be present for a group if(!gbUseProteinGroupLevelInference){ originalN[k] = Counter( groups[k].size() ); }else{ // each group is either present or absent originalN[k] = Counter( 1 ); } } // remove all but the first of each group from the graph for (k=0; k<groups.size(); k++) { Set reps = groups[k].without( Set::SingletonSet(groups[k][0]) ); for (Set::Iterator iter = reps.begin(); iter != reps.end(); iter++) { disconnectProtein(*iter); } } reindex(); }
/** * Set the value for a given parameter. See setParameters for a description * of parameter indexing in SumCF. * @param p the parameter number, between 0 and the total number of parameters * (from all covariance functions) * @param value the new value for the parameter */ void SumCF::setParameter(const int p, const double value) { int cfIndex; int parcfIndex; reindex(cfIndex, parcfIndex, p); covFunctions[cfIndex]->setParameter(parcfIndex, value); }
/** * Gradient of the covariance matrix with respect to a given * parameter, i.e. d/dparameter cov(X,X) * * @param D the gradient of the covariance matrix cov(X,X) with respect * to parameter number p * @param p the parameter number * @param X a set of inputs */ void SumCF::covarianceGradient(mat& D, const int p, const mat& X) const { int cfIndex; int parcfIndex; reindex(cfIndex, parcfIndex, p); covFunctions[cfIndex]->covarianceGradient(D, parcfIndex, X); }
//------------------------------------------------------------------------------ AssignmentRule* AssignmentRules::insert(int index, uint ruleId, uint estimateId, const QList<AssignmentRule::Condition>& conditions) { AssignmentRule* rule = new AssignmentRule(ruleId, estimateId, conditions, this); rules.insert(index, rule); reindex(); emit ruleAdded(rule, index); return rule; }
/** * Return the name of the given parameter. See setParameters for a description * of parameter indexing in SumCF. * * @param p the parameter number, between 0 and the total number of parameters * (from all covariance functions) * @return the name of the parameter */ string SumCF::getParameterName(const int p) const { int cfIndex; int parcfIndex; reindex(cfIndex, parcfIndex, p); return (covFunctions[cfIndex]->getParameterName(parcfIndex)); }
/** * Get a given parameter (out of the parameters from all covariance functions) * @param p the parameter number, between 0 and the total number of parameters * @return * @note parameters are indexed in the order in which the covariance functions * are added to the sum, i.e. for a sum of 2 covariance functions, each with * 3 parameters, parameters 0-2 correspond to the parameters of the 1st * covariance function, and parameters 3-5 correspond to those of the second * covariance function. * @see reindex */ double SumCF::getParameter(const int p) const { int cfIndex; int parcfIndex; reindex(cfIndex, parcfIndex, p); return covFunctions[cfIndex]->getParameter(parcfIndex); }
/** * Set the transform for parameter number p * * @param p the parameter number * @param t a pointer to the new transform for parameter number p */ void SumCF::setTransform(int p, Transform* t) { int cfIndex; int parcfIndex; reindex(cfIndex, parcfIndex, p); covFunctions[cfIndex]->setTransform(parcfIndex, t); }
/** * Return the transform for parameter number p * * @param p the parameter number * @return a pointer to the transform object for p */ Transform* SumCF::getTransform(int p) const { int cfIndex; int parcfIndex; reindex(cfIndex, parcfIndex, p); return covFunctions[cfIndex]->getTransform(parcfIndex); }
inline pcl::PointIndices reindex(const pcl::PointIndices &indexer, const pcl::PointIndices &indices) { // Takes a PointIndices that relates to an original cloud and another that relates to a cloud that was filtered // by the original and returns a PointIndices with the contents of the second that relates to the original cloud // (Turns cloud[indexer[indices[i]]] into cloud[reindexed[i]] for i = 0..indices.size()) pcl::PointIndices reindexed; reindexed.header = indices.header; reindexed.indices = reindex(indexer.indices, indices.indices); return reindexed; }
//------------------------------------------------------------------------------ void AssignmentRules::remove(int index) { if (index >= 0 && index < rules.size()) { AssignmentRule* rule = rules.takeAt(index); reindex(); emit ruleRemoved(rule, index); delete rule; } }
//------------------------------------------------------------------------------ void AssignmentRules::moveRule(int from, int to) { // Make sure new index is within the bounds of the rules list if (to < 0) to = 0; if (to >= rules.size()) to = rules.size() - 1; AssignmentRule* rule = at(from); rules.move(from, to); reindex(); emit ruleMoved(rule, from, to); }
void ASTFunctionTable::build(ASTFunctionMap& functions) { // we assume that the base class table is already assigned // now insert local functions into the table ASTFunctionMap::Iterator it = functions.getIterator(); while ( functions.hasNext(it) ) { ASTFunction& function = functions.getNext(it); insert(function); } reindex(2); }
void SymbolTable::addDefault( const std::string &name ) { if ( myDefaultAdded ) throw std::logic_error( "Default Symbol already specified" ); SymbolMapIter i; i = mySymbols.find( name ); if ( i == mySymbols.end() ) { Symbol *tmp = new Symbol( name ); myDefaultSymbol = name; mySymbols[ name ] = tmp; reindex(); } else throw std::logic_error( "Default Symbol collides with existing symbol" ); myDefaultAdded = true; }
Symbol * SymbolTable::findOrCreate( const std::string &name ) { SymbolMapIter i; Symbol *retval = 0; i = mySymbols.find( name ); if ( i == mySymbols.end() ) { retval = new Symbol( name ); mySymbols[ name ] = retval; reindex(); if ( Symbol::TERMINAL == retval->getType() ) ++myNumTerminals; } else retval = (*i).second; return retval; }
void StarComponent::draw( SkyPainter *skyp ) { if( !selected() ) return; SkyMap *map = SkyMap::Instance(); const Projector *proj = map->projector(); KStarsData* data = KStarsData::Instance(); UpdateID updateID = data->updateID(); bool checkSlewing = ( map->isSlewing() && Options::hideOnSlew() ); m_hideLabels = checkSlewing || !( Options::showStarMagnitudes() || Options::showStarNames() ); //shortcuts to inform whether to draw different objects bool hideFaintStars = checkSlewing && Options::hideStars(); double hideStarsMag = Options::magLimitHideStar(); reindex( data->updateNum() ); double lgmin = log10(MINZOOM); double lgmax = log10(MAXZOOM); double lgz = log10(Options::zoomFactor()); double maglim; m_zoomMagLimit = maglim = zoomMagnitudeLimit(); double labelMagLim = Options::starLabelDensity() / 5.0; labelMagLim += ( 12.0 - labelMagLim ) * ( lgz - lgmin) / (lgmax - lgmin ); if( labelMagLim > 8.0 ) labelMagLim = 8.0; //Calculate sizeMagLim // Old formula: // float sizeMagLim = ( 2.000 + 2.444 * Options::memUsage() / 10.0 ) * ( lgz - lgmin ) + 5.8; // Using the maglim to compute the sizes of stars reduces // discernability between brighter and fainter stars at high zoom // levels. To fix that, we use an "arbitrary" constant in place of // the variable star density. // Not using this formula now. // float sizeMagLim = 4.444 * ( lgz - lgmin ) + 5.0; float sizeMagLim = zoomMagnitudeLimit(); if( sizeMagLim > faintMagnitude() * ( 1 - 1.5/16 ) ) sizeMagLim = faintMagnitude() * ( 1 - 1.5/16 ); skyp->setSizeMagLimit(sizeMagLim); //Loop for drawing star images MeshIterator region(m_skyMesh, DRAW_BUF); magLim = maglim; // If we are hiding faint stars, then maglim is really the brighter of hideStarsMag and maglim if( hideFaintStars && maglim > hideStarsMag ) maglim = hideStarsMag; m_StarBlockFactory->drawID = m_skyMesh->drawID(); int nTrixels = 0; while( region.hasNext() ) { ++nTrixels; Trixel currentRegion = region.next(); StarList* starList = m_starIndex->at( currentRegion ); for (int i=0; i < starList->size(); ++i) { StarObject *curStar = starList->at( i ); if( !curStar ) continue; float mag = curStar->mag(); // break loop if maglim is reached if ( mag > maglim ) break; if ( curStar->updateID != updateID ) curStar->JITupdate(); bool drawn = skyp->drawPointSource( curStar, mag, curStar->spchar() ); //FIXME_SKYPAINTER: find a better way to do this. if ( drawn && !(m_hideLabels || mag > labelMagLim) ) addLabel( proj->toScreen(curStar), curStar ); } } // Draw focusStar if not null if( focusStar ) { if ( focusStar->updateID != updateID ) focusStar->JITupdate(); float mag = focusStar->mag(); skyp->drawPointSource(focusStar, mag, focusStar->spchar() ); } // Now draw each of our DeepStarComponents for( int i =0; i < m_DeepStarComponents.size(); ++i ) { m_DeepStarComponents.at( i )->draw( skyp ); } }
std::vector<fwdpp::uint_t> compact_mutations(T &pop) /// \brief Sort mutation positions in population. /// /// Reorders the population mutation container /// so that it is sorted by increasing mutation position. /// The reordering requires assigning new key values into /// all gametes, which is also done. The mutation counts /// and mut_lookup data structures also get updated. /// /// Running this periodically is a performance increase /// due to improved cache performance. /// /// \param pop A population. /// /// \return A vector containing the mapping of old to /// new mutation index { std::vector<fwdpp::uint_t> indexes(pop.mutations.size()); std::iota(std::begin(indexes), std::end(indexes), 0); auto new_indexes_end = std::stable_partition( std::begin(indexes), std::end(indexes), [&pop](const fwdpp::uint_t i) { return pop.mcounts[i]; }); std::sort(std::begin(indexes), new_indexes_end, [&pop](const fwdpp::uint_t i, const fwdpp::uint_t j) { return pop.mutations[i].pos < pop.mutations[j].pos; }); std::vector<fwdpp::uint_t> reindex(indexes.size()); std::size_t new_indexes_size = std::distance(std::begin(indexes), new_indexes_end); for (std::size_t i = 0; i < new_indexes_size; ++i) { reindex[indexes[i]] = i; } for (auto &g : pop.gametes) { if (g.n) { for (auto &m : g.mutations) { m = reindex[m]; } for (auto &m : g.smutations) { m = reindex[m]; } } } decltype(pop.mutations) reordered_muts; decltype(pop.mcounts) reordered_mcounts; reordered_muts.reserve(pop.mutations.size()); reordered_mcounts.reserve(pop.mutations.size()); for (auto i : indexes) { reordered_muts.emplace_back(std::move(pop.mutations[i])); reordered_mcounts.push_back(pop.mcounts[i]); if (reordered_mcounts.back() > 0) { auto x = pop.mut_lookup.equal_range( reordered_muts.back().pos); while (x.first != x.second) { if (x.first->second == i) { x.first->second = reordered_muts.size() - 1; break; } ++x.first; } } } pop.mutations.swap(reordered_muts); pop.mcounts.swap(reordered_mcounts); return reindex; }
void CaseInsensitiveHashTable<T>::resize(size_t new_capacity) { reset(new_capacity); reindex(); }
void IconList::directoryChanged(const QString &path) { QDir new_dir (path); if(m_dir.absolutePath() != new_dir.absolutePath()) { m_dir.setPath(path); m_dir.refresh(); if(is_watching) stopWatching(); startWatching(); } if(!m_dir.exists()) if(!ensureFolderPathExists(m_dir.absolutePath())) return; m_dir.refresh(); auto new_list = m_dir.entryList(QDir::Files, QDir::Name); for (auto it = new_list.begin(); it != new_list.end(); it++) { QString &foo = (*it); foo = m_dir.filePath(foo); } auto new_set = new_list.toSet(); QList<QString> current_list; for (auto &it : icons) { if (!it.has(MMCIcon::FileBased)) continue; current_list.push_back(it.m_images[MMCIcon::FileBased].filename); } QSet<QString> current_set = current_list.toSet(); QSet<QString> to_remove = current_set; to_remove -= new_set; QSet<QString> to_add = new_set; to_add -= current_set; for (auto remove : to_remove) { QLOG_INFO() << "Removing " << remove; QFileInfo rmfile(remove); QString key = rmfile.baseName(); int idx = getIconIndex(key); if (idx == -1) continue; icons[idx].remove(MMCIcon::FileBased); if (icons[idx].type() == MMCIcon::ToBeDeleted) { beginRemoveRows(QModelIndex(), idx, idx); icons.remove(idx); reindex(); endRemoveRows(); } else { dataChanged(index(idx), index(idx)); } m_watcher->removePath(remove); emit iconUpdated(key); } for (auto add : to_add) { QLOG_INFO() << "Adding " << add; QFileInfo addfile(add); QString key = addfile.baseName(); if (addIcon(key, QString(), addfile.filePath(), MMCIcon::FileBased)) { m_watcher->addPath(add); emit iconUpdated(key); } } }
void socketMode(tArvoreBB **tree, FILE **arq) { WSADATA wsaData; WSAStartup(MAKEWORD(2,2), &wsaData); SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); char buf[32] = {0}, op = 1; if(sock != INVALID_SOCKET) { struct sockaddr_in serv_addr = {0}; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(PORT); if(bind(sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr)) == 0) { int len; struct sockaddr_in cli_addr; SOCKET newsock; listen(sock, BACKLOG); len = sizeof(struct sockaddr_in); newsock = accept(sock, (struct sockaddr *) &cli_addr, &len); // if (newsock != INVALID_SOCKET) // printf("Nova conexao: %s:%d\n", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port)); while(op != 0) { if (newsock != INVALID_SOCKET) { while(recv(newsock, buf, sizeof(buf)-1, 0) <=0); //printf("received: %s\n", buf); op = buf[strlen(buf)-1] - 48; tfunc func; char buffer[30]={0}; strncpy(buffer, buf, 3); buffer[3] = '\0'; func.mat = atoi(buffer); strncpy(func.nome,buf+3,20); func.nome[20] = '\0'; strncpy(buffer,buf+23,7); buffer[7] = '\0'; func.sal = atof(buffer); switch(op) { case 1: { insertFunc(*arq, tree, func); break; } case 2: { alterSalary(arq, *tree, func.mat, func.sal); break; } case 3: { deleteFunc(tree,func.mat); break; } case 4: { listFunc(*arq, *tree, func.mat); break; } case 5: listAll(*arq, *tree); break; case 6: listStruct(*tree); break; case 7: reindex(arq, tree); break; case 8: deleteAll(tree, arq); break; } } else { printf("Erro ao conectar\n"); } } } else { printf("Erro no bind()\n"); } } }
int main (int argc, char *argv[]) { /* Vars */ GtkWidget *vbox; GtkWidget *window; GtkWidget *table; GtkWidget *label; GtkWidget *entry; GtkWidget *button; GtkWidget* scrolled; GtkWidget *menubar; GtkWidget *filemenu; GtkWidget *file; GtkWidget *quit; GtkWidget *reindexer; /* Set default directory to index */ indexdir = "."; /* Run the indexer */ reindex(NULL, NULL); /* Create the search objects */ createSearch(); /* Make the GUI */ gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); initialize_window(window); /* Create a 10x5 table */ table = gtk_table_new (10, 5, FALSE); gtk_container_add (GTK_CONTAINER (window), table); /* create a new label. */ label = gtk_label_new ("Search Terms:" ); gtk_table_set_homogeneous(GTK_TABLE (table), TRUE); gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2); entry = gtk_entry_new (); gtk_entry_set_max_length (GTK_ENTRY (entry),1000); gtk_table_attach_defaults (GTK_TABLE (table), entry, 1, 3, 1, 2); button = gtk_button_new_with_label ("OR Search"); gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (orsearch), (gpointer) entry); gtk_table_attach_defaults (GTK_TABLE (table), button, 3, 4, 1, 2); button = gtk_button_new_with_label ("AND Search"); gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (andsearch), (gpointer) entry); gtk_table_attach_defaults (GTK_TABLE (table), button, 4, 5, 1, 2); textview = gtk_text_view_new(); gtk_text_view_set_editable( GTK_TEXT_VIEW (textview), 0); gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (textview), 0); scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_container_add (GTK_CONTAINER (scrolled), textview); gtk_table_attach_defaults (GTK_TABLE (table), scrolled, 0, 5, 2, 10); vbox = gtk_vbox_new(FALSE, 0); gtk_table_attach_defaults (GTK_TABLE (table), vbox, 0, 5, 0, 1); menubar = gtk_menu_bar_new(); filemenu = gtk_menu_new(); file = gtk_menu_item_new_with_label("File"); reindexer = gtk_menu_item_new_with_label("Reindex"); gtk_signal_connect (GTK_OBJECT (reindexer), "activate", G_CALLBACK(reindex), NULL); quit = gtk_menu_item_new_with_label("Quit"); gtk_signal_connect (GTK_OBJECT (quit), "activate", G_CALLBACK(destroy), NULL); gtk_menu_item_set_submenu(GTK_MENU_ITEM(file), filemenu); gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), reindexer); gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), quit); gtk_menu_shell_append(GTK_MENU_SHELL(menubar), file); gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 3); gtk_widget_show_all(window); gtk_main (); return 0; }
void ChangeJournalWatcher::update(bool force_write, std::wstring vol_str) { char buffer[BUF_LEN]; bool started_transaction=false; for(std::map<std::wstring, SChangeJournal>::iterator it=wdirs.begin();it!=wdirs.end();++it) { if(!vol_str.empty() && it->first!=vol_str) continue; if(!indexing_in_progress) { std::vector<UsnInt> jd=getJournalData(it->first); for(size_t i=0;i<jd.size();++i) { updateWithUsn(it->first, it->second, &jd[i]); it->second.last_record=jd[i].NextUsn; } deleteJournalData(it->first); } if(it->second.last_record_update) { if(started_transaction==false) { started_transaction=true; db->BeginTransaction(); } it->second.last_record_update=false; q_update_lastusn->Bind(it->second.last_record); q_update_lastusn->Bind(it->first); q_update_lastusn->Write(); q_update_lastusn->Reset(); } USN startUsn=it->second.last_record; unsigned int update_bytes=0; bool remove_it=false; bool c=true; while(c) { c=false; READ_USN_JOURNAL_DATA data; data.StartUsn=it->second.last_record; data.ReasonMask=0xFFFFFFFF;//USN_REASON_DATA_EXTEND|USN_REASON_BASIC_INFO_CHANGE|USN_REASON_DATA_OVERWRITE|USN_REASON_DATA_TRUNCATION|USN_REASON_EA_CHANGE|USN_REASON_FILE_CREATE|USN_REASON_FILE_DELETE|USN_REASON_HARD_LINK_CHANGE|USN_REASON_NAMED_DATA_EXTEND|USN_REASON_NAMED_DATA_OVERWRITE|USN_REASON_NAMED_DATA_TRUNCATION|USN_REASON_RENAME_NEW_NAME|USN_REASON_REPARSE_POINT_CHANGE|USN_REASON_SECURITY_CHANGE|USN_REASON_STREAM_CHANGE; data.ReturnOnlyOnClose=0; data.Timeout=0; data.BytesToWaitFor=0; data.UsnJournalID=it->second.journal_id; DWORD read; memset(buffer, 0, BUF_LEN); BOOL b=DeviceIoControl(it->second.hVolume, FSCTL_READ_USN_JOURNAL, &data, sizeof(READ_USN_JOURNAL_DATA), buffer, BUF_LEN, &read, NULL); if(b!=0) { DWORD dwRetBytes=read-sizeof(USN); PUSN_RECORD TUsnRecord = (PUSN_RECORD)(((PUCHAR)buffer) + sizeof(USN)); if(dwRetBytes>0) { c=true; } else if(update_bytes>5000) { update_bytes=0; /*q_update_lastusn->Bind(it->second.last_record); q_update_lastusn->Bind(it->first); q_update_lastusn->Write(); q_update_lastusn->Reset(); startUsn=it->second.last_record;*/ } USN nextUsn=*(USN *)&buffer; while(dwRetBytes>0) { std::string fn; fn.resize(TUsnRecord->FileNameLength); memcpy(&fn[0], (char*)TUsnRecord->FileName, TUsnRecord->FileNameLength); dwRetBytes-=TUsnRecord->RecordLength; update_bytes+=TUsnRecord->RecordLength; if(!indexing_in_progress) { UsnInt UsnRecord; UsnRecord.Filename=Server->ConvertFromUTF16(fn); UsnRecord.FileReferenceNumber=TUsnRecord->FileReferenceNumber; UsnRecord.ParentFileReferenceNumber=TUsnRecord->ParentFileReferenceNumber; UsnRecord.Reason=TUsnRecord->Reason; UsnRecord.Usn=TUsnRecord->Usn; UsnRecord.attributes=TUsnRecord->FileAttributes; if(UsnRecord.Filename!=L"backup_client.db" && UsnRecord.Filename!=L"backup_client.db-journal") { if(started_transaction==false) { started_transaction=true; db->BeginTransaction(); } updateWithUsn(it->first, it->second, &UsnRecord); } } else { if(fn!="backup_client.db" && fn!="backup_client.db-journal") { saveJournalData(it->second.journal_id, it->first, TUsnRecord, nextUsn); } } TUsnRecord = (PUSN_RECORD)(((PCHAR)TUsnRecord) + TUsnRecord->RecordLength); } it->second.last_record=nextUsn; } else { DWORD err=GetLastError(); if(err==ERROR_JOURNAL_ENTRY_DELETED) { Server->Log(L"Error for Volume '"+it->first+L"': Journal entry deleted", LL_ERROR); USN_JOURNAL_DATA data; DWORD r_bytes; BOOL bv=DeviceIoControl(it->second.hVolume, FSCTL_QUERY_USN_JOURNAL, NULL, 0, &data, sizeof(USN_JOURNAL_DATA), &r_bytes, NULL); if(indexing_in_progress==false) { if(bv!=0 ) { it->second.last_record=data.NextUsn; Server->Log(L"Reindexing Volume '"+it->first+L"'", LL_ERROR); if(started_transaction) { started_transaction=false; db->EndTransaction(); } reindex(it->second.rid, it->first, &it->second); return; } else if(indexing_in_progress==false) { Server->Log("Journal Data not acessible. Errorcode: "+nconvert((int)GetLastError()), LL_ERROR); has_error=true; error_dirs.push_back(it->first); } } else { if(indexing_volume==it->first) { Server->Log("Access error during indexing. Change journal too small?", LL_ERROR); has_error=true; error_dirs.push_back(it->first); } else { Server->Log("Journal Data deleted on nonindexing volume.", LL_ERROR); has_error=true; error_dirs.push_back(it->first); deleteJournalId(it->first); CloseHandle(it->second.hVolume); remove_it=true; } } listener->On_ResetAll(it->first); } else { Server->Log(L"Unknown error for Volume '"+it->first+L"' - update err="+convert((int)err), LL_ERROR); listener->On_ResetAll(it->first); deleteJournalId(it->first); has_error=true; CloseHandle(it->second.hVolume); remove_it=true; error_dirs.push_back(it->first); } } } if(startUsn!=it->second.last_record) { it->second.last_record_update=true; } if(force_write) { q_update_lastusn->Bind(it->second.last_record); q_update_lastusn->Bind(it->first); q_update_lastusn->Write(); q_update_lastusn->Reset(); } if(remove_it) { wdirs.erase(it); break; } } if(started_transaction) { db->EndTransaction(); } }
void ChangeJournalWatcher::watchDir(const std::wstring &dir) { WCHAR volume_path[MAX_PATH]; BOOL ok = GetVolumePathNameW(dir.c_str(), volume_path, MAX_PATH); if(!ok) { Server->Log("GetVolumePathName(dir, volume_path, MAX_PATH) failed in ChangeJournalWatcher::watchDir", LL_ERROR); listener->On_ResetAll(dir); has_error=true; error_dirs.push_back(dir); return; } std::wstring vol=volume_path; if(vol.size()>0) { if(vol[vol.size()-1]=='\\') { vol.erase(vol.size()-1,1); } } std::map<std::wstring, SChangeJournal>::iterator it=wdirs.find(vol); if(it!=wdirs.end()) { it->second.path.push_back(dir); return; } bool do_index=false; _i64 rid=hasRoot(vol); if(rid==-1) { listener->On_ResetAll(vol); do_index=true; rid=addRoot(vol); setIndexDone(vol, 0); } HANDLE hVolume=CreateFileW((L"\\\\.\\"+vol).c_str(), GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hVolume==INVALID_HANDLE_VALUE) { Server->Log(L"CreateFile of volume '"+vol+L"' failed. - watchDir", LL_ERROR); listener->On_ResetAll(vol); error_dirs.push_back(vol); CloseHandle(hVolume); has_error=true; return; } USN_JOURNAL_DATA data; DWORD r_bytes; BOOL b=DeviceIoControl(hVolume, FSCTL_QUERY_USN_JOURNAL, NULL, 0, &data, sizeof(USN_JOURNAL_DATA), &r_bytes, NULL); if(b==0) { DWORD err=GetLastError(); if(err==ERROR_INVALID_FUNCTION) { Server->Log(L"Change Journals not supported for Volume '"+vol+L"'", LL_ERROR); listener->On_ResetAll(vol); error_dirs.push_back(vol); CloseHandle(hVolume); has_error=true; return; } else if(err==ERROR_JOURNAL_DELETE_IN_PROGRESS) { Server->Log(L"Change Journals for Volume '"+vol+L"' is being deleted", LL_ERROR); listener->On_ResetAll(vol); error_dirs.push_back(vol); CloseHandle(hVolume); has_error=true; return; } else if(err==ERROR_JOURNAL_NOT_ACTIVE) { CREATE_USN_JOURNAL_DATA dat; dat.AllocationDelta=10485760; //10 MB dat.MaximumSize=73400320; // 70 MB DWORD bret; BOOL r=DeviceIoControl(hVolume, FSCTL_CREATE_USN_JOURNAL, &dat, sizeof(CREATE_USN_JOURNAL_DATA), NULL, 0, &bret, NULL); if(r==0) { Server->Log(L"Error creating change journal for Volume '"+vol+L"'", LL_ERROR); listener->On_ResetAll(vol); error_dirs.push_back(vol); CloseHandle(hVolume); has_error=true; return; } b=DeviceIoControl(hVolume, FSCTL_QUERY_USN_JOURNAL, NULL, 0, &data, sizeof(USN_JOURNAL_DATA), &r_bytes, NULL); if(b==0) { Server->Log(L"Unknown error for Volume '"+vol+L"' after creation - watchDir", LL_ERROR); listener->On_ResetAll(vol); error_dirs.push_back(vol); CloseHandle(hVolume); has_error=true; return; } } else { Server->Log(L"Unknown error for Volume '"+vol+L"' - watchDir ec: "+convert((int)err), LL_ERROR); listener->On_ResetAll(vol); error_dirs.push_back(vol); CloseHandle(hVolume); has_error=true; return; } } SDeviceInfo info=getDeviceInfo(vol); if(info.has_info) { if(info.journal_id!=data.UsnJournalID) { Server->Log(L"Journal id for '"+vol+L"' wrong - reindexing", LL_WARNING); listener->On_ResetAll(vol); do_index=true; setIndexDone(vol, 0); info.last_record=data.NextUsn; q_update_journal_id->Bind((_i64)data.UsnJournalID); q_update_journal_id->Bind(vol); q_update_journal_id->Write(); q_update_journal_id->Reset(); } bool needs_reindex=false; if( do_index==false && (info.last_record<data.FirstUsn || info.last_record>data.NextUsn) ) { Server->Log(L"Last record not readable at '"+vol+L"' - reindexing", LL_WARNING); needs_reindex=true; } if( do_index==false && data.NextUsn-info.last_record>usn_reindex_num ) { Server->Log(L"There are "+convert(data.NextUsn-info.last_record)+L" new USN entries at '"+vol+L"' - reindexing", LL_WARNING); needs_reindex=true; } if(needs_reindex) { listener->On_ResetAll(vol); do_index=true; setIndexDone(vol, 0); info.last_record=data.NextUsn; } if(do_index==false && info.index_done==0) { Server->Log(L"Indexing was not finished at '"+vol+L"' - reindexing", LL_WARNING); do_index=true; setIndexDone(vol, 0); info.last_record=data.NextUsn; } } else { listener->On_ResetAll(vol); Server->Log(L"Info not found at '"+vol+L"' - reindexing", LL_WARNING); do_index=true; } SChangeJournal cj; cj.journal_id=data.UsnJournalID; if(!info.has_info) cj.last_record=data.NextUsn; else cj.last_record=info.last_record; cj.path.push_back(dir); cj.hVolume=hVolume; cj.rid=rid; cj.last_record_update=false; cj.vol_str=vol; if(!info.has_info) { q_add_journal->Bind((_i64)data.UsnJournalID); q_add_journal->Bind(vol); q_add_journal->Bind(cj.last_record); q_add_journal->Write(); q_add_journal->Reset(); setIndexDone(vol, 0); } wdirs.insert(std::pair<std::wstring, SChangeJournal>(vol, cj) ); if(do_index) { reindex(rid, vol, &cj); Server->Log(L"Reindexing of '"+vol+L"' done.", LL_INFO); } }