Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7fdaf78

Browse files
committed
Reduce amount of memory used per tuple for after-event triggers. This
is still a memory leak, but a little less bad than it was.
1 parent c9f26d7 commit 7fdaf78

File tree

2 files changed

+30
-25
lines changed

2 files changed

+30
-25
lines changed

src/backend/commands/trigger.c

+24-23
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.87 2001/03/12 23:02:00 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.88 2001/03/14 21:50:32 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -1153,15 +1153,18 @@ static List *deftrig_trigstates;
11531153

11541154
/* ----------
11551155
* The list of events during the entire transaction. deftrig_events
1156-
* is the head, deftrig_event_tail is the last entry.
1156+
* is the head, deftrig_event_tail is the last entry. Because this can
1157+
* grow pretty large, we don't use separate List nodes, but instead thread
1158+
* the list through the dte_next fields of the member nodes. Saves just a
1159+
* few bytes per entry, but that adds up.
11571160
*
11581161
* XXX Need to be able to shove this data out to a file if it grows too
11591162
* large...
11601163
* ----------
11611164
*/
11621165
static int deftrig_n_events;
1163-
static List *deftrig_events;
1164-
static List *deftrig_event_tail;
1166+
static DeferredTriggerEvent deftrig_events;
1167+
static DeferredTriggerEvent deftrig_event_tail;
11651168

11661169

11671170
/* ----------
@@ -1242,16 +1245,17 @@ deferredTriggerAddEvent(DeferredTriggerEvent event)
12421245
* list tail and append there, rather than just doing a stupid "lappend".
12431246
* This avoids O(N^2) behavior for large numbers of events.
12441247
*/
1245-
if (deftrig_event_tail == NIL)
1248+
event->dte_next = NULL;
1249+
if (deftrig_event_tail == NULL)
12461250
{
12471251
/* first list entry */
1248-
deftrig_events = makeList1(event);
1249-
deftrig_event_tail = deftrig_events;
1252+
deftrig_events = event;
1253+
deftrig_event_tail = event;
12501254
}
12511255
else
12521256
{
1253-
lnext(deftrig_event_tail) = makeList1(event);
1254-
deftrig_event_tail = lnext(deftrig_event_tail);
1257+
deftrig_event_tail->dte_next = event;
1258+
deftrig_event_tail = event;
12551259
}
12561260
deftrig_n_events++;
12571261
}
@@ -1268,13 +1272,11 @@ static DeferredTriggerEvent
12681272
deferredTriggerGetPreviousEvent(Oid relid, ItemPointer ctid)
12691273
{
12701274
DeferredTriggerEvent previous = NULL;
1271-
List *dtev;
1275+
DeferredTriggerEvent prev;
12721276

12731277
/* Search the list to find the last event affecting this tuple */
1274-
foreach(dtev, deftrig_events)
1278+
for (prev = deftrig_events; prev != NULL; prev = prev->dte_next)
12751279
{
1276-
DeferredTriggerEvent prev = (DeferredTriggerEvent) lfirst(dtev);
1277-
12781280
if (prev->dte_relid != relid)
12791281
continue;
12801282
if (prev->dte_event & TRIGGER_DEFERRED_CANCELED)
@@ -1411,7 +1413,6 @@ deferredTriggerExecute(DeferredTriggerEvent event, int itemno,
14111413
static void
14121414
deferredTriggerInvokeEvents(bool immediate_only)
14131415
{
1414-
List *el;
14151416
DeferredTriggerEvent event;
14161417
int still_deferred_ones;
14171418
int i;
@@ -1435,19 +1436,18 @@ deferredTriggerInvokeEvents(bool immediate_only)
14351436
ALLOCSET_DEFAULT_INITSIZE,
14361437
ALLOCSET_DEFAULT_MAXSIZE);
14371438

1438-
foreach(el, deftrig_events)
1439+
for (event = deftrig_events; event != NULL; event = event->dte_next)
14391440
{
1440-
MemoryContextReset(per_tuple_context);
1441-
14421441
/* ----------
1443-
* Get the event and check if it is completely done.
1442+
* Check if event is completely done.
14441443
* ----------
14451444
*/
1446-
event = (DeferredTriggerEvent) lfirst(el);
14471445
if (event->dte_event & (TRIGGER_DEFERRED_DONE |
14481446
TRIGGER_DEFERRED_CANCELED))
14491447
continue;
14501448

1449+
MemoryContextReset(per_tuple_context);
1450+
14511451
/* ----------
14521452
* Check each trigger item in the event.
14531453
* ----------
@@ -1561,8 +1561,8 @@ DeferredTriggerBeginXact(void)
15611561
MemoryContextSwitchTo(oldcxt);
15621562

15631563
deftrig_n_events = 0;
1564-
deftrig_events = NIL;
1565-
deftrig_event_tail = NIL;
1564+
deftrig_events = NULL;
1565+
deftrig_event_tail = NULL;
15661566
}
15671567

15681568

@@ -1957,16 +1957,16 @@ DeferredTriggerSaveEvent(Relation rel, int event,
19571957

19581958
ntriggers = rel->trigdesc->n_after_row[event];
19591959
triggers = rel->trigdesc->tg_after_row[event];
1960-
new_size = sizeof(DeferredTriggerEventData) +
1960+
new_size = offsetof(DeferredTriggerEventData, dte_item[0]) +
19611961
ntriggers * sizeof(DeferredTriggerEventItem);
19621962

19631963
new_event = (DeferredTriggerEvent) palloc(new_size);
1964+
new_event->dte_next = NULL;
19641965
new_event->dte_event = event & TRIGGER_EVENT_OPMASK;
19651966
new_event->dte_relid = rel->rd_id;
19661967
ItemPointerCopy(&oldctid, &(new_event->dte_oldctid));
19671968
ItemPointerCopy(&newctid, &(new_event->dte_newctid));
19681969
new_event->dte_n_items = ntriggers;
1969-
new_event->dte_item[ntriggers].dti_state = new_size;
19701970
for (i = 0; i < ntriggers; i++)
19711971
{
19721972
new_event->dte_item[i].dti_tgoid = triggers[i]->tgoid;
@@ -1978,6 +1978,7 @@ DeferredTriggerSaveEvent(Relation rel, int event,
19781978
((rel->trigdesc->n_before_row[event] > 0) ?
19791979
TRIGGER_DEFERRED_HAS_BEFORE : 0);
19801980
}
1981+
19811982
MemoryContextSwitchTo(oldcxt);
19821983

19831984
switch (event & TRIGGER_EVENT_OPMASK)

src/include/commands/trigger.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: trigger.h,v 1.24 2001/01/24 19:43:23 momjian Exp $
9+
* $Id: trigger.h,v 1.25 2001/03/14 21:50:32 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -110,6 +110,7 @@ typedef struct DeferredTriggerStatusData
110110
Oid dts_tgoid;
111111
bool dts_tgisdeferred;
112112
} DeferredTriggerStatusData;
113+
113114
typedef struct DeferredTriggerStatusData *DeferredTriggerStatus;
114115

115116

@@ -120,16 +121,19 @@ typedef struct DeferredTriggerEventItem
120121
} DeferredTriggerEventItem;
121122

122123

124+
typedef struct DeferredTriggerEventData *DeferredTriggerEvent;
125+
123126
typedef struct DeferredTriggerEventData
124127
{
128+
DeferredTriggerEvent dte_next; /* list link */
125129
int32 dte_event;
126130
Oid dte_relid;
127131
ItemPointerData dte_oldctid;
128132
ItemPointerData dte_newctid;
129133
int32 dte_n_items;
134+
/* dte_item is actually a variable-size array, of length dte_n_items */
130135
DeferredTriggerEventItem dte_item[1];
131136
} DeferredTriggerEventData;
132-
typedef struct DeferredTriggerEventData *DeferredTriggerEvent;
133137

134138

135139
extern void DeferredTriggerInit(void);

0 commit comments

Comments
 (0)