@@ -672,9 +672,39 @@ ptrack_walkdir(const char *path, Oid tablespaceOid, Oid dbOid)
672672FreeDir (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+
678708void
679709ptrack_mark_block (RelFileNodeBackend smgr_rnode ,
680710ForkNumber forknum ,BlockNumber blocknum )
@@ -703,7 +733,7 @@ ptrack_mark_block(RelFileNodeBackend smgr_rnode,
703733
704734hash = BID_HASH_FUNC (bid );
705735slot1 = (size_t )(hash %PtrackContentNblocks );
706- slot2 = ( size_t )((( hash << 32 ) | ( hash >> 32 )) % PtrackContentNblocks );
736+ slot2 = get_slot2 ( slot1 , hash );
707737
708738if (RecoveryInProgress ())
709739new_lsn = GetXLogReplayRecPtr (NULL );