From 7a5bc7809c8d9b00424fd1b5c7ffbc730a684e66 Mon Sep 17 00:00:00 2001 From: Yoni Fogel <yoni@tokutek.com> Date: Tue, 15 Sep 2009 15:50:26 +0000 Subject: [PATCH] Addresses #1737 refs[t:1737] Optimized le_has_xids In the case where |XIDS| <= num xids in leafentry, and outermost uncommitted xid matches, and |XIDS|>2 git-svn-id: file:///svn/toku/tokudb@14588 c7de825b-a66e-492c-adef-691d508d4ae1 --- newbrt/ule.c | 72 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 17 deletions(-) diff --git a/newbrt/ule.c b/newbrt/ule.c index fc6d4c2dc0..8974b61885 100644 --- a/newbrt/ule.c +++ b/newbrt/ule.c @@ -88,17 +88,6 @@ le_malloc(OMT omt, struct mempool *mp, size_t size, void **maybe_free) return toku_malloc(size); } -///////////// end scaffolding/upgrade -///////////// ENDTEMP ENDTEMP ENDTEMP ENDTEMP - - - - - - - - - ///////////////////////////////////////////////////////////////////////////////// // This is the big enchilada. (Bring Tums.) Note that this level of abstraction // has no knowledge of the inner structure of either leafentry or msg. It makes @@ -783,13 +772,62 @@ le_has_xids(LEAFENTRY le, XIDS xids) { goto have_answer; } //Hard case: shares outermost uncommitted xid, but has more in the stack. - //TODO: Optimize hard case by using leafentry_memsize as a template to do part of the 'unpacking' + // Need to unpack iteratively till we reach the right xid. + //Read the keylen + u_int32_t keylen = toku_dtoh32(le->keylen); - ULE_S ule; - le_unpack(&ule, le); - u_int8_t idx = num_xids -1; - rval = xids_get_xid(xids, idx) == ule_get_xid(&ule, idx); - goto have_answer; + //Read the vallen of innermost insert + u_int32_t vallen_of_innermost_insert = toku_dtoh32(le->innermost_inserted_vallen); + + assert(num_uxrs > 1); + //A 'provisional leafentry' (Uncommitted transactions exist) + //Read in type. + u_int8_t innermost_type = le->u.prov.innermost_type; + assert(!uxr_type_is_placeholder(innermost_type)); + //Set p to immediately after key,val (begginning of transaction records) + u_int8_t *p = &le->u.prov.key_val_xrs[keylen + vallen_of_innermost_insert]; + + BOOL found_innermost_insert = FALSE; + u_int8_t i; //would be index in ULE.uxrs[] were we to unpack + //Loop inner to outer + UXR_S current_uxr; + UXR uxr = ¤t_uxr; + for (i = num_uxrs - 1; i >= num_xids-1; i--) { + //Innermost's type is in header. + if (i < num_uxrs - 1) { + //Not innermost, so load the type. + uxr->type = *p; + p += 1; + } + else { + //Innermost, load the type previously read from header + uxr->type = innermost_type; + } + + //Committed txn id is implicit (0). (i==0) + //Outermost uncommitted txnid is stored in header. (i==1) + //Not committed nor outermost uncommitted, so load the xid. + if (i == num_xids-1) { + //Done. This is the interesting txn. + TXNID candidate_txn = toku_dtoh64(*(TXNID*)p); + TXNID target_txn = xids_get_innermost_xid(xids); + rval = candidate_txn == target_txn; + goto have_answer; + } + p += 8; + + if (uxr_is_insert(uxr)) { + if (found_innermost_insert) { + //Not the innermost insert. Load vallen/valp + uxr->vallen = toku_dtoh32(*(u_int32_t*)p); + p += 4; + p += uxr->vallen; + } + else + found_innermost_insert = TRUE; + } + } + assert(FALSE); have_answer: #if ULE_DEBUG { -- 2.30.9