Re: POC: converting Lists into arrays

Tom Lane <tgl@sss.pgh.pa.us>

From: Tom Lane <tgl@sss.pgh.pa.us>
To: jesper.pedersen@redhat.com
Cc: David Rowley <david.rowley@2ndquadrant.com>, Andres Freund <andres@anarazel.de>, Robert Haas <robertmhaas@gmail.com>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2019-07-01T23:27:21Z
Lists: pgsql-hackers

Attachments

I spent some time experimenting with the idea mentioned upthread of
adding a macro to support deletion of a foreach loop's current element
(adjusting the loop's state behind the scenes).  This turns out to work
really well: it reduces the complexity of fixing existing loops around
element deletions quite a bit.  Whereas in existing code you have to not
use foreach() at all, and you have to track both the next list element and
the previous undeleted element, now you can use foreach() and you don't
have to mess with extra variables at all.

A good example appears in the trgm_regexp.c changes below.  Typically
we've coded such loops with a handmade expansion of foreach, like

	prev = NULL;
	cell = list_head(state->enterKeys);
	while (cell)
	{
		TrgmStateKey *existingKey = (TrgmStateKey *) lfirst(cell);

		next = lnext(cell);
		if (need to delete)
			state->enterKeys = list_delete_cell(state->enterKeys,
							cell, prev);
		else
			prev = cell;
		cell = next;
	}

My previous patch would have had you replace this with a loop using
an integer list-position index.  You can still do that if you like,
but it's less change to convert the loop to a foreach(), drop the
prev/next variables, and replace the list_delete_cell call with
foreach_delete_current:

	foreach(cell, state->enterKeys)
	{
		TrgmStateKey *existingKey = (TrgmStateKey *) lfirst(cell);

		if (need to delete)
			state->enterKeys = foreach_delete_current(state->enterKeys,
								cell);
	}

So I think this is a win, and attached is v7.

			regards, tom lane

Commits

  1. Remove EState.es_range_table_array.

  2. Rationalize use of list_concat + list_copy combinations.

  3. Cosmetic improvements in setup of planner's per-RTE arrays.

  4. Make better use of the new List implementation in a couple of places

  5. Fix sepgsql test results for commit d97b714a2.

  6. Avoid using lcons and list_delete_first where it's easy to do so.

  7. Remove lappend_cell...() family of List functions.

  8. Clean up some ad-hoc code for sorting and de-duplicating Lists.

  9. Redesign the API for list sorting (list_qsort becomes list_sort).

  10. Remove dead code.

  11. Represent Lists as expansible arrays, not chains of cons-cells.

  12. Standardize some more loops that chase down parallel lists.

  13. Reimplement the linked list data structure used throughout the backend.