Generalized comparator, fixed some bugs in record length handling.
git-svn-id: svn+ssh://svn.corp.yahoo.com/yahoo/yrl/labs/pnuts/code/logstore@613 8dad8b1f-cf64-0410-95b6-bcf113ffbcfe
This commit is contained in:
parent
a0a9d726fd
commit
6a2d6a1cd4
5 changed files with 35 additions and 15 deletions
|
@ -276,7 +276,7 @@ bool DataPage<TUPLE>::recordRead(typename TUPLE::key_t key, size_t keySize, TUP
|
||||||
int match = -1;
|
int match = -1;
|
||||||
while((*buf=itr.getnext()) != 0)
|
while((*buf=itr.getnext()) != 0)
|
||||||
{
|
{
|
||||||
match = TUPLE::compare((*buf)->key(), key);
|
match = TUPLE::compare((*buf)->key(), (*buf)->keylen(), key, keySize);
|
||||||
|
|
||||||
if(match<0) //keep searching
|
if(match<0) //keep searching
|
||||||
{
|
{
|
||||||
|
|
25
datatuple.h
25
datatuple.h
|
@ -49,7 +49,7 @@ public:
|
||||||
|
|
||||||
//this is used by the stl set
|
//this is used by the stl set
|
||||||
bool operator() (const datatuple* lhs, const datatuple* rhs) const {
|
bool operator() (const datatuple* lhs, const datatuple* rhs) const {
|
||||||
return compare(lhs->key(), rhs->key()) < 0; //strcmp((char*)lhs.key(),(char*)rhs.key()) < 0;
|
return compare(lhs->key(), lhs->keylen(), rhs->key(), rhs->keylen()) < 0; //strcmp((char*)lhs.key(),(char*)rhs.key()) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,14 +57,27 @@ public:
|
||||||
* 0 if k1 == k2
|
* 0 if k1 == k2
|
||||||
* 1 of k1 > k2
|
* 1 of k1 > k2
|
||||||
**/
|
**/
|
||||||
static int compare(const byte* k1,const byte* k2) {
|
static int compare(const byte* k1,size_t k1l, const byte* k2, size_t k2l) {
|
||||||
// XXX string comparison is probably not the right approach.
|
// This function handles ASCII and UTF-8 correctly.
|
||||||
//for char* ending with \0
|
// It also handles a Sherpa LSM-Tree specific encoding, where multiple utf-8 strings
|
||||||
return strcmp((char*)k1,(char*)k2);
|
// are concatenated with \254., and the \254 is replaced with a \255 for 'max value in range'.
|
||||||
|
|
||||||
|
size_t min_l = k1l < k2l ? k1l : k2l;
|
||||||
|
|
||||||
|
int ret = memcmp(k1,k2, min_l);
|
||||||
|
if(ret) return ret;
|
||||||
|
if(k1l < k2l) return -1;
|
||||||
|
if(k1l == k2l) return 0;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
//for testing with char* ending with \0
|
||||||
|
/*assert(strlen((char*)k1) == k1l - 1);
|
||||||
|
assert(strlen((char*)k2) == k2l - 1);
|
||||||
|
return strcmp((char*)k1,(char*)k2); */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int compare_obj(const datatuple * a, const datatuple* b) {
|
static int compare_obj(const datatuple * a, const datatuple* b) {
|
||||||
return compare(a->key(), b->key());
|
return compare(a->key(), a->keylen(), b->key(), b->keylen());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setDelete() {
|
inline void setDelete() {
|
||||||
|
|
|
@ -726,7 +726,8 @@ recordid diskTreeComponent::lookup(int xid,
|
||||||
for(int i = FIRST_SLOT+1; i < *stasis_page_slotted_numslots_ptr(node); i++)
|
for(int i = FIRST_SLOT+1; i < *stasis_page_slotted_numslots_ptr(node); i++)
|
||||||
{
|
{
|
||||||
rec = (const indexnode_rec*)readRecord(xid,node,i,0);
|
rec = (const indexnode_rec*)readRecord(xid,node,i,0);
|
||||||
int cmpval = datatuple::compare((datatuple::key_t) (rec+1),(datatuple::key_t) key);
|
int cmpval = datatuple::compare((datatuple::key_t) (rec+1), *stasis_page_slotted_slot_length_ptr(node, i)-sizeof(*rec),
|
||||||
|
(datatuple::key_t) key, keySize);
|
||||||
if(cmpval>0) //changed it from >
|
if(cmpval>0) //changed it from >
|
||||||
break;
|
break;
|
||||||
match = i;
|
match = i;
|
||||||
|
@ -738,7 +739,7 @@ recordid diskTreeComponent::lookup(int xid,
|
||||||
pageid_t child_id = ((const indexnode_rec*)readRecord(xid,node,match,0))->ptr;
|
pageid_t child_id = ((const indexnode_rec*)readRecord(xid,node,match,0))->ptr;
|
||||||
Page* child_page = loadPage(xid, child_id);
|
Page* child_page = loadPage(xid, child_id);
|
||||||
readlock(child_page->rwlatch,0);
|
readlock(child_page->rwlatch,0);
|
||||||
recordid ret = lookup(xid,child_page,depth-1,key,0);
|
recordid ret = lookup(xid,child_page,depth-1,key,keySize);
|
||||||
unlock(child_page->rwlatch);
|
unlock(child_page->rwlatch);
|
||||||
releasePage(child_page);
|
releasePage(child_page);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -263,6 +263,7 @@ void logserver::eventLoop()
|
||||||
//wake up the thread to do work
|
//wake up the thread to do work
|
||||||
pthread_mutex_lock(idle_th.data->th_mut);
|
pthread_mutex_lock(idle_th.data->th_mut);
|
||||||
//set the job of the idle thread
|
//set the job of the idle thread
|
||||||
|
assert(currsock != -1);
|
||||||
*(idle_th.data->workitem) = currsock;
|
*(idle_th.data->workitem) = currsock;
|
||||||
pthread_cond_signal(idle_th.data->th_cond);
|
pthread_cond_signal(idle_th.data->th_cond);
|
||||||
pthread_mutex_unlock(idle_th.data->th_mut);
|
pthread_mutex_unlock(idle_th.data->th_mut);
|
||||||
|
@ -362,9 +363,10 @@ void *serverLoop(void *args)
|
||||||
//insert the given element to the ready queue
|
//insert the given element to the ready queue
|
||||||
sdata->ready_queue->push(newsockfd);
|
sdata->ready_queue->push(newsockfd);
|
||||||
|
|
||||||
if(sdata->ready_queue->size() == 1) //signal the event loop
|
/* if(sdata->ready_queue->size() == 1) //signal the event loop
|
||||||
pthread_cond_signal(sdata->selcond);
|
pthread_cond_signal(sdata->selcond);
|
||||||
|
else */ if(sdata->ready_queue->size()) //in case multiple events were received in race.
|
||||||
|
pthread_cond_broadcast(sdata->selcond);
|
||||||
pthread_mutex_unlock(sdata->qlock);
|
pthread_mutex_unlock(sdata->qlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,6 +447,10 @@ void * thread_work_fn( void * args)
|
||||||
if(!err) { tuple2 = readtuplefromsocket(*(item->data->workitem), &err); }
|
if(!err) { tuple2 = readtuplefromsocket(*(item->data->workitem), &err); }
|
||||||
//step 3: process the tuple
|
//step 3: process the tuple
|
||||||
|
|
||||||
|
if(tuple) {
|
||||||
|
printf("Tuple req = %d key = >%s<\n", opcode, tuple->key());
|
||||||
|
}
|
||||||
|
|
||||||
if(opcode == OP_INSERT)
|
if(opcode == OP_INSERT)
|
||||||
{
|
{
|
||||||
//insert/update/delete
|
//insert/update/delete
|
||||||
|
@ -464,7 +470,7 @@ void * thread_work_fn( void * args)
|
||||||
} else if( dt->datalen() != 1024) {
|
} else if( dt->datalen() != 1024) {
|
||||||
DEBUG("data len for\t%s:\t%d\n", datatuple::key_to_str(tuple.key()).c_str(),
|
DEBUG("data len for\t%s:\t%d\n", datatuple::key_to_str(tuple.key()).c_str(),
|
||||||
dt->datalen);
|
dt->datalen);
|
||||||
if(datatuple::compare(tuple->key(), dt->key()) != 0) {
|
if(datatuple::compare(tuple->key(), tuple->keylen(), dt->key(), dt->keylen()) != 0) {
|
||||||
DEBUG("key not equal:\t%s\t%s\n", datatuple::key_to_str(tuple.key()).c_str(),
|
DEBUG("key not equal:\t%s\t%s\n", datatuple::key_to_str(tuple.key()).c_str(),
|
||||||
datatuple::key_to_str(dt->key).c_str());
|
datatuple::key_to_str(dt->key).c_str());
|
||||||
}
|
}
|
||||||
|
@ -481,7 +487,7 @@ void * thread_work_fn( void * args)
|
||||||
} else {
|
} else {
|
||||||
dt_needs_free = true;
|
dt_needs_free = true;
|
||||||
}
|
}
|
||||||
|
fprintf(stderr, "find result: %s\n", dt->isDelete() ? "not found" : "found");
|
||||||
//send the reply code
|
//send the reply code
|
||||||
int err = writeoptosocket(*(item->data->workitem), LOGSTORE_RESPONSE_SENDING_TUPLES);
|
int err = writeoptosocket(*(item->data->workitem), LOGSTORE_RESPONSE_SENDING_TUPLES);
|
||||||
if(!err) {
|
if(!err) {
|
||||||
|
|
|
@ -488,7 +488,7 @@ int64_t merge_iterators(int xid,
|
||||||
DEBUG("tuple\t%lld: keylen %d datalen %d\n",
|
DEBUG("tuple\t%lld: keylen %d datalen %d\n",
|
||||||
ntuples, *(t2->keylen),*(t2->datalen) );
|
ntuples, *(t2->keylen),*(t2->datalen) );
|
||||||
|
|
||||||
while(t1 != 0 && datatuple::compare(t1->key(), t2->key()) < 0) // t1 is less than t2
|
while(t1 != 0 && datatuple::compare(t1->key(), t1->keylen(), t2->key(), t2->keylen()) < 0) // t1 is less than t2
|
||||||
{
|
{
|
||||||
//insert t1
|
//insert t1
|
||||||
dp = insertTuple(xid, dp, t1, ltable, scratch_tree,
|
dp = insertTuple(xid, dp, t1, ltable, scratch_tree,
|
||||||
|
@ -500,7 +500,7 @@ int64_t merge_iterators(int xid,
|
||||||
t1 = itrA->getnext();
|
t1 = itrA->getnext();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(t1 != 0 && datatuple::compare(t1->key(), t2->key()) == 0)
|
if(t1 != 0 && datatuple::compare(t1->key(), t1->keylen(), t2->key(), t2->keylen()) == 0)
|
||||||
{
|
{
|
||||||
datatuple *mtuple = ltable->gettuplemerger()->merge(t1,t2);
|
datatuple *mtuple = ltable->gettuplemerger()->merge(t1,t2);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue