template<class X> void splay_forest<X>::remove (Pos p)
{
    POMAGMA_ASSERT5(is_inserted(p), "pos not inserted before removal");

    Pos u = U(p);
    Pos& d = u ? (is_left_of(p,u) ? L(u)
                                     : R(u))
               : root(p);

    if (Pos l = L(p)) {
        if (Pos r = R(p)) {     //   u      u
            join(&d,u,l,r);     //   p  -> l+r
        }                       //  l r
        else {
            d = l;              //   u      u
            U(l) = u;           //   p  ->  l
        }                       //  l
    } else {
        if (Pos r = R(p)) {     //   u      u
            d = r;              //   p  ->  r
            U(r) = u;           //    r
        }
        else d = Pos(0);        //   u  ->  u
    }                           //   p

    POMAGMA_ASSERT5(not is_inserted(p), "pos inserted after removal");
}
template<class X> void splay_forest<X>::Iterator::next ()
{//inorder next
    //PROFILE: Iterator<CLR>::next is very expensive: 74% of total time
    //move DR DL^*
    if (Pos r = R(m_pos)) { m_pos = LL(r); return; }

    //move UL^* UR or finish
    for (Pos d = m_pos; (m_pos = U(d)); d = m_pos) {
        if (is_left_of(d,m_pos)) break;
    }
}
Exemple #3
0
void MyView::CopyRegion(BRegion *region, int32 xOffset, int32 yOffset)
{
wind->Lock();
		int32 count = region->CountRects();

		// TODO: make this step unnecessary
		// (by using different stack impl inside node)
		node nodes[count];
		for (int32 i= 0; i < count; i++) {
			nodes[i].init(region->RectAt(i), count);
		}

		for (int32 i = 0; i < count; i++) {
			BRect a = region->RectAt(i);
			for (int32 k = i + 1; k < count; k++) {
				BRect b = region->RectAt(k);
				int cmp = 0;
				// compare horizontally
				if (xOffset > 0) {
					if (is_left_of(a, b)) {
						cmp -= 1;
					} else if (is_left_of(b, a)) {
						cmp += 1;
					}
				} else if (xOffset < 0) {
					if (is_left_of(a, b)) {
						cmp += 1;
					} else if (is_left_of(b, a)) {
						cmp -= 1;
					}
				}
				// compare vertically
				if (yOffset > 0) {
					if (is_above(a, b)) {
						cmp -= 1;	
					} else if (is_above(b, a)) {
						cmp += 1;
					}
				} else if (yOffset < 0) {
					if (is_above(a, b)) {
						cmp += 1;
					} else if (is_above(b, a)) {
						cmp -= 1;
					}
				}
				// add appropriate node as successor
				if (cmp > 0) {
					nodes[i].push(&nodes[k]);
					nodes[k].in_degree++;
				} else if (cmp < 0) {
					nodes[k].push(&nodes[i]);
					nodes[i].in_degree++;
				}
			}
		}
		// put all nodes onto a stack that have an "indegree" count of zero
		stack<node*> inDegreeZeroNodes;
		for (int32 i = 0; i < count; i++) {
			if (nodes[i].in_degree == 0) {
				inDegreeZeroNodes.push(&nodes[i]);
			}
		}
		// pop the rects from the stack, do the actual copy operation
		// and decrease the "indegree" count of the other rects not
		// currently on the stack and to which the current rect pointed
		// to. If their "indegree" count reaches zero, put them onto the
		// stack as well.

		while (!inDegreeZeroNodes.empty()) {
			node* n = inDegreeZeroNodes.top();
			inDegreeZeroNodes.pop();

			CopyBits(n->rect, BRect(n->rect).OffsetByCopy(xOffset, yOffset));

			for (int32 k = 0; k < n->next_pointer; k++) {
				n->pointers[k]->in_degree--;
				if (n->pointers[k]->in_degree == 0)
					inDegreeZeroNodes.push(n->pointers[k]);
			}
		}
wind->Unlock();
}
//tree manipulation
template<class X> void splay_forest<X>::splay (Pos x)
{
    POMAGMA_ASSERT5(is_inserted(x), "node is not inserted before splaying");

    Pos y = U(x);
    if (!y) { //quit if x is root
        POMAGMA_ASSERT5(root(x) == x, "parentless x is not root after splaying");
        return;
    }
    bool x_y = is_left_of(x,y); //get initial direction

    while (true) {
        Pos z = U(y);

        //swap x and y if y is root
        if (!z) {
            if (x_y) {              //      zig
                set_L(y,R(x));      //    y      x
                set_R(x,y);         //   x . -> . y
            }                       //  . .      . .

            else {                  //      zag
                set_R(y,L(x));      //   y        x
                set_L(x,y);         //  . x  ->  y .
            }                       //   . .    . .
            set_root(x);
            return;
        }

        //remember z's parent
        Pos new_y = U(z);

        //splay x above y,z
        if (is_left_of(y,z)) {      //zig-
            if (x_y) {              //      zig-zig
                set_L(z,R(y));      //     z        x
                set_L(y,R(x));      //    y .  ->  . y
                set_R(y,z);         //   x .        . z
                set_R(x,y);         //  . .          . .
            }
            else {                  //      zig-zag
                set_L(z,R(x));      //    z         x
                set_R(y,L(x));      //   y .  ->  y   z
                set_L(x,y);         //  . x      . . . .
                set_R(x,z);         //   . .
            }
        } else { //zag-
            if (x_y) {              //      zag-zig
                set_L(y,R(x));      //   z          x
                set_R(z,L(x));      //  . y   ->  z   y
                set_L(x,z);         //   x .     . . . .
                set_R(x,y);         //  . .
            }
            else {                  //     zag-zag
                set_R(z,L(y));      //   z          x
                set_R(y,L(x));      //  . y   ->   y .
                set_L(y,z);         //   . x      z .
                set_L(x,y);         //    . .    . .
            }
        }

        //update direction
        if ((y = new_y)) {
            x_y = is_left_of(z,y);
        } else {
            set_root(x);
            return;
        }
    }
}