提炼出的GiST调用流程方面的代码
2.粉红色与蓝色线部分,为了实现特定的功能而扩展GiST的时候需要格外关注
ExecutePlan
{
/*Loop until we've processed the
proper number of tuples from the plan*/
for(;;){
planSlot = ExecProcNode(planstate);
if(TupIsNull(planSlot)) return result =
NULL;
slot = planSlot;
ExecSelect(slot, dest,
estate);------>返回结果给dest,或伴随着Projection操作
current_tuple_count++;
if(numberTuples && numberTuples ==
current_tuple_count)
break;
}
}
ExecprocNode(PlanState *node) return
TupleTableSlot*
{ return
ExecIndexScan((IndexScanState*)node); }
ExecIndexScan(IndexScanState *node) return
TupleTableSlot *
{ return
ExecScan(&node->ss,(ExecScanAccessMtd)IndexNext); }
ExecScan(ScanState *node, ExecScanAccessMtd*
accessMtd) return TupleTableSlot*
{
for(;;)
{
TupleTableSlot * slot;
slot = (*accessMtd)(node);------>equal to slot
= IndexNext(node);
if(TupIsNull(slot))
return projInfo ?
ExecClearTuple(projInfo->pi_slot) : slot;
return projInfo ? resultSlot =
ExecProject(projInfo, &isDone) : slot;
}
}
IndexNext(IndexScanState *node) return
TupleTableSlot*
{
IndexScanDesc scandesc =
node->iss_ScanDesc;
HeapTuple tuple;
TupleTableSlot *slot =
node->ss.ss_ScanTupleSlot;
if((tuple = index_getnext(scandesc, direction) !=
NULL)
{
ExecStoreTuple(tuple, slot,
scandesc->xs_cbuf,false);
return slot;
}
}
index_getnext(IndexScanDesc scan, ScanDirection
direction) return HeapTuple
------>find return non-null or nomore tuple return null
{
HeapTuple heapTuple = &scan->xs_ctup;------------------------------------------------------
FmgrInfo *procedure;
procedure = gistgettuple;
for(;;)
{
gistgettuple(scan, direction);
if(heap_release_fetch(scan->heapRelation,
scan->xs_snapshot, heapTuple, &scan->xs_cbuf, true,
&scan->xs_pgstat_info))
break;
if(heapTuple->t_data == NULL)
continue;
}
//Success exit
return heapTuple;
//return &scan->xs_ctup;---------------------------------------------------------------------
}
gistgettuple(IndexScandesc scan, ...) return
bool ------>not gistgetmulti
{
ItemPointData
tid;---------------------------->局部变量,基本无用
return gistnext(scan,direction, &tid, 1, ...);
}
gistnext(IndexScanDesc scan,ScanDirection dir, ItemPoint tids, int maxtids,...) return int/bool
------>return true if and only if a
matching tuple was found
{
OffsetNumber n;
int ntids = 0;
for(;;)
{
make a stack for the page tree seeking
and
ether
find a gist page stored in p variant.
of
return ntids = 0 , when the stack is empey
for(;;)
{
n = gistfindnext(scan, n, dir);
if(!OffsetNumberIsValid(n)) break;
if(GistPageIsLeaf(p))
{
IndexTuple it = (IndexTuple)
PageGetItem(p,pageGetItemId(p,n));
tids[ntids++]
= scan->xs_ctup.t_self =
it->t_tid;------------------------------
------>tids在gistgettuple中没有使用,基本上依赖scan->xs_ctup,
并且是HeapTupleData中的一个字段,
我们可以充分利用其余字段的
if(ntids == maxtids) return ntids;
}//end of if
}//end of inner for
}//end of outer for
}//end of function
gistfindnext(IndexScanDesc scan, OffsetNumber n,
ScanDirection dir) return OffsetNumber
------>在当前页面中,在偏移量n之后,返回第一个满足条件的偏移量
{
IndexTuple it;
GISTScanOpaque so = (GISTScanOpaque)
scan->opaque;
Page p = BufferGetPage(so->curbuf);
while( n >= FirstOffsetNumber && n
<=maxoff)
{
it = (IndexTuple)PageGetItem(p, PageGetItem(p,
n));
if(gistindex_keytest(it,scan,n)) break;
n = forward ? OffsetNumberNext(n) :
OffsetNumberPre(n);
}//end of while
return (n >= FirstOffsetNumber &&
n<= maxoff) ? n: InvalidOffsetNumber;
}
gistindex_keytest(IndexTuple tuple, IndexScanDesc
scan, OffsetNumber offset) return bool
{
int keySize = scan->numberOfKeys;
ScanKey key = scan->keyData;
GISTScanOpaque so =
(GISTScanOpaque)scan->opaque;
GISTSTATE *giststate = so->giststate;
page p = BufferGetPage(so->curbuf);
Relation r = scan->indexRelation;
while( keySize >0)
{
Datum datum;
GISTENTRY
de;-------------------->里面存储有HeapTuple的页面信息
可以考虑暂时存储在IndexScanDesc中去,
毕竟scan在多个函数中“穿越”
datum = index_getattr(tuple,key->sk_attno,
giststate->tupdesc,...);
gistdentryinit(giststate, key->sk_attno - 1,
&de, datum, r, p, offset, ...);
Datum test = gistconsistent(&de,
key->sk_argument ,
key->sk_strategy,key->sk_subtype);
//Datum test = gistconsistent(&de,
scan->keyData->sk_argument,
key->sk_strategy,key->sk_subtype);
keySize--;
key++;
}//end of while
}
https://blog.sciencenet.cn/blog-643407-517652.html
上一篇:
计算机前辈Dijkstra被采访的视频中,摘录的部分字幕下一篇:
Postgres分析文档