PostgreSQL Source Code: src/test/modules/test_slru/test_slru.c Source File

PostgreSQL Source Code git master
test_slru.c
Go to the documentation of this file.
1/*--------------------------------------------------------------------------
2 *
3 * test_slru.c
4 * Test correctness of SLRU functions.
5 *
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 * IDENTIFICATION
10 * src/test/modules/test_slru/test_slru.c
11 *
12 * -------------------------------------------------------------------------
13 */
14
15#include "postgres.h"
16
17#include "access/slru.h"
18#include "access/transam.h"
19#include "miscadmin.h"
20#include "storage/fd.h"
21#include "storage/ipc.h"
22#include "storage/shmem.h"
23#include "utils/builtins.h"
24
25 PG_MODULE_MAGIC;
26
27/*
28 * SQL-callable entry points
29 */
30 PG_FUNCTION_INFO_V1(test_slru_page_write);
31 PG_FUNCTION_INFO_V1(test_slru_page_writeall);
32 PG_FUNCTION_INFO_V1(test_slru_page_read);
33 PG_FUNCTION_INFO_V1(test_slru_page_readonly);
34 PG_FUNCTION_INFO_V1(test_slru_page_exists);
35 PG_FUNCTION_INFO_V1(test_slru_page_sync);
36 PG_FUNCTION_INFO_V1(test_slru_page_delete);
37 PG_FUNCTION_INFO_V1(test_slru_page_truncate);
38 PG_FUNCTION_INFO_V1(test_slru_delete_all);
39
40/* Number of SLRU page slots */
41 #define NUM_TEST_BUFFERS 16
42
43 static SlruCtlData TestSlruCtlData;
44 #define TestSlruCtl (&TestSlruCtlData)
45
46 static shmem_request_hook_type prev_shmem_request_hook = NULL;
47 static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
48
49static bool
50 test_slru_scan_cb(SlruCtl ctl, char *filename, int64 segpage, void *data)
51{
52 elog(NOTICE, "Calling test_slru_scan_cb()");
53 return SlruScanDirCbDeleteAll(ctl, filename, segpage, data);
54}
55
56Datum
57 test_slru_page_write(PG_FUNCTION_ARGS)
58{
59 int64 pageno = PG_GETARG_INT64(0);
60 char *data = text_to_cstring(PG_GETARG_TEXT_PP(1));
61 int slotno;
62 LWLock *lock = SimpleLruGetBankLock(TestSlruCtl, pageno);
63
64 LWLockAcquire(lock, LW_EXCLUSIVE);
65 slotno = SimpleLruZeroPage(TestSlruCtl, pageno);
66
67 /* these should match */
68 Assert(TestSlruCtl->shared->page_number[slotno] == pageno);
69
70 /* mark the page as dirty so as it would get written */
71 TestSlruCtl->shared->page_dirty[slotno] = true;
72 TestSlruCtl->shared->page_status[slotno] = SLRU_PAGE_VALID;
73
74 /* write given data to the page, up to the limit of the page */
75 strncpy(TestSlruCtl->shared->page_buffer[slotno], data,
76 BLCKSZ - 1);
77
78 SimpleLruWritePage(TestSlruCtl, slotno);
79 LWLockRelease(lock);
80
81 PG_RETURN_VOID();
82}
83
84Datum
85 test_slru_page_writeall(PG_FUNCTION_ARGS)
86{
87 SimpleLruWriteAll(TestSlruCtl, true);
88 PG_RETURN_VOID();
89}
90
91Datum
92 test_slru_page_read(PG_FUNCTION_ARGS)
93{
94 int64 pageno = PG_GETARG_INT64(0);
95 bool write_ok = PG_GETARG_BOOL(1);
96 char *data = NULL;
97 int slotno;
98 LWLock *lock = SimpleLruGetBankLock(TestSlruCtl, pageno);
99
100 /* find page in buffers, reading it if necessary */
101 LWLockAcquire(lock, LW_EXCLUSIVE);
102 slotno = SimpleLruReadPage(TestSlruCtl, pageno,
103 write_ok, InvalidTransactionId);
104 data = (char *) TestSlruCtl->shared->page_buffer[slotno];
105 LWLockRelease(lock);
106
107 PG_RETURN_TEXT_P(cstring_to_text(data));
108}
109
110Datum
111 test_slru_page_readonly(PG_FUNCTION_ARGS)
112{
113 int64 pageno = PG_GETARG_INT64(0);
114 char *data = NULL;
115 int slotno;
116 LWLock *lock = SimpleLruGetBankLock(TestSlruCtl, pageno);
117
118 /* find page in buffers, reading it if necessary */
119 slotno = SimpleLruReadPage_ReadOnly(TestSlruCtl,
120 pageno,
121 InvalidTransactionId);
122 Assert(LWLockHeldByMe(lock));
123 data = (char *) TestSlruCtl->shared->page_buffer[slotno];
124 LWLockRelease(lock);
125
126 PG_RETURN_TEXT_P(cstring_to_text(data));
127}
128
129Datum
130 test_slru_page_exists(PG_FUNCTION_ARGS)
131{
132 int64 pageno = PG_GETARG_INT64(0);
133 bool found;
134 LWLock *lock = SimpleLruGetBankLock(TestSlruCtl, pageno);
135
136 LWLockAcquire(lock, LW_EXCLUSIVE);
137 found = SimpleLruDoesPhysicalPageExist(TestSlruCtl, pageno);
138 LWLockRelease(lock);
139
140 PG_RETURN_BOOL(found);
141}
142
143Datum
144 test_slru_page_sync(PG_FUNCTION_ARGS)
145{
146 int64 pageno = PG_GETARG_INT64(0);
147 FileTag ftag;
148 char path[MAXPGPATH];
149
150 /* note that this flushes the full file a segment is located in */
151 ftag.segno = pageno / SLRU_PAGES_PER_SEGMENT;
152 SlruSyncFileTag(TestSlruCtl, &ftag, path);
153
154 elog(NOTICE, "Called SlruSyncFileTag() for segment %" PRIu64 " on path %s",
155 ftag.segno, path);
156
157 PG_RETURN_VOID();
158}
159
160Datum
161 test_slru_page_delete(PG_FUNCTION_ARGS)
162{
163 int64 pageno = PG_GETARG_INT64(0);
164 FileTag ftag;
165
166 ftag.segno = pageno / SLRU_PAGES_PER_SEGMENT;
167 SlruDeleteSegment(TestSlruCtl, ftag.segno);
168
169 elog(NOTICE, "Called SlruDeleteSegment() for segment %" PRIu64,
170 ftag.segno);
171
172 PG_RETURN_VOID();
173}
174
175Datum
176 test_slru_page_truncate(PG_FUNCTION_ARGS)
177{
178 int64 pageno = PG_GETARG_INT64(0);
179
180 SimpleLruTruncate(TestSlruCtl, pageno);
181 PG_RETURN_VOID();
182}
183
184Datum
185 test_slru_delete_all(PG_FUNCTION_ARGS)
186{
187 /* this calls SlruScanDirCbDeleteAll() internally, ensuring deletion */
188 SlruScanDirectory(TestSlruCtl, test_slru_scan_cb, NULL);
189
190 PG_RETURN_VOID();
191}
192
193/*
194 * Module load callbacks and initialization.
195 */
196
197static void
198 test_slru_shmem_request(void)
199{
200 if (prev_shmem_request_hook)
201 prev_shmem_request_hook();
202
203 /* reserve shared memory for the test SLRU */
204 RequestAddinShmemSpace(SimpleLruShmemSize(NUM_TEST_BUFFERS, 0));
205}
206
207static bool
208 test_slru_page_precedes_logically(int64 page1, int64 page2)
209{
210 return page1 < page2;
211}
212
213static void
214 test_slru_shmem_startup(void)
215{
216 /*
217 * Short segments names are well tested elsewhere so in this test we are
218 * focusing on long names.
219 */
220 const bool long_segment_names = true;
221 const char slru_dir_name[] = "pg_test_slru";
222 int test_tranche_id = -1;
223 int test_buffer_tranche_id = -1;
224
225 if (prev_shmem_startup_hook)
226 prev_shmem_startup_hook();
227
228 /*
229 * Create the SLRU directory if it does not exist yet, from the root of
230 * the data directory.
231 */
232 (void) MakePGDirectory(slru_dir_name);
233
234 /*
235 * Initialize the SLRU facility. In EXEC_BACKEND builds, the
236 * shmem_startup_hook is called in the postmaster and in each backend, but
237 * we only need to generate the LWLock tranches once. Note that these
238 * tranche ID variables are not used by SimpleLruInit() when
239 * IsUnderPostmaster is true.
240 */
241 if (!IsUnderPostmaster)
242 {
243 test_tranche_id = LWLockNewTrancheId("test_slru_tranche");
244 test_buffer_tranche_id = LWLockNewTrancheId("test_buffer_tranche");
245 }
246
247 TestSlruCtl->PagePrecedes = test_slru_page_precedes_logically;
248 SimpleLruInit(TestSlruCtl, "TestSLRU",
249 NUM_TEST_BUFFERS, 0, slru_dir_name,
250 test_buffer_tranche_id, test_tranche_id, SYNC_HANDLER_NONE,
251 long_segment_names);
252}
253
254void
255 _PG_init(void)
256{
257 if (!process_shared_preload_libraries_in_progress)
258 ereport(ERROR,
259 (errmsg("cannot load \"%s\" after startup", "test_slru"),
260 errdetail("\"%s\" must be loaded with \"shared_preload_libraries\".",
261 "test_slru")));
262
263 prev_shmem_request_hook = shmem_request_hook;
264 shmem_request_hook = test_slru_shmem_request;
265
266 prev_shmem_startup_hook = shmem_startup_hook;
267 shmem_startup_hook = test_slru_shmem_startup;
268}
int64_t int64
Definition: c.h:535
int errdetail(const char *fmt,...)
Definition: elog.c:1207
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
#define NOTICE
Definition: elog.h:35
#define ereport(elevel,...)
Definition: elog.h:150
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3975
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool IsUnderPostmaster
Definition: globals.c:120
Assert(PointerIsAligned(start, uint64))
void(* shmem_startup_hook_type)(void)
Definition: ipc.h:22
shmem_startup_hook_type shmem_startup_hook
Definition: ipci.c:58
void RequestAddinShmemSpace(Size size)
Definition: ipci.c:74
bool LWLockHeldByMe(LWLock *lock)
Definition: lwlock.c:1977
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1174
int LWLockNewTrancheId(const char *name)
Definition: lwlock.c:596
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1894
@ LW_EXCLUSIVE
Definition: lwlock.h:112
void(* shmem_request_hook_type)(void)
Definition: miscadmin.h:532
shmem_request_hook_type shmem_request_hook
Definition: miscinit.c:1789
bool process_shared_preload_libraries_in_progress
Definition: miscinit.c:1786
#define MAXPGPATH
const void * data
static char * filename
Definition: pg_dumpall.c:120
uint64_t Datum
Definition: postgres.h:70
tree ctl
Definition: radixtree.h:1838
void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, const char *subdir, int buffer_tranche_id, int bank_tranche_id, SyncRequestHandler sync_handler, bool long_segment_names)
Definition: slru.c:252
int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int64 pageno, TransactionId xid)
Definition: slru.c:630
void SimpleLruWritePage(SlruCtl ctl, int slotno)
Definition: slru.c:757
void SimpleLruWriteAll(SlruCtl ctl, bool allow_redirtied)
Definition: slru.c:1347
bool SimpleLruDoesPhysicalPageExist(SlruCtl ctl, int64 pageno)
Definition: slru.c:771
void SlruDeleteSegment(SlruCtl ctl, int64 segno)
Definition: slru.c:1551
bool SlruScanDirectory(SlruCtl ctl, SlruScanCallback callback, void *data)
Definition: slru.c:1816
bool SlruScanDirCbDeleteAll(SlruCtl ctl, char *filename, int64 segpage, void *data)
Definition: slru.c:1769
int SimpleLruReadPage(SlruCtl ctl, int64 pageno, bool write_ok, TransactionId xid)
Definition: slru.c:527
int SlruSyncFileTag(SlruCtl ctl, const FileTag *ftag, char *path)
Definition: slru.c:1856
int SimpleLruZeroPage(SlruCtl ctl, int64 pageno)
Definition: slru.c:375
void SimpleLruTruncate(SlruCtl ctl, int64 cutoffPage)
Definition: slru.c:1433
Size SimpleLruShmemSize(int nslots, int nlsns)
Definition: slru.c:198
static LWLock * SimpleLruGetBankLock(SlruCtl ctl, int64 pageno)
Definition: slru.h:175
#define SLRU_PAGES_PER_SEGMENT
Definition: slru.h:39
@ SLRU_PAGE_VALID
Definition: slru.h:51
Definition: sync.h:51
uint64 segno
Definition: sync.h:55
Definition: lwlock.h:42
Definition: slru.h:128
@ SYNC_HANDLER_NONE
Definition: sync.h:42
static void test_slru_shmem_startup(void)
Definition: test_slru.c:214
Datum test_slru_page_delete(PG_FUNCTION_ARGS)
Definition: test_slru.c:161
static bool test_slru_page_precedes_logically(int64 page1, int64 page2)
Definition: test_slru.c:208
Datum test_slru_page_write(PG_FUNCTION_ARGS)
Definition: test_slru.c:57
void _PG_init(void)
Definition: test_slru.c:255
Datum test_slru_page_exists(PG_FUNCTION_ARGS)
Definition: test_slru.c:130
Datum test_slru_page_writeall(PG_FUNCTION_ARGS)
Definition: test_slru.c:85
PG_MODULE_MAGIC
Definition: test_slru.c:25
Datum test_slru_page_readonly(PG_FUNCTION_ARGS)
Definition: test_slru.c:111
Datum test_slru_page_truncate(PG_FUNCTION_ARGS)
Definition: test_slru.c:176
static shmem_startup_hook_type prev_shmem_startup_hook
Definition: test_slru.c:47
static shmem_request_hook_type prev_shmem_request_hook
Definition: test_slru.c:46
Datum test_slru_page_read(PG_FUNCTION_ARGS)
Definition: test_slru.c:92
#define NUM_TEST_BUFFERS
Definition: test_slru.c:41
Datum test_slru_delete_all(PG_FUNCTION_ARGS)
Definition: test_slru.c:185
static void test_slru_shmem_request(void)
Definition: test_slru.c:198
PG_FUNCTION_INFO_V1(test_slru_page_write)
static SlruCtlData TestSlruCtlData
Definition: test_slru.c:43
Datum test_slru_page_sync(PG_FUNCTION_ARGS)
Definition: test_slru.c:144
static bool test_slru_scan_cb(SlruCtl ctl, char *filename, int64 segpage, void *data)
Definition: test_slru.c:50
#define TestSlruCtl
Definition: test_slru.c:44
#define InvalidTransactionId
Definition: transam.h:31
text * cstring_to_text(const char *s)
Definition: varlena.c:181
char * text_to_cstring(const text *t)
Definition: varlena.c:214

AltStyle によって変換されたページ (->オリジナル) /