📄 nbtree.c
字号:
itup->t_tid = *ht_ctid; /* * See comments in btbuild. * * if (itup->t_info & INDEX_NULL_MASK) return (InsertIndexResult) NULL; */ btitem = _bt_formitem(itup); res = _bt_doinsert(rel, btitem, IndexIsUnique(RelationGetRelid(rel)), heapRel); pfree(btitem); pfree(itup); return res;}/* * btgettuple() -- Get the next tuple in the scan. */char *btgettuple(IndexScanDesc scan, ScanDirection dir){ RetrieveIndexResult res; /* * If we've already initialized this scan, we can just advance it in * the appropriate direction. If we haven't done so yet, we call a * routine to get the first item in the scan. */ if (ItemPointerIsValid(&(scan->currentItemData))) { /* * Restore scan position using heap TID returned by previous call * to btgettuple(). _bt_restscan() locks buffer. */ _bt_restscan(scan); res = _bt_next(scan, dir); } else res = _bt_first(scan, dir); /* * Save heap TID to use it in _bt_restscan. Unlock buffer before * leaving index ! */ if (res) { ((BTScanOpaque) scan->opaque)->curHeapIptr = res->heap_iptr; LockBuffer(((BTScanOpaque) scan->opaque)->btso_curbuf, BUFFER_LOCK_UNLOCK); } return (char *) res;}/* * btbeginscan() -- start a scan on a btree index */char *btbeginscan(Relation rel, bool fromEnd, uint16 keysz, ScanKey scankey){ IndexScanDesc scan; /* get the scan */ scan = RelationGetIndexScan(rel, fromEnd, keysz, scankey); /* register scan in case we change pages it's using */ _bt_regscan(scan); return (char *) scan;}/* * btrescan() -- rescan an index relation */voidbtrescan(IndexScanDesc scan, bool fromEnd, ScanKey scankey){ ItemPointer iptr; BTScanOpaque so; so = (BTScanOpaque) scan->opaque; /* we don't hold a read lock on the current page in the scan */ if (ItemPointerIsValid(iptr = &(scan->currentItemData))) { ReleaseBuffer(so->btso_curbuf); so->btso_curbuf = InvalidBuffer; ItemPointerSetInvalid(iptr); } /* and we don't hold a read lock on the last marked item in the scan */ if (ItemPointerIsValid(iptr = &(scan->currentMarkData))) { ReleaseBuffer(so->btso_mrkbuf); so->btso_mrkbuf = InvalidBuffer; ItemPointerSetInvalid(iptr); } if (so == NULL) /* if called from btbeginscan */ { so = (BTScanOpaque) palloc(sizeof(BTScanOpaqueData)); so->btso_curbuf = so->btso_mrkbuf = InvalidBuffer; so->keyData = (ScanKey) NULL; if (scan->numberOfKeys > 0) so->keyData = (ScanKey) palloc(scan->numberOfKeys * sizeof(ScanKeyData)); scan->opaque = so; scan->flags = 0x0; } /* * Reset the scan keys. Note that keys ordering stuff moved to * _bt_first. - vadim 05/05/97 */ so->numberOfKeys = scan->numberOfKeys; if (scan->numberOfKeys > 0) { memmove(scan->keyData, scankey, scan->numberOfKeys * sizeof(ScanKeyData)); memmove(so->keyData, scankey, so->numberOfKeys * sizeof(ScanKeyData)); }}voidbtmovescan(IndexScanDesc scan, Datum v){ ItemPointer iptr; BTScanOpaque so; so = (BTScanOpaque) scan->opaque; /* we don't hold a read lock on the current page in the scan */ if (ItemPointerIsValid(iptr = &(scan->currentItemData))) { ReleaseBuffer(so->btso_curbuf); so->btso_curbuf = InvalidBuffer; ItemPointerSetInvalid(iptr); }/* scan->keyData[0].sk_argument = v; */ so->keyData[0].sk_argument = v;}/* * btendscan() -- close down a scan */voidbtendscan(IndexScanDesc scan){ ItemPointer iptr; BTScanOpaque so; so = (BTScanOpaque) scan->opaque; /* we don't hold any read locks */ if (ItemPointerIsValid(iptr = &(scan->currentItemData))) { if (BufferIsValid(so->btso_curbuf)) ReleaseBuffer(so->btso_curbuf); so->btso_curbuf = InvalidBuffer; ItemPointerSetInvalid(iptr); } if (ItemPointerIsValid(iptr = &(scan->currentMarkData))) { if (BufferIsValid(so->btso_mrkbuf)) ReleaseBuffer(so->btso_mrkbuf); so->btso_mrkbuf = InvalidBuffer; ItemPointerSetInvalid(iptr); } if (so->keyData != (ScanKey) NULL) pfree(so->keyData); pfree(so); _bt_dropscan(scan);}/* * btmarkpos() -- save current scan position */voidbtmarkpos(IndexScanDesc scan){ ItemPointer iptr; BTScanOpaque so; so = (BTScanOpaque) scan->opaque; /* we don't hold any read locks */ if (ItemPointerIsValid(iptr = &(scan->currentMarkData))) { ReleaseBuffer(so->btso_mrkbuf); so->btso_mrkbuf = InvalidBuffer; ItemPointerSetInvalid(iptr); } /* bump pin on current buffer */ if (ItemPointerIsValid(&(scan->currentItemData))) { so->btso_mrkbuf = ReadBuffer(scan->relation, BufferGetBlockNumber(so->btso_curbuf)); scan->currentMarkData = scan->currentItemData; so->mrkHeapIptr = so->curHeapIptr; }}/* * btrestrpos() -- restore scan to last saved position */voidbtrestrpos(IndexScanDesc scan){ ItemPointer iptr; BTScanOpaque so; so = (BTScanOpaque) scan->opaque; /* we don't hold any read locks */ if (ItemPointerIsValid(iptr = &(scan->currentItemData))) { ReleaseBuffer(so->btso_curbuf); so->btso_curbuf = InvalidBuffer; ItemPointerSetInvalid(iptr); } /* bump pin on marked buffer */ if (ItemPointerIsValid(&(scan->currentMarkData))) { so->btso_curbuf = ReadBuffer(scan->relation, BufferGetBlockNumber(so->btso_mrkbuf)); scan->currentItemData = scan->currentMarkData; so->curHeapIptr = so->mrkHeapIptr; }}/* stubs */voidbtdelete(Relation rel, ItemPointer tid){ /* adjust any active scans that will be affected by this deletion */ _bt_adjscans(rel, tid); /* delete the data from the page */ _bt_pagedel(rel, tid);}static void_bt_restscan(IndexScanDesc scan){ Relation rel = scan->relation; BTScanOpaque so = (BTScanOpaque) scan->opaque; Buffer buf = so->btso_curbuf; Page page; ItemPointer current = &(scan->currentItemData); OffsetNumber offnum = ItemPointerGetOffsetNumber(current), maxoff; BTPageOpaque opaque; ItemPointerData target = so->curHeapIptr; BTItem item; BlockNumber blkno; LockBuffer(buf, BT_READ); /* lock buffer first! */ page = BufferGetPage(buf); maxoff = PageGetMaxOffsetNumber(page); opaque = (BTPageOpaque) PageGetSpecialPointer(page); /* * We use this as flag when first index tuple on page is deleted but * we do not move left (this would slowdown vacuum) - so we set * current->ip_posid before first index tuple on the current page * (_bt_step will move it right)... */ if (!ItemPointerIsValid(&target)) { ItemPointerSetOffsetNumber(&(scan->currentItemData), OffsetNumberPrev(P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY)); return; } if (maxoff >= offnum) { /* * if the item is where we left it or has just moved right on this * page, we're done */ for (; offnum <= maxoff; offnum = OffsetNumberNext(offnum)) { item = (BTItem) PageGetItem(page, PageGetItemId(page, offnum)); if (item->bti_itup.t_tid.ip_blkid.bi_hi == \ target.ip_blkid.bi_hi && \ item->bti_itup.t_tid.ip_blkid.bi_lo == \ target.ip_blkid.bi_lo && \ item->bti_itup.t_tid.ip_posid == target.ip_posid) { current->ip_posid = offnum; return; } } } /* * By here, the item we're looking for moved right at least one page */ for (;;) { if (P_RIGHTMOST(opaque)) elog(FATAL, "_bt_restscan: my bits moved right off the end of the world!"); blkno = opaque->btpo_next; _bt_relbuf(rel, buf, BT_READ); buf = _bt_getbuf(rel, blkno, BT_READ); page = BufferGetPage(buf); maxoff = PageGetMaxOffsetNumber(page); opaque = (BTPageOpaque) PageGetSpecialPointer(page); /* see if it's on this page */ for (offnum = P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY; offnum <= maxoff; offnum = OffsetNumberNext(offnum)) { item = (BTItem) PageGetItem(page, PageGetItemId(page, offnum)); if (item->bti_itup.t_tid.ip_blkid.bi_hi == \ target.ip_blkid.bi_hi && \ item->bti_itup.t_tid.ip_blkid.bi_lo == \ target.ip_blkid.bi_lo && \ item->bti_itup.t_tid.ip_posid == target.ip_posid) { ItemPointerSet(current, blkno, offnum); so->btso_curbuf = buf; return; } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -