示例#1
0
SearchResultList ShareManager::search(SearchQuery&& query, size_t maxResults) noexcept {
	SearchResultList results;

	Lock l(cs);

	if(query.root != NULL) {
		auto i = tthIndex.find(*(query.root));
		if(i != tthIndex.end()) {
			results.push_back(new SearchResult(SearchResult::TYPE_FILE, i->second->getSize(),
				i->second->getParent()->getFullName() + i->second->getName(), i->second->tth));
			addHits(1);
		}
		return results;
	}

	for(auto& i: query.includeInit) {
		if(!bloom.match(i.getPattern()))
			return results;
	}

	for(auto& dir: directories) {
		dir.second->search(results, query, maxResults);

		if(results.size() >= maxResults) { return results; }
	}

	return results;
}
示例#2
0
void SearchResult::pickResults(SearchResultList& aResults, int aMaxCount) noexcept {
	if (static_cast<int>(aResults.size()) <= aMaxCount) {
		// we can pick all matches
	} else {
		// pick the best matches
		sort(aResults.begin(), aResults.end(), SearchResult::SpeedSortOrder());
		aResults.erase(aResults.begin() + aMaxCount, aResults.end());
	}
}
示例#3
0
void SearchResult::pickResults(SearchResultList& aResults, int pickedNum) {
	if (static_cast<int>(aResults.size()) <= pickedNum) {
		//we can pick all matches
	} else {
		//pick the best matches
		sort(aResults.begin(), aResults.end(), SearchResult::SpeedSortOrder());
		aResults.erase(aResults.begin()+pickedNum, aResults.end());
	}
}
示例#4
0
/**
 * Alright, the main point here is that when searching, a search string is most often found in
 * the filename, not directory name, so we want to make that case faster. Also, we want to
 * avoid changing StringLists unless we absolutely have to --> this should only be done if a string
 * has been matched in the directory name. This new stringlist should also be used in all descendants,
 * but not the parents...
 */
void ShareManager::Directory::search(SearchResultList& results, SearchQuery& query, size_t maxResults) const noexcept {
	if(query.isExcluded(name))
		return;

	// Find any matches in the directory name and removed matched terms from the query.
	StringSearch::List newTerms;

	for(auto& term: query.include) {
		if(term.match(name)) {
			if(!newTerms.empty()) {
				newTerms = query.include;
			}
			newTerms.erase(remove(newTerms.begin(), newTerms.end(), term), newTerms.end());
		}
	}

//	auto const old = query.include;

	if(!newTerms.empty()) {
		query.include = newTerms;
	}

	if(query.include.empty() && query.ext.empty() && query.gt == 0) {
		// We satisfied all the search words! Add the directory...
		/// @todo send the directory hash when we have one
		results.push_back(new SearchResult(SearchResult::TYPE_DIRECTORY, getSize(), getFullName(), TTHValue(string(39, 'A'))));
		ShareManager::getInstance()->addHits(1);
	}

	if(!query.isDirectory) {
		for(auto& i: files) {
			if(!i.tth) { continue; }

			// check the size
			if(!(i.getSize() >= query.gt)) {
				continue;
			} else if(!(i.getSize() <= query.lt)) {
				continue;
			}

			if(query.isExcluded(i.getName()))
				continue;

			// check if the name matches
			auto j = query.include.begin();
			for(; j != query.include.end() && j->match(i.getName()); ++j)
				;	// Empty
			if(j != query.include.end())
				continue;

			// check extensions
			if(!query.hasExt(i.getName()))
				continue;

			results.push_back(new SearchResult(SearchResult::TYPE_FILE, i.getSize(),
				getFullName() + i.getName(), (i.tth)));
			ShareManager::getInstance()->addHits(1);

			if(results.size() >= maxResults) { return; }
		}
	}

	for(auto& dir: directories) {
		dir.second->search(results, query, maxResults);

		if(results.size() >= maxResults) { return; }
	}
}
示例#5
0
int main( int /*argc*/, char** /*argv*/ )
{
  int fail = 0;
  std::string name;

  // -------
  {
    name = "fetch fields";
    Search::Query sq;
    Tag* t = sq.tag();
    if( !t || t->xml() != "<query xmlns='" + XMLNS_SEARCH + "'/>" )
    {
      ++fail;
      printf( "test '%s' failed\n", name.c_str() );
    }
    delete t;
  }

  // -------
  {
    name = "receive search fields";
    Tag* d = new Tag( "query" );
    d->setXmlns( XMLNS_SEARCH );
    new Tag( d, "instructions", "foobar" );
    new Tag( d, "first" );
    new Tag( d, "last" );
    new Tag( d, "email" );
    new Tag( d, "nick" );
    Search::Query sq( d );
    Tag* t = sq.tag();
    if( !t || t->xml() != "<query xmlns='" + XMLNS_SEARCH + "'>"
         "<instructions>foobar</instructions>"
         "<first/>"
         "<last/>"
         "<nick/>"
         "<email/>"
         "</query>"
         || sq.instructions() != "foobar"
         || sq.fields() != ( SearchFieldFirst | SearchFieldLast | SearchFieldNick | SearchFieldEmail ) )
    {
      ++fail;
      printf( "test '%s' failed\n", name.c_str() );
    }
    delete t;
    delete d;
  }

  // -------
  {
    name = "receive search form";
    Tag* d = new Tag( "query" );
    d->setXmlns( XMLNS_SEARCH );
    Tag* f = new Tag( d, "x" );
    f->setXmlns( XMLNS_X_DATA );
    f->addAttribute( "type", "form" );
    Search::Query sq( d );
    Tag* t = sq.tag();
    if( !t || t->xml() != "<query xmlns='" + XMLNS_SEARCH + "'>"
         "<x xmlns='" + XMLNS_X_DATA + "' type='form'/>"
         "</query>"
         || !sq.form() )
    {
      ++fail;
      printf( "test '%s' failed: %s\n", name.c_str(), t->xml().c_str() );
    }
    delete t;
    delete d;
  }

  // -------
  {
    name = "search by form";
    DataForm* form = new DataForm( TypeSubmit );
    Search::Query sq( form );
    Tag* t = sq.tag();
    if( !t || t->xml() != "<query xmlns='" + XMLNS_SEARCH + "'>"
       "<x xmlns='" + XMLNS_X_DATA + "' type='submit'/>"
       "</query>" )
    {
      ++fail;
      printf( "test '%s' failed\n", name.c_str() );
    }
    delete t;
  }

  // -------
  {
    name = "search by fields";
    SearchFieldStruct sfs( "first", "last", "nick", "email" );
    Search::Query sq( SearchFieldFirst | SearchFieldLast | SearchFieldNick | SearchFieldEmail, sfs );
    Tag* t = sq.tag();
    if( !t || t->xml() != "<query xmlns='" + XMLNS_SEARCH + "'>"
         "<first>first</first>"
         "<last>last</last>"
         "<nick>nick</nick>"
         "<email>email</email>"
         "</query>" )
    {
      ++fail;
      printf( "test '%s' failed\n", name.c_str() );
    }
    delete t;
  }

  // -------
  {
    name = "receive form result";
    Tag* d = new Tag( "query" );
    d->setXmlns( XMLNS_SEARCH );
    Tag* f = new Tag( d, "x" );
    f->setXmlns( XMLNS_X_DATA );
    f->addAttribute( "type", "result" );
    Search::Query sq( d );
    Tag* t = sq.tag();
    if( !t || t->xml() != "<query xmlns='" + XMLNS_SEARCH + "'>"
         "<x xmlns='" + XMLNS_X_DATA + "' type='result'/>"
         "</query>" )
    {
      ++fail;
      printf( "test '%s' failed\n", name.c_str() );
    }
    delete t;
    delete d;
  }

  // -------
  {
    name = "receive fields result";
    Tag* d = new Tag( "query" );
    d->setXmlns( XMLNS_SEARCH );
    Tag* i = new Tag( d, "item" );
    i->addAttribute( "jid", "foo@bar" );
    new Tag( i, "first", "first1" );
    new Tag( i, "last", "last1" );
    new Tag( i, "email", "email1" );
    new Tag( i, "nick", "nick1" );
    i = new Tag( d, "item" );
    i->addAttribute( "jid", "foo@bar2" );
    new Tag( i, "first", "first2" );
    new Tag( i, "last", "last2" );
    new Tag( i, "nick", "nick2" );
    new Tag( i, "email", "email2" );
    Search::Query sq( d );
    Tag* t = sq.tag();
    SearchResultList srl = sq.result();
    if( !t || t->xml() != "<query xmlns='" + XMLNS_SEARCH + "'>"
         "<item jid='foo@bar'>"
         "<first>first1</first>"
         "<last>last1</last>"
         "<nick>nick1</nick>"
         "<email>email1</email></item>"
         "<item jid='foo@bar2'>"
         "<first>first2</first>"
         "<last>last2</last>"
         "<nick>nick2</nick>"
         "<email>email2</email></item>"
         "</query>"
       || srl.size() != 2 )
    {
      ++fail;
      printf( "test '%s' failed: %s\n", name.c_str(), t->xml().c_str() );
    }
    delete t;
    delete d;
  }




  // -------
  name = "Search::Query/SEFactory test";
  StanzaExtensionFactory sef;
  sef.registerExtension( new Search::Query() );
  Tag* f = new Tag( "iq" );
  new Tag( f, "query", "xmlns", XMLNS_SEARCH );
  IQ iq( IQ::Get, JID() );
  sef.addExtensions( iq, f );
  const Search::Query* se = iq.findExtension<Search::Query>( ExtSearch );
  if( se == 0 )
  {
    ++fail;
    printf( "test '%s' failed\n", name.c_str() );
  }
  delete f;



  printf( "Search::Query: " );
  if( fail == 0 )
  {
    printf( "OK\n" );
    return 0;
  }
  else
  {
    printf( "%d test(s) failed\n", fail );
    return 1;
  }

}