Example #1
0
/* Insertion never needs more than 2 rotations */
struct avltree_node *avltree_insert(struct avltree_node *node, struct avltree *tree) {
    struct avltree_node *parent = 0, *unbalanced = tree->root;
    bool is_left;

    // Find a suitable parent.
    for (struct avltree_node *next_parent = tree->root; next_parent != 0;) {
        parent = next_parent;
        if (get_balance(parent) != 0)
            unbalanced = parent;
        int cmp_r = tree->cmp_fn(parent, node);
        if (cmp_r == 0) {
            if (tree->unique_index)
                return parent;
            // For non unique indexes any insert direction is acceptable.
            if (parent->left == 0) {
                is_left = true;
                break;
            } else if (parent->right == 0) {
                is_left = false;
                break;
            } else {
                // Be smart and travel to the least balanced subtree to minimize balancing overhead.
                next_parent = (get_balance(parent) <= 0)? parent->left: parent->right;
            }
        } else {
            is_left = (cmp_r > 0);
            next_parent = is_left? parent->left: parent->right;
        }
    }

    INIT_NODE(node);

    if (!parent) {
        tree->root = node;
        tree->first = tree->last = node;
        tree->height++;
        return 0;
    }
    if (is_left) {
        if (parent == tree->first)
            tree->first = node;
    } else {
        if (parent == tree->last)
            tree->last = node;
    }
    set_parent(parent, node);
    set_child(node, parent, is_left);

    for (;;) {
        if (parent->left == node)
            dec_balance(parent);
        else
            inc_balance(parent);

        if (parent == unbalanced) {
            for (;;) {
                node = parent;
                node->count++;
                if (is_root(node))
                    break;
                parent = get_parent(parent);
            }
            break;
        }
        node = parent;
        node->count++;
        parent = get_parent(parent);
    }

    switch (get_balance(unbalanced)) {
        case 1: case -1:
            tree->height++;
            /* fall through */
        case 0:
            break;
        case 2:
        {
            struct avltree_node *right = unbalanced->right;

            if (get_balance(right) == 1) {
                set_balance(0, unbalanced);
                set_balance(0, right);
            } else {
                switch (get_balance(right->left)) {
                    case 1:
                        set_balance(-1, unbalanced);
                        set_balance(0, right);
                        break;
                    case 0:
                        set_balance(0, unbalanced);
                        set_balance(0, right);
                        break;
                    case -1:
                        set_balance(0, unbalanced);
                        set_balance(1, right);
                        break;
                }
                set_balance(0, right->left);

                rotate_right(right, tree);
            }
            rotate_left(unbalanced, tree);
            break;
        }
        case -2:
        {
            struct avltree_node *left = unbalanced->left;

            if (get_balance(left) == -1) {
                set_balance(0, unbalanced);
                set_balance(0, left);
            } else {
                switch (get_balance(left->right)) {
                    case 1:
                        set_balance(0, unbalanced);
                        set_balance(-1, left);
                        break;
                    case 0:
                        set_balance(0, unbalanced);
                        set_balance(0, left);
                        break;
                    case -1:
                        set_balance(1, unbalanced);
                        set_balance(0, left);
                        break;
                }
                set_balance(0, left->right);

                rotate_left(left, tree);
            }
            rotate_right(unbalanced, tree);
            break;
        }
    }
    return 0;
}
Example #2
0
void process_tree(struct rooted_tree *tree, struct parameters params)
{
	struct llist *descendants;

	switch (params.mode) {
	case EXACT:
		descendants = nodes_from_labels(tree, params.labels);
		if (NULL == descendants) { perror(NULL); exit(EXIT_FAILURE); }
		if (0 == descendants->count) {
			fprintf (stderr, "WARNING: no label matches.\n");
			/* I don't consider this a failure: it is just the case
			 * that the tree does not contain the specified labels.
			 * */
			exit(EXIT_SUCCESS);
		}
		break;
	case REGEXP:
		descendants = nodes_from_regexp(tree, params.regexp);
		if (NULL == descendants) { perror(NULL); exit(EXIT_FAILURE); }
		if (0 == descendants->count) {
			fprintf (stderr, "WARNING: no match for regexp /%s/\n",
					params.regexp_string);
			exit(EXIT_SUCCESS); /** see above */
		}
		break;
	default:
		fprintf (stderr, "Unknown mode %d\n", params.mode);
		exit(EXIT_FAILURE);
	}

	/* We need a copy b/c lca() modifies its arg */
	struct llist *desc_clone = shallow_copy(descendants);
	if (NULL == desc_clone) { perror(NULL); exit(EXIT_FAILURE); }
	struct rnode *subtree_root = lca(tree, desc_clone);
	if (NULL == subtree_root) { perror(NULL); exit(EXIT_FAILURE); }
	free(desc_clone); /* elems freed in lca() */

	/* Jump up tree to get context, if any was required ('context' > 0) */
	int context;
	for (context = params.context; context > 0; context--)
		if (! is_root(subtree_root))
			subtree_root = subtree_root->parent;

	// TODO: could not replace to_newick() by dump_newick() due to side
	// effects. Investigate.

	if (NULL != subtree_root) {
		if ((! params.check_monophyly) ||
		    (is_monophyletic(descendants, subtree_root))) {
			/* monophyly of input labels is verified or not
			 * requested */
			char *newick;
			if (params.siblings) {
				struct llist *sibs = siblings(subtree_root);
				if (NULL == sibs) {
					perror(NULL);
					exit(EXIT_FAILURE);
				}
				struct list_elem *el;
				for (el=sibs->head;NULL!=el;el=el->next) {
					struct rnode *sib;
					sib = el->data;
					newick = to_newick(sib);
					printf ("%s\n", newick);
					free(newick);
				}
				destroy_llist(sibs);
			} else {
				/* normal operation: print clade defined by
				 * labels. */
				newick = to_newick(subtree_root);
				printf ("%s\n", newick);
				free(newick);
			}
		}
	} else {
		fprintf (stderr, "WARNING: LCA not found\n");
	}

	destroy_llist(descendants);

}
Example #3
0
void draw_branches_ortho (struct rooted_tree *tree, const double h_scale,
		const double v_scale, int align_leaves, double dmax)
{
	printf("<g "
	       	" style='stroke:black;fill:none;stroke-width:1;"
		"stroke-linecap:round'>"
		);

	struct list_elem *elem;
	for (elem=tree->nodes_in_order->head; NULL!=elem; elem=elem->next) {
		struct rnode *node = elem->data;
		struct svg_data *node_data = (struct svg_data *) node->data;

		/* For cladograms */
		if (align_leaves && is_leaf(node))
			node_data->depth = dmax;

		double svg_h_pos = ROOT_SPACE + (h_scale * node_data->depth);
		double svg_top_pos = v_scale * node_data->top; 
		double svg_bottom_pos = v_scale * node_data->bottom; 
		double svg_mid_pos =
			0.5 * v_scale * (node_data->top+node_data->bottom);

		/* draw node (vertical line), except for leaves */
		if (! is_leaf(node)) {
		printf("<line class='clade_%d' "
			"x1='%.4f' y1='%.4f' x2='%.4f' y2='%.4f'/>",
			node_data->group_nb, svg_h_pos, svg_top_pos, svg_h_pos,
			svg_bottom_pos);
		}
		/* draw horizontal line */
		if (is_root(node)) {
			printf("<line x1='0' y1='%.4f' x2='%.4f' y2='%.4f'/>",
				svg_mid_pos, svg_h_pos, svg_mid_pos);

		} else {
			struct svg_data *parent_data = node->parent->data;
			double svg_parent_h_pos = ROOT_SPACE + (
				h_scale * parent_data->depth);
			printf ("<line class='clade_%d' "
				"x1='%.4f' y1='%.4f' x2='%.4f' y2='%.4f'/>",
				node_data->group_nb, svg_parent_h_pos,
				 svg_mid_pos, svg_h_pos, svg_mid_pos);
		}
		/* draw ornament, if any */
		if (NULL != node_data->ornament) {
			/* ornament is considered text IFF it starts
			 * with "<text" */
			if (strstr(node_data->ornament, "<text") == 
					node_data->ornament) {
				printf ("<g style='text-anchor:end;"
					"stroke:none;fill:black'"
					" transform='"
					"translate(%g,%g)'>%s</g>",
					svg_h_pos,
					svg_mid_pos + edge_length_v_offset,
					node_data->ornament);
			} else { /* not text */
				printf ("<g transform='"
					"translate(%g,%g)'>%s</g>",
						svg_h_pos, svg_mid_pos,
						node_data->ornament);
			}

		}
	}
	printf("</g>");
}
Example #4
0
void MPILock::add_resource(Resource resource, unsigned tokens) {
  resources[resource] = new MPIResource(resource, sides.size(), tokens, is_root());
}
Example #5
0
int 
store_cred(const char* user, const char* pw, int mode, Daemon* d, bool force) {
	
	int result;
	int return_val;
	Sock* sock = NULL;

		// to help future debugging, print out the mode we are in
	static const int mode_offset = 100;
	static const char *mode_name[] = {
		ADD_CREDENTIAL,
		DELETE_CREDENTIAL,
		QUERY_CREDENTIAL
#ifdef WIN32
		, CONFIG_CREDENTIAL
#endif
	};	
	dprintf ( D_ALWAYS, 
		"STORE_CRED: In mode '%s'\n", 
		mode_name[mode - mode_offset] );
	
		// If we are root / SYSTEM and we want a local daemon, 
		// then do the work directly to the local registry.
		// If not, then send the request over the wire to a remote credd or schedd.

	if ( is_root() && d == NULL ) {
			// do the work directly onto the local registry
		return_val = store_cred_service(user,pw,mode);
	} else {
			// send out the request remotely.

			// first see if we're operating on the pool password
		int cmd = STORE_CRED;
		char const *tmp = strchr(user, '@');
		if (tmp == NULL || tmp == user || *(tmp + 1) == '\0') {
			dprintf(D_ALWAYS, "store_cred: user not in user@domain format\n");
			return FAILURE;
		}
		if (((mode == ADD_MODE) || (mode == DELETE_MODE)) &&
		    ( (size_t)(tmp - user) == strlen(POOL_PASSWORD_USERNAME)) &&
		    (memcmp(POOL_PASSWORD_USERNAME, user, tmp - user) == 0))
		{
			cmd = STORE_POOL_CRED;
			user = tmp + 1;	// we only need to send the domain name for STORE_POOL_CRED
		}

		if (d == NULL) {
			if (cmd == STORE_POOL_CRED) {
				// need to go to the master for setting the pool password
				dprintf(D_FULLDEBUG, "Storing credential to local master\n");
				Daemon my_master(DT_MASTER);
				sock = my_master.startCommand(cmd, Stream::reli_sock, 0);
			}
			else {
				dprintf(D_FULLDEBUG, "Storing credential to local schedd\n");
				Daemon my_schedd(DT_SCHEDD);
				sock = my_schedd.startCommand(cmd, Stream::reli_sock, 0);
			}
		} else {
			dprintf(D_FULLDEBUG, "Starting a command on a REMOTE schedd\n");
			sock = d->startCommand(cmd, Stream::reli_sock, 0);
		}
		
		if( !sock ) {
			dprintf(D_ALWAYS, 
				"STORE_CRED: Failed to start command.\n");
			dprintf(D_ALWAYS, 
				"STORE_CRED: Unable to contact the REMOTE schedd.\n");
			return FAILURE;
		}

		// for remote updates (which send the password), verify we have a secure channel,
		// unless "force" is specified
		if (((mode == ADD_MODE) || (mode == DELETE_MODE)) && !force && (d != NULL) &&
			((sock->type() != Stream::reli_sock) || !((ReliSock*)sock)->triedAuthentication() || !sock->get_encryption())) {
			dprintf(D_ALWAYS, "STORE_CRED: blocking attempt to update over insecure channel\n");
			delete sock;
			return FAILURE_NOT_SECURE;
		}
		
		if (cmd == STORE_CRED) {
			result = code_store_cred(sock, const_cast<char*&>(user),
				const_cast<char*&>(pw), mode);
			if( result == FALSE ) {
				dprintf(D_ALWAYS, "store_cred: code_store_cred failed.\n");
				delete sock;
				return FAILURE;
			}
		}
		else {
				// only need to send the domain and password for STORE_POOL_CRED
			if (!sock->code(const_cast<char*&>(user)) ||
				!sock->code(const_cast<char*&>(pw)) ||
				!sock->end_of_message()) {
				dprintf(D_ALWAYS, "store_cred: failed to send STORE_POOL_CRED message\n");
				delete sock;
				return FAILURE;
			}
		}
		
		sock->decode();
		
		result = sock->code(return_val);
		if( !result ) {
			dprintf(D_ALWAYS, "store_cred: failed to recv answer.\n");
			delete sock;
			return FAILURE;
		}
		
		result = sock->end_of_message();
		if( !result ) {
			dprintf(D_ALWAYS, "store_cred: failed to recv eom.\n");
			delete sock;
			return FAILURE;
		}
	}	// end of case where we send out the request remotely
	
	
	switch(mode)
	{
	case ADD_MODE:
		if( return_val == SUCCESS ) {
			dprintf(D_FULLDEBUG, "Addition succeeded!\n");					
		} else {
			dprintf(D_FULLDEBUG, "Addition failed!\n");
		}
		break;
	case DELETE_MODE:
		if( return_val == SUCCESS ) {
			dprintf(D_FULLDEBUG, "Delete succeeded!\n");
		} else {
			dprintf(D_FULLDEBUG, "Delete failed!\n");
		}
		break;
	case QUERY_MODE:
		if( return_val == SUCCESS ) {
			dprintf(D_FULLDEBUG, "We have a credential stored!\n");
		} else {
			dprintf(D_FULLDEBUG, "Query failed!\n");
		}
		break;
	}

	if ( sock ) delete sock;

	return return_val;
}