/*
* Insert the given datum at position 'pos' (measured from 0) in the list.
* 'pos' must be valid, ie, 0 <= pos <= list's length.
+ *
+ * Note that this takes time proportional to the distance to the end of the
+ * list, since the following entries must be moved.
*/
List *
list_insert_nth(List *list, int pos, void *datum)
* value, rather than continuing to use the pointer passed as the
* second argument.
*
+ * Note that this takes time proportional to the length of the list,
+ * since the existing entries must be moved.
+ *
* Caution: before Postgres 8.0, the original List was unmodified and
* could be considered to retain its separate identity. This is no longer
* the case.
* Callers should be sure to use the return value as the new pointer to the
* concatenated list: the 'list1' input pointer may or may not be the same
* as the returned pointer.
+ *
+ * Note that this takes at least time proportional to the length of list2.
+ * It'd typically be the case that we have to enlarge list1's storage,
+ * probably adding time proportional to the length of list1.
*/
List *
list_concat(List *list1, const List *list2)
* Return true iff 'datum' is a member of the list. Equality is
* determined via equal(), so callers should ensure that they pass a
* Node as 'datum'.
+ *
+ * This does a simple linear search --- avoid using it on long lists.
*/
bool
list_member(const List *list, const void *datum)
* Delete the n'th cell (counting from 0) in list.
*
* The List is pfree'd if this was the last member.
+ *
+ * Note that this takes time proportional to the distance to the end of the
+ * list, since the following entries must be moved.
*/
List *
list_delete_nth_cell(List *list, int n)
*
* The List is pfree'd if this was the last member. However, we do not
* touch any data the cell might've been pointing to.
+ *
+ * Note that this takes time proportional to the distance to the end of the
+ * list, since the following entries must be moved.
*/
List *
list_delete_cell(List *list, ListCell *cell)
/*
* Delete the first cell in list that matches datum, if any.
* Equality is determined via equal().
+ *
+ * This does a simple linear search --- avoid using it on long lists.
*/
List *
list_delete(List *list, void *datum)
* where the intent is to alter the list rather than just traverse it.
* Beware that the list is modified, whereas the Lisp-y coding leaves
* the original list head intact in case there's another pointer to it.
+ *
+ * Note that this takes time proportional to the length of the list,
+ * since the remaining entries must be moved. Consider reversing the
+ * list order so that you can use list_delete_last() instead. However,
+ * if that causes you to replace lappend() with lcons(), you haven't
+ * improved matters. (In short, you can make an efficient stack from
+ * a List, but not an efficient FIFO queue.)
*/
List *
list_delete_first(List *list)
/*
* Delete the last element of the list.
- *
- * This is the opposite of list_delete_first(), but is noticeably cheaper
- * with a long list, since no data need be moved.
*/
List *
list_delete_last(List *list)
* Delete the first N cells of the list.
*
* The List is pfree'd if the request causes all cells to be deleted.
+ *
+ * Note that this takes time proportional to the distance to the end of the
+ * list, since the following entries must be moved.
*/
List *
list_delete_first_n(List *list, int n)
* you probably want to use list_concat_unique() instead to avoid wasting
* the storage of the old x list.
*
- * This function could probably be implemented a lot faster if it is a
- * performance bottleneck.
+ * Note that this takes time proportional to the product of the list
+ * lengths, so beware of using it on long lists. (We could probably
+ * improve that, but really you should be using some other data structure
+ * if this'd be a performance bottleneck.)
*/
List *
list_union(const List *list1, const List *list2)
* This variant works on lists of pointers, and determines list
* membership via equal(). Note that the list1 member will be pointed
* to in the result.
+ *
+ * Note that this takes time proportional to the product of the list
+ * lengths, so beware of using it on long lists. (We could probably
+ * improve that, but really you should be using some other data structure
+ * if this'd be a performance bottleneck.)
*/
List *
list_intersection(const List *list1, const List *list2)
*
* This variant works on lists of pointers, and determines list
* membership via equal()
+ *
+ * Note that this takes time proportional to the product of the list
+ * lengths, so beware of using it on long lists. (We could probably
+ * improve that, but really you should be using some other data structure
+ * if this'd be a performance bottleneck.)
*/
List *
list_difference(const List *list1, const List *list2)
*
* Whether an element is already a member of the list is determined
* via equal().
+ *
+ * This does a simple linear search --- avoid using it on long lists.
*/
List *
list_append_unique(List *list, void *datum)
* modified in-place rather than being copied. However, callers of this
* function may have strict ordering expectations -- i.e. that the relative
* order of those list2 elements that are not duplicates is preserved.
+ *
+ * Note that this takes time proportional to the product of the list
+ * lengths, so beware of using it on long lists. (We could probably
+ * improve that, but really you should be using some other data structure
+ * if this'd be a performance bottleneck.)
*/
List *
list_concat_unique(List *list1, const List *list2)
*
* It is caller's responsibility to have sorted the list to bring duplicates
* together, perhaps via list_sort(list, list_oid_cmp).
+ *
+ * Note that this takes time proportional to the length of the list.
*/
void
list_deduplicate_oid(List *list)
*
* Like qsort(), this provides no guarantees about sort stability
* for equal keys.
+ *
+ * This is based on qsort(), so it likewise has O(N log N) runtime.
*/
void
list_sort(List *list, list_sort_comparator cmp)