greenplumn appendonly_visimap_store 源码
greenplumn appendonly_visimap_store 代码
文件路径:/src/backend/access/appendonly/appendonly_visimap_store.c
/*------------------------------------------------------------------------------
*
* appendonly_visimap
* maintain a visibility bitmap for all rows in a
* minipage.
*
* Copyright (c) 2013-Present VMware, Inc. or its affiliates.
*
*
* IDENTIFICATION
* src/backend/access/appendonly/appendonly_visimap_store.c
*
*------------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/genam.h"
#include "access/table.h"
#include "catalog/aovisimap.h"
#include "catalog/indexing.h"
#include "access/appendonly_visimap_store.h"
#include "parser/parse_oper.h"
#include "utils/lsyscache.h"
#include "utils/fmgroids.h"
#include "utils/guc.h"
#include "utils/snapmgr.h"
#define APPENDONLY_VISIMAP_INDEX_SCAN_KEY_NUM 2
/*
* Frees the data allocated by the visimap store
*
* No function using the visibility map store should be called
* after this function call.
*/
void
AppendOnlyVisimapStore_Finish(AppendOnlyVisimapStore *visiMapStore,
LOCKMODE lockmode)
{
if (visiMapStore->scanKeys)
{
pfree(visiMapStore->scanKeys);
visiMapStore->scanKeys = NULL;
}
UnregisterSnapshot(visiMapStore->snapshot);
index_close(visiMapStore->visimapIndex, lockmode);
table_close(visiMapStore->visimapRelation, lockmode);
}
/*
* Inits the visimap store.
* The store is ready for usage after this function call.
*
* Assumes a zero-allocated visimap store data structure.
* Assumes that the visimap memory context is active.
*/
void
AppendOnlyVisimapStore_Init(AppendOnlyVisimapStore *visiMapStore,
Oid visimapRelid,
Oid visimapIdxid,
LOCKMODE lockmode,
Snapshot snapshot,
MemoryContext memoryContext)
{
TupleDesc heapTupleDesc;
ScanKey scanKey;
Assert(visiMapStore);
Assert(CurrentMemoryContext == memoryContext);
Assert(OidIsValid(visimapRelid));
Assert(OidIsValid(visimapIdxid));
visiMapStore->snapshot = RegisterSnapshot(snapshot);
visiMapStore->memoryContext = memoryContext;
visiMapStore->visimapRelation = table_open(visimapRelid, lockmode);
visiMapStore->visimapIndex = index_open(visimapIdxid, lockmode);
heapTupleDesc =
RelationGetDescr(visiMapStore->visimapRelation);
Assert(heapTupleDesc->natts == Natts_pg_aovisimap);
visiMapStore->scanKeys = palloc0(sizeof(ScanKeyData) * APPENDONLY_VISIMAP_INDEX_SCAN_KEY_NUM);
/* scan key: segno */
scanKey = visiMapStore->scanKeys;
ScanKeyInit(scanKey,
Anum_pg_aovisimap_segno, /* segno */
BTEqualStrategyNumber,
F_INT4EQ,
0);
/* scan key: firstRowNum */
scanKey++;
ScanKeyInit(scanKey,
Anum_pg_aovisimap_firstrownum, /* attribute number to scan */
BTEqualStrategyNumber, /* strategy */
F_INT8EQ, /* reg proc to use */
0);
}
/*
* Stores the visibility map entry.
*
* The entry/tuple is invalidated after this function call.
*
* Assumes that a valid visimap entry is passed.
* Assumes that the entry corresponds to the latest tuple
* returned by AppendOnlyVisimapStore_find.
*
* Should not be called twice in the same command.
*/
void
AppendOnlyVisimapStore_Store(
AppendOnlyVisimapStore *visiMapStore,
AppendOnlyVisimapEntry *visiMapEntry)
{
MemoryContext oldContext;
Relation visimapRelation;
TupleDesc heapTupleDesc;
HeapTuple tuple;
Datum values[Natts_pg_aovisimap];
bool nulls[Natts_pg_aovisimap];
Assert(visiMapStore);
Assert(visiMapEntry);
elogif(Debug_appendonly_print_visimap, LOG,
"Append-only visi map store: Store visimap entry: "
"(segFileNum, firstRowNum) = (%u, " INT64_FORMAT ")",
visiMapEntry->segmentFileNum, visiMapEntry->firstRowNum);
oldContext = MemoryContextSwitchTo(visiMapStore->memoryContext);
AppendOnlyVisimapEntry_Write(visiMapEntry, values,
nulls);
visimapRelation = visiMapStore->visimapRelation;
heapTupleDesc = RelationGetDescr(visimapRelation);
tuple = heap_form_tuple(heapTupleDesc,
values,
nulls);
/*
* Write out the visimap entry to the relation. If this visimap entry
* already in the relation, we update the row. Otherwise, a new row is
* inserted.
*/
if (ItemPointerIsValid(&visiMapEntry->tupleTid))
{
CatalogTupleUpdate(visimapRelation, &visiMapEntry->tupleTid, tuple);
}
else
{
CatalogTupleInsert(visimapRelation, tuple);
}
heap_freetuple(tuple);
MemoryContextSwitchTo(oldContext);
/* Invalidate the data after storing it. */
ItemPointerSetInvalid(&visiMapEntry->tupleTid);
}
/**
* Finds the visibility map entry tuple for a given
* segmentFileNum and firstRowNum.
*
* Note: The firstRowNum needs to be a valid firstRowNum. It is
* especially not the tuple id of the append-only tuple checked, updated,
* or deleted.
*
* Returns true if there is such a tuple and
* the tuple is used as current tuple.
* Otherwise false is returned.
*
* Assumes that the store data structure has been initialized, but not finished.
*/
bool
AppendOnlyVisimapStore_Find(AppendOnlyVisimapStore *visiMapStore,
int32 segmentFileNum,
int64 firstRowNum,
AppendOnlyVisimapEntry *visiMapEntry)
{
ScanKey scanKeys;
SysScanDesc indexScan;
Assert(visiMapStore);
Assert(visiMapEntry);
Assert(RelationIsValid(visiMapStore->visimapRelation));
Assert(RelationIsValid(visiMapStore->visimapIndex));
elogif(Debug_appendonly_print_visimap, LOG,
"Append-only visi map store: Load entry: "
"(segFileNum, firstRowNum) = (%u, " INT64_FORMAT ")",
segmentFileNum, firstRowNum);
scanKeys = visiMapStore->scanKeys;
scanKeys[0].sk_argument = Int32GetDatum(segmentFileNum);
scanKeys[1].sk_argument = Int64GetDatum(firstRowNum);
indexScan = AppendOnlyVisimapStore_BeginScan(visiMapStore,
APPENDONLY_VISIMAP_INDEX_SCAN_KEY_NUM,
scanKeys);
if (!AppendOnlyVisimapStore_GetNext(
visiMapStore,
indexScan,
BackwardScanDirection,
visiMapEntry,
&visiMapEntry->tupleTid))
{
elogif(Debug_appendonly_print_visimap, LOG,
"Append-only visi map store: Visimap entry does not exist: "
"(segFileNum, firstRowNum) = (%u, " INT64_FORMAT ")",
segmentFileNum, firstRowNum);
/* failed to lookup row */
AppendOnlyVisimapStore_EndScan(visiMapStore, indexScan);
return false;
}
AppendOnlyVisimapStore_EndScan(visiMapStore, indexScan);
return true;
}
/*
* Fetches the next entry from a visimap store index scan.
*
* It is the responsibility of the caller to decode the return value
* correctly.
*
*/
static HeapTuple
AppendOnlyVisimapStore_GetNextTuple(AppendOnlyVisimapStore *visiMapStore,
SysScanDesc indexScan,
ScanDirection scanDirection)
{
Assert(visiMapStore);
Assert(RelationIsValid(visiMapStore->visimapRelation));
Assert(RelationIsValid(visiMapStore->visimapIndex));
Assert(indexScan);
return systable_getnext_ordered(indexScan, scanDirection);
}
/*
* Fetches the next entry from a visimap store index scan.
*
* Parameter visiMapEntry may be NULL. If it is not NULL and
* the scan returns an entry, the entry data is copied to the
* visimapEntry.
* Parameter tupleTid may be NULL. If it is not NULL and the scan
* returns an entry, the (heap) tuple id is copied to the parameter.
*/
bool
AppendOnlyVisimapStore_GetNext(AppendOnlyVisimapStore *visiMapStore,
SysScanDesc indexScan,
ScanDirection scanDirection,
AppendOnlyVisimapEntry *visiMapEntry,
ItemPointerData *tupleTid)
{
HeapTuple tuple;
TupleDesc heapTupleDesc;
Assert(visiMapStore);
Assert(RelationIsValid(visiMapStore->visimapRelation));
Assert(RelationIsValid(visiMapStore->visimapIndex));
Assert(indexScan);
tuple = AppendOnlyVisimapStore_GetNextTuple(visiMapStore, indexScan, scanDirection);
if (tuple == NULL)
{
return false;
}
heapTupleDesc = RelationGetDescr(visiMapStore->visimapRelation);
if (visiMapEntry)
{
AppendOnlyVisimapEntry_Copyout(visiMapEntry, tuple,
heapTupleDesc);
}
if (tupleTid)
{
ItemPointerCopy(&tuple->t_self, tupleTid);
}
return true;
}
/*
* Deletes all visibility map information from a given
* segment file.
*/
void
AppendOnlyVisimapStore_DeleteSegmentFile(AppendOnlyVisimapStore *visiMapStore,
int segmentFileNum)
{
ScanKeyData scanKey;
SysScanDesc indexScan;
ItemPointerData tid;
Assert(visiMapStore);
Assert(RelationIsValid(visiMapStore->visimapRelation));
Assert(RelationIsValid(visiMapStore->visimapIndex));
elogif(Debug_appendonly_print_visimap, LOG,
"Append-only visi map store: Delete segment file: "
"(segFileNum) = (%u)", segmentFileNum);
ScanKeyInit(&scanKey,
Anum_pg_aovisimap_segno, /* segno */
BTEqualStrategyNumber,
F_INT4EQ,
Int32GetDatum(segmentFileNum));
indexScan = AppendOnlyVisimapStore_BeginScan(visiMapStore,
1,
&scanKey);
while (AppendOnlyVisimapStore_GetNext(visiMapStore,
indexScan,
ForwardScanDirection,
NULL,
&tid))
{
CatalogTupleDelete(visiMapStore->visimapRelation, &tid);
}
AppendOnlyVisimapStore_EndScan(visiMapStore, indexScan);
}
/*
* Returns the number of hidden tuples in a given segment file
*/
int64
AppendOnlyVisimapStore_GetSegmentFileHiddenTupleCount(AppendOnlyVisimapStore *visiMapStore,
AppendOnlyVisimapEntry *visiMapEntry,
int segmentFileNum)
{
ScanKeyData scanKey;
SysScanDesc indexScan;
int64 hiddenTupcount = 0;
Assert(visiMapStore);
Assert(visiMapEntry);
Assert(RelationIsValid(visiMapStore->visimapRelation));
Assert(RelationIsValid(visiMapStore->visimapIndex));
ScanKeyInit(&scanKey,
Anum_pg_aovisimap_segno, /* segno */
BTEqualStrategyNumber,
F_INT4EQ,
Int32GetDatum(segmentFileNum));
indexScan = AppendOnlyVisimapStore_BeginScan(visiMapStore,
1,
&scanKey);
while (AppendOnlyVisimapStore_GetNext(visiMapStore,
indexScan, ForwardScanDirection,
visiMapEntry, NULL))
{
hiddenTupcount += AppendOnlyVisimapEntry_GetHiddenTupleCount(visiMapEntry);
}
AppendOnlyVisimapStore_EndScan(visiMapStore, indexScan);
return hiddenTupcount;
}
/*
* Returns the number of hidden tuples in a given relation
*/
int64
AppendOnlyVisimapStore_GetRelationHiddenTupleCount(AppendOnlyVisimapStore *visiMapStore,
AppendOnlyVisimapEntry *visiMapEntry)
{
SysScanDesc indexScan;
int64 hiddenTupcount = 0;
Assert(visiMapStore);
Assert(visiMapEntry);
Assert(RelationIsValid(visiMapStore->visimapRelation));
Assert(RelationIsValid(visiMapStore->visimapIndex));
indexScan = AppendOnlyVisimapStore_BeginScan(visiMapStore,
0,
NULL);
while (AppendOnlyVisimapStore_GetNext(visiMapStore,
indexScan, ForwardScanDirection,
visiMapEntry, NULL))
{
hiddenTupcount += AppendOnlyVisimapEntry_GetHiddenTupleCount(visiMapEntry);
}
AppendOnlyVisimapStore_EndScan(visiMapStore, indexScan);
return hiddenTupcount;
}
/*
* Starts a scan over the visimap store.
*
* Parameter keys may be NULL iff nkeys is zero.
*/
SysScanDesc
AppendOnlyVisimapStore_BeginScan(AppendOnlyVisimapStore *visiMapStore,
int nkeys,
ScanKey keys)
{
Assert(visiMapStore);
Assert(RelationIsValid(visiMapStore->visimapRelation));
return systable_beginscan_ordered(visiMapStore->visimapRelation,
visiMapStore->visimapIndex,
visiMapStore->snapshot,
nkeys,
keys);
}
/*
* Ends a index scan over the visimap store.
*/
void
AppendOnlyVisimapStore_EndScan(AppendOnlyVisimapStore *visiMapStore,
SysScanDesc indexScan)
{
Assert(visiMapStore);
Assert(indexScan);
systable_endscan_ordered(indexScan);
}
相关信息
相关文章
greenplumn aomd_filehandler 源码
greenplumn appendonly_blkdir_udf 源码
greenplumn appendonly_compaction 源码
greenplumn appendonly_visimap 源码
greenplumn appendonly_visimap_entry 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦