129 lines
4.0 KiB
C
129 lines
4.0 KiB
C
/****************************************************************
|
|
* *
|
|
* Copyright 2001, 2010 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 "cdb_sc.h"
|
|
#include "gdsroot.h"
|
|
#include "gdsblk.h"
|
|
#include "gtm_facility.h"
|
|
#include "fileinfo.h"
|
|
#include "gdsbt.h"
|
|
#include "gdsfhead.h"
|
|
#include "copy.h"
|
|
|
|
/* Include prototypes */
|
|
#include "t_qread.h"
|
|
#include "gvcst_protos.h" /* for gvcst_search_blk,gvcst_rtsib prototype */
|
|
|
|
/* construct a new array which is the path to the
|
|
right sibling of the leaf of the old array
|
|
note: the offset's will be correct, but NOT the 'match' members
|
|
*/
|
|
|
|
/* WARNING: assumes that the search history for the current target is in gv_target.hist */
|
|
|
|
GBLREF sgmnt_addrs *cs_addrs;
|
|
GBLREF gv_namehead *gv_target;
|
|
GBLREF gv_key *gv_currkey;
|
|
GBLREF unsigned char rdfail_detail;
|
|
GBLREF unsigned int t_tries;
|
|
GBLREF srch_blk_status *first_tp_srch_status; /* overriding value of srch_blk_status given by t_qread in case of TP */
|
|
|
|
enum cdb_sc gvcst_rtsib(srch_hist *full_hist, int level)
|
|
{
|
|
srch_blk_status *old, *new, *old_base, *new_base;
|
|
rec_hdr_ptr_t rp;
|
|
enum cdb_sc ret_val;
|
|
block_id blk;
|
|
unsigned short rec_size, temp_short;
|
|
sm_uc_ptr_t buffer_address;
|
|
int4 cycle;
|
|
|
|
new_base = &full_hist->h[level];
|
|
old = old_base = &gv_target->hist.h[level];
|
|
for (;;)
|
|
{
|
|
old++;
|
|
if (0 == old->blk_num)
|
|
return cdb_sc_endtree;
|
|
if (old->cr && (old->blk_num != old->cr->blk))
|
|
{
|
|
assert(CDB_STAGNATE > t_tries);
|
|
return cdb_sc_lostcr;
|
|
}
|
|
if (cdb_sc_normal != (ret_val = gvcst_search_blk(gv_currkey, old)))
|
|
return ret_val;
|
|
buffer_address = old->buffaddr;
|
|
temp_short = old->curr_rec.offset;
|
|
rp = (rec_hdr_ptr_t)((sm_uc_ptr_t)buffer_address + temp_short);
|
|
GET_USHORT(rec_size, &rp->rsiz);
|
|
if ((sm_uc_ptr_t)rp + rec_size > buffer_address + (unsigned int)((blk_hdr_ptr_t)buffer_address)->bsiz)
|
|
{
|
|
assert(CDB_STAGNATE > t_tries);
|
|
return cdb_sc_rmisalign;
|
|
}
|
|
if ((unsigned int)((blk_hdr_ptr_t)buffer_address)->bsiz > (temp_short + rec_size))
|
|
break;
|
|
}
|
|
/* old now points to the first block which did not have a star key pointer*/
|
|
new = new_base + (old - old_base + 1);
|
|
full_hist->depth = (int)(level + old - old_base);
|
|
(new--)->blk_num = 0;
|
|
new->tn = old->tn;
|
|
new->cse = NULL;
|
|
new->first_tp_srch_status = old->first_tp_srch_status;
|
|
assert(new->level == old->level);
|
|
assert(new->blk_target == old->blk_target);
|
|
new->blk_num = old->blk_num;
|
|
new->buffaddr = old->buffaddr;
|
|
new->prev_rec = old->curr_rec;
|
|
new->cycle = old->cycle;
|
|
new->cr = old->cr;
|
|
temp_short = new->prev_rec.offset;
|
|
rp = (rec_hdr_ptr_t)(temp_short + new->buffaddr);
|
|
GET_USHORT(rec_size, &rp->rsiz);
|
|
temp_short += rec_size;
|
|
new->curr_rec.offset = temp_short;
|
|
new->curr_rec.match = 0;
|
|
if (((blk_hdr_ptr_t)old->buffaddr)->bsiz < temp_short)
|
|
{
|
|
assert(CDB_STAGNATE > t_tries);
|
|
return cdb_sc_rmisalign;
|
|
}
|
|
rp = (rec_hdr_ptr_t)(old->buffaddr + temp_short);
|
|
while (--new >= new_base)
|
|
{
|
|
--old;
|
|
GET_USHORT(rec_size, &rp->rsiz);
|
|
if ((sm_uc_ptr_t)rp + rec_size > buffer_address + (unsigned int)((blk_hdr_ptr_t)buffer_address)->bsiz)
|
|
{
|
|
assert(CDB_STAGNATE > t_tries);
|
|
return cdb_sc_rmisalign;
|
|
}
|
|
GET_LONG(blk, ((sm_int_ptr_t)((sm_uc_ptr_t)rp + rec_size - SIZEOF(block_id))));
|
|
new->tn = cs_addrs->ti->curr_tn;
|
|
new->cse = NULL;
|
|
if (NULL == (buffer_address = t_qread(blk, &new->cycle, &new->cr)))
|
|
return((enum cdb_sc)rdfail_detail);
|
|
new->first_tp_srch_status = first_tp_srch_status;
|
|
assert(new->level == old->level);
|
|
assert(new->blk_target == old->blk_target);
|
|
new->blk_num = blk;
|
|
new->buffaddr = buffer_address;
|
|
new->prev_rec.match = 0;
|
|
new->prev_rec.offset = 0;
|
|
new->curr_rec.match = 0;
|
|
new->curr_rec.offset = SIZEOF(blk_hdr);
|
|
rp = (rec_hdr_ptr_t)(buffer_address + SIZEOF(blk_hdr));
|
|
}
|
|
return cdb_sc_normal;
|
|
}
|