Esempio n. 1
0
mflt *lv_prv_num_inx (sbs_blk *root, mval *key)
{
	sbs_blk		*blk;
	sbs_flt_struct 	*p, *bot;
	mval		tmp ;

	assert (root);
	assert (root->cnt);
	assert (root->ptr.sbs_flt[0].lv);
	MV_ASGN_FLT2MVAL(tmp,root->ptr.sbs_flt[0].flt);
	if (eb_atmost(key, &tmp))
		return 0;
	for (blk = root; ; blk = blk->nxt)
	{
		if (!blk->nxt)
			break;
		MV_ASGN_FLT2MVAL(tmp,blk->nxt->ptr.sbs_flt[0].flt);
		if (eb_atmost(key, &tmp))
			break;
	}
	bot = blk->ptr.sbs_flt ;
	p = &blk->ptr.sbs_flt[blk->cnt - 1];
	while (MV_ASGN_FLT2MVAL(tmp,p->flt) , eb_atmost(key, &tmp))
	{
		--p;
		if (p < bot)
			return 0;
	}
	return &p->flt;
}
Esempio n. 2
0
lv_val *lv_get_num_inx(sbs_blk *root, mval *key, sbs_search_status *status)
{
       	sbs_blk	       	*blk, *nxt, *prev;
       	sbs_flt_struct 	*p, *top;
	mval		tmp ;
	int4		x ;

	assert(root);
       	prev = root;
       	for (blk = root; ; prev = blk, blk = nxt)
       	{      	if (!(nxt = blk->nxt))
		{	break;
	 	}
		MV_ASGN_FLT2MVAL(tmp,nxt->ptr.sbs_flt[0].flt) ;
		if (key->mvtype & MV_INT & tmp.mvtype)
			x = key->m[1] - tmp.m[1];
		else
	       	       	x = numcmp(key,&tmp) ;
		if (x < 0)
		{	break;
		}
       	       	if (x == 0)
       	       	{      	status->blk = nxt;
			status->prev = blk;
			status->ptr = (char*)&nxt->ptr.sbs_str[0];
       	       	      	return(nxt->ptr.sbs_flt[0].lv);
		}
	}
	status->blk = blk;
	status->prev = prev;
       	for (p = (sbs_flt_struct*)&blk->ptr.sbs_flt[0], top =  (sbs_flt_struct*)&blk->ptr.sbs_flt[blk->cnt]; p < top; p++)
       	{
		MV_ASGN_FLT2MVAL(tmp,p->flt);
		if (key->mvtype & MV_INT & tmp.mvtype)
			x = key->m[1] - tmp.m[1];
		else
	       	       	x = numcmp(key,&tmp) ;
	 	if (x < 0)
	 	{	break;
	 	}
	 	if (x == 0)
       	       	{      	status->ptr = (char*)p;
	 		return(p->lv);
	 	}
	}
	status->ptr = (char*)p;
	return(0);
}
Esempio n. 3
0
void op_fnorder(lv_val *src, mval *key, mval *dst)
{
	int			cur_subscr;
	mval			tmp_sbs;
	int             	length;
	sbs_blk			*num, *str;
	boolean_t		found, is_neg;
	int4			i;
	lv_val			**lv;
	lv_sbs_tbl		*tbl;
	sbs_search_status	status;
	boolean_t		is_fnnext;

	is_fnnext = in_op_fnnext;
	in_op_fnnext = FALSE;
	found = FALSE;
	if (src)
	{
		if (tbl = src->ptrs.val_ent.children)
		{
			MV_FORCE_DEFINED(key);
			num = tbl->num;
			str = tbl->str;
			assert(tbl->ident == MV_SBS);
			if ((MV_IS_STRING(key) && key->str.len == 0) || (is_fnnext && MV_IS_INT(key) && key->m[1] == MINUS_ONE))
			{ /* With GT.M collation , if last subscript is null, $o returns the first subscript in that level */
				if (tbl->int_flag)
				{
					assert(num);
					for (i = 0, lv = &num->ptr.lv[0]; i < SBS_NUM_INT_ELE; i++, lv++)
					{
						if (*lv)
						{
							MV_FORCE_MVAL(dst,i);
							found = TRUE;
							break;
						}
					}
				} else if (num)
				{
					assert(num->cnt);
					MV_ASGN_FLT2MVAL((*dst),num->ptr.sbs_flt[0].flt);
					found = TRUE;
				}
			} else
			{
				if (MV_IS_CANONICAL(key))
				{
					MV_FORCE_NUM(key);
					if (tbl->int_flag)
					{
						assert(num);
						is_neg = (key->mvtype & MV_INT) ? key->m[1] < 0 : key->sgn;
						if (is_neg)
							i = 0;
						else
						{
							if (!is_fnnext && (1 == numcmp(key, (mval *)&SBS_MVAL_INT_ELE)))
								i = SBS_NUM_INT_ELE;
							else
							{
								i =  MV_FORCE_INT(key);
								i++;
							}
						}
						for (lv = &num->ptr.lv[i]; i < SBS_NUM_INT_ELE; i++, lv++)
						{
							if (*lv)
							{
								MV_FORCE_MVAL(dst,i);
								found = TRUE;
								break;
							}
						}
					} else if (num && lv_nxt_num_inx(num, key, &status))
					{
						MV_ASGN_FLT2MVAL((*dst),((sbs_flt_struct*)status.ptr)->flt);
						found = TRUE;
					}
				} else
				{
					if (local_collseq)
					{
						ALLOC_XFORM_BUFF(&key->str);
						tmp_sbs.mvtype = MV_STR;
						tmp_sbs.str.len = max_lcl_coll_xform_bufsiz;
						assert(NULL != lcl_coll_xform_buff);
						tmp_sbs.str.addr = lcl_coll_xform_buff;
						do_xform(local_collseq, XFORM, &key->str,
								&tmp_sbs.str, &length);
						tmp_sbs.str.len = length;
						s2pool(&(tmp_sbs.str));
						key = &tmp_sbs;
					}
					if (str && lv_nxt_str_inx(str, &key->str, &status))
					{
						dst->mvtype = MV_STR;
						dst->str = ((sbs_str_struct *)status.ptr)->str;
					} else
					{
						if (!is_fnnext)
						{
							dst->mvtype = MV_STR;
							dst->str.len = 0;
						} else
							MV_FORCE_MVAL(dst, -1);
					}
					found = TRUE;
				}
			}
			if (!found && str)
			{	/* We are here because
				 * a. key is "" and there is no numeric subscript, OR
				 * b. key is numeric and it is >= the largest numeric subscript at this level implying a switch from
				 *    numeric to string subscripts
				 * Either case, return the first string subscript. However, for STDNULLCOLL, skip to the next
				 * subscript should the first subscript be ""
				 */
				assert(str->cnt);
				dst->mvtype = MV_STR;
				dst->str = str->ptr.sbs_str[0].str;
				found = TRUE;
				if (local_collseq_stdnull && 0 == dst->str.len)
				{
					assert(lv_null_subs);
					if (lv_nxt_str_inx(str, &dst->str, &status))
					{
						dst->str = ((sbs_str_struct*)status.ptr)->str;
					} else
						found = FALSE;
				}
			}
		}
	}
	if (!found)
	{
		if (!is_fnnext)
		{
			dst->mvtype = MV_STR;
			dst->str.len = 0;
		} else
			MV_FORCE_MVAL(dst, -1);
	} else if (dst->mvtype == MV_STR && local_collseq)
	{
		ALLOC_XFORM_BUFF(&dst->str);
		assert(NULL != lcl_coll_xform_buff);
		tmp_sbs.str.addr = lcl_coll_xform_buff;
		tmp_sbs.str.len = max_lcl_coll_xform_bufsiz;
		do_xform(local_collseq, XBACK,
				&dst->str, &tmp_sbs.str, &length);
		tmp_sbs.str.len = length;
		s2pool(&(tmp_sbs.str));
		dst->str = tmp_sbs.str;
	}
}