fis-gtm/sr_port/gvcst_gblmod.c

142 lines
4.4 KiB
C

/****************************************************************
* *
* Copyright 2001, 2012 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gdsroot.h"
#include "gdsblk.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "filestruct.h" /* needed for jnl.h */
#include "gdscc.h" /* needed for tp.h */
#include "jnl.h" /* needed for tp.h */
#include "gdskill.h" /* needed for tp.h */
#include "buddy_list.h" /* needed for tp.h */
#include "hashtab_int4.h" /* needed for tp.h */
#include "tp.h" /* needed for T_BEGIN_READ_NONTP_OR_TP macro */
#include "t_end.h" /* prototypes */
#include "t_retry.h"
#include "t_begin.h"
#include "gvcst_protos.h" /* for gvcst_gblmod,gvcst_search prototype */
#include "copy.h"
#include "gtmimagename.h" /* needed for spanning nodes */
GBLREF gv_namehead *gv_target;
GBLREF gv_key *gv_currkey;
GBLREF sgmnt_addrs *cs_addrs;
GBLREF gd_region *gv_cur_region;
GBLREF uint4 dollar_tlevel;
GBLREF unsigned int t_tries;
LITREF mstr nsb_dummy;
error_def(ERR_GBLMODFAIL);
bool gvcst_gblmod(mval *v)
{
boolean_t gblmod, is_dummy;
enum cdb_sc status;
int key_size, key_size2, data_len;
srch_hist *alt_history;
blk_hdr_ptr_t bp;
rec_hdr_ptr_t rp;
unsigned short match, match2, rsiz, offset_to_value, oldend;
srch_blk_status *bh;
sm_uc_ptr_t b_top;
trans_num tn_to_compare;
T_BEGIN_READ_NONTP_OR_TP(ERR_GBLMODFAIL);
assert(t_tries < CDB_STAGNATE || cs_addrs->now_crit); /* we better hold crit in the final retry (TP & non-TP) */
for (;;)
{
gblmod = TRUE;
if (cdb_sc_normal == (status = gvcst_search(gv_currkey, NULL)))
{
alt_history = gv_target->alt_hist;
alt_history->h[0].blk_num = 0;
VMS_ONLY(
if (cs_addrs->hdr->resync_tn >= ((blk_hdr_ptr_t)gv_target->hist.h[0].buffaddr)->tn)
gblmod = FALSE;
)
# ifdef UNIX
tn_to_compare = ((blk_hdr_ptr_t)gv_target->hist.h[0].buffaddr)->tn;
bh = gv_target->hist.h;
bp = (blk_hdr_ptr_t) bh->buffaddr;
rp = (rec_hdr_ptr_t) (bh->buffaddr + bh->curr_rec.offset);
b_top = bh->buffaddr + bp->bsiz;
GET_USHORT(rsiz, &rp->rsiz);
key_size = gv_currkey->end + 1;
data_len = rsiz + EVAL_CMPC(rp) - SIZEOF(rec_hdr) - key_size;
match = bh->curr_rec.match;
if (key_size == match)
{
if ((0 > data_len) || ((sm_uc_ptr_t)rp + rsiz > b_top))
{
status = cdb_sc_rmisalign1;
t_retry(status);
continue;
}
offset_to_value = SIZEOF(rec_hdr) + key_size - EVAL_CMPC(rp);
/* If it could be a spanning node, i.e., has special value, then try to get tn from the
* block that contains the first special subscript. Since dummy nodes always have the
* same value, the tn number is not updated It s enough to do only the first piece
* since all pieces of a spanning node are killed before an update is applied.
*/
if (IS_SN_DUMMY(data_len, (sm_uc_ptr_t)rp + offset_to_value))
{
oldend = gv_currkey->end;
APPEND_HIDDEN_SUB(gv_currkey);
if (cdb_sc_normal == (status = gvcst_search(gv_currkey, alt_history)))
{
key_size2 = gv_currkey->end + 1;
match = alt_history->h[0].curr_rec.match;
if (key_size2 == match)
tn_to_compare = ((blk_hdr_ptr_t)alt_history->h[0].buffaddr)->tn;
}
else
{
gv_currkey->end = oldend;
gv_currkey->base[gv_currkey->end - 1] = KEY_DELIMITER;
gv_currkey->base[gv_currkey->end] = KEY_DELIMITER;
t_retry(status);
continue;
}
gv_currkey->end = oldend;
gv_currkey->base[gv_currkey->end - 1] = KEY_DELIMITER;
gv_currkey->base[gv_currkey->end] = KEY_DELIMITER;
}
}
if (cs_addrs->hdr->zqgblmod_tn > tn_to_compare)
gblmod = FALSE;
# endif
if (!dollar_tlevel)
{
if ((trans_num)0 == t_end(&gv_target->hist, 0 == alt_history->h[0].blk_num ? NULL : alt_history,
TN_NOT_SPECIFIED))
continue;
} else
{
status = tp_hist(0 == alt_history->h[0].blk_num ? NULL : alt_history);
if (cdb_sc_normal != status)
{
t_retry(status);
continue;
}
}
return gblmod;
}
t_retry(status);
}
}