From b79da29a94663293f00f3b27a04c1662e405f233 Mon Sep 17 00:00:00 2001 From: chenxiaobin19 <1025221611@qq.com> Date: Tue, 8 Nov 2022 11:35:41 +0800 Subject: [PATCH] ignore opt field when computing hash value --- src/common/backend/catalog/catalog.cpp | 2 + .../optimizer/commands/verifyrepair.cpp | 10 +- .../process/postmaster/bgwriter.cpp | 17 +- .../process/postmaster/checkpointer.cpp | 6 +- .../process/postmaster/pagerepair.cpp | 14 +- src/gausskernel/process/postmaster/pgstat.cpp | 20 +- .../tde_key_management/tde_key_storage.cpp | 6 +- .../storage/access/common/Makefile | 2 +- .../access/common/relfilenode_hash.cpp | 310 ++++++++++++++++++ .../storage/access/transam/cbmparsexlog.cpp | 6 +- .../access/transam/extreme_rto/batch_redo.cpp | 6 +- .../access/transam/extreme_rto/page_redo.cpp | 8 +- .../transam/parallel_recovery/page_redo.cpp | 8 +- .../storage/access/transam/xlogutils.cpp | 28 +- src/gausskernel/storage/buffer/buf_table.cpp | 4 +- src/gausskernel/storage/buffer/localbuf.cpp | 6 +- .../storage/replication/datarcvwriter.cpp | 6 +- .../replication/logical/reorderbuffer.cpp | 6 +- src/gausskernel/storage/sync/knl_usync.cpp | 6 +- src/include/access/extreme_rto/batch_redo.h | 2 - src/include/storage/buf/buf_internals.h | 2 + src/include/storage/smgr/relfilenode.h | 1 + src/include/storage/smgr/relfilenode_hash.h | 83 +++++ 23 files changed, 508 insertions(+), 51 deletions(-) create mode 100644 src/gausskernel/storage/access/common/relfilenode_hash.cpp create mode 100644 src/include/storage/smgr/relfilenode_hash.h diff --git a/src/common/backend/catalog/catalog.cpp b/src/common/backend/catalog/catalog.cpp index 8523c69c69..5f5a38cbad 100644 --- a/src/common/backend/catalog/catalog.cpp +++ b/src/common/backend/catalog/catalog.cpp @@ -61,6 +61,7 @@ #include "commands/directory.h" #include "cstore.h" #include "storage/custorage.h" +#include "storage/page_compression.h" #include "threadpool/threadpool.h" #include "catalog/pg_resource_pool.h" #include "catalog/pg_workload_group.h" @@ -1171,6 +1172,7 @@ Oid GetNewRelFileNode(Oid reltablespace, Relation pg_class, char relpersistence) rnode.node.spcNode = ConvertToRelfilenodeTblspcOid(reltablespace); rnode.node.dbNode = (rnode.node.spcNode == GLOBALTABLESPACE_OID) ? InvalidOid : u_sess->proc_cxt.MyDatabaseId; rnode.node.bucketNode = InvalidBktId; + rnode.node.opt = DefaultFileNodeOpt; /* * The relpath will vary based on the backend ID, so we must initialize diff --git a/src/gausskernel/optimizer/commands/verifyrepair.cpp b/src/gausskernel/optimizer/commands/verifyrepair.cpp index 4d17f6ba4c..983fe7ab57 100644 --- a/src/gausskernel/optimizer/commands/verifyrepair.cpp +++ b/src/gausskernel/optimizer/commands/verifyrepair.cpp @@ -34,6 +34,7 @@ #include "access/tableam.h" #include "commands/tablespace.h" #include "storage/smgr/fd.h" +#include "storage/smgr/relfilenode_hash.h" #include "storage/smgr/segment.h" #include "storage/cfs/cfs_converter.h" #include "storage/cfs/cfs_repair.h" @@ -63,11 +64,12 @@ void initRepairBadBlockStat() securec_check(rc, "", ""); info.keysize = sizeof(BadBlockKey); info.entrysize = sizeof(BadBlockEntry); - info.hash = tag_hash; + info.hash = BadBlockKeyHash; + info.match = BadBlockKeyMatch; info.hcxt = INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE); - g_instance.repair_cxt.global_repair_bad_block_stat = hash_create("Page Repair Hash Table", - MAX_REPAIR_PAGE_NUM, &info, - HASH_ELEM | HASH_FUNCTION |HASH_CONTEXT); + g_instance.repair_cxt.global_repair_bad_block_stat = + hash_create("Page Repair Hash Table", MAX_REPAIR_PAGE_NUM, &info, + HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT | HASH_COMPARE); if (!g_instance.repair_cxt.global_repair_bad_block_stat) { ereport(FATAL, (errcode(ERRCODE_INITIALIZE_FAILED), (errmsg("could not initialize page repair Hash table")))); diff --git a/src/gausskernel/process/postmaster/bgwriter.cpp b/src/gausskernel/process/postmaster/bgwriter.cpp index 87d9df9190..b7e85f24cd 100755 --- a/src/gausskernel/process/postmaster/bgwriter.cpp +++ b/src/gausskernel/process/postmaster/bgwriter.cpp @@ -52,6 +52,7 @@ #include "storage/proc.h" #include "storage/shmem.h" #include "storage/smgr/smgr.h" +#include "storage/smgr/relfilenode_hash.h" #include "storage/spin.h" #include "storage/standby.h" #include "utils/guc.h" @@ -642,7 +643,8 @@ HTAB *relfilenode_hashtbl_create(const char *name, bool use_heap_mem) rc = memset_s(&hashCtrl, sizeof(hashCtrl), 0, sizeof(hashCtrl)); securec_check(rc, "", ""); hashCtrl.hcxt = (MemoryContext)CurrentMemoryContext; - hashCtrl.hash = tag_hash; + hashCtrl.match = file_node_ignore_opt_match; + hashCtrl.hash = file_node_ignore_opt_hash; hashCtrl.keysize = sizeof(RelFileNode); /* keep entrysize >= keysize, stupid limits */ hashCtrl.entrysize = sizeof(DelFileTag); @@ -650,12 +652,13 @@ HTAB *relfilenode_hashtbl_create(const char *name, bool use_heap_mem) if (use_heap_mem) { hashtbl = HeapMemInitHash(name, HASH_TABLE_ELEMENT_MIN_NUM, Max(g_instance.attr.attr_common.max_files_per_process, t_thrd.storage_cxt.max_userdatafiles), &hashCtrl, - (HASH_FUNCTION | HASH_ELEM)); + (HASH_FUNCTION | HASH_ELEM | HASH_COMPARE)); if (hashtbl == NULL) { ereport(FATAL, (errmsg("could not initialize unlinik relation hash table"))); } } else { - hashtbl = hash_create(name, HASH_TABLE_ELEMENT_MIN_NUM, &hashCtrl, (HASH_CONTEXT | HASH_FUNCTION | HASH_ELEM)); + hashtbl = hash_create(name, HASH_TABLE_ELEMENT_MIN_NUM, &hashCtrl, + (HASH_CONTEXT | HASH_FUNCTION | HASH_ELEM | HASH_COMPARE)); } return hashtbl; } @@ -669,7 +672,8 @@ HTAB *relfilenode_fork_hashtbl_create(const char* name, bool use_heap_mem) rc = memset_s(&hashCtrl, sizeof(hashCtrl), 0, sizeof(hashCtrl)); securec_check(rc, "", ""); hashCtrl.hcxt = (MemoryContext)CurrentMemoryContext; - hashCtrl.hash = tag_hash; + hashCtrl.match = fork_file_node_ignore_opt_match; + hashCtrl.hash = fork_file_node_ignore_opt_hash; hashCtrl.keysize = sizeof(ForkRelFileNode); /* keep entrysize >= keysize, stupid limits */ hashCtrl.entrysize = sizeof(DelForkFileTag); @@ -677,12 +681,13 @@ HTAB *relfilenode_fork_hashtbl_create(const char* name, bool use_heap_mem) if (use_heap_mem) { hashtbl = HeapMemInitHash(name, HASH_TABLE_ELEMENT_MIN_NUM, Max(g_instance.attr.attr_common.max_files_per_process, t_thrd.storage_cxt.max_userdatafiles), - &hashCtrl, (HASH_FUNCTION | HASH_ELEM)); + &hashCtrl, (HASH_FUNCTION | HASH_ELEM | HASH_COMPARE)); if (hashtbl == NULL) { ereport(FATAL, (errmsg("could not initialize unlinik relation hash table"))); } } else { - hashtbl = hash_create(name, HASH_TABLE_ELEMENT_MIN_NUM, &hashCtrl, (HASH_CONTEXT | HASH_FUNCTION | HASH_ELEM)); + hashtbl = hash_create(name, HASH_TABLE_ELEMENT_MIN_NUM, &hashCtrl, + (HASH_CONTEXT | HASH_FUNCTION | HASH_ELEM | HASH_COMPARE)); } return hashtbl; } diff --git a/src/gausskernel/process/postmaster/checkpointer.cpp b/src/gausskernel/process/postmaster/checkpointer.cpp index b6afd04950..aae43be215 100755 --- a/src/gausskernel/process/postmaster/checkpointer.cpp +++ b/src/gausskernel/process/postmaster/checkpointer.cpp @@ -50,6 +50,7 @@ #include "storage/ipc.h" #include "storage/lock/lwlock.h" #include "storage/smgr/knl_usync.h" +#include "storage/smgr/relfilenode_hash.h" #include "storage/proc.h" #include "storage/shmem.h" #include "storage/smgr/smgr.h" @@ -1236,11 +1237,12 @@ int getDuplicateRequest(CheckpointerRequest *requests, int num_requests, bool *s securec_check(rc, "\0", "\0"); ctl.keysize = sizeof(CheckpointerRequest); ctl.entrysize = sizeof(struct CheckpointerSlotMapping); - ctl.hash = tag_hash; + ctl.hash = CheckpointerRequestHash; + ctl.match = CheckpointerRequestMatch; ctl.hcxt = CurrentMemoryContext; htab = hash_create("CompactRequestQueue", num_requests, &ctl, - HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT); + HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT | HASH_COMPARE); /* * The basic idea here is that a request can be skipped if it's followed diff --git a/src/gausskernel/process/postmaster/pagerepair.cpp b/src/gausskernel/process/postmaster/pagerepair.cpp index c9e8f66354..a5ce26c513 100644 --- a/src/gausskernel/process/postmaster/pagerepair.cpp +++ b/src/gausskernel/process/postmaster/pagerepair.cpp @@ -35,6 +35,7 @@ #include "storage/copydir.h" #include "storage/lmgr.h" #include "storage/remote_read.h" +#include "storage/smgr/relfilenode_hash.h" #include "storage/smgr/fd.h" #include "pgstat.h" #include "postmaster/pagerepair.h" @@ -231,10 +232,12 @@ void PageRepairHashTblInit(void) securec_check(rc, "", ""); ctl.keysize = sizeof(RepairBlockKey); ctl.entrysize = sizeof(RepairBlockEntry); - ctl.hash = tag_hash; + ctl.hash = RepairBlockKeyHash; + ctl.match = RepairBlockKeyMatch; ctl.hcxt = INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE); - g_instance.repair_cxt.page_repair_hashtbl = hash_create("Page Repair Hash Table", MAX_REPAIR_PAGE_NUM, &ctl, - HASH_ELEM | HASH_FUNCTION |HASH_CONTEXT); + g_instance.repair_cxt.page_repair_hashtbl = + hash_create("Page Repair Hash Table", MAX_REPAIR_PAGE_NUM, &ctl, + HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT | HASH_COMPARE); if (!g_instance.repair_cxt.page_repair_hashtbl) ereport(FATAL, (errmsg("could not initialize page repair Hash table"))); @@ -891,10 +894,11 @@ void FileRepairHashTblInit(void) securec_check(rc, "", ""); ctl.keysize = sizeof(RepairFileKey); ctl.entrysize = sizeof(RepairFileEntry); - ctl.hash = tag_hash; + ctl.hash = RepairFileKeyHash; + ctl.match = RepairFileKeyMatch; ctl.hcxt = INSTANCE_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE); g_instance.repair_cxt.file_repair_hashtbl = hash_create("File Repair Hash Table", MAX_REPAIR_FILE_NUM, &ctl, - HASH_ELEM | HASH_FUNCTION |HASH_CONTEXT); + HASH_ELEM | HASH_FUNCTION |HASH_CONTEXT | HASH_COMPARE); if (!g_instance.repair_cxt.file_repair_hashtbl) ereport(FATAL, (errmsg("could not initialize file repair Hash table"))); diff --git a/src/gausskernel/process/postmaster/pgstat.cpp b/src/gausskernel/process/postmaster/pgstat.cpp index 2edfd4cd5d..3e9443c708 100644 --- a/src/gausskernel/process/postmaster/pgstat.cpp +++ b/src/gausskernel/process/postmaster/pgstat.cpp @@ -67,6 +67,7 @@ #include "storage/pg_shmem.h" #include "storage/procsignal.h" #include "storage/procarray.h" +#include "storage/smgr/relfilenode_hash.h" #include "threadpool/threadpool.h" #include "utils/ascii.h" #include "utils/atomic.h" @@ -9691,10 +9692,11 @@ void initGlobalBadBlockStat() hash_ctl.hcxt = global_bad_block_mcxt; hash_ctl.keysize = sizeof(BadBlockHashKey); hash_ctl.entrysize = sizeof(BadBlockHashEnt); - hash_ctl.hash = tag_hash; + hash_ctl.hash = BadBlockHashKeyHash; + hash_ctl.match = BadBlockHashKeyMatch; - global_bad_block_stat = - hash_create("bad block stat global hash table", 64, &hash_ctl, HASH_ELEM | HASH_SHRCTX | HASH_FUNCTION); + global_bad_block_stat = hash_create("bad block stat global hash table", 64, &hash_ctl, + HASH_ELEM | HASH_SHRCTX | HASH_FUNCTION | HASH_COMPARE); } LWLockRelease(BadBlockStatHashLock); @@ -9724,10 +9726,11 @@ void initLocalBadBlockStat() hash_ctl.hcxt = t_thrd.stat_cxt.local_bad_block_mcxt; hash_ctl.keysize = sizeof(BadBlockHashKey); hash_ctl.entrysize = sizeof(BadBlockHashEnt); - hash_ctl.hash = tag_hash; + hash_ctl.hash = BadBlockHashKeyHash; + hash_ctl.match = BadBlockHashKeyMatch; - t_thrd.stat_cxt.local_bad_block_stat = - hash_create("bad block stat session hash table", 16, &hash_ctl, HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT); + t_thrd.stat_cxt.local_bad_block_stat = hash_create("bad block stat session hash table", 16, &hash_ctl, + HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT | HASH_COMPARE); } } @@ -9799,10 +9802,11 @@ void resetBadBlockStat() hash_ctl.hcxt = global_bad_block_mcxt; hash_ctl.keysize = sizeof(BadBlockHashKey); hash_ctl.entrysize = sizeof(BadBlockHashEnt); - hash_ctl.hash = tag_hash; + hash_ctl.hash = BadBlockHashKeyHash; + hash_ctl.match = BadBlockHashKeyMatch; global_bad_block_stat = - hash_create("bad block stat hash table", 64, &hash_ctl, HASH_ELEM | HASH_SHRCTX | HASH_FUNCTION); + hash_create("bad block stat hash table", 64, &hash_ctl, HASH_ELEM | HASH_SHRCTX | HASH_FUNCTION | HASH_COMPARE); LWLockRelease(BadBlockStatHashLock); } diff --git a/src/gausskernel/security/tde_key_management/tde_key_storage.cpp b/src/gausskernel/security/tde_key_management/tde_key_storage.cpp index fffd9f8e4b..148a970d81 100755 --- a/src/gausskernel/security/tde_key_management/tde_key_storage.cpp +++ b/src/gausskernel/security/tde_key_management/tde_key_storage.cpp @@ -27,6 +27,7 @@ #include "utils/memutils.h" #include "utils/elog.h" #include "access/hash.h" +#include "storage/smgr/relfilenode_hash.h" namespace TDE { void TDEKeyStorage::init() @@ -304,10 +305,11 @@ void TDEBufferCache::init() securec_check(rc, "", ""); tde_buffer_ctl.keysize = sizeof(RelFileNode); tde_buffer_ctl.entrysize = sizeof(TdeFileNodeEntry); - tde_buffer_ctl.hash = tag_hash; + tde_buffer_ctl.hash = file_node_ignore_opt_hash; + tde_buffer_ctl.match = file_node_ignore_opt_match; tde_buffer_ctl.hcxt = tde_buffer_mem; tde_buffer_cache = hash_create(tde_buffer_name, max_bucket, &tde_buffer_ctl, - HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT); + HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT | HASH_COMPARE); if (tde_buffer_cache == NULL) { ereport(ERROR, (errmodule(MOD_SEC_TDE), errcode(ERRCODE_FUNCTION_HASH_NOT_INITED), errmsg("init TDE buffer cache is NULL"), errdetail("N/A"), diff --git a/src/gausskernel/storage/access/common/Makefile b/src/gausskernel/storage/access/common/Makefile index 7f33a43afe..797ac8a4d2 100644 --- a/src/gausskernel/storage/access/common/Makefile +++ b/src/gausskernel/storage/access/common/Makefile @@ -10,6 +10,6 @@ ifneq "$(MAKECMDGOALS)" "clean" endif endif OBJS = heaptuple.o indextuple.o printtup.o reloptions.o scankey.o \ - tupconvert.o tupdesc.o cstorescankey.o + tupconvert.o tupdesc.o cstorescankey.o relfilenode_hash.o include $(top_srcdir)/src/gausskernel/common.mk diff --git a/src/gausskernel/storage/access/common/relfilenode_hash.cpp b/src/gausskernel/storage/access/common/relfilenode_hash.cpp new file mode 100644 index 0000000000..3cb0a814ef --- /dev/null +++ b/src/gausskernel/storage/access/common/relfilenode_hash.cpp @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2020 Huawei Technologies Co.,Ltd. + * + * openGauss is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * ------------------------------------------------------------------------- + * + * relfilenode_hash.cpp + * hash/match function of relfilenode + * + * IDENTIFICATION + * src/gausskernel/storage/access/common/relfilenode_hash.cpp + * + * ------------------------------------------------------------------------- + */ +#include "storage/buf/buf_internals.h" +#include "access/cbmparsexlog.h" +#include "replication/reorderbuffer.h" +#include "access/extreme_rto/batch_redo.h" +#include "replication/datareceiver.h" +#include "pgstat.h" +#include "storage/smgr/relfilenode_hash.h" + +uint32 fork_file_node_ignore_opt_hash(const void *key, Size keysize) +{ + ForkRelFileNode rnode = *(const ForkRelFileNode *)key; + rnode.rnode.opt = DefaultFileNodeOpt; + return DatumGetUInt32(hash_any((const unsigned char *)&rnode, (int)keysize)); +} + +int fork_file_node_ignore_opt_match(const void *left, const void *right, Size keysize) +{ + const ForkRelFileNode *lnode = (const ForkRelFileNode *)left; + const ForkRelFileNode *rnode = (const ForkRelFileNode *)right; + Assert(lnode != NULL && rnode != NULL); + Assert(keysize == sizeof(ForkRelFileNode)); + + /* we just care whether the result is 0 or not */ + if (RelFileNodeEquals(lnode->rnode, rnode->rnode) && lnode->forkNum == rnode->forkNum) { + return 0; + } + return 1; +} + +int file_node_ignore_opt_match(const void *left, const void *right, Size keysize) +{ + const RelFileNode *lnode = (const RelFileNode *)left; + const RelFileNode *rnode = (const RelFileNode *)right; + Assert(lnode != NULL && rnode != NULL); + Assert(keysize == sizeof(RelFileNode)); + + /* we just care whether the result is 0 or not */ + if (RelFileNodeEquals(*lnode, *rnode)) { + return 0; + } + + return 1; +} + +uint32 file_node_ignore_opt_hash(const void *key, Size keysize) +{ + RelFileNode rnode = *(const RelFileNode *)key; + rnode.opt = DefaultFileNodeOpt; + return DatumGetUInt32(hash_any((const unsigned char *)&rnode, (int)keysize)); +} + +uint32 FileTagHashWithoutOpt(const void *key, Size keysize) +{ + FileTag fileTag = *(const FileTag *)key; + fileTag.rnode.opt = 0; + return tag_hash((const void *)&fileTag, keysize); +} + +int FileTagMatchWithoutOpt(const void *left, const void *right, Size keysize) +{ + const FileTag *lnode = (const FileTag *)left; + const FileTag *rnode = (const FileTag *)right; + Assert(keysize == sizeof(FileTag)); + + /* we just care whether the result is 0 or not */ + if (RelFileNodeEquals(lnode->rnode, rnode->rnode) && lnode->handler == rnode->handler && + rnode->segno == lnode->segno && rnode->forknum == lnode->forknum) { + return 0; + } + + return 1; +} + +uint32 BufTagHashWithoutOpt(const void *key, Size keysize) +{ + return BufTableHashCode((BufferTag *)key); +} + +int BufTagMatchWithoutOpt(const void *left, const void *right, Size keysize) +{ + const BufferTag *leftBufferTag = (const BufferTag *)left; + const BufferTag *rightBufferTag = (const BufferTag *)right; + Assert(keysize == sizeof(BufferTag)); + + /* we just care whether the result is 0 or not */ + if (RelFileNodeEquals(leftBufferTag->rnode, rightBufferTag->rnode) && + leftBufferTag->forkNum == rightBufferTag->forkNum && leftBufferTag->blockNum == rightBufferTag->blockNum) { + return 0; + } + + return 1; +} + +uint32 ReorderBufferTupleCidKeyHash(const void *key, Size keysize) +{ + ReorderBufferTupleCidKey reorderBufferTupleCidKey = *(const ReorderBufferTupleCidKey *)key; + reorderBufferTupleCidKey.relnode.opt = DefaultFileNodeOpt; + return DatumGetUInt32(hash_any((const unsigned char *)&reorderBufferTupleCidKey, (int)keysize)); +} + +int ReorderBufferTupleCidKeyMatch(const void *left, const void *right, Size keysize) +{ + const ReorderBufferTupleCidKey *leftKey = (const ReorderBufferTupleCidKey *)left; + const ReorderBufferTupleCidKey *rightKey = (const ReorderBufferTupleCidKey *)right; + Assert(keysize == sizeof(ReorderBufferTupleCidKey)); + + /* we just care whether the result is 0 or not */ + if (RelFileNodeEquals(leftKey->relnode, rightKey->relnode) && + BlockIdEquals(&(leftKey->tid.ip_blkid), &(rightKey->tid.ip_blkid)) && + leftKey->tid.ip_posid == rightKey->tid.ip_posid) { + return 0; + } + + return 1; +} + +uint32 CBMPageTagHash(const void *key, Size keysize) +{ + CBMPageTag cbmPage = *(const CBMPageTag *)key; + cbmPage.rNode.opt = DefaultFileNodeOpt; + return DatumGetUInt32(hash_any((const unsigned char *)&cbmPage, (int)keysize)); +} + +int CBMPageTagMatch(const void *left, const void *right, Size keysize) +{ + const CBMPageTag *leftKey = (const CBMPageTag *)left; + const CBMPageTag *rightKey = (const CBMPageTag *)right; + Assert(keysize == sizeof(CBMPageTag)); + + /* we just care whether the result is 0 or not */ + if (RelFileNodeEquals(leftKey->rNode, rightKey->rNode) && leftKey->forkNum == rightKey->forkNum) { + return 0; + } + + return 1; +} + +uint32 RedoItemTagHash(const void *key, Size keysize) +{ + extreme_rto::RedoItemTag redoItemTag = *(const extreme_rto::RedoItemTag *)key; + redoItemTag.rNode.opt = DefaultFileNodeOpt; + return DatumGetUInt32(hash_any((const unsigned char *)&redoItemTag, (int)keysize)); +} + +int RedoItemTagMatch(const void *left, const void *right, Size keysize) +{ + const extreme_rto::RedoItemTag *leftKey = (const extreme_rto::RedoItemTag *)left; + const extreme_rto::RedoItemTag *rightKey = (const extreme_rto::RedoItemTag *)right; + Assert(keysize == sizeof(extreme_rto::RedoItemTag)); + + /* we just care whether the result is 0 or not */ + if (RelFileNodeEquals(leftKey->rNode, rightKey->rNode) && leftKey->forkNum == rightKey->forkNum && + leftKey->blockNum == rightKey->blockNum) { + return 0; + } + + return 1; +} + +uint32 DataWriterRelKeyHash(const void *key, Size keysize) +{ + data_writer_rel_key dataWriterRelKey = *(const data_writer_rel_key *)key; + dataWriterRelKey.node.opt = DefaultFileNodeOpt; + return DatumGetUInt32(hash_any((const unsigned char *)&dataWriterRelKey, (int)keysize)); +} + +int DataWriterRelKeyMatch(const void *left, const void *right, Size keysize) +{ + const data_writer_rel_key *leftKey = (const data_writer_rel_key *)left; + const data_writer_rel_key *rightKey = (const data_writer_rel_key *)right; + Assert(keysize == sizeof(data_writer_rel_key)); + + /* we just care whether the result is 0 or not */ + if (RelFileNodeEquals(leftKey->node, rightKey->node) && leftKey->forkno == rightKey->forkno && + leftKey->attid == rightKey->attid && leftKey->type == rightKey->type) { + return 0; + } + + return 1; +} + +uint32 CheckpointerRequestHash(const void *key, Size keysize) +{ + CheckpointerRequest checkpointerRequest = *(const CheckpointerRequest *)key; + checkpointerRequest.ftag.rnode.opt = DefaultFileNodeOpt; + return DatumGetUInt32(hash_any((const unsigned char *)&checkpointerRequest, (int)keysize)); +} + +int CheckpointerRequestMatch(const void *left, const void *right, Size keysize) +{ + const CheckpointerRequest *leftKey = (const CheckpointerRequest *)left; + const CheckpointerRequest *rightKey = (const CheckpointerRequest *)right; + Assert(keysize == sizeof(CheckpointerRequest)); + + /* we just care whether the result is 0 or not */ + if (FileTagMatchWithoutOpt((const void *)(&leftKey->ftag), (const void *)(&rightKey->ftag), sizeof(FileTag)) == 0) { + if (leftKey->type == rightKey->type) { + return 0; + } + } + return 1; +} + +uint32 BadBlockKeyHash(const void *key, Size keysize) +{ + BadBlockKey badBlockKey = *(const BadBlockKey *)key; + badBlockKey.relfilenode.opt = DefaultFileNodeOpt; + return DatumGetUInt32(hash_any((const unsigned char *)&badBlockKey, (int)keysize)); +} + +int BadBlockKeyMatch(const void *left, const void *right, Size keysize) +{ + const BadBlockKey *leftKey = (const BadBlockKey *)left; + const BadBlockKey *rightKey = (const BadBlockKey *)right; + Assert(keysize == sizeof(BadBlockKey)); + + /* we just care whether the result is 0 or not */ + if (RelFileNodeEquals(leftKey->relfilenode, rightKey->relfilenode) && leftKey->forknum == rightKey->forknum && + leftKey->blocknum == rightKey->blocknum) { + return 0; + } + + return 1; +} + +uint32 BadBlockHashKeyHash(const void *key, Size keysize) +{ + BadBlockHashKey badBlockHashKey = *(const BadBlockHashKey *)key; + badBlockHashKey.relfilenode.opt = DefaultFileNodeOpt; + return DatumGetUInt32(hash_any((const unsigned char *)&badBlockHashKey, (int)keysize)); +} + +int BadBlockHashKeyMatch(const void *left, const void *right, Size keysize) +{ + const BadBlockHashKey *leftKey = (const BadBlockHashKey *)left; + const BadBlockHashKey *rightKey = (const BadBlockHashKey *)right; + Assert(keysize == sizeof(BadBlockHashKey)); + + /* we just care whether the result is 0 or not */ + if (RelFileNodeEquals(leftKey->relfilenode, rightKey->relfilenode) && leftKey->forknum == rightKey->forknum) { + return 0; + } + + return 1; +} + +uint32 RepairBlockKeyHash(const void *key, Size keysize) +{ + RepairBlockKey repairBlockKey = *(const RepairBlockKey *)key; + repairBlockKey.relfilenode.opt = DefaultFileNodeOpt; + return DatumGetUInt32(hash_any((const unsigned char *)&repairBlockKey, (int)keysize)); +} + +int RepairBlockKeyMatch(const void *left, const void *right, Size keysize) +{ + const RepairBlockKey *leftKey = (const RepairBlockKey *)left; + const RepairBlockKey *rightKey = (const RepairBlockKey *)right; + Assert(keysize == sizeof(RepairBlockKey)); + + /* we just care whether the result is 0 or not */ + if (RelFileNodeEquals(leftKey->relfilenode, rightKey->relfilenode) && leftKey->forknum == rightKey->forknum && + leftKey->blocknum == rightKey->blocknum) { + return 0; + } + return 1; +} + +uint32 RepairFileKeyHash(const void *key, Size keysize) +{ + RepairFileKey repairFileKey = *(const RepairFileKey *)key; + repairFileKey.relfilenode.opt = DefaultFileNodeOpt; + return DatumGetUInt32(hash_any((const unsigned char *)&repairFileKey, (int)keysize)); +} + +int RepairFileKeyMatch(const void *left, const void *right, Size keysize) +{ + const RepairFileKey *leftKey = (const RepairFileKey *)left; + const RepairFileKey *rightKey = (const RepairFileKey *)right; + Assert(keysize == sizeof(RepairFileKey)); + + /* we just care whether the result is 0 or not */ + if (RelFileNodeEquals(leftKey->relfilenode, rightKey->relfilenode) && leftKey->forknum == rightKey->forknum && + leftKey->segno == rightKey->segno) { + return 0; + } + return 1; +} diff --git a/src/gausskernel/storage/access/transam/cbmparsexlog.cpp b/src/gausskernel/storage/access/transam/cbmparsexlog.cpp index 8bf0b45bdd..3dd5b72796 100644 --- a/src/gausskernel/storage/access/transam/cbmparsexlog.cpp +++ b/src/gausskernel/storage/access/transam/cbmparsexlog.cpp @@ -44,6 +44,7 @@ #include "postmaster/cbmwriter.h" #include "storage/copydir.h" #include "storage/smgr/fd.h" +#include "storage/smgr/relfilenode_hash.h" #include "storage/freespace.h" #include "storage/lock/lwlock.h" #include "storage/proc.h" @@ -636,9 +637,10 @@ static HTAB *CBMPageHashInitialize(MemoryContext memoryContext) ctl.hcxt = memoryContext; ctl.keysize = sizeof(CBMPageTag); ctl.entrysize = sizeof(CbmHashEntry); - ctl.hash = tag_hash; + ctl.hash = CBMPageTagHash; + ctl.match = CBMPageTagMatch; hTab = hash_create("CBM page hash by relfilenode and forknum", INITCBMPAGEHASHSIZE, &ctl, - HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT); + HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT | HASH_COMPARE); return hTab; } diff --git a/src/gausskernel/storage/access/transam/extreme_rto/batch_redo.cpp b/src/gausskernel/storage/access/transam/extreme_rto/batch_redo.cpp index 66d53f5d67..92b94fedca 100644 --- a/src/gausskernel/storage/access/transam/extreme_rto/batch_redo.cpp +++ b/src/gausskernel/storage/access/transam/extreme_rto/batch_redo.cpp @@ -33,6 +33,7 @@ #include "commands/dbcommands.h" #include "commands/tablespace.h" #include "storage/freespace.h" +#include "storage/smgr/relfilenode_hash.h" #include "utils/relmapper.h" #include "access/extreme_rto/batch_redo.h" @@ -83,9 +84,10 @@ HTAB *PRRedoItemHashInitialize(MemoryContext context) ctl.hcxt = context; ctl.keysize = sizeof(RedoItemTag); ctl.entrysize = sizeof(RedoItemHashEntry); - ctl.hash = tag_hash; + ctl.hash = RedoItemTagHash; + ctl.match = RedoItemTagMatch; hTab = hash_create("Redo item hash by relfilenode and blocknum", INITredoItemHashSIZE, &ctl, - HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT); + HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT | HASH_COMPARE); return hTab; } diff --git a/src/gausskernel/storage/access/transam/extreme_rto/page_redo.cpp b/src/gausskernel/storage/access/transam/extreme_rto/page_redo.cpp index 6ec2266241..23e37d0689 100755 --- a/src/gausskernel/storage/access/transam/extreme_rto/page_redo.cpp +++ b/src/gausskernel/storage/access/transam/extreme_rto/page_redo.cpp @@ -48,6 +48,7 @@ #include "storage/ipc.h" #include "storage/freespace.h" #include "storage/smgr/smgr.h" +#include "storage/smgr/relfilenode_hash.h" #include "storage/standby.h" #include "storage/pmsignal.h" #include "utils/guc.h" @@ -2811,9 +2812,10 @@ HTAB* BadBlockHashTblCreate() ctl.keysize = sizeof(RepairBlockKey); ctl.entrysize = sizeof(BadBlockRecEnt); - ctl.hash = tag_hash; - - return hash_create("recovery thread bad block hashtbl", MAX_REMOTE_READ_INFO_NUM, &ctl, HASH_ELEM | HASH_FUNCTION); + ctl.hash = RepairBlockKeyHash; + ctl.match = RepairBlockKeyMatch; + return hash_create("recovery thread bad block hashtbl", MAX_REMOTE_READ_INFO_NUM, &ctl, + HASH_ELEM | HASH_FUNCTION | HASH_COMPARE); } diff --git a/src/gausskernel/storage/access/transam/parallel_recovery/page_redo.cpp b/src/gausskernel/storage/access/transam/parallel_recovery/page_redo.cpp index 4ff7077fe4..c9b465f221 100755 --- a/src/gausskernel/storage/access/transam/parallel_recovery/page_redo.cpp +++ b/src/gausskernel/storage/access/transam/parallel_recovery/page_redo.cpp @@ -45,6 +45,7 @@ #include "postmaster/pagerepair.h" #include "storage/ipc.h" #include "storage/standby.h" +#include "storage/smgr/relfilenode_hash.h" #include "access/nbtree.h" #include "utils/guc.h" #include "utils/palloc.h" @@ -1141,9 +1142,10 @@ HTAB* BadBlockHashTblCreate() ctl.keysize = sizeof(RepairBlockKey); ctl.entrysize = sizeof(BadBlockRecEnt); - ctl.hash = tag_hash; - - return hash_create("recovery thread bad block hashtbl", MAX_REMOTE_READ_INFO_NUM, &ctl, HASH_ELEM | HASH_FUNCTION); + ctl.hash = RepairBlockKeyHash; + ctl.match = RepairBlockKeyMatch; + return hash_create("recovery thread bad block hashtbl", MAX_REMOTE_READ_INFO_NUM, &ctl, + HASH_ELEM | HASH_FUNCTION | HASH_COMPARE); } /* RecordBadBlockAndPushToRemote diff --git a/src/gausskernel/storage/access/transam/xlogutils.cpp b/src/gausskernel/storage/access/transam/xlogutils.cpp index 5fab4c308e..4304e3f12e 100644 --- a/src/gausskernel/storage/access/transam/xlogutils.cpp +++ b/src/gausskernel/storage/access/transam/xlogutils.cpp @@ -20,6 +20,7 @@ #include "postgres.h" #include "knl/knl_variable.h" +#include "access/hash.h" #include "access/nbtree.h" #include "access/xlog.h" #include "access/xlogutils.h" @@ -141,6 +142,28 @@ static inline void SetCurrentXLogLSN(XLogRecPtr lsn) t_thrd.xlog_cxt.current_redo_xlog_lsn = lsn; } +uint32 XlInvalidPageKeyHash(const void *key, Size keysize) +{ + xl_invalid_page_key invalidPageKey = *(const xl_invalid_page_key *)key; + invalidPageKey.node.opt = 0; + return DatumGetUInt32(hash_any((const unsigned char *)&invalidPageKey, (int)keysize)); +} + +int XlInvalidPageKeyMatch(const void *left, const void *right, Size keysize) +{ + const xl_invalid_page_key *leftKey = (const xl_invalid_page_key *)left; + const xl_invalid_page_key *rightKey = (const xl_invalid_page_key *)right; + Assert(keysize == sizeof(xl_invalid_page_key)); + + /* we just care whether the result is 0 or not */ + if (RelFileNodeEquals(leftKey->node, rightKey->node) && leftKey->forkno == rightKey->forkno && + leftKey->blkno == rightKey->blkno) { + return 0; + } + + return 1; +} + /* Log a reference to an invalid page */ void log_invalid_page(const RelFileNode &node, ForkNumber forkno, BlockNumber blkno, InvalidPageType type, const XLogPhyBlock *pblk) @@ -168,8 +191,9 @@ void log_invalid_page(const RelFileNode &node, ForkNumber forkno, BlockNumber bl ctl.keysize = sizeof(xl_invalid_page_key); ctl.entrysize = sizeof(xl_invalid_page); - ctl.hash = tag_hash; - int flag = HASH_ELEM | HASH_FUNCTION; + ctl.hash = XlInvalidPageKeyHash; + ctl.match = XlInvalidPageKeyMatch; + int flag = HASH_ELEM | HASH_FUNCTION | HASH_COMPARE; if (IsMultiThreadRedoRunning()) { ctl.hcxt = g_instance.comm_cxt.predo_cxt.parallelRedoCtx; flag |= HASH_SHRCTX; diff --git a/src/gausskernel/storage/buffer/buf_table.cpp b/src/gausskernel/storage/buffer/buf_table.cpp index 04e79f4739..4fd0dcece4 100644 --- a/src/gausskernel/storage/buffer/buf_table.cpp +++ b/src/gausskernel/storage/buffer/buf_table.cpp @@ -72,7 +72,9 @@ void InitBufTable(int size) */ uint32 BufTableHashCode(BufferTag *tagPtr) { - return hashquickany(0xFFFFFFFF, (unsigned char *)tagPtr, sizeof(BufferTag)); + BufferTag tag = *tagPtr; + tag.rnode.opt = DefaultFileNodeOpt; + return hashquickany(0xFFFFFFFF, (unsigned char *)&tag, sizeof(BufferTag)); } /* diff --git a/src/gausskernel/storage/buffer/localbuf.cpp b/src/gausskernel/storage/buffer/localbuf.cpp index 29b2c0fd54..6ac87aef6f 100644 --- a/src/gausskernel/storage/buffer/localbuf.cpp +++ b/src/gausskernel/storage/buffer/localbuf.cpp @@ -23,6 +23,7 @@ #include "storage/buf/buf_internals.h" #include "storage/buf/bufmgr.h" #include "storage/smgr/segment.h" +#include "storage/smgr/relfilenode_hash.h" #include "utils/guc.h" #include "utils/memutils.h" #include "utils/resowner.h" @@ -443,11 +444,12 @@ static void InitLocalBuffers(void) securec_check(ret, "\0", "\0"); info.keysize = sizeof(BufferTag); info.entrysize = sizeof(LocalBufferLookupEnt); - info.hash = tag_hash; + info.match = BufTagMatchWithoutOpt; + info.hash = BufTagHashWithoutOpt; info.hcxt = SESS_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE); u_sess->storage_cxt.LocalBufHash = hash_create( - "Local Buffer Lookup Table", nbufs, &info, HASH_ELEM | HASH_CONTEXT | HASH_FUNCTION); + "Local Buffer Lookup Table", nbufs, &info, HASH_ELEM | HASH_CONTEXT | HASH_FUNCTION | HASH_COMPARE); if (!u_sess->storage_cxt.LocalBufHash) { ereport(ERROR, (errcode(ERRCODE_INITIALIZE_FAILED), diff --git a/src/gausskernel/storage/replication/datarcvwriter.cpp b/src/gausskernel/storage/replication/datarcvwriter.cpp index 5ba7a67645..de341a93b9 100755 --- a/src/gausskernel/storage/replication/datarcvwriter.cpp +++ b/src/gausskernel/storage/replication/datarcvwriter.cpp @@ -32,6 +32,7 @@ #include "storage/proc.h" #include "storage/lmgr.h" #include "storage/smgr/smgr.h" +#include "storage/smgr/relfilenode_hash.h" #include "postmaster/alarmchecker.h" #include "utils/guc.h" #include "utils/hsearch.h" @@ -746,9 +747,10 @@ static void DataWriterHashCreate(void) securec_check(rc, "", ""); ctl.keysize = sizeof(data_writer_rel_key); ctl.entrysize = sizeof(data_writer_rel); - ctl.hash = tag_hash; + ctl.hash = DataWriterRelKeyHash; + ctl.match = DataWriterRelKeyMatch; t_thrd.datarcvwriter_cxt.data_writer_rel_tab = hash_create("data writer rel table", 100, &ctl, - HASH_ELEM | HASH_FUNCTION); + HASH_ELEM | HASH_FUNCTION | HASH_COMPARE); } else return; } diff --git a/src/gausskernel/storage/replication/logical/reorderbuffer.cpp b/src/gausskernel/storage/replication/logical/reorderbuffer.cpp index c49b1b2ccf..46fabc86a3 100644 --- a/src/gausskernel/storage/replication/logical/reorderbuffer.cpp +++ b/src/gausskernel/storage/replication/logical/reorderbuffer.cpp @@ -74,6 +74,7 @@ #include "storage/buf/bufmgr.h" #include "storage/smgr/fd.h" +#include "storage/smgr/relfilenode_hash.h" #include "storage/sinval.h" #include "utils/acl.h" @@ -1179,7 +1180,8 @@ static void ReorderBufferBuildTupleCidHash(ReorderBuffer *rb, ReorderBufferTXN * hash_ctl.keysize = sizeof(ReorderBufferTupleCidKey); hash_ctl.entrysize = sizeof(ReorderBufferTupleCidEnt); - hash_ctl.hash = tag_hash; + hash_ctl.hash = ReorderBufferTupleCidKeyHash; + hash_ctl.match = ReorderBufferTupleCidKeyMatch; hash_ctl.hcxt = rb->context; /* @@ -1187,7 +1189,7 @@ static void ReorderBufferBuildTupleCidHash(ReorderBuffer *rb, ReorderBufferTXN * * the start */ txn->tuplecid_hash = hash_create("ReorderBufferTupleCid", txn->ntuplecids, &hash_ctl, - HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT); + HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT | HASH_COMPARE); dlist_foreach(iter, &txn->tuplecids) { diff --git a/src/gausskernel/storage/sync/knl_usync.cpp b/src/gausskernel/storage/sync/knl_usync.cpp index f83a9e9615..04f702dbbc 100644 --- a/src/gausskernel/storage/sync/knl_usync.cpp +++ b/src/gausskernel/storage/sync/knl_usync.cpp @@ -28,6 +28,7 @@ #include "postmaster/bgwriter.h" #include "postmaster/pagewriter.h" #include "storage/buf/bufmgr.h" +#include "storage/smgr/relfilenode_hash.h" #include "storage/ipc.h" #include "storage/smgr/segment.h" #include "storage/smgr/smgr.h" @@ -136,9 +137,10 @@ void InitPendingOps(void) hashCtl.keysize = sizeof(FileTag); hashCtl.entrysize = sizeof(PendingFsyncEntry); hashCtl.hcxt = u_sess->storage_cxt.pendingOpsCxt; - hashCtl.hash = tag_hash; + hashCtl.hash = FileTagHashWithoutOpt; + hashCtl.match = FileTagMatchWithoutOpt; u_sess->storage_cxt.pendingOps = hash_create("Pending Ops Table", - 100L, &hashCtl, HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); + 100L, &hashCtl, HASH_ELEM | HASH_BLOBS | HASH_CONTEXT | HASH_COMPARE | HASH_FUNCTION); } } diff --git a/src/include/access/extreme_rto/batch_redo.h b/src/include/access/extreme_rto/batch_redo.h index 5d8cbfedca..327fb3a746 100644 --- a/src/include/access/extreme_rto/batch_redo.h +++ b/src/include/access/extreme_rto/batch_redo.h @@ -46,8 +46,6 @@ namespace extreme_rto { #define INIT_REDO_ITEM_TAG(a, xx_rnode, xx_forkNum, xx_blockNum) \ ((a).rNode = (xx_rnode), (a).forkNum = (xx_forkNum), (a).blockNum = (xx_blockNum)) -#define InvalidRelFileNode ((RelFileNode){ 0, 0, 0 }) - /* * Note: if there are any pad bytes in the struct, INIT_RedoItemTag have * to be fixed to zero them, since this struct is used as a hash key. diff --git a/src/include/storage/buf/buf_internals.h b/src/include/storage/buf/buf_internals.h index 15d98e8eed..9222a264f4 100644 --- a/src/include/storage/buf/buf_internals.h +++ b/src/include/storage/buf/buf_internals.h @@ -121,6 +121,7 @@ typedef struct { (a).rnode.dbNode = InvalidOid, \ (a).rnode.relNode = InvalidOid, \ (a).rnode.bucketNode = -1,\ + (a).rnode.opt = DefaultFileNodeOpt, \ (a).forkNum = InvalidForkNumber, \ (a).blockNum = InvalidBlockNumber) @@ -138,6 +139,7 @@ typedef struct { (a)->rnode.dbNode = (b)->rnode.dbNode, \ (a)->rnode.relNode = (b)->rnode.relNode, \ (a)->rnode.bucketNode = (b)->rnode.bucketNode,\ + (a)->rnode.opt = (b)->rnode.opt, \ (a)->forkNum = (b)->forkNum, \ (a)->blockNum = (b)->blockNum) diff --git a/src/include/storage/smgr/relfilenode.h b/src/include/storage/smgr/relfilenode.h index 573f081a15..89a3725c78 100644 --- a/src/include/storage/smgr/relfilenode.h +++ b/src/include/storage/smgr/relfilenode.h @@ -121,6 +121,7 @@ typedef struct RelFileNodeV2 { #define IsSegmentPhysicalRelNode(rNode) (IsSegmentFileNode(rNode) && (rNode).relNode <= 5) #define IsBucketFileNode(rnode) ((rnode).bucketNode > InvalidBktId && (rnode).bucketNode < SegmentBktId) +#define DefaultFileNodeOpt 0 /*RelFileNodeOld: Old version relfilenode. Compatible with older versions of relfilenode.*/ diff --git a/src/include/storage/smgr/relfilenode_hash.h b/src/include/storage/smgr/relfilenode_hash.h new file mode 100644 index 0000000000..b8c12f02ca --- /dev/null +++ b/src/include/storage/smgr/relfilenode_hash.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2020 Huawei Technologies Co.,Ltd. + * + * openGauss is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * --------------------------------------------------------------------------------------- + * + * relfilenode_hash.h + * hash/match function of relfilenode + * + * + * IDENTIFICATION + * src/include/storage/smgr/relfilenode_hash.h + * + * --------------------------------------------------------------------------------------- + */ + +#ifndef RELFILENODE_HASH_H +#define RELFILENODE_HASH_H + +#include "access/hash.h" +#include "storage/smgr/relfilenode.h" + +/* ForkRelFileNode hash/match function */ +uint32 fork_file_node_ignore_opt_hash(const void *key, Size keysize); +int fork_file_node_ignore_opt_match(const void *left, const void *right, Size keysize); + +/* relfilenode hash/match function */ +extern int file_node_ignore_opt_match(const void* left, const void* right, Size keysize); +extern uint32 file_node_ignore_opt_hash(const void* key, Size keysize); + +/* fileTag hash/match function */ +extern uint32 FileTagHashWithoutOpt(const void *key, Size keysize); +extern int FileTagMatchWithoutOpt(const void *left, const void *right, Size keysize); + +/* BufferTag hash/match function */ +extern uint32 BufTagHashWithoutOpt(const void *key, Size keysize); +extern int BufTagMatchWithoutOpt(const void *left, const void *right, Size keysize); + +/* ReorderBufferTupleCidKey hash/match function */ +extern uint32 ReorderBufferTupleCidKeyHash(const void *key, Size keysize); +extern int ReorderBufferTupleCidKeyMatch(const void *left, const void *right, Size keysize); + +/* CBMPageTag hash/match function */ +extern uint32 CBMPageTagHash(const void *key, Size keysize); +extern int CBMPageTagMatch(const void *left, const void *right, Size keysize); + +/* RedoItemTag hash/match function */ +extern uint32 RedoItemTagHash(const void *key, Size keysize); +extern int RedoItemTagMatch(const void *left, const void *right, Size keysize); + +/* data_writer_rel_key hash/match function */ +extern uint32 DataWriterRelKeyHash(const void *key, Size keysize); +extern int DataWriterRelKeyMatch(const void *left, const void *right, Size keysize); + +/* CheckpointerRequest hash/match function */ +extern uint32 CheckpointerRequestHash(const void *key, Size keysize); +extern int CheckpointerRequestMatch(const void *left, const void *right, Size keysize); + +/* BadBlockKey hash/match function */ +extern uint32 BadBlockKeyHash(const void *key, Size keysize); +extern int BadBlockKeyMatch(const void *left, const void *right, Size keysize); + +/* BadBlockHashKey hash/match function */ +extern uint32 BadBlockHashKeyHash(const void *key, Size keysize); +extern int BadBlockHashKeyMatch(const void *left, const void *right, Size keysize); + +/* RepairBlockKey hash/match function */ +extern uint32 RepairBlockKeyHash(const void *key, Size keysize); +extern int RepairBlockKeyMatch(const void *left, const void *right, Size keysize); + +/* RepairFileKey hash/match function */ +extern uint32 RepairFileKeyHash(const void *key, Size keysize); +extern int RepairFileKeyMatch(const void *left, const void *right, Size keysize); +#endif -- Gitee