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); }
/** * 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); }
/** * 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; }
/** * 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; }
/** * 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); }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }