/* PROGRAM: rlmemwt - write the transaction table and phy. backout flag * into an rlnote * * RETURNS: DSMVOID */ DSMVOID rlmemwt(dsmContext_t *pcontext) { dbcontext_t *pdbcontext = pcontext->pdbcontext; dbshm_t *pdbpub = pdbcontext->pdbpub; MEMNOTE note; TEXT *ptx; TX *ptrn; TEXT *pdata; COUNT dlen; TRANTAB *ptran = pdbcontext->ptrantab; int i,j,numToGo; TRACE_CB(pcontext, "rlmemwt") INITNOTE(note, RL_INMEM, RL_PHY ); note.rlpbkout = pdbcontext->prlctl->rlpbkout; note.lasttask = pdbcontext->pmstrblk->mb_lasttask; note.numLive = pdbcontext->ptrantab->numlive; note.numMemnotes = (note.numLive / (UCOUNT)MAX_ENTRIES_PER_NOTE) + 1; note.tmsize = sizeof (TX) - sizeof(txPlus_t); /* This is a funny note. It describes physical state but since no action is taken and no database blocks depend on it so we'll write it with... */ note.rlnote.rlArea = 0; /* bug 20000114-034 by dmeyer in v9.1b */ note.rlnote.rldbk = 0; note.rlnote.rlupdctr = 0; note.spare[0] = 0; note.spare[1] = 0; /* put 0 in the trn id part of the note */ note.rlnote.rlTrid = 0; if ( ptran->numlive > MAX_ENTRIES_PER_NOTE ) note.numThisNote = MAX_ENTRIES_PER_NOTE; else note.numThisNote = ptran->numlive; dlen = note.numThisNote * note.tmsize; /* bug 93-01-21-035: use stRent instead of stkpush */ pdata = (TEXT *)stRentd (pcontext, pdsmStoragePool, (unsigned)dlen); numToGo = ptran->numlive; ptrn = ptran->trn; for ( j = 0; j < (int)note.numMemnotes; j++) { note.noteSequence = j + 1; MT_LOCK_AIB(); note.aiupdctr = pdbcontext->pmstrblk->mb_aictr; note.ainew = pdbcontext->pmstrblk->mb_ai.ainew; if(pdbcontext->ptlctl) { note.tlWriteBlockNumber = pdbcontext->ptlctl->writeLocation; note.tlWriteOffset = pdbcontext->ptlctl->writeOffset; } else { note.tlWriteBlockNumber = 0; note.tlWriteOffset = 0; } if (pdbpub->qaictl) note.aiwrtloc = pdbcontext->paictl->ailoc + pdbcontext->paictl->aiofst; else note.aiwrtloc = 0; /* bug 20000114-034 by dmeyer in v9.1b */ MT_UNLK_AIB(); for(i=note.numThisNote, ptx = pdata; i > 0; ptrn++) { /* Only copy the transaction if it is in an active state */ if (ptrn->txstate && (ptrn->txstate != TM_TS_ALLOCATED) ) { bufcop (ptx, (TEXT *)ptrn, note.tmsize); ptx += note.tmsize; i--; } } /* Why not just use rlputnote here? */ rlwrite(pcontext, (RLNOTE *)¬e, dlen, pdata); if (rlainote (pcontext, (RLNOTE *)¬e)) { /* write note to ai also. Notice that the ai information which is recorded in the note will change when we do this. */ MT_LOCK_AIB (); rlaiwrt (pcontext, (RLNOTE *)¬e, dlen, pdata, ++pdbcontext->pmstrblk->mb_aictr, pcontext->pusrctl->uc_lstdpend); MT_UNLK_AIB (); } numToGo -= note.numThisNote; if( numToGo > MAX_ENTRIES_PER_NOTE ) note.numThisNote = MAX_ENTRIES_PER_NOTE; else { note.numThisNote = numToGo; dlen = numToGo * note.tmsize; } } /* bug 93-01-21-035: use stVacate instead of stkpop */ stVacate (pcontext, pdsmStoragePool, pdata); /* Write out the ready to commit tx table if there any */ if( pdbcontext->ptrcmtab != NULL ) rlrctwt(pcontext); } /* end rlmemwt */
int cxDoSplit( dsmContext_t *pcontext, dsmTable_t table, /* Table number the index is on */ FINDP *pfndp, /* parameter block for the FIND */ CXBAP *pbap, /* block access params at the next higher level. */ /* Its descrption is put here */ int leftents) /* number of entry left in the left block by split*/ { CXBLK *pixblk; /* the idx block to be split */ TEXT *pos; TEXT *pend; COUNT len1, len2; CXSPLIT note; int cs; TEXT tmp[MAXDBBLOCKSIZE+MAXKEYSZ]; pixblk = pfndp->pblkbuf; /* get a firm grip on both blocks */ /**** the in use count guaranties that the old block is there */ /* get new block - the right block */ cxGetNewBlock(pcontext, table, pfndp->pkykey->index, pfndp->pkykey->area,pbap); /* decide the split point */ pos = pfndp->position; /* split position */ len1 = pos - pixblk->ixchars; len2 = pixblk->IXLENENT - len1; INITNOTE( note, RL_CXSP1, RL_PHY ); INIT_S_CXSPLIT_FILLERS( note ); /* bug 20000114-034 by dmeyer in v9.1b */ bufcop( &(note.ixhdr1), &(pixblk->ix_hdr), sizeof(note.ixhdr1) ); bufcop( &(note.ixhdr2), &(pixblk->ix_hdr), sizeof(note.ixhdr2) ); note.extracs = 0; /* if (len2 && *pos) if key in split position is compressed */ cs = CS_GET(pos); if (len2 && cs) /* if key in split position is compressed */ { /* the 1st entry in the new block is compressed, we must have the missing part in the note to allow decompression */ /* note.extracs = *pos; */ note.extracs = cs; pend = pixblk->ixchars + pixblk->IXLENENT; if ((MAXIXCHRS - pixblk->IXLENENT) < note.extracs) { /* no space in the block, use tmp area */ bufcop(&tmp[0], pos, len2); bufcop(&tmp[0] + len2, pfndp->pinpkey, note.extracs); pos = &tmp[0]; } else { /* there is space to attach the extra at end of the block data */ bufcop(pend, pfndp->pinpkey, note.extracs); } } note.ixhdr1.ih_lnent = len1; note.ixhdr2.ih_lnent = len2 + note.extracs; note.ixhdr1.ih_nment = leftents; note.ixhdr2.ih_nment -= leftents; /* Do the original block */ rlLogAndDo (pcontext, (RLNOTE *)¬e, pfndp->bufHandle, (COUNT)(len2+note.extracs), (TEXT *)pos); /* and then the new block */ note.rlnote.rlcode = RL_CXSP2; rlLogAndDo (pcontext, (RLNOTE *)¬e, pbap->bufHandle, (COUNT)(len2+note.extracs), (TEXT *)pos); return(0); } /* cxDoSplit */