Skip to content

Commit d0b4399

Browse files
author
Neil Conway
committed
Reimplement the linked list data structure used throughout the backend.
In the past, we used a 'Lispy' linked list implementation: a "list" was merely a pointer to the head node of the list. The problem with that design is that it makes lappend() and length() linear time. This patch fixes that problem (and others) by maintaining a count of the list length and a pointer to the tail node along with each head node pointer. A "list" is now a pointer to a structure containing some meta-data about the list; the head and tail pointers in that structure refer to ListCell structures that maintain the actual linked list of nodes. The function names of the list API have also been changed to, I hope, be more logically consistent. By default, the old function names are still available; they will be disabled-by-default once the rest of the tree has been updated to use the new API names.
1 parent 18d0d10 commit d0b4399

File tree

125 files changed

+3438
-2837
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+3438
-2837
lines changed

src/backend/access/common/printtup.c

+9-8
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/access/common/printtup.c,v 1.80 2004/01/07 18:56:23 neilc Exp $
12+
* $PostgreSQL: pgsql/src/backend/access/common/printtup.c,v 1.81 2004/05/26 04:41:03 neilc Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -138,7 +138,7 @@ printtup_startup(DestReceiver *self, int operation, TupleDesc typeinfo)
138138
List *targetlist;
139139

140140
if (portal->strategy == PORTAL_ONE_SELECT)
141-
targetlist = ((Query *) lfirst(portal->parseTrees))->targetList;
141+
targetlist = ((Query *) linitial(portal->parseTrees))->targetList;
142142
else
143143
targetlist = NIL;
144144

@@ -176,6 +176,7 @@ SendRowDescriptionMessage(TupleDesc typeinfo, List *targetlist, int16 *formats)
176176
int proto = PG_PROTOCOL_MAJOR(FrontendProtocol);
177177
int i;
178178
StringInfoData buf;
179+
ListCell *tlist_item = list_head(targetlist);
179180

180181
pq_beginmessage(&buf, 'T'); /* tuple descriptor message type */
181182
pq_sendint(&buf, natts, 2); /* # of attrs in tuples */
@@ -191,16 +192,16 @@ SendRowDescriptionMessage(TupleDesc typeinfo, List *targetlist, int16 *formats)
191192
if (proto >= 3)
192193
{
193194
/* Do we have a non-resjunk tlist item? */
194-
while (targetlist &&
195-
((TargetEntry *) lfirst(targetlist))->resdom->resjunk)
196-
targetlist = lnext(targetlist);
197-
if (targetlist)
195+
while (tlist_item &&
196+
((TargetEntry *) lfirst(tlist_item))->resdom->resjunk)
197+
tlist_item = lnext(tlist_item);
198+
if (tlist_item)
198199
{
199-
Resdom *res = ((TargetEntry *) lfirst(targetlist))->resdom;
200+
Resdom *res = ((TargetEntry *) lfirst(tlist_item))->resdom;
200201

201202
pq_sendint(&buf, res->resorigtbl, 4);
202203
pq_sendint(&buf, res->resorigcol, 2);
203-
targetlist = lnext(targetlist);
204+
tlist_item = lnext(tlist_item);
204205
}
205206
else
206207
{

src/backend/access/common/tupdesc.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.102 2004/04/01 21:28:43 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/common/tupdesc.c,v 1.103 2004/05/26 04:41:03 neilc Exp $
1212
*
1313
* NOTES
1414
* some of the executor utility code such as "ExecTypeFromTL" should be
@@ -472,7 +472,7 @@ BuildDescForRelation(List *schema)
472472
{
473473
int natts;
474474
AttrNumber attnum;
475-
List *p;
475+
ListCell *l;
476476
TupleDesc desc;
477477
AttrDefault *attrdef = NULL;
478478
TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr));
@@ -490,9 +490,9 @@ BuildDescForRelation(List *schema)
490490

491491
attnum = 0;
492492

493-
foreach(p, schema)
493+
foreach(l, schema)
494494
{
495-
ColumnDef *entry = lfirst(p);
495+
ColumnDef *entry = lfirst(l);
496496

497497
/*
498498
* for each entry in the list, get the name and type information
@@ -661,7 +661,7 @@ TypeGetTupleDesc(Oid typeoid, List *colaliases)
661661
errmsg("number of aliases does not match number of columns")));
662662

663663
/* OK, get the column alias */
664-
attname = strVal(lfirst(colaliases));
664+
attname = strVal(linitial(colaliases));
665665

666666
tupdesc = CreateTemplateTupleDesc(1, false);
667667
TupleDescInitEntry(tupdesc,

src/backend/access/nbtree/nbtxlog.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.10 2004/01/07 18:56:24 neilc Exp $
11+
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.11 2004/05/26 04:41:05 neilc Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -59,7 +59,7 @@ forget_matching_split(Relation reln, RelFileNode node,
5959
Page page;
6060
BTItem btitem;
6161
BlockNumber rightblk;
62-
List *l;
62+
ListCell *l;
6363

6464
/* Get downlink TID from page */
6565
buffer = XLogReadBuffer(false, reln, insertblk);
@@ -964,7 +964,7 @@ btree_xlog_startup(void)
964964
void
965965
btree_xlog_cleanup(void)
966966
{
967-
List *l;
967+
ListCell *l;
968968

969969
foreach(l, incomplete_splits)
970970
{

src/backend/bootstrap/bootparse.y

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.67 2004/05/21 05:07:56 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.68 2004/05/26 04:41:05 neilc Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -271,7 +271,7 @@ Boot_BuildIndsStmt:
271271

272272
boot_index_params:
273273
boot_index_params COMMA boot_index_param { $$ = lappend($1, $3); }
274-
| boot_index_param { $$ = makeList1($1); }
274+
| boot_index_param { $$ = list_make1($1); }
275275
;
276276

277277
boot_index_param:
@@ -280,7 +280,7 @@ boot_index_param:
280280
IndexElem *n = makeNode(IndexElem);
281281
n->name = LexIDStr($1);
282282
n->expr = NULL;
283-
n->opclass = makeList1(makeString(LexIDStr($2)));
283+
n->opclass = list_make1(makeString(LexIDStr($2)));
284284
$$ = n;
285285
}
286286
;

src/backend/catalog/aclchk.c

+17-17
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.98 2004/05/11 17:36:12 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.99 2004/05/26 04:41:06 neilc Exp $
1212
*
1313
* NOTES
1414
* See acl.h.
@@ -110,7 +110,7 @@ merge_acl_with_grant(Acl *old_acl, bool is_grant,
110110
AclId grantor_uid, AclId owner_uid)
111111
{
112112
unsigned modechg;
113-
List *j;
113+
ListCell *j;
114114
Acl *new_acl;
115115

116116
modechg = is_grant ? ACL_MODECHG_ADD : ACL_MODECHG_DEL;
@@ -221,16 +221,16 @@ static void
221221
ExecuteGrantStmt_Relation(GrantStmt *stmt)
222222
{
223223
AclMode privileges;
224-
List *i;
224+
ListCell *i;
225225

226-
if (lfirsti(stmt->privileges) == ACL_ALL_RIGHTS)
226+
if (linitial_int(stmt->privileges) == ACL_ALL_RIGHTS)
227227
privileges = ACL_ALL_RIGHTS_RELATION;
228228
else
229229
{
230230
privileges = ACL_NO_RIGHTS;
231231
foreach(i, stmt->privileges)
232232
{
233-
AclMode priv = lfirsti(i);
233+
AclMode priv = lfirst_int(i);
234234

235235
if (priv & ~((AclMode) ACL_ALL_RIGHTS_RELATION))
236236
ereport(ERROR,
@@ -328,16 +328,16 @@ static void
328328
ExecuteGrantStmt_Database(GrantStmt *stmt)
329329
{
330330
AclMode privileges;
331-
List *i;
331+
ListCell *i;
332332

333-
if (lfirsti(stmt->privileges) == ACL_ALL_RIGHTS)
333+
if (linitial_int(stmt->privileges) == ACL_ALL_RIGHTS)
334334
privileges = ACL_ALL_RIGHTS_DATABASE;
335335
else
336336
{
337337
privileges = ACL_NO_RIGHTS;
338338
foreach(i, stmt->privileges)
339339
{
340-
AclMode priv = lfirsti(i);
340+
AclMode priv = lfirst_int(i);
341341

342342
if (priv & ~((AclMode) ACL_ALL_RIGHTS_DATABASE))
343343
ereport(ERROR,
@@ -433,16 +433,16 @@ static void
433433
ExecuteGrantStmt_Function(GrantStmt *stmt)
434434
{
435435
AclMode privileges;
436-
List *i;
436+
ListCell *i;
437437

438-
if (lfirsti(stmt->privileges) == ACL_ALL_RIGHTS)
438+
if (linitial_int(stmt->privileges) == ACL_ALL_RIGHTS)
439439
privileges = ACL_ALL_RIGHTS_FUNCTION;
440440
else
441441
{
442442
privileges = ACL_NO_RIGHTS;
443443
foreach(i, stmt->privileges)
444444
{
445-
AclMode priv = lfirsti(i);
445+
AclMode priv = lfirst_int(i);
446446

447447
if (priv & ~((AclMode) ACL_ALL_RIGHTS_FUNCTION))
448448
ereport(ERROR,
@@ -534,16 +534,16 @@ static void
534534
ExecuteGrantStmt_Language(GrantStmt *stmt)
535535
{
536536
AclMode privileges;
537-
List *i;
537+
ListCell *i;
538538

539-
if (lfirsti(stmt->privileges) == ACL_ALL_RIGHTS)
539+
if (linitial_int(stmt->privileges) == ACL_ALL_RIGHTS)
540540
privileges = ACL_ALL_RIGHTS_LANGUAGE;
541541
else
542542
{
543543
privileges = ACL_NO_RIGHTS;
544544
foreach(i, stmt->privileges)
545545
{
546-
AclMode priv = lfirsti(i);
546+
AclMode priv = lfirst_int(i);
547547

548548
if (priv & ~((AclMode) ACL_ALL_RIGHTS_LANGUAGE))
549549
ereport(ERROR,
@@ -643,16 +643,16 @@ static void
643643
ExecuteGrantStmt_Namespace(GrantStmt *stmt)
644644
{
645645
AclMode privileges;
646-
List *i;
646+
ListCell *i;
647647

648-
if (lfirsti(stmt->privileges) == ACL_ALL_RIGHTS)
648+
if (linitial_int(stmt->privileges) == ACL_ALL_RIGHTS)
649649
privileges = ACL_ALL_RIGHTS_NAMESPACE;
650650
else
651651
{
652652
privileges = ACL_NO_RIGHTS;
653653
foreach(i, stmt->privileges)
654654
{
655-
AclMode priv = lfirsti(i);
655+
AclMode priv = lfirst_int(i);
656656

657657
if (priv & ~((AclMode) ACL_ALL_RIGHTS_NAMESPACE))
658658
ereport(ERROR,

src/backend/catalog/dependency.c

+17-25
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.35 2004/05/05 04:48:45 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.36 2004/05/26 04:41:06 neilc Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -841,7 +841,7 @@ recordDependencyOnExpr(const ObjectAddress *depender,
841841
init_object_addresses(&context.addrs);
842842

843843
/* Set up interpretation for Vars at varlevelsup = 0 */
844-
context.rtables = makeList1(rtable);
844+
context.rtables = list_make1(rtable);
845845

846846
/* Scan the expression tree for referenceable objects */
847847
find_expr_references_walker(expr, &context);
@@ -883,7 +883,7 @@ recordDependencyOnSingleRelExpr(const ObjectAddress *depender,
883883
rte.rtekind = RTE_RELATION;
884884
rte.relid = relId;
885885

886-
context.rtables = makeList1(makeList1(&rte));
886+
context.rtables = list_make1(list_make1(&rte));
887887

888888
/* Scan the expression tree for referenceable objects */
889889
find_expr_references_walker(expr, &context);
@@ -960,24 +960,14 @@ find_expr_references_walker(Node *node,
960960
if (IsA(node, Var))
961961
{
962962
Var *var = (Var *) node;
963-
int levelsup;
964-
List *rtable,
965-
*rtables;
963+
List *rtable;
966964
RangeTblEntry *rte;
967965

968966
/* Find matching rtable entry, or complain if not found */
969-
levelsup = var->varlevelsup;
970-
rtables = context->rtables;
971-
while (levelsup--)
972-
{
973-
if (rtables == NIL)
974-
break;
975-
rtables = lnext(rtables);
976-
}
977-
if (rtables == NIL)
967+
if (var->varlevelsup >= list_length(context->rtables))
978968
elog(ERROR, "invalid varlevelsup %d", var->varlevelsup);
979-
rtable = lfirst(rtables);
980-
if (var->varno <= 0 || var->varno > length(rtable))
969+
rtable = (List *) list_nth(context->rtables, var->varlevelsup);
970+
if (var->varno <= 0 || var->varno > list_length(rtable))
981971
elog(ERROR, "invalid varno %d", var->varno);
982972
rte = rt_fetch(var->varno, rtable);
983973
if (rte->rtekind == RTE_RELATION)
@@ -994,13 +984,15 @@ find_expr_references_walker(Node *node,
994984

995985
/* We must make the context appropriate for join's level */
996986
save_rtables = context->rtables;
997-
context->rtables = rtables;
987+
context->rtables = list_copy_tail(context->rtables,
988+
var->varlevelsup);
998989
if (var->varattno <= 0 ||
999-
var->varattno > length(rte->joinaliasvars))
990+
var->varattno > list_length(rte->joinaliasvars))
1000991
elog(ERROR, "invalid varattno %d", var->varattno);
1001-
find_expr_references_walker((Node *) nth(var->varattno - 1,
1002-
rte->joinaliasvars),
992+
find_expr_references_walker((Node *) list_nth(rte->joinaliasvars,
993+
var->varattno - 1),
1003994
context);
995+
list_free(context->rtables);
1004996
context->rtables = save_rtables;
1005997
}
1006998
return false;
@@ -1056,11 +1048,11 @@ find_expr_references_walker(Node *node,
10561048
if (IsA(node, SubLink))
10571049
{
10581050
SubLink *sublink = (SubLink *) node;
1059-
List *opid;
1051+
ListCell *opid;
10601052

10611053
foreach(opid, sublink->operOids)
10621054
{
1063-
add_object_address(OCLASS_OPERATOR, lfirsto(opid), 0,
1055+
add_object_address(OCLASS_OPERATOR, lfirst_oid(opid), 0,
10641056
&context->addrs);
10651057
}
10661058
/* fall through to examine arguments */
@@ -1074,7 +1066,7 @@ find_expr_references_walker(Node *node,
10741066
{
10751067
/* Recurse into RTE subquery or not-yet-planned sublink subquery */
10761068
Query *query = (Query *) node;
1077-
List *rtable;
1069+
ListCell *rtable;
10781070
bool result;
10791071

10801072
/*
@@ -1099,7 +1091,7 @@ find_expr_references_walker(Node *node,
10991091
find_expr_references_walker,
11001092
(void *) context,
11011093
QTW_IGNORE_JOINALIASES);
1102-
context->rtables = lnext(context->rtables);
1094+
context->rtables = list_delete_first(context->rtables);
11031095
return result;
11041096
}
11051097
return expression_tree_walker(node, find_expr_references_walker,

0 commit comments

Comments
 (0)