Skip to content

Commit 02eb07e

Browse files
committed
Allow table AM to store complex data structures in rd_amcache
The new table AM method free_rd_amcache is responsible for freeing all the memory related to rd_amcache and setting free_rd_amcache to NULL. If the new method is not specified, we still assume rd_amcache to be a single chunk of memory, which could be just pfree'd. Discussion: https://postgr.es/m/CAPpHfdurb9ycV8udYqM%3Do0sPS66PJ4RCBM1g-bBpvzUfogY0EA%40mail.gmail.com Reviewed-by: Matthias van de Meent, Mark Dilger, Pavel Borisov Reviewed-by: Nikita Malakhov, Japin Li
1 parent 57184c3 commit 02eb07e

File tree

4 files changed

+44
-12
lines changed

4 files changed

+44
-12
lines changed

src/backend/access/heap/heapam_handler.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2582,6 +2582,7 @@ static const TableAmRoutine heapam_methods = {
25822582
.index_build_range_scan = heapam_index_build_range_scan,
25832583
.index_validate_scan = heapam_index_validate_scan,
25842584

2585+
.free_rd_amcache = NULL,
25852586
.relation_size = table_block_relation_size,
25862587
.relation_needs_toast_table = heapam_relation_needs_toast_table,
25872588
.relation_toast_am = heapam_relation_toast_am,

src/backend/utils/cache/relcache.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2262,9 +2262,7 @@ RelationReloadIndexInfo(Relation relation)
22622262
RelationCloseSmgr(relation);
22632263

22642264
/* Must free any AM cached data upon relcache flush */
2265-
if (relation->rd_amcache)
2266-
pfree(relation->rd_amcache);
2267-
relation->rd_amcache = NULL;
2265+
table_free_rd_amcache(relation);
22682266

22692267
/*
22702268
* If it's a shared index, we might be called before backend startup has
@@ -2484,8 +2482,7 @@ RelationDestroyRelation(Relation relation, bool remember_tupdesc)
24842482
pfree(relation->rd_options);
24852483
if (relation->rd_indextuple)
24862484
pfree(relation->rd_indextuple);
2487-
if (relation->rd_amcache)
2488-
pfree(relation->rd_amcache);
2485+
table_free_rd_amcache(relation);
24892486
if (relation->rd_fdwroutine)
24902487
pfree(relation->rd_fdwroutine);
24912488
if (relation->rd_indexcxt)
@@ -2547,9 +2544,7 @@ RelationClearRelation(Relation relation, bool rebuild)
25472544
RelationCloseSmgr(relation);
25482545

25492546
/* Free AM cached data, if any */
2550-
if (relation->rd_amcache)
2551-
pfree(relation->rd_amcache);
2552-
relation->rd_amcache = NULL;
2547+
table_free_rd_amcache(relation);
25532548

25542549
/*
25552550
* Treat nailed-in system relations separately, they always need to be

src/include/access/tableam.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,14 @@ typedef struct TableAmRoutine
708708
* ------------------------------------------------------------------------
709709
*/
710710

711+
/*
712+
* This callback frees relation private cache data stored in rd_amcache.
713+
* After the call all memory related to rd_amcache must be freed,
714+
* rd_amcache must be set to NULL. If this callback is not provided,
715+
* rd_amcache is assumed to point to a single memory chunk.
716+
*/
717+
void (*free_rd_amcache) (Relation rel);
718+
711719
/*
712720
* See table_relation_size().
713721
*
@@ -1847,6 +1855,32 @@ table_index_validate_scan(Relation table_rel,
18471855
* ----------------------------------------------------------------------------
18481856
*/
18491857

1858+
/*
1859+
* Frees relation private cache data stored in rd_amcache. Uses
1860+
* free_rd_amcache method if provided. Assumes rd_amcache to point to single
1861+
* memory chunk otherwise.
1862+
*/
1863+
static inline void
1864+
table_free_rd_amcache(Relation rel)
1865+
{
1866+
if (rel->rd_tableam && rel->rd_tableam->free_rd_amcache)
1867+
{
1868+
rel->rd_tableam->free_rd_amcache(rel);
1869+
1870+
/*
1871+
* We are assuming free_rd_amcache() did clear the cache and left NULL
1872+
* in rd_amcache.
1873+
*/
1874+
Assert(rel->rd_amcache == NULL);
1875+
}
1876+
else
1877+
{
1878+
if (rel->rd_amcache)
1879+
pfree(rel->rd_amcache);
1880+
rel->rd_amcache = NULL;
1881+
}
1882+
}
1883+
18501884
/*
18511885
* Return the current size of `rel` in bytes. If `forkNumber` is
18521886
* InvalidForkNumber, return the relation's overall size, otherwise the size

src/include/utils/rel.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,12 @@ typedef struct RelationData
221221
* rd_amcache is available for index and table AMs to cache private data
222222
* about the relation. This must be just a cache since it may get reset
223223
* at any time (in particular, it will get reset by a relcache inval
224-
* message for the relation). If used, it must point to a single memory
225-
* chunk palloc'd in CacheMemoryContext, or in rd_indexcxt for an index
226-
* relation. A relcache reset will include freeing that chunk and setting
227-
* rd_amcache = NULL.
224+
* message for the relation). If used for table AM it must point to a
225+
* single memory chunk palloc'd in CacheMemoryContext, or more complex
226+
* data structure in that memory context to be freed by free_rd_amcache
227+
* method. If used for index AM it must point to a single memory chunk
228+
* palloc'd in rd_indexcxt memory context. A relcache reset will include
229+
* freeing that chunk and setting rd_amcache = NULL.
228230
*/
229231
void *rd_amcache; /* available for use by index/table AM */
230232

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy