Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc1ec02b

Browse files
committed
Reuse BrinDesc and BrinRevmap in brininsert
The brininsert code used to initialize (and destroy) BrinDesc andBrinRevmap for each tuple, which is not free. This patch initializesthese structures only once, and reuses them for all inserts in the samecommand. The data is passed through indexInfo->ii_AmCache.This also introduces an optional AM callback "aminsertcleanup" thatallows performing custom cleanup in case simply pfree-ing ii_AmCache isnot sufficient (which is the case when the cache contains TupleDesc,Buffers, and so on).Author: Soumyadeep ChakrabortyReviewed-by: Alvaro Herrera, Matthias van de Meent, Tomas VondraDiscussion:https://postgr.es/m/CAE-ML%2B9r2%3DaO1wwji1sBN9gvPz2xRAtFUGfnffpd0ZqyuzjamA%40mail.gmail.com
1 parent6ec8262 commitc1ec02b

File tree

13 files changed

+113
-12
lines changed

13 files changed

+113
-12
lines changed

‎contrib/bloom/blutils.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ blhandler(PG_FUNCTION_ARGS)
131131
amroutine->ambuild=blbuild;
132132
amroutine->ambuildempty=blbuildempty;
133133
amroutine->aminsert=blinsert;
134+
amroutine->aminsertcleanup=NULL;
134135
amroutine->ambulkdelete=blbulkdelete;
135136
amroutine->amvacuumcleanup=blvacuumcleanup;
136137
amroutine->amcanreturn=NULL;

‎doc/src/sgml/indexam.sgml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ typedef struct IndexAmRoutine
139139
ambuild_function ambuild;
140140
ambuildempty_function ambuildempty;
141141
aminsert_function aminsert;
142+
aminsertcleanup_function aminsertcleanup;
142143
ambulkdelete_function ambulkdelete;
143144
amvacuumcleanup_function amvacuumcleanup;
144145
amcanreturn_function amcanreturn; /* can be NULL */
@@ -359,7 +360,21 @@ aminsert (Relation indexRelation,
359360
within an SQL statement, it can allocate space
360361
in <literal>indexInfo-&gt;ii_Context</literal> and store a pointer to the
361362
data in <literal>indexInfo-&gt;ii_AmCache</literal> (which will be NULL
362-
initially).
363+
initially). After the index insertions complete, the memory will be freed
364+
automatically. If additional cleanup is required (e.g. if the cache contains
365+
buffers and tuple descriptors), the AM may define an optional function
366+
<literal>indexinsertcleanup</literal>, called before the memory is released.
367+
</para>
368+
369+
<para>
370+
<programlisting>
371+
void
372+
aminsertcleanup (IndexInfo *indexInfo);
373+
</programlisting>
374+
Clean up state that was maintained across successive inserts in
375+
<literal>indexInfo-&gt;ii_AmCache</literal>. This is useful if the data
376+
requires additional cleanup steps, and simply releasing the memory is not
377+
sufficient.
363378
</para>
364379

365380
<para>

‎src/backend/access/brin/brin.c

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,17 @@ typedef struct BrinBuildState
5858
BrinMemTuple*bs_dtuple;
5959
}BrinBuildState;
6060

61+
/*
62+
* We use a BrinInsertState to capture running state spanning multiple
63+
* brininsert invocations, within the same command.
64+
*/
65+
typedefstructBrinInsertState
66+
{
67+
BrinRevmap*bis_rmAccess;
68+
BrinDesc*bis_desc;
69+
BlockNumberbis_pages_per_range;
70+
}BrinInsertState;
71+
6172
/*
6273
* Struct used as "opaque" during index scans
6374
*/
@@ -72,6 +83,7 @@ typedef struct BrinOpaque
7283

7384
staticBrinBuildState*initialize_brin_buildstate(RelationidxRel,
7485
BrinRevmap*revmap,BlockNumberpagesPerRange);
86+
staticBrinInsertState*initialize_brin_insertstate(RelationidxRel,IndexInfo*indexInfo);
7587
staticvoidterminate_brin_buildstate(BrinBuildState*state);
7688
staticvoidbrinsummarize(Relationindex,RelationheapRel,BlockNumberpageRange,
7789
boolinclude_partial,double*numSummarized,double*numExisting);
@@ -117,6 +129,7 @@ brinhandler(PG_FUNCTION_ARGS)
117129
amroutine->ambuild=brinbuild;
118130
amroutine->ambuildempty=brinbuildempty;
119131
amroutine->aminsert=brininsert;
132+
amroutine->aminsertcleanup=brininsertcleanup;
120133
amroutine->ambulkdelete=brinbulkdelete;
121134
amroutine->amvacuumcleanup=brinvacuumcleanup;
122135
amroutine->amcanreturn=NULL;
@@ -140,6 +153,27 @@ brinhandler(PG_FUNCTION_ARGS)
140153
PG_RETURN_POINTER(amroutine);
141154
}
142155

156+
/*
157+
* Initialize a BrinInsertState to maintain state to be used across multiple
158+
* tuple inserts, within the same command.
159+
*/
160+
staticBrinInsertState*
161+
initialize_brin_insertstate(RelationidxRel,IndexInfo*indexInfo)
162+
{
163+
BrinInsertState*bistate;
164+
MemoryContextoldcxt;
165+
166+
oldcxt=MemoryContextSwitchTo(indexInfo->ii_Context);
167+
bistate=palloc0(sizeof(BrinInsertState));
168+
bistate->bis_desc=brin_build_desc(idxRel);
169+
bistate->bis_rmAccess=brinRevmapInitialize(idxRel,
170+
&bistate->bis_pages_per_range);
171+
indexInfo->ii_AmCache=bistate;
172+
MemoryContextSwitchTo(oldcxt);
173+
174+
returnbistate;
175+
}
176+
143177
/*
144178
* A tuple in the heap is being inserted. To keep a brin index up to date,
145179
* we need to obtain the relevant index tuple and compare its stored values
@@ -162,14 +196,24 @@ brininsert(Relation idxRel, Datum *values, bool *nulls,
162196
BlockNumberpagesPerRange;
163197
BlockNumberorigHeapBlk;
164198
BlockNumberheapBlk;
165-
BrinDesc*bdesc= (BrinDesc*)indexInfo->ii_AmCache;
199+
BrinInsertState*bistate= (BrinInsertState*)indexInfo->ii_AmCache;
166200
BrinRevmap*revmap;
201+
BrinDesc*bdesc;
167202
Bufferbuf=InvalidBuffer;
168203
MemoryContexttupcxt=NULL;
169204
MemoryContextoldcxt=CurrentMemoryContext;
170205
boolautosummarize=BrinGetAutoSummarize(idxRel);
171206

172-
revmap=brinRevmapInitialize(idxRel,&pagesPerRange);
207+
/*
208+
* If firt time through in this statement, initialize the insert state
209+
* that we keep for all the inserts in the command.
210+
*/
211+
if (!bistate)
212+
bistate=initialize_brin_insertstate(idxRel,indexInfo);
213+
214+
revmap=bistate->bis_rmAccess;
215+
bdesc=bistate->bis_desc;
216+
pagesPerRange=bistate->bis_pages_per_range;
173217

174218
/*
175219
* origHeapBlk is the block number where the insertion occurred. heapBlk
@@ -228,14 +272,6 @@ brininsert(Relation idxRel, Datum *values, bool *nulls,
228272
if (!brtup)
229273
break;
230274

231-
/* First time through in this statement? */
232-
if (bdesc==NULL)
233-
{
234-
MemoryContextSwitchTo(indexInfo->ii_Context);
235-
bdesc=brin_build_desc(idxRel);
236-
indexInfo->ii_AmCache= (void*)bdesc;
237-
MemoryContextSwitchTo(oldcxt);
238-
}
239275
/* First time through in this brininsert call? */
240276
if (tupcxt==NULL)
241277
{
@@ -306,7 +342,6 @@ brininsert(Relation idxRel, Datum *values, bool *nulls,
306342
break;
307343
}
308344

309-
brinRevmapTerminate(revmap);
310345
if (BufferIsValid(buf))
311346
ReleaseBuffer(buf);
312347
MemoryContextSwitchTo(oldcxt);
@@ -316,6 +351,24 @@ brininsert(Relation idxRel, Datum *values, bool *nulls,
316351
return false;
317352
}
318353

354+
/*
355+
* Callback to clean up the BrinInsertState once all tuple inserts are done.
356+
*/
357+
void
358+
brininsertcleanup(IndexInfo*indexInfo)
359+
{
360+
BrinInsertState*bistate= (BrinInsertState*)indexInfo->ii_AmCache;
361+
362+
Assert(bistate);
363+
/*
364+
* Clean up the revmap. Note that the brinDesc has already been cleaned up
365+
* as part of its own memory context.
366+
*/
367+
brinRevmapTerminate(bistate->bis_rmAccess);
368+
bistate->bis_rmAccess=NULL;
369+
bistate->bis_desc=NULL;
370+
}
371+
319372
/*
320373
* Initialize state for a BRIN index scan.
321374
*

‎src/backend/access/gin/ginutil.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ ginhandler(PG_FUNCTION_ARGS)
6464
amroutine->ambuild=ginbuild;
6565
amroutine->ambuildempty=ginbuildempty;
6666
amroutine->aminsert=gininsert;
67+
amroutine->aminsertcleanup=NULL;
6768
amroutine->ambulkdelete=ginbulkdelete;
6869
amroutine->amvacuumcleanup=ginvacuumcleanup;
6970
amroutine->amcanreturn=NULL;

‎src/backend/access/gist/gist.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ gisthandler(PG_FUNCTION_ARGS)
8686
amroutine->ambuild=gistbuild;
8787
amroutine->ambuildempty=gistbuildempty;
8888
amroutine->aminsert=gistinsert;
89+
amroutine->aminsertcleanup=NULL;
8990
amroutine->ambulkdelete=gistbulkdelete;
9091
amroutine->amvacuumcleanup=gistvacuumcleanup;
9192
amroutine->amcanreturn=gistcanreturn;

‎src/backend/access/hash/hash.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ hashhandler(PG_FUNCTION_ARGS)
8383
amroutine->ambuild=hashbuild;
8484
amroutine->ambuildempty=hashbuildempty;
8585
amroutine->aminsert=hashinsert;
86+
amroutine->aminsertcleanup=NULL;
8687
amroutine->ambulkdelete=hashbulkdelete;
8788
amroutine->amvacuumcleanup=hashvacuumcleanup;
8889
amroutine->amcanreturn=NULL;

‎src/backend/access/index/indexam.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,21 @@ index_insert(Relation indexRelation,
196196
indexInfo);
197197
}
198198

199+
/* -------------------------
200+
*index_insert_cleanup - clean up after all index inserts are done
201+
* -------------------------
202+
*/
203+
void
204+
index_insert_cleanup(RelationindexRelation,
205+
IndexInfo*indexInfo)
206+
{
207+
RELATION_CHECKS;
208+
Assert(indexInfo);
209+
210+
if (indexRelation->rd_indam->aminsertcleanup)
211+
indexRelation->rd_indam->aminsertcleanup(indexInfo);
212+
}
213+
199214
/*
200215
* index_beginscan - start a scan of an index with amgettuple
201216
*

‎src/backend/access/nbtree/nbtree.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ bthandler(PG_FUNCTION_ARGS)
122122
amroutine->ambuild=btbuild;
123123
amroutine->ambuildempty=btbuildempty;
124124
amroutine->aminsert=btinsert;
125+
amroutine->aminsertcleanup=NULL;
125126
amroutine->ambulkdelete=btbulkdelete;
126127
amroutine->amvacuumcleanup=btvacuumcleanup;
127128
amroutine->amcanreturn=btcanreturn;

‎src/backend/access/spgist/spgutils.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ spghandler(PG_FUNCTION_ARGS)
7070
amroutine->ambuild=spgbuild;
7171
amroutine->ambuildempty=spgbuildempty;
7272
amroutine->aminsert=spginsert;
73+
amroutine->aminsertcleanup=NULL;
7374
amroutine->ambulkdelete=spgbulkdelete;
7475
amroutine->amvacuumcleanup=spgvacuumcleanup;
7576
amroutine->amcanreturn=spgcanreturn;

‎src/backend/executor/execIndexing.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,15 +233,20 @@ ExecCloseIndices(ResultRelInfo *resultRelInfo)
233233
inti;
234234
intnumIndices;
235235
RelationPtrindexDescs;
236+
IndexInfo**indexInfos;
236237

237238
numIndices=resultRelInfo->ri_NumIndices;
238239
indexDescs=resultRelInfo->ri_IndexRelationDescs;
240+
indexInfos=resultRelInfo->ri_IndexRelationInfo;
239241

240242
for (i=0;i<numIndices;i++)
241243
{
242244
if (indexDescs[i]==NULL)
243245
continue;/* shouldn't happen? */
244246

247+
/* Give the index a chance to do some post-insert cleanup */
248+
index_insert_cleanup(indexDescs[i],indexInfos[i]);
249+
245250
/* Drop lock acquired by ExecOpenIndices */
246251
index_close(indexDescs[i],RowExclusiveLock);
247252
}

‎src/include/access/amapi.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ typedef bool (*aminsert_function) (Relation indexRelation,
113113
boolindexUnchanged,
114114
structIndexInfo*indexInfo);
115115

116+
/* cleanup after insert */
117+
typedefvoid (*aminsertcleanup_function) (structIndexInfo*indexInfo);
118+
116119
/* bulk delete */
117120
typedefIndexBulkDeleteResult*(*ambulkdelete_function) (IndexVacuumInfo*info,
118121
IndexBulkDeleteResult*stats,
@@ -261,6 +264,7 @@ typedef struct IndexAmRoutine
261264
ambuild_functionambuild;
262265
ambuildempty_functionambuildempty;
263266
aminsert_functionaminsert;
267+
aminsertcleanup_functionaminsertcleanup;
264268
ambulkdelete_functionambulkdelete;
265269
amvacuumcleanup_functionamvacuumcleanup;
266270
amcanreturn_functionamcanreturn;/* can be NULL */

‎src/include/access/brin_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ extern bool brininsert(Relation idxRel, Datum *values, bool *nulls,
9696
IndexUniqueCheckcheckUnique,
9797
boolindexUnchanged,
9898
structIndexInfo*indexInfo);
99+
externvoidbrininsertcleanup(structIndexInfo*indexInfo);
99100
externIndexScanDescbrinbeginscan(Relationr,intnkeys,intnorderbys);
100101
externint64bringetbitmap(IndexScanDescscan,TIDBitmap*tbm);
101102
externvoidbrinrescan(IndexScanDescscan,ScanKeyscankey,intnscankeys,

‎src/include/access/genam.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ extern bool index_insert(Relation indexRelation,
148148
IndexUniqueCheckcheckUnique,
149149
boolindexUnchanged,
150150
structIndexInfo*indexInfo);
151+
externvoidindex_insert_cleanup(RelationindexRelation,
152+
structIndexInfo*indexInfo);
151153

152154
externIndexScanDescindex_beginscan(RelationheapRelation,
153155
RelationindexRelation,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp