pgwater的个人博客分享 http://blog.sciencenet.cn/u/pgwater

博文

Postgres中有关GiST索引的某些调用流程

已有 4470 次阅读 2011-12-12 14:32 |个人分类:postgres|系统分类:科研笔记| postgres, GiST

提炼出的GiST调用流程方面的代码
1.请查看pdf附件portal_run_printed.pdf
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
 
}



http://blog.sciencenet.cn/blog-643407-517652.html

上一篇:计算机前辈Dijkstra被采访的视频中,摘录的部分字幕
下一篇:Postgres分析文档

2 刘洋 王保魁

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2021-4-18 11:54

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部