コード例 #1
0
ファイル: dtree.c プロジェクト: Ankit77/cmusphinx
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;
    }
}
コード例 #2
0
ファイル: BasicGroupBigraph.cpp プロジェクト: cbielow/Fido
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();
}
コード例 #3
0
/**
 * 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);
}
コード例 #4
0
/**
 * 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);
}
コード例 #5
0
//------------------------------------------------------------------------------
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;
}
コード例 #6
0
/**
 * 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));
}
コード例 #7
0
/**
 * 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);
}
コード例 #8
0
/**
 * 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);
}
コード例 #9
0
/**
 * 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);
}
コード例 #10
0
 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;
 }
コード例 #11
0
//------------------------------------------------------------------------------
void AssignmentRules::remove(int index)
{
	if (index >= 0 && index < rules.size())
	{
		AssignmentRule* rule = rules.takeAt(index);
		reindex();
		emit ruleRemoved(rule, index);
		delete rule;
	}
}
コード例 #12
0
//------------------------------------------------------------------------------
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);
}
コード例 #13
0
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);
}
コード例 #14
0
ファイル: SymbolTable.cpp プロジェクト: iangodin/lime
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;
}
コード例 #15
0
ファイル: SymbolTable.cpp プロジェクト: iangodin/lime
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;
}
コード例 #16
0
ファイル: starcomponent.cpp プロジェクト: Bugsbane/kstars
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 );
    }
}
コード例 #17
0
ファイル: compact_mutations.hpp プロジェクト: molpopgen/fwdpp
    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;
    }
コード例 #18
0
ファイル: hash_table.hpp プロジェクト: Shauwe/cpp-driver
void CaseInsensitiveHashTable<T>::resize(size_t new_capacity) {
  reset(new_capacity);
  reindex();
}
コード例 #19
0
ファイル: IconList.cpp プロジェクト: Mattia98/MultiMC5
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);
		}
	}
}
コード例 #20
0
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");
        }
    }
    
}
コード例 #21
0
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;
}
コード例 #22
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();
	}
}
コード例 #23
0
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);
	}
}