コード例 #1
0
ファイル: upload_stats.c プロジェクト: Haxe/gtk-gnutella
static void
upload_stats_add(const char *pathname, filesize_t size, const char *name,
	guint32 attempts, guint32 complete, guint64 ul_bytes,
	time_t rtime, time_t dtime, const struct sha1 *sha1)
{
	static const struct ul_stats zero_stats;
	struct ul_stats *s;

	g_assert(pathname != NULL);
	g_assert(name != NULL);

	WALLOC(s);
	*s = zero_stats;
	s->pathname = atom_str_get(pathname);
	s->filename = atom_str_get(name);
	s->size = size;
	s->attempts = attempts;
	s->complete = complete;
	s->norm = size > 0 ? 1.0 * ul_bytes / size : 0.0;
	s->bytes_sent = ul_bytes;
	s->rtime = rtime;
	s->dtime = dtime;
	s->sha1 = sha1 ? atom_sha1_get(sha1) : NULL;

	if (!upload_stats_list) {
		g_assert(!upload_stats_by_sha1);
		upload_stats_list = hash_list_new(ul_stats_hash, ul_stats_eq);
		upload_stats_by_sha1 = g_hash_table_new(sha1_hash, sha1_eq);
	}
	hash_list_append(upload_stats_list, s);
	if (s->sha1)
		gm_hash_table_insert_const(upload_stats_by_sha1, s->sha1, s);
	gcu_upload_stats_gui_add(s);
}
コード例 #2
0
/**
 * Initializations.
 */
void G_COLD
uhc_init(void)
{
	uint i;

	g_return_if_fail(NULL == uhc_list);
	uhc_list = hash_list_new(uhc_hash, uhc_equal);

	for (i = 0; i < N_ITEMS(boot_hosts); i++) {
		const char *host, *ep, *uhc;
		uint16 port;

		uhc = boot_hosts[i].uhc;

		/* Some consistency checks */
		uhc_get_host_port(uhc, &host, &port);
		g_assert(NULL != host);
		g_assert(0 != port);

		ep = is_strprefix(uhc, host);
		g_assert(NULL != ep);
		g_assert(':' == ep[0]);

		uhc_list_append(uhc);
	}

	hash_list_shuffle(uhc_list);
}
コード例 #3
0
ファイル: xattr.c プロジェクト: luciomarinelli/gtk-gnutella
/**
 * Create a new attribute table.
 */
xattr_table_t *
xattr_table_make(void)
{
	xattr_table_t *xat;

	WALLOC(xat);
	xat->magic = XATTR_TABLE_MAGIC;
	xat->hl = hash_list_new(xattr_hash, xattr_eq);

	return xat;
}
コード例 #4
0
/**
 * Create a new ordered hash table.
 *
 * @param hash_func			the hash function for keys
 * @param keys_eq_func		the key comparison function
 *
 * @return the new ordered hash table.
 */
ohash_table_t *
ohash_table_new(hash_fn_t hash_func, eq_fn_t key_eq_func)
{
	ohash_table_t *oh;

	WALLOC(oh);
	oh->magic = OHASH_TABLE_MAGIC;
	oh->hl = hash_list_new(ohash_key_hash, ohash_key_eq);
	oh->hash_func = hash_func;
	oh->key_eq_func = key_eq_func;

	return oh;
}
コード例 #5
0
ファイル: udp.c プロジェクト: MrJoe/gtk-gnutella
/**
 * UDP layer startup
 */
void
udp_init(void)
{
	/*
	 * Limit sending of UDP pings to 1 per UDP_PING_FREQ seconds.
	 */

	udp_aging_pings = aging_make(UDP_PING_FREQ,
		host_addr_hash_func, host_addr_eq_func, wfree_host_addr);

	udp_pings = hash_list_new(guid_hash, guid_eq);
	udp_ping_ev = cq_periodic_main_add(UDP_PING_PERIODIC_MS,
		udp_ping_timer, NULL);
}
コード例 #6
0
ファイル: wq.c プロジェクト: gtk-gnutella/gtk-gnutella
/**
 * Record a waiting event.
 *
 * @param key		waiting key
 * @param cb		callback to invoke on wakeup
 * @param arg		additional callback argument
 *
 * @return the registered event, whose reference must be kept if it is meant
 * to be cancelled.
 */
wq_event_t *
wq_sleep(const void *key, wq_callback_t cb, void *arg)
{
	wq_event_t *we;
	hash_list_t *hl;

	we = wq_event_alloc(key, cb, arg);
	hl = htable_lookup(waitqueue, key);
	if (NULL == hl) {
		hl = hash_list_new(pointer_hash, NULL);
		htable_insert(waitqueue, key, hl);
	}
	hash_list_append(hl, we);		/* FIFO layout */

	return we;
}
コード例 #7
0
ファイル: lru.c プロジェクト: luciomarinelli/gtk-gnutella
/**
 * Setup allocated LRU page cache.
 */
static int
setup_cache(struct lru_cache *cache, long pages, bool wdelay)
{
	cache->arena = vmm_alloc(pages * DBM_PBLKSIZ);
	if (NULL == cache->arena)
		return -1;
	cache->pagnum = htable_create(HASH_KEY_SELF, 0);
	cache->used = hash_list_new(NULL, NULL);
	cache->available = slist_new();
	cache->pages = pages;
	cache->next = 0;
	cache->write_deferred = wdelay;
	cache->dirty = walloc(cache->pages);
	WALLOC_ARRAY(cache->numpag, cache->pages);

	return 0;
}
コード例 #8
0
/**
 * Setup allocated LRU page cache.
 */
static int
setup_cache(struct lru_cache *cache, long pages, gboolean wdelay)
{
	cache->arena = vmm_alloc(pages * DBM_PBLKSIZ);
	if (NULL == cache->arena)
		return -1;
	cache->pagnum = g_hash_table_new(NULL, NULL);
	cache->used = hash_list_new(NULL, NULL);
	cache->available = slist_new();
	cache->pages = pages;
	cache->next = 0;
	cache->write_deferred = wdelay;
	cache->dirty = walloc(cache->pages);
	cache->numpag = walloc(cache->pages * sizeof(long));

	return 0;
}
コード例 #9
0
/**
 * Creates a new UDP TX scheduling layer.
 *
 * The layer can be attached to multiple TX layers, which will then share
 * the same bandwidth limitation.  This is given by the "bws" parameter.
 *
 * The sockets are dynamically fetched, since the application can disable
 * them and recreate them depending on dynamic user reconfiguration.
 *
 * @param bws			the bandwidth scheduler used for output
 * @param get_socket	callback to get the UDP socket to write to
 *
 * @return a new scheduler.
 */
udp_sched_t *
udp_sched_make(
	bsched_bws_t bws, udp_sched_socket_cb_t get_socket)
{
	udp_sched_t *us;
	unsigned i;

	WALLOC0(us);
	us->magic = UDP_SCHED_MAGIC;
	us->txpool = pool_create("UDP TX descriptors", sizeof(struct udp_tx_desc),
		udp_tx_desc_alloc, udp_tx_desc_free, NULL);
	us->get_socket = get_socket;
	us->bws = bws;
	udp_sched_update_sockets(us);
	for (i = 0; i < N_ITEMS(us->lifo); i++) {
		eslist_init(&us->lifo[i], offsetof(struct udp_tx_desc, lnk));
	}
	eslist_init(&us->tx_released, offsetof(struct udp_tx_desc, lnk));
	us->seen =
		hset_create_any(gnet_host_hash, gnet_host_hash2, gnet_host_equal);
	us->stacks = hash_list_new(udp_tx_stack_hash, udp_tx_stack_eq);

	return us;
}
コード例 #10
0
ファイル: dbmw.c プロジェクト: Haxe/gtk-gnutella
/**
 * Create a new DBM wrapper over already created DB map.
 *
 * If value_data_size is 0, the length for value_size is used.
 *
 * @param dm				The database (already opened)
 * @param name				Database name, for logs
 * @param value_size		Maximum value size, in bytes (structure)
 * @param value_data_size	Maximum value size, in bytes (serialized form)
 * @param pack				Serialization routine for values
 * @param unpack			Deserialization routine for values
 * @param valfree			Free routine for value (or NULL if none needed)
 * @param cache_size		Amount of items to cache (0 = no cache, 1 = default)
 * @param hash_func			Key hash function
 * @param eq_func			Key equality test function
 *
 * If serialization and deserialization routines are NULL pointers, data
 * will be stored and retrieved as-is.  In that case, they must be both
 * NULL.
 */
dbmw_t *
dbmw_create(dbmap_t *dm, const char *name,
	size_t value_size, size_t value_data_size,
	dbmw_serialize_t pack, dbmw_deserialize_t unpack, dbmw_free_t valfree,
	size_t cache_size, GHashFunc hash_func, GEqualFunc eq_func)
{
	dbmw_t *dw;

	g_assert(pack == NULL || value_size);
	g_assert((pack != NULL) == (unpack != NULL));
	g_assert(valfree == NULL || unpack != NULL);
	g_assert(dm);

	WALLOC0(dw);
	dw->magic = DBMW_MAGIC;
	dw->dm = dm;
	dw->name = name;

	dw->key_size = dbmap_key_size(dm);
	dw->key_len = dbmap_key_length(dm);
	dw->value_size = value_size;
	dw->value_data_size = 0 == value_data_size ? value_size : value_data_size;

	/* Make sure we do not violate the SDBM constraint */
	g_assert(sdbm_is_storable(dw->key_size, dw->value_data_size));

	/*
	 * There must be a serialization routine if the serialized length is not
	 * the same as the structure length.
	 */
	g_assert(dw->value_size == dw->value_data_size || pack != NULL);

	/*
	 * For a small amount of items, a PATRICIA tree is more efficient
	 * than a hash table although it uses more memory.
	 */

	if (
		NULL == dw->key_len &&
		dw->key_size * 8 <= PATRICIA_MAXBITS &&
		cache_size <= DBMW_CACHE
	) {
		dw->values = map_create_patricia(dw->key_size * 8);
	} else {
		dw->values = map_create_hash(hash_func, eq_func);
	}

	dw->keys = hash_list_new(hash_func, eq_func);
	dw->pack = pack;
	dw->unpack = unpack;
	dw->valfree = valfree;

	/*
	 * If a serialization routine is provided, we'll also have a need for
	 * deserialization.  Allocate the message in/out streams.
	 *
	 * We're allocating one more byte than necessary to be able to check
	 * whether serialization stays within the imposed boundaries.
	 */

	if (dw->pack) {
		dw->bs = bstr_create();
		dw->mb = pmsg_new(PMSG_P_DATA, NULL, dw->value_data_size + 1);
	}

	/*
	 * If cache_size is zero, we won't cache anything but the latest
	 * value requested, in deserialized form.  If modified, it will be
	 * written back immediately.
	 *
	 * If cache_size is one, use the default (DBMW_CACHE).
	 *
	 * Any other value is used as-is.
	 */

	if (0 == cache_size)
		dw->max_cached = 1;		/* No cache, only keep latest around */
	else if (cache_size == 1)
		dw->max_cached = DBMW_CACHE;
	else
		dw->max_cached = cache_size;

	if (common_dbg)
		g_debug("DBMW created \"%s\" with %s back-end "
			"(max cached = %lu, key=%lu bytes, value=%lu bytes, "
			"%lu max serialized)",
			dw->name, dbmw_map_type(dw) == DBMAP_SDBM ? "sdbm" : "map",
			(gulong) dw->max_cached,
			(gulong) dw->key_size, (gulong) dw->value_size,
			(gulong) dw->value_data_size);

	return dw;
}