⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 list.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
	prev = NULL;	foreach(cell, list)	{		if (lfirst_int(cell) == datum)			return list_delete_cell(list, cell, prev);		prev = cell;	}	/* Didn't find a match: return the list unmodified */	return list;}/* As above, but for OIDs */List *list_delete_oid(List *list, Oid datum){	ListCell   *cell;	ListCell   *prev;	Assert(IsOidList(list));	check_list_invariants(list);	prev = NULL;	foreach(cell, list)	{		if (lfirst_oid(cell) == datum)			return list_delete_cell(list, cell, prev);		prev = cell;	}	/* Didn't find a match: return the list unmodified */	return list;}/* * Delete the first element of the list. * * This is useful to replace the Lisp-y code "list = lnext(list);" in cases * where the intent is to alter the list rather than just traverse it. * Beware that the removed cell is freed, whereas the lnext() coding leaves * the original list head intact if there's another pointer to it. */List *list_delete_first(List *list){	check_list_invariants(list);	if (list == NIL)		return NIL;				/* would an error be better? */	return list_delete_cell(list, list_head(list), NULL);}/* * Generate the union of two lists. This is calculated by copying * list1 via list_copy(), then adding to it all the members of list2 * that aren't already in list1. * * Whether an element is already a member of the list is determined * via equal(). * * The returned list is newly-allocated, although the content of the * cells is the same (i.e. any pointed-to objects are not copied). * * NB: this function will NOT remove any duplicates that are present * in list1 (so it only performs a "union" if list1 is known unique to * start with).  Also, if you are about to write "x = list_union(x, y)" * you probably want to use list_concat_unique() instead to avoid wasting * the list cells of the old x list. * * This function could probably be implemented a lot faster if it is a * performance bottleneck. */List *list_union(List *list1, List *list2){	List	   *result;	ListCell   *cell;	Assert(IsPointerList(list1));	Assert(IsPointerList(list2));	result = list_copy(list1);	foreach(cell, list2)	{		if (!list_member(result, lfirst(cell)))			result = lappend(result, lfirst(cell));	}	check_list_invariants(result);	return result;}/* * This variant of list_union() determines duplicates via simple * pointer comparison. */List *list_union_ptr(List *list1, List *list2){	List	   *result;	ListCell   *cell;	Assert(IsPointerList(list1));	Assert(IsPointerList(list2));	result = list_copy(list1);	foreach(cell, list2)	{		if (!list_member_ptr(result, lfirst(cell)))			result = lappend(result, lfirst(cell));	}	check_list_invariants(result);	return result;}/* * This variant of list_union() operates upon lists of integers. */List *list_union_int(List *list1, List *list2){	List	   *result;	ListCell   *cell;	Assert(IsIntegerList(list1));	Assert(IsIntegerList(list2));	result = list_copy(list1);	foreach(cell, list2)	{		if (!list_member_int(result, lfirst_int(cell)))			result = lappend_int(result, lfirst_int(cell));	}	check_list_invariants(result);	return result;}/* * This variant of list_union() operates upon lists of OIDs. */List *list_union_oid(List *list1, List *list2){	List	   *result;	ListCell   *cell;	Assert(IsOidList(list1));	Assert(IsOidList(list2));	result = list_copy(list1);	foreach(cell, list2)	{		if (!list_member_oid(result, lfirst_oid(cell)))			result = lappend_oid(result, lfirst_oid(cell));	}	check_list_invariants(result);	return result;}/* * Return a list that contains all the cells in list1 that are not in * list2. The returned list is freshly allocated via palloc(), but the * cells themselves point to the same objects as the cells of the * input lists. * * This variant works on lists of pointers, and determines list * membership via equal() */List *list_difference(List *list1, List *list2){	ListCell   *cell;	List	   *result = NIL;	Assert(IsPointerList(list1));	Assert(IsPointerList(list2));	if (list2 == NIL)		return list_copy(list1);	foreach(cell, list1)	{		if (!list_member(list2, lfirst(cell)))			result = lappend(result, lfirst(cell));	}	check_list_invariants(result);	return result;}/* * This variant of list_difference() determines list membership via * simple pointer equality. */List *list_difference_ptr(List *list1, List *list2){	ListCell   *cell;	List	   *result = NIL;	Assert(IsPointerList(list1));	Assert(IsPointerList(list2));	if (list2 == NIL)		return list_copy(list1);	foreach(cell, list1)	{		if (!list_member_ptr(list2, lfirst(cell)))			result = lappend(result, lfirst(cell));	}	check_list_invariants(result);	return result;}/* * This variant of list_difference() operates upon lists of integers. */List *list_difference_int(List *list1, List *list2){	ListCell   *cell;	List	   *result = NIL;	Assert(IsIntegerList(list1));	Assert(IsIntegerList(list2));	if (list2 == NIL)		return list_copy(list1);	foreach(cell, list1)	{		if (!list_member_int(list2, lfirst_int(cell)))			result = lappend_int(result, lfirst_int(cell));	}	check_list_invariants(result);	return result;}/* * This variant of list_difference() operates upon lists of OIDs. */List *list_difference_oid(List *list1, List *list2){	ListCell   *cell;	List	   *result = NIL;	Assert(IsOidList(list1));	Assert(IsOidList(list2));	if (list2 == NIL)		return list_copy(list1);	foreach(cell, list1)	{		if (!list_member_oid(list2, lfirst_oid(cell)))			result = lappend_oid(result, lfirst_oid(cell));	}	check_list_invariants(result);	return result;}/* * Append datum to list, but only if it isn't already in the list. * * Whether an element is already a member of the list is determined * via equal(). */List *list_append_unique(List *list, void *datum){	if (list_member(list, datum))		return list;	else		return lappend(list, datum);}/* * This variant of list_append_unique() determines list membership via * simple pointer equality. */List *list_append_unique_ptr(List *list, void *datum){	if (list_member_ptr(list, datum))		return list;	else		return lappend(list, datum);}/* * This variant of list_append_unique() operates upon lists of integers. */List *list_append_unique_int(List *list, int datum){	if (list_member_int(list, datum))		return list;	else		return lappend_int(list, datum);}/* * This variant of list_append_unique() operates upon lists of OIDs. */List *list_append_unique_oid(List *list, Oid datum){	if (list_member_oid(list, datum))		return list;	else		return lappend_oid(list, datum);}/* * Append to list1 each member of list2 that isn't already in list1. * * Whether an element is already a member of the list is determined * via equal(). * * This is almost the same functionality as list_union(), but list1 is * modified in-place rather than being copied.	Note also that list2's cells * are not inserted in list1, so the analogy to list_concat() isn't perfect. */List *list_concat_unique(List *list1, List *list2){	ListCell   *cell;	Assert(IsPointerList(list1));	Assert(IsPointerList(list2));	foreach(cell, list2)	{		if (!list_member(list1, lfirst(cell)))			list1 = lappend(list1, lfirst(cell));	}	check_list_invariants(list1);	return list1;}/* * This variant of list_concat_unique() determines list membership via * simple pointer equality. */List *list_concat_unique_ptr(List *list1, List *list2){	ListCell   *cell;	Assert(IsPointerList(list1));	Assert(IsPointerList(list2));	foreach(cell, list2)	{		if (!list_member_ptr(list1, lfirst(cell)))			list1 = lappend(list1, lfirst(cell));	}	check_list_invariants(list1);	return list1;}/* * This variant of list_concat_unique() operates upon lists of integers. */List *list_concat_unique_int(List *list1, List *list2){	ListCell   *cell;	Assert(IsIntegerList(list1));	Assert(IsIntegerList(list2));	foreach(cell, list2)	{		if (!list_member_int(list1, lfirst_int(cell)))			list1 = lappend_int(list1, lfirst_int(cell));	}	check_list_invariants(list1);	return list1;}/* * This variant of list_concat_unique() operates upon lists of OIDs. */List *list_concat_unique_oid(List *list1, List *list2){	ListCell   *cell;	Assert(IsOidList(list1));	Assert(IsOidList(list2));	foreach(cell, list2)	{		if (!list_member_oid(list1, lfirst_oid(cell)))			list1 = lappend_oid(list1, lfirst_oid(cell));	}	check_list_invariants(list1);	return list1;}/* * Free all storage in a list, and optionally the pointed-to elements */static voidlist_free_private(List *list, bool deep){	ListCell   *cell;	check_list_invariants(list);	cell = list_head(list);	while (cell != NULL)	{		ListCell   *tmp = cell;		cell = lnext(cell);		if (deep)			pfree(lfirst(tmp));		pfree(tmp);	}	if (list)		pfree(list);}/* * Free all the cells of the list, as well as the list itself. Any * objects that are pointed-to by the cells of the list are NOT * free'd. * * On return, the argument to this function has been freed, so the * caller would be wise to set it to NIL for safety's sake. */voidlist_free(List *list){	list_free_private(list, false);}/* * Free all the cells of the list, the list itself, and all the * objects pointed-to by the cells of the list (each element in the * list must contain a pointer to a palloc()'d region of memory!) * * On return, the argument to this function has been freed, so the * caller would be wise to set it to NIL for safety's sake. */voidlist_free_deep(List *list){	/*	 * A "deep" free operation only makes sense on a list of pointers.	 */	Assert(IsPointerList(list));	list_free_private(list, true);}/* * Return a shallow copy of the specified list. */List *list_copy(List *oldlist){	List	   *newlist;	ListCell   *newlist_prev;	ListCell   *oldlist_cur;	if (oldlist == NIL)		return NIL;	newlist = new_list(oldlist->type);	newlist->length = oldlist->length;	/*	 * Copy over the data in the first cell; new_list() has already allocated	 * the head cell itself	 */	newlist->head->data = oldlist->head->data;	newlist_prev = newlist->head;	oldlist_cur = oldlist->head->next;	while (oldlist_cur)	{		ListCell   *newlist_cur;		newlist_cur = (ListCell *) palloc(sizeof(*newlist_cur));		newlist_cur->data = oldlist_cur->data;		newlist_prev->next = newlist_cur;		newlist_prev = newlist_cur;		oldlist_cur = oldlist_cur->next;	}	newlist_prev->next = NULL;	newlist->tail = newlist_prev;	check_list_invariants(newlist);	return newlist;}/* * Return a shallow copy of the specified list, without the first N elements. */List *list_copy_tail(List *oldlist, int nskip){	List	   *newlist;	ListCell   *newlist_prev;	ListCell   *oldlist_cur;	if (nskip < 0)		nskip = 0;				/* would it be better to elog? */	if (oldlist == NIL || nskip >= oldlist->length)		return NIL;	newlist = new_list(oldlist->type);	newlist->length = oldlist->length - nskip;	/*	 * Skip over the unwanted elements.	 */	oldlist_cur = oldlist->head;	while (nskip-- > 0)		oldlist_cur = oldlist_cur->next;	/*	 * Copy over the data in the first remaining cell; new_list() has already	 * allocated the head cell itself	 */	newlist->head->data = oldlist_cur->data;	newlist_prev = newlist->head;	oldlist_cur = oldlist_cur->next;	while (oldlist_cur)	{		ListCell   *newlist_cur;		newlist_cur = (ListCell *) palloc(sizeof(*newlist_cur));		newlist_cur->data = oldlist_cur->data;		newlist_prev->next = newlist_cur;		newlist_prev = newlist_cur;		oldlist_cur = oldlist_cur->next;	}	newlist_prev->next = NULL;	newlist->tail = newlist_prev;	check_list_invariants(newlist);	return newlist;}/* * When using non-GCC compilers, we can't define these as inline * functions in pg_list.h, so they are defined here. * * TODO: investigate supporting inlining for some non-GCC compilers. */#ifndef __GNUC__ListCell *list_head(List *l){	return l ? l->head : NULL;}ListCell *list_tail(List *l){	return l ? l->tail : NULL;}intlist_length(List *l){	return l ? l->length : 0;}#endif   /* ! __GNUC__ *//* * Temporary compatibility functions * * In order to avoid warnings for these function definitions, we need * to include a prototype here as well as in pg_list.h. That's because * we don't enable list API compatibility in list.c, so we * don't see the prototypes for these functions. *//* * Given a list, return its length. This is merely defined for the * sake of backward compatibility: we can't afford to define a macro * called "length", so it must be a function. New code should use the * list_length() macro in order to avoid the overhead of a function * call. */int			length(List *list);intlength(List *list){	return list_length(list);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -