Skip to content

Commit 93ea719

Browse files
author
Daniel Shelepanov
committed
intermediate
1 parent f4c24d6 commit 93ea719

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

engine.c

+31-1
Original file line numberDiff line numberDiff line change
@@ -672,9 +672,39 @@ ptrack_walkdir(const char *path, Oid tablespaceOid, Oid dbOid)
672672
FreeDir(dir); /* we ignore any error here */
673673
}
674674

675+
/*
676+
* Get a second position within ptrack map so that it fits
677+
* within the same cache line.
678+
*/
679+
size_t
680+
get_slot2(size_t slot1, uint64 hash) {
681+
size_t cache_line_ep; // ending point of a cache line
682+
size_t cache_line_sp; // starting point of a cache line
683+
size_t cache_line_interval;
684+
size_t slot2;
685+
686+
/* Get the ending point of a cache line within entries[]. */
687+
cache_line_ep = (CACHE_LINE_ALIGN(offsetof(PtrackMapHdr, entries) + slot1*sizeof(XLogRecPtr))
688+
- offsetof(PtrackMapHdr, entries)) / sizeof(XLogRecPtr);
689+
/* handling an overflow beyond the entries boundary */
690+
cache_line_ep = cache_line_ep > PtrackContentNblocks ? PtrackContentNblocks : cache_line_ep;
691+
692+
/* Get the starting point of a cache line within entries[]. */
693+
cache_line_sp = cache_line_ep - ENTRIES_PER_LINE;
694+
695+
/* Handling overflow below zero (sp then must be larger than ep) */
696+
cache_line_sp = cache_line_sp > cache_line_ep ? 0 : cache_line_sp;
697+
698+
cache_line_interval = cache_line_ep - cache_line_sp;
699+
slot2 = (size_t)(cache_line_sp + (((hash << 32) | (hash >> 32)) % cache_line_interval));
700+
slot2 = (slot1 == slot2) ? ((slot1+1) % cache_line_interval) : slot2;
701+
return slot2;
702+
}
703+
675704
/*
676705
* Mark modified block in ptrack_map.
677706
*/
707+
678708
void
679709
ptrack_mark_block(RelFileNodeBackend smgr_rnode,
680710
ForkNumber forknum, BlockNumber blocknum)
@@ -703,7 +733,7 @@ ptrack_mark_block(RelFileNodeBackend smgr_rnode,
703733

704734
hash = BID_HASH_FUNC(bid);
705735
slot1 = (size_t)(hash % PtrackContentNblocks);
706-
slot2 = (size_t)(((hash << 32) | (hash >> 32)) % PtrackContentNblocks);
736+
slot2 = get_slot2(slot1, hash);
707737

708738
if (RecoveryInProgress())
709739
new_lsn = GetXLogReplayRecPtr(NULL);

engine.h

+9
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@
4040
*/
4141
#define PTRACK_BUF_SIZE ((uint64) 8000)
4242

43+
/*
44+
* A reasonable assumption for most systems. Postgres core
45+
* leverages the same value for this purpose.
46+
*/
47+
#define CACHE_LINE_SIZE 64
48+
#define CACHE_LINE_ALIGN(LEN) TYPEALIGN(CACHE_LINE_SIZE, (LEN))
49+
#define ENTRIES_PER_LINE (CACHE_LINE_SIZE/sizeof(XLogRecPtr))
50+
4351
/* Ptrack magic bytes */
4452
#define PTRACK_MAGIC "ptk"
4553
#define PTRACK_MAGIC_SIZE 4
@@ -117,6 +125,7 @@ extern void ptrack_mark_block(RelFileNodeBackend smgr_rnode,
117125
ForkNumber forkno, BlockNumber blkno);
118126

119127
extern bool is_cfm_file_path(const char *path);
128+
extern size_t get_slot2(size_t slot1, uint64 hash);
120129
#ifdef PGPRO_EE
121130
extern off_t get_cfs_relation_file_decompressed_size(RelFileNodeBackend rnode,
122131
const char *fullpath, ForkNumber forknum);

ptrack.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,7 @@ ptrack_get_pagemapset(PG_FUNCTION_ARGS)
651651
/* Only probe the second slot if the first one is marked */
652652
if (update_lsn1 >= ctx->lsn)
653653
{
654-
slot2 = (size_t)(((hash << 32) | (hash >> 32)) % PtrackContentNblocks);
654+
slot2 = get_slot2(slot1, hash);
655655
update_lsn2 = pg_atomic_read_u64(&ptrack_map->entries[slot2]);
656656

657657
if (update_lsn2 != InvalidXLogRecPtr)

0 commit comments

Comments
 (0)