* Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
*
* 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.
* ---------------------------------------------------------------------------------------
*
* knl_localsystupcache.h
*
*
*
* IDENTIFICATION
* src/include/utils/knl_localsystupcache.h
*
* ---------------------------------------------------------------------------------------
*/
#ifndef KNL_LOCALSYSTUPCACHE_H
#define KNL_LOCALSYSTUPCACHE_H
#include "utils/knl_globalsysdbcache.h"
#include "utils/knl_globalsystabcache.h"
#include "utils/knl_globalsystupcache.h"
#include "utils/knl_localsyscache_common.h"
#include "utils/syscache.h"
class LocalSysTupCache;
struct LocalCatCTup {
int ct_magic;
#define CT_MAGIC 0x57261502
uint32 hash_value;
* Each tuple in a cache is a member of a Dllist that stores the elements
* of its hash bucket. We keep each Dllist in LRU order to speed repeated
* lookups.
*/
Dlelem cache_elem;
Datum keys[CATCACHE_MAXKEYS];
* A tuple marked "dead" must not be returned by subsequent searches.
* However, it won't be physically deleted from the cache until its
* refcount goes to zero.
*
* A negative cache entry is an assertion that there is no tuple matching
* a particular key. This is just as useful as a normal entry so far as
* avoiding catalog searches is concerned. Management of positive and
* negative entries is identical.
*/
int refcount;
GlobalCatCTup *global_ct;
void Release()
{
Assert(ct_magic == CT_MAGIC);
Assert(refcount > 0);
Assert(global_ct != NULL);
refcount--;
}
};
struct LocalCatCList : CatCList {
GlobalCatCList *global_cl;
void Release()
{
Assert(cl_magic == CL_MAGIC);
Assert(refcount > 0);
refcount--;
}
};
class LocalSysTupCache : public BaseObject {
public:
LocalSysTupCache(int cache_id);
void ResetInitFlag();
void AtEOXact_CatCache(bool isCommit)
{
invalid_entries.ResetInitFlag();
}
int GetCCNKeys() const
{
return m_relinfo.cc_nkeys;
}
int GetCCKeyNo(int index) const
{
return m_relinfo.cc_keyno[index];
}
Oid GetCCRelOid() const
{
return m_relinfo.cc_reloid;
}
Oid GetCCIndexOid() const
{
return m_relinfo.cc_indexoid;
}
bool GetCCRelIsShared()
{
return m_relinfo.cc_relisshared;
}
const MemoryContext GetMemoryCxt()
{
InitPhase2();
return m_local_mem_cxt;
}
const TupleDesc GetCCTupleDesc()
{
InitPhase2();
return m_relinfo.cc_tupdesc;
}
void CreateCatBucket();
void Init()
{
Assert(!m_is_inited || m_relinfo.cc_relisshared);
m_is_inited = true;
}
uint32 GetCatCacheHashValue(Datum v1, Datum v2, Datum v3, Datum v4);
LocalCatCTup *SearchLocalCatCTuple(int nkeys, Datum v1, Datum v2, Datum v3, Datum v4, int level = DEBUG2)
{
InitPhase2();
return SearchTupleInternal(nkeys, v1, v2, v3, v4, level);
}
#ifndef ENABLE_MULTIPLE_NODES
* Specific SearchLocalCatCTuple Function to support ProcedureCreate!
*/
LocalCatCTup *SearchTupleFromGlobalForProcAllArgs(
Datum *arguments, uint32 hash_value, Index hash_index, oidvector* argModes);
LocalCatCTup *SearchLocalCatCTupleForProcAllArgs(Datum v1, Datum v2, Datum v3, Datum v4, Datum proArgModes);
#endif
LocalCatCList *SearchLocalCatCList(int nkeys, Datum v1, Datum v2, Datum v3, Datum v4, int level = DEBUG2)
{
InitPhase2();
return SearchListInternal(nkeys, v1, v2, v3, v4, level);
}
void ReleaseGlobalRefcount();
template <bool reset>
void FlushGlobalByInvalidMsg(Oid db_id, uint32 hash_value);
void ResetCatalogCache();
void ResetGlobal(Oid db_id, bool is_commit)
{
if (!is_commit) {
invalid_entries.ResetCatalog();
return;
}
FlushGlobalByInvalidMsg<true>(db_id, 0);
}
void HashValueInvalidateLocal(uint32 hash_value);
void HashValueInvalidateGlobal(Oid db_id, uint32 hash_value, bool is_commit)
{
if (!is_commit) {
invalid_entries.InsertInvalidDefValue(hash_value);
return;
}
FlushGlobalByInvalidMsg<false>(db_id, hash_value);
}
void PrepareToInvalidateCacheTuple(HeapTuple tuple, HeapTuple newtuple, void (*function)(int, uint32, Oid));
InvalidBaseEntry invalid_entries;
private:
* SearchTupleInternal
*
* This call searches a system cache for a tuple, opening the relation
* if necessary (on the first access to a particular cache).
*
* The result is NULL if not found, or a pointer to a HeapTuple in
* the cache. The caller must not modify the tuple, and must call
* ReleaseTuple() when done with it.
*
* The search key values should be expressed as Datums of the key columns'
* datatype(s). (Pass zeroes for any unused parameters.) As a special
* exception, the passed-in key for a NAME column can be just a C string;
* the caller need not go to the trouble of converting it to a fully
* null-padded NAME.
*/
LocalCatCTup *SearchTupleInternal(int nkeys, Datum v1, Datum v2, Datum v3, Datum v4, int level);
LocalCatCTup *SearchTupleFromGlobal(Datum *arguments, uint32 hash_value, Index hash_index, int level);
LocalCatCList *SearchListInternal(int nkeys, Datum v1, Datum v2, Datum v3, Datum v4, int level);
LocalCatCList *SearchListFromGlobal(int nkeys, Datum *arguments, uint32 hash_value, int level);
void FreeLocalCatCList(LocalCatCList *cl);
void HandleDeadLocalCatCList(LocalCatCList *cl);
void FreeDeadCls();
void FreeLocalCatCTup(LocalCatCTup *ct);
void HandleDeadLocalCatCTup(LocalCatCTup *ct);
void FreeDeadCts();
LocalCatCTup *CreateLocalCatCTup(GlobalCatCTup *global_ct, Datum *arguments, uint32 hash_value, Index hash_index);
void InitPhase2()
{
if (unlikely(!m_is_inited_phase2)) {
InitPhase2Impl();
}
if (unlikely(m_global_systupcache->enable_rls)) {
FlushRlsUserImpl();
}
}
void FlushRlsUserImpl();
void InitPhase2Impl();
void RemoveTailTupleElements(Index hash_index);
void RemoveTailListElements();
Dllist *GetBucket(Index hash_index)
{
return &(cc_buckets[hash_index]);
}
bool m_is_inited;
bool m_is_inited_phase2;
Oid m_rls_user;
Dllist m_dead_cts;
Dllist m_dead_cls;
MemoryContext m_local_mem_cxt;
GlobalSysTupCache *m_global_systupcache;
Oid m_db_id;
Oid m_cache_id;
int cc_id;
CatTupRelInfoMsg m_relinfo;
int cc_nbuckets;
Dllist cc_lists;
Dllist *cc_buckets;
long cc_searches;
long cc_hits;
long cc_neg_hits;
long cc_newloads;
* cc_searches - (cc_hits + cc_neg_hits + cc_newloads) is number of failed
* searches, each of which will result in loading a negative entry
*/
long cc_invals;
long cc_lsearches;
long cc_lhits;
};
extern bool CheckPrivilegeOfTuple(HeapTuple ct);
#endif