示例#1
0
文件: radix.c 项目: Aivaras/lighttpd2
gpointer li_radixtree_lookup_exact(liRadixTree *tree, const void *key, guint32 bits) {
	liRadixNode *node;
	rdxBase input[INPUT_SIZE(bits)], current;
	guint32 pos = 0;

	rdx_get_input(input, key, bits);

	pos = 0;
	current = input[0];

	node = tree->zero;

	while (node) {
		rdxBase mask = RDX_MASK(node->width);

		if (node->width > bits) break; /* prefix longer than key */

		if ((current & mask) != node->key) break; /* doesn't match */

		if (node->width == bits) return node->data; /* exact match */

		if (mask & 0x1) {
			/* next "layer" */
			current = input[++pos];
			bits -= RDXBITS;
			node = (current & RDX_BIT(0)) ? node->right : node->left;
		} else {
			node = (current & RDX_BIT(node->width)) ? node->right : node->left;
		}
	}

	return NULL;
}
示例#2
0
文件: radix.c 项目: Aivaras/lighttpd2
gpointer li_radixtree_remove(liRadixTree *tree, const void *key, guint32 bits) {
	rdxBase input[INPUT_SIZE(bits)];
	gpointer data;
	rdx_get_input(input, key, bits);

	data = radixtree_remove(&tree->zero, input, bits);

	return data;
}
示例#3
0
文件: radix.c 项目: Sciumo/lighttpd2
gpointer li_radixtree_lookup(liRadixTree *tree, const void *key, guint32 bits) { /* longest matching prefix */
	liRadixNode *node;
	rdxBase input[INPUT_SIZE(bits)], current;
	guint32 pos = 0;
	gpointer data = NULL;

	rdx_get_input(input, key, bits);

	pos = 0;
	current = input[0];

	node = tree->zero;

	while (node) {
		rdxBase mask = RDX_MASK(node->width);

		if (node->width > bits) break; /* prefix longer than key */

		if ((current & mask) != node->key) break; /* doesn't match */

		if (node->data) data = node->data; /* longest matching prefix */

		if (node->width == bits) break; /* "end of key" */

		if (mask & 0x1) {
			/* next "layer" */
			current = input[++pos];
			bits -= RDXBITS;
			node = (current & (1 << (RDXBITS-1))) ? node->right : node->left;
		} else {
			node = (current & (1 << (RDXBITS-node->width-1))) ? node->right : node->left;
		}
	}

	return data;
}
示例#4
0
文件: radix.c 项目: Aivaras/lighttpd2
gpointer li_radixtree_insert(liRadixTree *tree, const void *key, guint32 bits, gpointer data) {
	liRadixNode *node, **nodeloc;
	rdxBase input[INPUT_SIZE(bits)], current;
	guint32 pos = 0;
	rdx_get_input(input, key, bits);

	if (!data) return NULL;

	pos = 0;
	current = input[0];

	nodeloc = &tree->zero;

	while (NULL != (node = *nodeloc)) {
		rdxBase mask = RDX_MASK(node->width);

		if (node->width > bits || (current & mask) != node->key) { /* prefix longer than key or key doesn't match */
			/* split node */
			liRadixNode *newnode;
			guint32 width = (node->width > bits) ? bits : node->width;
			assert(width <= RDXBITS);
			mask = RDX_MASK(width);
			while ((current & mask) != (node->key & mask)) {
				width--;
				mask <<= 1;
			}
			assert(width <= RDXBITS-1);
			newnode = g_slice_new0(liRadixNode);
			newnode->width = width;
			newnode->key = current & mask;
			if (node->key & RDX_BIT(width)) { /* current may not have a "next" bit */
				newnode->right = node;
				*nodeloc = newnode;
				nodeloc = &newnode->left;
			} else {
				newnode->left = node;
				*nodeloc = newnode;
				nodeloc = &newnode->right;
			}
			if (width == bits) {
				newnode->data = data;
				return NULL;
			} else {
				/* NULL == *nodeloc */
				break;
			}
		}

		if (node->width == bits) { /* exact match */
			gpointer olddata = node->data;
			node->data = data;
			return olddata;
		}

		if (mask & 0x1) {
			/* next "layer" */
			current = input[++pos];
			bits -= RDXBITS;
			nodeloc = (current & RDX_BIT(0)) ? &node->right : &node->left;
		} else {
			nodeloc = (current & RDX_BIT(node->width)) ? &node->right : &node->left;
		}
	}

	while (bits > RDXBITS) {
		node = g_slice_new0(liRadixNode);
		node->width = RDXBITS;
		node->key = current;
		*nodeloc = node;

		/* next "layer" */
		current = input[++pos];
		bits -= RDXBITS;
		nodeloc = (current & RDX_BIT(0)) ? &node->right : &node->left;
	}

	node = g_slice_new0(liRadixNode);
	node->width = bits;
	node->key = current & RDX_MASK(bits);
	node->data = data;
	*nodeloc = node;

	return NULL;
}