コード例 #1
0
ファイル: tree.c プロジェクト: sdstrowes/util
/* lpm_init:
 * Constructs a fresh tree ready for use by the other functions.
 */
struct lpm_tree* lpm_init()
{
	/* Build empty internal node, and attach it to new tree. */
	struct internal_node* node = create_internal_node();

	struct lpm_tree* tree = (struct lpm_tree*)malloc(sizeof(struct lpm_tree));
	DEBUG("## Created tree %p\n", (void*)tree);
	tree->head = node;

	return tree;
}
コード例 #2
0
ファイル: tree.c プロジェクト: sdstrowes/util
/*
 * This function used internally; see lpm_insert().
 */
void insert(struct sockaddr_storage *prefix, uint32_t nm, struct internal_node* n)
{
	uint8_t b = 0;
	uint8_t depth = 0;
	struct internal_node* parent;
	struct internal_node* next = n;

	if (prefix->ss_family == AF_INET6) {
		b = MAX_BITS6;
	}
	else if (prefix->ss_family == AF_INET) {
		b = MAX_BITS4;
	}


	/* First, find the correct location for the prefix. Burrow down to
	   the correct depth, potentially creating internal nodes as I
	   go. */
	do {
		n = next;
		b--;
		depth++;

		parent = (struct internal_node*)n;
		bool v_bit = test_v_bit(prefix, b);

		/* Determine which direction to descend. */
		if (v_bit) {
			if (n->r == NULL) {
				n->r = create_internal_node();
			}
			next = n->r;
		}
		else {
			if (n->l == NULL) {
				n->l = create_internal_node();
			}
			next = n->l;
		}
	} while (depth < nm);

	if (next == NULL) {
		/* The easy case. */
		struct data_node* node = create_data_node(prefix, nm);
		bool v_bit = test_v_bit(prefix, b);
		if (v_bit) {
			parent->r = (struct internal_node*)node;
		}
		else {
			parent->l = (struct internal_node*)node;
		}
	}
	else if (next->type == INT_NODE) {
		/* In this case, we've descended as far as we can. Attach the
		   prefix here. */
		bool v_bit = test_v_bit(prefix, b);
		struct data_node* newnode = create_data_node(prefix, nm);
		newnode->l = next->l;
		newnode->r = next->r;

		if (v_bit) {
			n->r = (struct internal_node*)newnode;
		}
		else {
			n->l = (struct internal_node*)newnode;
		}

		DEBUG("## Freeing %p\n", (void*)next);
		free(next);
	}
}
コード例 #3
0
ファイル: tree.c プロジェクト: Gug42/flow-inspector
/*
 * This function used internally; see lpm_insert().
 */
void insert(uint32_t prefix, uint32_t nm, struct internal_node* n, uint32_t network_owner)
{
	uint8_t b = MAX_BITS;
	uint8_t depth = 0;
	struct internal_node* parent;
	struct internal_node* next = n;

	/* First, find the correct location for the prefix. Burrow down to
	   the correct depth, potentially creating internal nodes as I
	   go. */
	do {
		n = next;
		b--;
		depth++;

		parent = (struct internal_node*)n;
		uint32_t v_bit = prefix & ((uint32_t)pow(2, b));

		/* Determine which direction to descend. */
		if (v_bit) {
			if (n->r == NULL) {
				n->r = create_internal_node();
			}
			next = n->r;
		}
		else {
			if (n->l == NULL) {
				n->l = create_internal_node();
			}
			next = n->l;
		}
	} while (depth < nm);

	if (next == NULL) {
		/* The easy case. */
		struct data_node* node = create_data_node(prefix, nm, network_owner);
		uint32_t v_bit = prefix & ((uint32_t)pow(2, b));
		if (v_bit) {
			parent->r = (struct internal_node*)node;
		}
		else {
			parent->l = (struct internal_node*)node;
		}
	}
	else if (next->type == INT_NODE) {
		/* In this case, we've descended as far as we can. Attach the
		   prefix here. */
		uint32_t v_bit = prefix & ((uint32_t)pow(2, b));
		struct data_node* newnode = create_data_node(prefix, nm, network_owner);
		newnode->l = next->l;
		newnode->r = next->r;

		if (v_bit) {
			n->r = (struct internal_node*)newnode;
		}
		else {
			n->l = (struct internal_node*)newnode;
		}

		DEBUG("## Freeing %p\n", (void*)n);
		free(next);
	}
}