|
|
/******************************************************************************
* * * BTKTSZIS.C * * * * Copyright (C) Microsoft Corporation 1989 - 1994. * * All Rights reserved. * * * ****************************************************************************** * * * Module Intent * * * * Functions for SZISCAND (0-terminated case insensitive Scandinavian * * string keys. * * * ****************************************************************************** * * * Current Owner: BinhN * * * ******************************************************************************/
static char s_aszModule[] = __FILE__; /* For error report */
#include <mvopsys.h>
#include <misc.h>
#include <iterror.h>
#include <orkin.h>
#include <wrapstor.h>
#include <_mvutil.h>
/***************************************************************************
* * @doc INTERNAL * * @func BK FAR PASCAL | BkScanSziScandInternal | * Scan an internal node for a key and return child BK. * * @parm BK | bk | * BK of internal node to scan * * @parm KEY | key | * key to search for * * @parm SHORT | wLevel | * level of btree bk lives on * * @parm QBTHR | qbthr | * btree header containing cache, and btree specs * qbthr->qCache bk's block will be cached * * @parm QW | qiKey | * address of an int or NULL to not get it * * @rdesc bk of subtree that might contain key; bkNil on error * qiKey - index into rgbBlock of first key >= key * Side Effects: bk's block will be cached * ***************************************************************************/
PUBLIC BK FAR PASCAL BkScanSziScandInternal(BK bk, KEY key, SHORT wLevel, QBTHR qbthr, QW qiKey, PHRESULT phr) { QCB qcb; QB q; SHORT cKeys;
if ((qcb = QFromBk(bk, wLevel, qbthr, phr)) == NULL) { return bkNil; } q = qcb->db.rgbBlock; cKeys = qcb->db.cKeys; bk = (BK)GETLONG(q); q += sizeof(BK);
while (cKeys-- > 0) { if (WCmpiScandSz((SZ)key, (SZ)q) >= 0) { q += STRLEN((SZ)q) + 1; bk = (BK)GETLONG(q); q += sizeof(BK); } else break; }
if (qiKey != NULL) { *qiKey = (WORD)(q - (QB)qcb->db.rgbBlock); }
return bk; }
/***************************************************************************
* * @doc INTERNAL * * @func HRESULT FAR PASCAL | RcScanSziScandLeaf | * Scan a leaf node for a key and copy the associated data. * * @parm BK | bk | * the leaf block * * @parm KEY | key | * the key we're looking for * * @parm SHORT | wLevel | * the level of leaves (unnecessary) * * @parm QBTHR | qbthr | * the btree header * * @parm QV | qRec | * if found, record gets copied into this buffer * * @parm QTPOS | qbtpos | * pos of first key >= key goes here * * @rdesc ERR_SUCCESS if found; ERR_NOTEXIST if not found * NOTE: If we are scanning for a key greater than any key in this * block, the pos returned will be invalid and will point just * past the last valid key in this block. * * ***************************************************************************/ PUBLIC HRESULT FAR PASCAL RcScanSziScandLeaf(BK bk, KEY key, SHORT wLevel, QBTHR qbthr, QV qRec, QBTPOS qbtpos) { QCB qcb; SZ sz; SHORT w, cKey; QB qb; HRESULT rc; HRESULT errb;
if ((qcb = QFromBk(bk, wLevel, qbthr, &errb)) == NULL) { return errb; } rc = E_NOTEXIST;
sz = qcb->db.rgbBlock + 2 * sizeof(BK);
for (cKey = 0; cKey < qcb->db.cKeys; cKey++) { w = WCmpiScandSz((SZ)key, sz);
if (w > 0) /* still looking for key */ { sz += STRLEN(sz) + 1; sz += CbSizeRec(sz, qbthr); } else if (w < 0) /* key not found */ { break; } else /* matched the key */ { if (qRec != NULL) { qb = (QB)sz + STRLEN(sz) + 1; QVCOPY(qRec, qb, (LONG)CbSizeRec(qb, qbthr)); }
rc = S_OK; break; } }
if (qbtpos != NULL) { qbtpos->bk = bk; qbtpos->cKey = cKey; qbtpos->iKey = (int)((QB)sz - (QB)qcb->db.rgbBlock); }
return rc; }
/* EOF */
|