static char *SccsId = "@(#)elem.c 4.10 (TU-Delft) 06/01/93";
/**********************************************************

Name/Version      : space/4.10

Language          : C
Operating system  : UNIX SYSTEM V
Host machine      : HP9000

Author(s)         : A.J. van Genderen
		  : N.P. van der Meijs
Creation date     : 15-Mar-1988
Modified by       :
Modification date :


        Delft University of Technology
        Department of Electrical Engineering
        Network Theory Section
        Mekelweg 4 - P.O.Box 5031
        2600 GA DELFT
        The Netherlands

        Phone : 015 - 786234

        COPYRIGHT (C) 1988. All rights reserved.
**********************************************************/
#include <stdio.h>
#include "include/config.h"
#include "include/type.h"
#include "aux/aux.h"
#include "lump/define.h"
#include "lump/extern.h"


mergeGrps (nAi, nBi)
node_t *nAi;
node_t *nBi;
{
    register node_t *nA;
    register node_t *nB;
    node_t *rtA;
    node_t *rtB;
    group_t *grA;
    group_t *grB;
    register tileRef_t *tileR;

    if (Grp (nAi) -> nod_cnt < Grp (nBi) -> nod_cnt) {
        nA = nBi;         /* swap nA and nB */
	nB = nAi;       /* (for efficiency reasons) */
    }
    else {
	nA = nAi;
	nB = nBi;
    }

    /* If needed, some findRoots can be optimized away.
     * For Example, Grp (..) above already does findRoot.
     */
    rtA = findRoot (nA);
    rtB = findRoot (nB);
    grA = rtA -> grp;
    grB = rtB -> grp;

    grA -> nod_cnt += grB -> nod_cnt;
    grA -> cap_cnt += grB -> cap_cnt;
    grA -> res_cnt += grB -> res_cnt;
    grA -> notReady += grB -> notReady;

    if ((grA -> supply == 1 && grB -> supply == 2)
        || (grA -> supply == 2 && grB -> supply == 1)) {
	supplyShort ();
    }
    grA -> supply = grA -> supply | grB -> supply;

    /*
     * Now, merge both groups (union of both sets)
     */
    rtB -> grp = NULL;
    rtB -> gr_father = rtA;
    rtA -> n_children++;

    groupDel (grB);
}

node_t * findRoot (node)
node_t * node;
{
    register node_t * n;
    register node_t * father;
    register node_t * root;

    /* find the root */
    for (n = node; n -> grp == NULL; n = n -> gr_father);

    /* n is the root */
    root = n;
    ASSERT (root -> grp != NULL);
    ASSERT (root -> gr_father == root);


    /* compress the path to the root, but kill the node
     * if its time has come
     */

    for (n = node; n != root; n = father) {
	ASSERT (n -> n_children >= 0);

	father = n -> gr_father;
	ASSERT (father != n);		/* true, since n is not the root */

	if (n -> n_children == 0 && n -> condemned == TRUE) {
	    DISPOSE (n);
	    father -> n_children--;
	    condemnCnt--;
	}
	else if (father != root) {
	    n -> gr_father = root;
	    father -> n_children--;
	    root   -> n_children++;
	}
    }

    /* special case:
     * dispose root node if its time has come.
     */
    if (n == root
    &&  root -> n_children == 0 && root -> condemned == TRUE) {
	DISPOSE (root);
	condemnCnt--;
	root = NULL;
    }

    return (root);
}

#ifdef NOTDEF
static mergeGroups (n1, n2)		/* merge the groups of these nodes */
node_t * n1, * n2;
{
    group_t * g1 = Grp (n1);
    group_t * g2 = Grp (n2);

    /* do union by rank */
    if (g1 -> rank < g2 -> rank) {
	n1 -> grp = g2;
    }

    else if (g1 -> rank > g2 -> rank) {
	n2 -> grp = g1;
    }

    else {
	n1 -> grp = g2;
	g2 -> rank++;
    }
}
#endif NOTDEF
