open-source-search-engine/RequestTable.cpp

127 lines
3.6 KiB
C++
Raw Normal View History

2013-08-03 00:12:24 +04:00
#include "RequestTable.h"
RequestTable::RequestTable ( ) {
m_bufSize = 2 * HT_BUF_SIZE;
m_htable.set ( 50 , m_buf, m_bufSize, true ); // allow dup keys?
m_processHash = 0;
}
RequestTable::~RequestTable ( ) {
reset();
}
void RequestTable::reset ( ) {
m_htable.reset();
m_processHash = 0;
}
long RequestTable::addRequest ( long long requestHash , void *state2 ) {
// sanity check
if ( requestHash == 0 ){
char *xx = NULL; *xx = 0;
}
// check if we have the state already in the hashtable
/*long n = m_htable.getOccupiedSlotNum ( requestHash );
while ( m_htable.m_keys[n] ){
// count if same key
if ( m_htable.m_keys[n] == requestHash &&
m_htable.m_vals[n] == ( long ) state2 ){
char *xx = NULL; *xx = 0;
}
// advance n, wrapping if necessary
if ( ++n >= m_htable.m_numSlots ) n = 0;
}*/
// returns false and set g_errno on error, so we should return -1
if ( ! m_htable.addKey(requestHash, (long)state2) ) return -1;
//log ( "requesttable: added hash=%lli state2=%lx", requestHash,
// (long) state2 );
// count the slots that have this key
long n = m_htable.getOccupiedSlotNum ( requestHash );
// sanity check
if ( n < 0 ) { char *xx = NULL; *xx = 0; }
// return more than 1 if we are processing the same hash in gotReply
// gotReply shall call it eventually so no need to send udpServer
if ( m_processHash == requestHash )
return 2;
// count how many of our key are in the table, since we allow dup keys
long count = 0;
while ( m_htable.m_keys[n] ){
// count if same key
if ( m_htable.m_keys[n] == requestHash ) count++;
// advance n, wrapping if necessary
if ( ++n >= m_htable.m_numSlots ) n = 0;
}
/*if ( count == 1 )
log( "requesttable: hash=%lli state2=%lx is getting quality",
requestHash, (long) state2 );*/
return count;
}
void RequestTable::gotReply ( long long requestHash ,
char *reply ,
long replySize ,
void *state1 ,
void (*callback)( char *reply ,
long replySize ,
void *state1 ,
void *state2 )){
// sanity check.
// We should never get a call when we are processing the request.
if ( m_processHash != 0 ){
char *xx = NULL; *xx = 0;
}
// lock the hashtable by adding the current key
m_processHash = requestHash;
// save g_errno in case callback resets it
long saved = g_errno;
long n = m_htable.getOccupiedSlotNum ( requestHash );
while ( n >= 0 ) {
// restore it before returning
g_errno = saved;
// state2 is in the table
void *state2 = (void *)m_htable.m_vals[n];
// remove from table BEFORE calling callback in case callback
// somehow alters the table!
//m_htable.removeKey ( requestHash );
m_htable.removeSlot ( n );
/*log ( "requesttable: removed hash=%lli state1=%lx state2=%lx",
requestHash, (long) state1, (long) state2 );*/
// restore it before calling callback
g_errno = saved;
// otherwise, it is, call callback
callback ( reply , replySize , state1 , state2 );
// get next
n = m_htable.getOccupiedSlotNum ( requestHash );
}
// all done, unlock the hash table.
m_processHash = 0;
return;
}
void RequestTable::cancelRequest ( long long requestHash , void *state2 ) {
// there should only be one request for this request hash
long n = m_htable.getOccupiedSlotNum ( requestHash );
if ( n < 0 ){
char *xx = NULL; *xx = 0;
}
m_htable.removeKey(requestHash);
// check if there is any other remaining. core if there is
n = m_htable.getOccupiedSlotNum ( requestHash );
if ( n >= 0 ){
char *xx = NULL; *xx = 0;
}
log( LOG_INFO, "reqtable: cancelled request hash=%lli state2=%lx",
requestHash, (long) state2 );
return;
}