Пример #1
0
/* copy of findnodekey */
int bt_init_iterator(struct btree *btr, bt_data_t k, struct btIterator *iter) {
    if (!btr->root) return -1;

    int i = 0;
    int r = 0;

    struct btreenode *x          = btr->root;
    unsigned char     only_right = 1;
    while (x != NULL) {
        i = findkindex(btr, x, k, &r, iter);

        if (i >= 0 && r == 0) return 0;

        if (r < 0 || i != (x->n - 1)) only_right = 0;
        if (x->leaf) {
            if (i != (x->n - 1)) only_right = 0;
            return only_right ? RET_ONLY_RIGHT : RET_LEAF_EXIT;
        }

        iter->bln->child = get_new_iter_child(iter);
        x                = NODES(btr, x)[i + 1];
        become_child(iter, x);
    }
    return -1;
}
Пример #2
0
static bool btScionFind(btSIter *siter, bt_n *x, ulong ofst, bt *btr, bool asc,
						cswc_t  *w,     long  lim) {
	int    i   = asc ? 0        : x->n;                 //DEBUG_SCION_PRE_LOOP1
	int    fin = asc ? x->n + 1 : -1;//LOOPS:(i=0,i<=x->n,i++)&(i=x->n,i>=0,i--)
	while (i != fin) {
		if (x->leaf) break;
		uint32_t scion = NODES(btr, x)[i]->scion;           //DEBUG_SCION_LOOP_1
		if (scion >= ofst) {
			bool i_end_n     = (i == siter->x.bln->self->n);
			siter->x.bln->in = i;
			siter->x.bln->ik = (i_end_n) ? i - 1 : i;  //DEBUG_SCION_LOOP_1_KID
			if (scion == ofst) {
				if (!asc) {
					siter->x.bln->in = siter->x.bln->ik = i - 1;
				}
				return 1;
			}
			siter->x.bln->child = get_new_iter_child(&siter->x);
			to_child(&siter->x, NODES(btr, x)[i]);
			bt_n *kid = NODES(btr, x)[i];          //DEBUG_SCION_LOOP_1_GOT_KID
			if (!kid->leaf) {
				btScionFind(siter, kid, ofst, btr, asc, w, lim);
				return 1;
			} else x = kid;
			break;
		} else ofst -= (scion + 1); // +1 for NODE itself
		i = asc ? i + 1 : i - 1;    // loop increment
	}
	// Now Find the rest of the OFFSET (respecting DRs)
	uint32  n    = siter->x.bln->self->n;
	i            = asc ? 0            : n - 1;
	fin          = asc ? MIN(ofst, n) : MAX(-1, (n - ofst));
	int last     = asc ? n - 1        : 0;
	ulong   cnt  = 0;
	//TODO findminnode() is too inefficient -> needs to be a part of btr
	bt_n   *minx = findminnode(btr, btr->root);
	int     btdl = btr->dirty_left;
	int     dr   = 0;                                   //DEBUG_SCION_PRE_LOOP2
	while (i != fin) {
		dr   = getDR(btr, x, i);
		cnt += dr;
		if (!i && x == minx) cnt += btdl;                   //DEBUG_SCION_LOOP2
		if (cnt >= ofst) break;
		cnt++;
		i = asc ? i + 1 : i - 1; // loop increment
	}                                              //DEBUG_SCION_OFFSET_TOO_BIG
	if      (i == fin && i == last) {
		if (cnt >= x->scion) return 0;
	}
	else if (cnt < ofst)                                   return 0; //OFST 2big
	siter->x.bln->ik = i;
	INIT_ITER_BEENTRY(siter, btr, x, siter->x.bln->ik);
	if (asc)  {
		if ((ofst + dr) != cnt) siter->missed = 1;
	}
	else      {
		if (!i && x == minx) {
			if (ofst != (cnt - btdl)) siter->missed = 1;
		}
		else                 {
			if (ofst != cnt)          siter->missed = 1;
		}
	}                                                  //DEBUG_SCION_POST_LOOP2
	return 1;
}