turtle search is now working. Next task: update search gui

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@1078 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2009-03-15 22:45:40 +00:00
parent 148c918ae1
commit 7b84b125df
26 changed files with 2329 additions and 118 deletions

View file

@ -405,7 +405,7 @@ int FileIndexStore::SearchHash(std::string hash, std::list<FileDetail> &results)
}
int FileIndexStore::SearchKeywords(std::list<std::string> keywords, std::list<FileDetail> &results) const
int FileIndexStore::SearchKeywords(std::list<std::string> keywords, std::list<FileDetail> &results,uint32_t flags) const
{
lockData();
std::map<RsPeerId, FileIndex *>::const_iterator pit;
@ -417,49 +417,52 @@ int FileIndexStore::SearchKeywords(std::list<std::string> keywords, std::list<Fi
#ifdef FIS_DEBUG
std::cerr << "FileIndexStore::SearchKeywords()" << std::endl;
#endif
for(pit = indices.begin(); pit != indices.end(); pit++)
{
firesults.clear();
(pit->second)->searchTerms(keywords, firesults);
/* translate results */
for(rit = firesults.begin(); rit != firesults.end(); rit++)
if(flags & DIR_FLAGS_REMOTE)
for(pit = indices.begin(); pit != indices.end(); pit++)
{
FileDetail fd;
fd.id = pit->first;
fd.name = (*rit)->name;
fd.hash = (*rit)->hash;
fd.path = ""; /* TODO */
fd.size = (*rit)->size;
fd.age = now - (*rit)->modtime;
fd.rank = (*rit)->pop;
firesults.clear();
(pit->second)->searchTerms(keywords, firesults);
/* translate results */
for(rit = firesults.begin(); rit != firesults.end(); rit++)
{
FileDetail fd;
fd.id = pit->first;
fd.name = (*rit)->name;
fd.hash = (*rit)->hash;
fd.path = ""; /* TODO */
fd.size = (*rit)->size;
fd.age = now - (*rit)->modtime;
fd.rank = (*rit)->pop;
results.push_back(fd);
}
results.push_back(fd);
}
}
if (localindex)
{
firesults.clear();
localindex->searchTerms(keywords, firesults);
/* translate results */
for(rit = firesults.begin(); rit != firesults.end(); rit++)
if(flags & DIR_FLAGS_LOCAL)
if (localindex)
{
FileDetail fd;
fd.id = "Local"; //localId;
fd.name = (*rit)->name;
fd.hash = (*rit)->hash;
fd.path = ""; /* TODO */
fd.size = (*rit)->size;
fd.age = now - (*rit)->modtime;
fd.rank = (*rit)->pop;
firesults.clear();
localindex->searchTerms(keywords, firesults);
/* translate results */
for(rit = firesults.begin(); rit != firesults.end(); rit++)
{
FileDetail fd;
fd.id = "Local"; //localId;
fd.name = (*rit)->name;
fd.hash = (*rit)->hash;
fd.path = ""; /* TODO */
fd.size = (*rit)->size;
fd.age = now - (*rit)->modtime;
fd.rank = (*rit)->pop;
results.push_back(fd);
}
results.push_back(fd);
}
}
unlockData();
return results.size();
}

View file

@ -74,7 +74,7 @@ virtual int loadCache(const CacheData &data); /* actual load, once data availa
int SearchHash(std::string hash, std::list<FileDetail> &results) const;
/* Search Interface - For Search Interface */
int SearchKeywords(std::list<std::string> terms, std::list<FileDetail> &results) const;
int SearchKeywords(std::list<std::string> terms, std::list<FileDetail> &results,uint32_t flags) const;
/* Search Interface - for Adv Search Interface */
int searchBoolExp(Expression * exp, std::list<FileDetail> &results) const;

View file

@ -383,7 +383,7 @@ int ftServer::RequestDirDetails(void *ref, DirDetails &details, uint32_t flags)
/***************************************************************/
int ftServer::SearchKeywords(std::list<std::string> keywords, std::list<FileDetail> &results)
int ftServer::SearchKeywords(std::list<std::string> keywords, std::list<FileDetail> &results,uint32_t flags)
{
#ifdef SERVER_DEBUG
std::cerr << "ftServer::SearchKeywords()";
@ -396,7 +396,7 @@ int ftServer::SearchKeywords(std::list<std::string> keywords, std::list<FileDeta
}
#endif
return mFiStore->SearchKeywords(keywords, results);
return mFiStore->SearchKeywords(keywords, results,flags);
}
int ftServer::SearchBoolExp(Expression * exp, std::list<FileDetail> &results)

View file

@ -140,7 +140,7 @@ virtual bool ExtraFileMove(std::string fname, std::string hash, uint64_t size,
virtual int RequestDirDetails(std::string uid, std::string path, DirDetails &details);
virtual int RequestDirDetails(void *ref, DirDetails &details, uint32_t flags);
virtual int SearchKeywords(std::list<std::string> keywords, std::list<FileDetail> &results);
virtual int SearchKeywords(std::list<std::string> keywords, std::list<FileDetail> &results,uint32_t flags);
virtual int SearchBoolExp(Expression * exp, std::list<FileDetail> &results);
/***

View file

@ -130,7 +130,7 @@ virtual bool ExtraFileMove(std::string fname, std::string hash, uint64_t size,
virtual int RequestDirDetails(std::string uid, std::string path, DirDetails &details) = 0;
virtual int RequestDirDetails(void *ref, DirDetails &details, uint32_t flags) = 0;
virtual int SearchKeywords(std::list<std::string> keywords, std::list<FileDetail> &results) = 0;
virtual int SearchKeywords(std::list<std::string> keywords, std::list<FileDetail> &results,uint32_t flags) = 0;
virtual int SearchBoolExp(Expression * exp, std::list<FileDetail> &results) = 0;
/***

View file

@ -35,6 +35,9 @@ class NotifyBase;
class RsIface;
class RsControl;
class RsInit;
#ifdef TURTLE_HOPPING
struct TurtleFileInfo ;
#endif
/* declare single RsIface for everyone to use! */
@ -200,6 +203,9 @@ class NotifyBase
virtual void notifyErrorMsg(int list, int sev, std::string msg) { (void) list; (void) sev; (void) msg; return; }
virtual void notifyChat() { return; }
virtual void notifyHashingInfo(std::string fileinfo) { (void)fileinfo; return ; }
#ifdef TURTLE_HOPPING
virtual void notifyTurtleSearchResult(uint32_t search_id,const std::list<TurtleFileInfo>& files) { (void)files; }
#endif
};
const int NOTIFY_LIST_NEIGHBOURS = 1;

View file

@ -35,6 +35,16 @@ extern RsTurtle *rsTurtle ;
typedef uint32_t TurtleRequestId ;
// This is the structure used to send back results of the turtle search
// to the notifyBase class.
struct TurtleFileInfo
{
std::string hash ;
std::string name ;
uint64_t size ;
};
// Interface class for turtle hopping.
//
// This class mainly interacts with the turtle router, that is responsible

View file

@ -252,12 +252,12 @@ int p3Files::RequestDirDetails(void *ref, DirDetails &details, uint32_t flags)
}
int p3Files::SearchKeywords(std::list<std::string> keywords, std::list<FileDetail> &results)
int p3Files::SearchKeywords(std::list<std::string> keywords, std::list<FileDetail> &results,uint32_t flags)
{
lockRsCore(); /* LOCK */
/* call to filedexmServer */
int val = mServer->SearchKeywords(keywords, results);
int val = mServer->SearchKeywords(keywords, results,flags);
unlockRsCore(); /* UNLOCK */

View file

@ -393,10 +393,9 @@ int filedexserver::RequestDirDetails(void *ref, DirDetails &details, uint32_t fl
return fiStore->RequestDirDetails(ref, details, flags);
}
int filedexserver::SearchKeywords(std::list<std::string> keywords,
std::list<FileDetail> &results)
int filedexserver::SearchKeywords(std::list<std::string> keywords,std::list<FileDetail> &results,uint32_t flags)
{
return fiStore->SearchKeywords(keywords, results);
return fiStore->SearchKeywords(keywords, results,flags);
}
int filedexserver::SearchBoolExp(Expression * exp, std::list<FileDetail> &results)

View file

@ -27,6 +27,7 @@
#include "rsiface/rsiface.h"
#include "rsiface/rspeers.h"
#include "rsiface/rsfiles.h"
#include "pqi/p3authmgr.h"
#include "pqi/p3connmgr.h"
@ -54,6 +55,7 @@ p3turtle::p3turtle(p3ConnectMgr *cm) :p3Service(RS_SERVICE_TYPE_TURTLE), mConnMg
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
srand48(time(NULL)) ;
addSerialType(new RsTurtleSerialiser());
}
@ -94,10 +96,20 @@ TurtleRequestId p3turtle::turtleSearch(const std::string& string_to_match)
TurtleRequestId id = generateRandomRequestId() ;
// form a request packet
// Form a request packet that simulates a request from us.
//
RsTurtleSearchRequestItem *item = new RsTurtleSearchRequestItem ;
#ifdef P3TURTLE_DEBUG
std::cerr << "performing search. OwnId = " << mConnMgr->getOwnId() << std::endl ;
#endif
while(mConnMgr->getOwnId() == "")
{
std::cerr << "... waitting for connect manager to form own id." << std::endl ;
sleep(1) ;
}
item->PeerId(mConnMgr->getOwnId()) ;
item->match_string = string_to_match ;
item->request_id = id ;
item->depth = 0 ;
@ -122,8 +134,8 @@ void p3turtle::turtleDownload(const std::string& file_hash)
int p3turtle::handleIncoming()
{
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle::handleIncoming()";
std::cerr << std::endl;
// std::cerr << "p3turtle::handleIncoming()";
// std::cerr << std::endl;
#endif
int nhandled = 0;
@ -160,7 +172,7 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
// - If the item destimation is
#ifdef P3TURTLE_DEBUG
std::cerr << "Received search request: " << std::endl ;
std::cerr << "Received search request from peer " << item->PeerId() << ": " << std::endl ;
item->print(std::cerr,0) ;
#endif
// If the item contains an already handled search request, give up. This
@ -186,7 +198,7 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
#ifdef P3TURTLE_DEBUG
std::cerr << " Request not from us. Performing local search" << std::endl ;
#endif
std::map<TurtleFileHash,TurtleFileName> result ;
std::list<TurtleFileInfo> result ;
performLocalSearch(item->match_string,result) ;
if(!result.empty())
@ -203,7 +215,7 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
res_item->PeerId(item->PeerId()) ; // send back to the same guy
#ifdef P3TURTLE_DEBUG
std::cerr << " " << result.size() << " matches found. Sending back to origin." << std::endl ;
std::cerr << " " << result.size() << " matches found. Sending back to origin (" << res_item->PeerId() << ")." << std::endl ;
#endif
sendItem(res_item) ;
}
@ -215,6 +227,9 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
{
std::list<std::string> onlineIds ;
mConnMgr->getOnlineList(onlineIds);
#ifdef P3TURTLE_DEBUG
std::cerr << " Looking for online peers" << std::endl ;
#endif
for(std::list<std::string>::const_iterator it(onlineIds.begin());it!=onlineIds.end();++it)
if(*it != item->PeerId())
@ -259,6 +274,8 @@ void p3turtle::handleSearchResult(RsTurtleSearchResultItem *item)
// Is this result's target actually ours ?
++(item->depth) ; // increase depth
if(it->second == mConnMgr->getOwnId())
returnSearchResult(item) ; // Yes, so send upward.
else
@ -268,8 +285,6 @@ void p3turtle::handleSearchResult(RsTurtleSearchResultItem *item)
#endif
RsTurtleSearchResultItem *fwd_item = new RsTurtleSearchResultItem(*item) ; // copy the item
++(fwd_item->depth) ; // increase depth
// normally here, we should setup the forward adress, so that the owner's of the files found can be further reached by a tunnel.
fwd_item->PeerId(it->second) ;
@ -281,6 +296,7 @@ void p3turtle::handleSearchResult(RsTurtleSearchResultItem *item)
std::ostream& RsTurtleSearchRequestItem::print(std::ostream& o, uint16_t)
{
o << "Search request:" << std::endl ;
o << " direct origin: \"" << PeerId() << "\"" << std::endl ;
o << " match string: \"" << match_string << "\"" << std::endl ;
o << " Req. Id: " << request_id << std::endl ;
o << " Depth : " << depth << std::endl ;
@ -292,13 +308,13 @@ std::ostream& RsTurtleSearchResultItem::print(std::ostream& o, uint16_t)
{
o << "Search result:" << std::endl ;
o << " Peer id: " << peer_id << std::endl ;
o << " Peer id: " << PeerId() << std::endl ;
o << " Depth : " << depth << std::endl ;
o << " Req. Id: " << request_id << std::endl ;
o << " Files:" << std::endl ;
for(std::map<TurtleFileHash,TurtleFileName>::const_iterator it(result.begin());it!=result.end();++it)
o << " " << it->first << " " << it->second << std::endl ;
for(std::list<TurtleFileInfo>::const_iterator it(result.begin());it!=result.end();++it)
o << " " << it->hash << " " << it->size << " " << it->name << std::endl ;
return o ;
}
@ -307,8 +323,11 @@ void p3turtle::returnSearchResult(RsTurtleSearchResultItem *item)
{
// just cout for now, but it should be notified to the gui
std::cerr << "Received result for search request: " << std::endl ;
item->print(std::cerr,0) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " Returning result for search request " << item->request_id << " upwards." << std::endl ;
#endif
rsicontrol->getNotify().notifyTurtleSearchResult(item->request_id,item->result) ;
}
/************* from pqiMonitor *******************/
@ -350,6 +369,61 @@ uint32_t RsTurtleSearchRequestItem::serial_size()
return s ;
}
uint32_t RsTurtleSearchResultItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // search request id
s += 2 ; // depth
s += 4 ; // number of results
for(std::list<TurtleFileInfo>::const_iterator it(result.begin());it!=result.end();++it)
{
s += 8 ; // file size
s += GetTlvStringSize(it->hash) ; // file hash
s += GetTlvStringSize(it->name) ; // file name
}
return s ;
}
RsItem *RsTurtleSerialiser::deserialise(void *data, uint32_t *size)
{
// look what we have...
/* get the type */
uint32_t rstype = getRsItemId(data);
#ifdef P3TURTLE_DEBUG
std::cerr << "p3turtle: deserialising packet: " << std::endl ;
#endif
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_TYPE_TURTLE != getRsItemService(rstype)))
{
#ifdef P3TURTLE_DEBUG
std::cerr << " Wrong type !!" << std::endl ;
#endif
return NULL; /* wrong type */
}
try
{
switch(getRsItemSubType(rstype))
{
case RS_TURTLE_SUBTYPE_SEARCH_REQUEST: return new RsTurtleSearchRequestItem(data,*size) ;
case RS_TURTLE_SUBTYPE_SEARCH_RESULT: return new RsTurtleSearchResultItem(data,*size) ;
default:
std::cerr << "Unknown packet type in RsTurtle!" << std::endl ;
return NULL ;
}
}
catch(std::exception& e)
{
std::cerr << "Exception raised: " << e.what() << std::endl ;
return NULL ;
}
}
bool RsTurtleSearchRequestItem::serialize(void *data,uint32_t& pktsize)
{
uint32_t tlvsize = serial_size();
@ -384,21 +458,24 @@ bool RsTurtleSearchRequestItem::serialize(void *data,uint32_t& pktsize)
return ok;
}
uint32_t RsTurtleSearchResultItem::serial_size()
RsTurtleSearchRequestItem::RsTurtleSearchRequestItem(void *data,uint32_t pktsize)
: RsTurtleItem(RS_TURTLE_SUBTYPE_SEARCH_REQUEST)
{
uint32_t s = 0 ;
#ifdef P3TURTLE_DEBUG
std::cerr << " type = search request" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
uint32_t rssize = getRsItemSize(data);
bool ok = true ;
s += 8 ; // header
s += 4 ; // search request id
s += 4 ; // number of results
ok &= GetTlvString(data, pktsize, &offset, TLV_TYPE_STR_VALUE, match_string); // file hash
ok &= getRawUInt32(data, pktsize, &offset, &request_id);
ok &= getRawUInt16(data, pktsize, &offset, &depth);
for(std::map<TurtleFileHash,TurtleFileName>::const_iterator it(result.begin());it!=result.end();++it)
{
s += GetTlvStringSize(it->first) ; // file hash
s += GetTlvStringSize(it->second) ; // file name
}
return s ;
if (offset != rssize)
throw std::runtime_error("Size error while deserializing.") ;
if (!ok)
throw std::runtime_error("Unknown error while deserializing.") ;
}
bool RsTurtleSearchResultItem::serialize(void *data,uint32_t& pktsize)
@ -421,12 +498,14 @@ bool RsTurtleSearchResultItem::serialize(void *data,uint32_t& pktsize)
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, request_id);
ok &= setRawUInt16(data, tlvsize, &offset, depth);
ok &= setRawUInt32(data, tlvsize, &offset, result.size());
for(std::map<TurtleFileHash,TurtleFileName>::const_iterator it(result.begin());it!=result.end();++it)
for(std::list<TurtleFileInfo>::const_iterator it(result.begin());it!=result.end();++it)
{
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_HASH_SHA1, it->first); // file hash
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, it->second); // file name
ok &= setRawUInt64(data, tlvsize, &offset, it->size); // file size
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_HASH_SHA1, it->hash); // file hash
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, it->name); // file name
}
if (offset != tlvsize)
@ -438,35 +517,15 @@ bool RsTurtleSearchResultItem::serialize(void *data,uint32_t& pktsize)
}
return ok;
}
RsItem *RsTurtleSerialiser::deserialise(void *data, uint32_t *size)
{
// look what we have...
/* get the type */
uint32_t rstype = getRsItemId(data);
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_TYPE_TURTLE != getRsItemService(rstype)))
{
return NULL; /* wrong type */
}
switch(getRsItemSubType(rstype))
{
case RS_TURTLE_SUBTYPE_SEARCH_REQUEST: return new RsTurtleSearchResultItem(data,*size) ;
case RS_TURTLE_SUBTYPE_SEARCH_RESULT: return new RsTurtleSearchResultItem(data,*size) ;
default:
std::cerr << "Unknown packet type in RsTurtle!" << std::endl ;
return NULL ;
}
}
RsTurtleSearchResultItem::RsTurtleSearchResultItem(void *data,uint32_t pktsize)
: RsTurtleItem(RS_TURTLE_SUBTYPE_SEARCH_RESULT)
{
#ifdef P3TURTLE_DEBUG
std::cerr << " type = search result" << std::endl ;
#endif
uint32_t offset = 8; // skip the header
uint32_t rssize = getRsItemSize(data);
@ -475,18 +534,23 @@ RsTurtleSearchResultItem::RsTurtleSearchResultItem(void *data,uint32_t pktsize)
bool ok = true ;
uint32_t s ;
ok &= getRawUInt32(data, pktsize, &offset, &request_id);
ok &= getRawUInt16(data, pktsize, &offset, &depth);
ok &= getRawUInt32(data, pktsize, &offset, &s) ;
#ifdef P3TURTLE_DEBUG
std::cerr << " reuqest_id=" << request_id << ", depth=" << depth << ", s=" << s << std::endl ;
#endif
result.clear() ;
for(uint i=0;i<s;++i)
{
std::string hash,filename ;
TurtleFileInfo f ;
ok &= GetTlvString(data, pktsize, &offset, TLV_TYPE_STR_HASH_SHA1, hash); // file hash
ok &= GetTlvString(data, pktsize, &offset, TLV_TYPE_STR_NAME, filename); // file name
ok &= getRawUInt64(data, pktsize, &offset, &(f.size)); // file size
ok &= GetTlvString(data, pktsize, &offset, TLV_TYPE_STR_HASH_SHA1, f.hash); // file hash
ok &= GetTlvString(data, pktsize, &offset, TLV_TYPE_STR_NAME, f.name); // file name
result[hash]=filename ;
result.push_back(f) ;
}
if (offset != rssize)
@ -495,3 +559,29 @@ RsTurtleSearchResultItem::RsTurtleSearchResultItem(void *data,uint32_t pktsize)
throw std::runtime_error("Unknown error while deserializing.") ;
}
void p3turtle::performLocalSearch(const std::string& s,std::list<TurtleFileInfo>& result)
{
/* call to core */
std::list<FileDetail> initialResults;
std::list<std::string> words ;
// to do: split search string into words.
words.push_back(s) ;
// now, search!
rsFiles->SearchKeywords(words, initialResults,DIR_FLAGS_LOCAL);
result.clear() ;
for(std::list<FileDetail>::const_iterator it(initialResults.begin());it!=initialResults.end();++it)
{
TurtleFileInfo i ;
i.hash = it->hash ;
i.size = it->size ;
i.name = it->name ;
result.push_back(i) ;
}
}

View file

@ -86,7 +86,7 @@ class RsTurtleSearchResultItem: public RsTurtleItem
TurtleRequestId request_id ; // randomly generated request id.
std::map<TurtleFileHash,TurtleFileName> result ;
std::list<TurtleFileInfo> result ;
virtual std::ostream& print(std::ostream& o, uint16_t) ;
protected:
@ -175,7 +175,7 @@ class p3turtle: public p3Service, public pqiMonitor, public RsTurtle
// int handleOutgoing();
// Performs a search calling local cache and search structure.
void performLocalSearch(const std::string& s,std::map<TurtleFileHash,TurtleFileName>& result) {}
void performLocalSearch(const std::string& s,std::list<TurtleFileInfo>& result) ;
void handleSearchRequest(RsTurtleSearchRequestItem *item);
void handleSearchResult(RsTurtleSearchResultItem *item);