Ejemplo n.º 1
0
Archivo: radix.c Proyecto: Sp1l/rspamd
uintptr_t
radix_insert_compressed (radix_compressed_t * tree,
	guint8 *key, gsize keylen,
	gsize masklen,
	uintptr_t value)
{
	guint keybits = keylen * NBBY;
	uintptr_t old;
	int ret;

	g_assert (tree != NULL);
	g_assert (keybits >= masklen);

	msg_debug_radix ("want insert value %p with mask %z, key: %*xs",
			(gpointer)value, keybits - masklen, (int)keylen, key);

	old = radix_find_compressed (tree, key, keylen);

	ret = btrie_add_prefix (tree->tree, key, keybits - masklen,
			(gconstpointer)value);

	if (ret != BTRIE_OKAY) {
		msg_err_radix ("cannot insert %p with mask %z, key: %*xs, duplicate value",
				(gpointer)value, keybits - masklen, (int)keylen, key);
	}
	else {
		tree->size ++;
	}

	return old;
}
Ejemplo n.º 2
0
Archivo: radix.c Proyecto: Sp1l/rspamd
uintptr_t
radix_find_compressed_addr (radix_compressed_t *tree,
		const rspamd_inet_addr_t *addr)
{
	const guchar *key;
	guint klen = 0;

	if (addr == NULL) {
		return RADIX_NO_VALUE;
	}

	key = rspamd_inet_address_get_radix_key (addr, &klen);

	if (key && klen) {
		return radix_find_compressed (tree, key, klen);
	}

	return RADIX_NO_VALUE;
}
Ejemplo n.º 3
0
/* Radix and hash table functions */
static gint
lua_radix_get_key (lua_State * L)
{
	radix_compressed_t *radix = lua_check_radix (L);
	guint32 key;

	if (radix) {
		key = htonl (luaL_checkint (L, 2));

		if (radix_find_compressed (radix, (guint8 *)&key, sizeof (key))
				!= RADIX_NO_VALUE) {
			lua_pushboolean (L, 1);
			return 1;
		}
	}

	lua_pushboolean (L, 0);
	return 1;
}
Ejemplo n.º 4
0
static void
rspamd_radix_text_vec (void)
{
	radix_compressed_t *tree = radix_create_compressed ();
	struct _tv *t = &test_vec[0];
	struct in_addr ina;
	struct in6_addr in6a;
	gulong i, val;

	while (t->ip != NULL) {
		t->addr = g_malloc (sizeof (in6a));
		t->naddr = g_malloc (sizeof (in6a));
		if (inet_pton (AF_INET, t->ip, &ina) == 1) {
			memcpy (t->addr, &ina, sizeof (ina));
			t->len = sizeof (ina);
		}
		else if (inet_pton (AF_INET6, t->ip, &in6a) == 1) {
			memcpy (t->addr, &in6a, sizeof (in6a));
			t->len = sizeof (in6a);
		}
		else {
			g_assert (0);
		}
		if (t->nip) {
			if (inet_pton (AF_INET, t->nip, &ina) == 1) {
				memcpy (t->naddr, &ina, sizeof (ina));
			}
			else if (inet_pton (AF_INET6, t->nip, &in6a) == 1) {
				memcpy (t->naddr, &in6a, sizeof (in6a));
			}
			else {
				g_assert (0);
			}
		}

		t->mask = t->len * NBBY - strtoul (t->m, NULL, 10);
		t ++;
	}
	t = &test_vec[0];

	i = 0;
	while (t->ip != NULL) {
		radix_insert_compressed (tree, t->addr, t->len, t->mask, ++i);
		t ++;
	}

	i = 0;
	t = &test_vec[0];
	while (t->ip != NULL) {
		val = radix_find_compressed (tree, t->addr, t->len);
		g_assert (val == ++i);
		//g_assert (val != RADIX_NO_VALUE);
		if (t->nip != NULL) {
			val = radix_find_compressed (tree, t->naddr, t->len);
			g_assert (val != i);
		}
		t ++;
	}

	radix_destroy_compressed (tree);
}
Ejemplo n.º 5
0
void
rspamd_radix_test_func (void)
{
#if 0
	radix_tree_t *tree = radix_tree_create ();
#endif
	radix_compressed_t *comp_tree = radix_create_compressed ();
	struct {
		guint32 addr;
		guint32 mask;
		guint8 addr6[16];
		guint32 mask6;
	} *addrs;
	gsize nelts, i;
	gint lc;
	gboolean all_good = TRUE;
	gdouble ts1, ts2;
	double diff;

	/* Test suite for the compressed trie */
	rspamd_radix_text_vec ();

	nelts = max_elts;
	/* First of all we generate many elements and push them to the array */
	addrs = g_malloc (nelts * sizeof (addrs[0]));

	for (i = 0; i < nelts; i ++) {
		addrs[i].addr = ottery_rand_uint32 ();
		addrs[i].mask = masks[ottery_rand_range(G_N_ELEMENTS (masks) - 1)];
		ottery_rand_bytes (addrs[i].addr6, sizeof(addrs[i].addr6));
		addrs[i].mask6 = ottery_rand_range(128);
	}
#if 0
	msg_info ("old radix performance (%z elts)", nelts);
	ts1 = rspamd_get_ticks ();
	for (i = 0; i < nelts; i ++) {
		guint32 mask = G_MAXUINT32 << (32 - addrs[i].mask);
		radix32tree_insert (tree, addrs[i].addr, mask, 1);
	}
	ts2 = rspamd_get_ticks ();
	diff = (ts2 - ts1) * 1000.0;

	msg_info ("Added %z elements in %.6f ms", nelts, diff);

	ts1 = rspamd_get_ticks ();
	for (lc = 0; lc < lookup_cycles; lc ++) {
		for (i = 0; i < nelts; i ++) {
			g_assert (radix32tree_find (tree, addrs[i].addr) != RADIX_NO_VALUE);
		}
	}
	ts2 = rspamd_get_ticks ();
	diff = (ts2 - ts1) * 1000.0;

	msg_info ("Checked %z elements in %.6f ms", nelts, diff);

	ts1 = rspamd_get_ticks ();
	for (i = 0; i < nelts; i ++) {
		radix32tree_delete (tree, addrs[i].addr, addrs[i].mask);
	}
	ts2 = rspamd_get_ticks ();
	diff = (ts2 - ts1) * 1000.;

	msg_info ("Deleted %z elements in %.6f ms", nelts, diff);

	radix_tree_free (tree);
#endif
	msg_info ("new radix performance (%z elts)", nelts);
	ts1 = rspamd_get_ticks ();
	for (i = 0; i < nelts; i ++) {
		radix_insert_compressed (comp_tree, addrs[i].addr6, sizeof (addrs[i].addr6),
				128 - addrs[i].mask6, i);
	}
	ts2 = rspamd_get_ticks ();
	diff = (ts2 - ts1) * 1000.0;

	msg_info ("Added %z elements in %.6f ms", nelts, diff);

	ts1 = rspamd_get_ticks ();
	for (lc = 0; lc < lookup_cycles; lc ++) {
		for (i = 0; i < nelts; i ++) {
			if (radix_find_compressed (comp_tree, addrs[i].addr6, sizeof (addrs[i].addr6))
					== RADIX_NO_VALUE) {
				all_good = FALSE;
			}
		}
	}
#if 1
	if (!all_good) {
		for (i = 0; i < nelts; i ++) {
			/* Used to write bad random vector */
			char ipbuf[INET6_ADDRSTRLEN + 1];
			inet_ntop(AF_INET6, addrs[i].addr6, ipbuf, sizeof(ipbuf));
			msg_info("{\"%s\", NULL, \"%ud\", 0, 0, 0, 0},",
					ipbuf,
					addrs[i].mask6);
		}
	}
#endif

	g_assert (all_good);
	ts2 = rspamd_get_ticks ();
	diff = (ts2 - ts1) * 1000.0;

	msg_info ("Checked %z elements in %.6f ms", nelts, diff);
	radix_destroy_compressed (comp_tree);

	g_free (addrs);
}