示例#1
0
/**
 * Insert `key' into the list.
 *
 * It is safe to call this routine whilst iterating although there is no
 * guarantee as to whether the iteration will see the new item.
 */
void
hash_list_insert_sorted(hash_list_t *hl, const void *key, cmp_fn_t func)
{
	link_t *lk;

	hash_list_check(hl);
	g_assert(NULL != func);
	g_assert(!hikset_contains(hl->ht, key));

	for (lk = elist_first(&hl->list); lk != NULL; lk = elist_next(lk)) {
		struct hash_list_item *item = ITEM(lk);
		if ((*func)(key, item->key) <= 0)
			break;
	}

	if (NULL == lk) {
		hash_list_append(hl, key);
	} else {
		struct hash_list_item *item;

		WALLOC(item);
		item->key = key;

		/* Inserting ``item'' before ``lk'' */

		elist_link_insert_before(&hl->list, lk, &item->lnk);
		hash_list_insert_item(hl, item);
	}
}
示例#2
0
/**
 * Dispose of the data structure, but not of the items it holds.
 *
 * @param hl_ptr	pointer to the variable containing the address of the list
 *
 * As a side effect, the variable containing the address of the list
 * is nullified, since it is no longer allowed to refer to the structure.
 */
void
hash_list_free(hash_list_t **hl_ptr)
{
	g_assert(NULL != hl_ptr);

	if (*hl_ptr) {
		hash_list_t *hl = *hl_ptr;
		link_t *lk, *next;

		hash_list_check(hl);

		if (--hl->refcount != 0) {
			g_carp("%s: hash list is still referenced! "
				"(hl=%p, hl->refcount=%d)",
				G_STRFUNC, cast_to_pointer(hl), hl->refcount);
		}

		hikset_free_null(&hl->ht);

		for (lk = elist_first(&hl->list); lk != NULL; lk = next) {
			struct hash_list_item *item = ITEM(lk);
			next = elist_next(lk);	/* Embedded, get next before freeing */
			WFREE(item);
		}

		elist_discard(&hl->list);
		hl->magic = 0;
		WFREE(hl);
		*hl_ptr = NULL;
	}
}
示例#3
0
		extern int attrlayer_flush(int flags)
		{
			static t_elist *curr = &loadedlist;
			static t_elist *next = NULL;
			t_attrgroup *attrgroup;
			unsigned int fcount;
			unsigned int tcount;

			fcount = tcount = 0;
			if (curr == &loadedlist || FLAG_ISSET(flags, FS_ALL)) {
				curr = elist_next(&loadedlist);
				next = elist_next(curr);
			}

			/* elist_for_each_safe splitted into separate startup for userstep function */
			for (; curr != &loadedlist; curr = next, next = elist_next(curr)) {
				if (!FLAG_ISSET(flags, FS_ALL) && tcount >= prefs_get_user_step()) break;

				attrgroup = elist_entry(curr, t_attrgroup, loadedlist);
				switch (attrgroup_flush(attrgroup, flags)) {
				case 0:
					/* stop on the first account not flushed (ie accessed too early) */
					goto loopout;
				case 1:
					fcount++;
					break;
				case -1:
					eventlog(eventlog_level_error, __FUNCTION__, "could not flush account");
					break;
				default:
					break;
				}
				tcount++;
			}

		loopout:
			if (fcount > 0)
				eventlog(eventlog_level_debug, __FUNCTION__, "flushed %u user accounts", fcount);

			if (!FLAG_ISSET(flags, FS_ALL) && curr != &loadedlist) return 1;

			return 0;
		}
示例#4
0
/**
 * Get the next item after a given key.
 *
 * This is more costly than taking an iterator and traversing the structure,
 * but it is safe to use when the processing of each item can remove the item
 * from the traversed structure.
 *
 * Here's template code demonstrating usage:
 *
 *		void *next = hash_list_head(hl);
 *		while (next) {
 *			struct <item> *item = next;
 *			next = hash_list_next(hl, next);
 *			<process item, can be safely removed from hl>
 *		}
 *
 * @return pointer to next item, NULL if we reached the end of the list.
 */
void *
hash_list_next(hash_list_t *hl, const void *key)
{
	struct hash_list_item *item;

	hash_list_check(hl);

	item = hikset_lookup(hl->ht, key);
	item = item ? elist_data(&hl->list, elist_next(&item->lnk)) : NULL;
	return item ? deconstify_pointer(item->key) : NULL;
}
示例#5
0
/**
 * Apply `func' to all the items in the structure.
 */
void
hash_list_foreach(const hash_list_t *hl, data_fn_t func, void *user_data)
{
	link_t *lk;
	
	hash_list_check(hl);
	g_assert(NULL != func);

	for (lk = elist_first(&hl->list); lk != NULL; lk = elist_next(lk)) {
		struct hash_list_item *item = ITEM(lk);
		(*func)(deconstify_pointer(item->key), user_data);
	}

	hash_list_regression(hl);
}
示例#6
0
/**
 * Get the previous data item from the iterator, or NULL if none.
 */
G_GNUC_HOT void *
hash_list_iter_previous(hash_list_iter_t *iter)
{
	link_t *prev;

	hash_list_iter_check(iter);

	prev = iter->prev;
	if (prev != NULL) {
		iter->item = ITEM(prev);
		iter->next = elist_next(prev);
		iter->prev = elist_prev(prev);
		return deconstify_pointer(iter->item->key);
	} else {
		return NULL;
	}
}
示例#7
0
/**
 * Get the next data item from the iterator, or NULL if none.
 */
G_GNUC_HOT void *
hash_list_iter_next(hash_list_iter_t *iter)
{
	link_t *next;

	hash_list_iter_check(iter);

	next = iter->next;
	if (next != NULL) {
		iter->item = ITEM(next);
		iter->prev = elist_prev(next);
		iter->next = elist_next(next);
		return deconstify_pointer(iter->item->key);
	} else {
		return NULL;
	}
}
示例#8
0
/**
 * Apply `func' to all the items in the structure, removing the entry
 * if `func' returns TRUE.
 *
 * @return the amount of entries removed from the list.
 */
size_t
hash_list_foreach_remove(hash_list_t *hl, data_rm_fn_t func, void *data)
{
	link_t *lk, *next;
	size_t removed = 0;
	
	hash_list_check(hl);
	g_assert(func != NULL);

	for (lk = elist_first(&hl->list); lk != NULL; lk = next) {
		struct hash_list_item *item = ITEM(lk);

		next = elist_next(lk);
		if ((*func)(deconstify_pointer(item->key), data)) {
			hash_list_remove_item(hl, item);
			removed++;
		}
	}

	hash_list_regression(hl);

	return removed;
}
示例#9
0
/**
 * Get an iterator on the list, positionned at the specified item.
 * Get next items with hash_list_iter_next() or hash_list_iter_previous().
 *
 * @return the iterator object or NULL if the key is not in the list.
 */
hash_list_iter_t *
hash_list_iterator_at(hash_list_t *hl, const void *key)
{
	if (hl) {
		struct hash_list_item *item;

		hash_list_check(hl);

		item = hikset_lookup(hl->ht, key);
		if (item) {
			hash_list_iter_t *iter;

			iter = hash_list_iterator_new(hl, HASH_LIST_ITER_UNDEFINED);
			iter->prev = elist_prev(&item->lnk);
			iter->next = elist_next(&item->lnk);
			iter->item = item;
			return iter;
		} else {
			return NULL;
		}
	} else {
		return NULL;
	}
}