open-source-search-engine/RequestTable.cpp

137 lines
3.9 KiB
C++

#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;
}
int32_t RequestTable::addRequest ( int64_t requestHash , void *state2 ) {
// sanity check
if ( requestHash == 0 ){
char *xx = NULL; *xx = 0;
}
if ( m_htable.m_ks == 0 ) {
//HashTableT <int64_t,int32_t> m_htable;
// allow dups!
m_htable.set(8,sizeof(char *),50,m_buf,m_bufSize,
true,0,"rqstbl");
}
// check if we have the state already in the hashtable
/*int32_t n = m_htable.getSlot ( requestHash );
while ( m_htable.m_keys[n] ){
// count if same key
if ( m_htable.m_keys[n] == requestHash &&
m_htable.m_vals[n] == ( int32_t ) 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, &state2) ) return -1;
//log ( "requesttable: added hash=%"INT64" state2=%"XINT32"", requestHash,
// (int32_t) state2 );
// count the slots that have this key
int32_t n = m_htable.getSlot ( &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
int32_t count = 0;
while ( m_htable.m_flags[n]) { // m_keys[n] ){
// count if same key
if ( *(int64_t *)m_htable.getValueFromSlot(n) == requestHash )
count++;
// advance n, wrapping if necessary
if ( ++n >= m_htable.m_numSlots ) n = 0;
}
/*if ( count == 1 )
log( "requesttable: hash=%"INT64" state2=%"XINT32" is getting quality",
requestHash, (int32_t) state2 );*/
return count;
}
void RequestTable::gotReply ( int64_t requestHash ,
char *reply ,
int32_t replySize ,
void *state1 ,
void (*callback)( char *reply ,
int32_t 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
int32_t saved = g_errno;
int32_t n = m_htable.getSlot ( &requestHash );
while ( n >= 0 ) {
// restore it before returning
g_errno = saved;
// state2 is in the table
//void *state2 = (void *)m_htable.m_vals[n];
void *state2 = *(void **)m_htable.getValueFromSlot(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=%"INT64" state1=%"XINT32" state2=%"XINT32"",
requestHash, (int32_t) state1, (int32_t) state2 );*/
// restore it before calling callback
g_errno = saved;
// otherwise, it is, call callback
callback ( reply , replySize , state1 , state2 );
// get next
n = m_htable.getSlot ( &requestHash );
}
// all done, unlock the hash table.
m_processHash = 0;
return;
}
void RequestTable::cancelRequest ( int64_t requestHash , void *state2 ) {
// there should only be one request for this request hash
int32_t n = m_htable.getSlot ( &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.getSlot ( &requestHash );
if ( n >= 0 ){
char *xx = NULL; *xx = 0;
}
log( LOG_INFO, "reqtable: cancelled "
"request hash=%"INT64" state2=%"PTRFMT"",
requestHash, (PTRTYPE) state2 );
return;
}