188 lines
4.5 KiB
C
188 lines
4.5 KiB
C
/*****************************************************************************
|
|
* *
|
|
* BTMAPWR.C *
|
|
* *
|
|
* Copyright (C) Microsoft Corporation 1989, 1990. *
|
|
* All Rights reserved. *
|
|
* *
|
|
******************************************************************************
|
|
* *
|
|
* Module Intent *
|
|
* *
|
|
* Routines to write btree map files. *
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include "help.h"
|
|
|
|
// #include "inc\btpriv.h"
|
|
|
|
/*----------------------------------------------------------------------------*
|
|
| Private functions |
|
|
*----------------------------------------------------------------------------*/
|
|
|
|
INLINE static void STDCALL DestroyHmapbt(HMAPBT hmapbt);
|
|
INLINE static HMAPBT STDCALL HmapbtCreateHbt(QBTHR qbthr);
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: HmapbtCreateHbt( hbt )
|
|
-
|
|
* Purpose: Create a HMAPBT index struct of a btree.
|
|
*
|
|
* ASSUMES
|
|
* args IN: hbt - the btree to map
|
|
*
|
|
* PROMISES
|
|
* returns: the map struct
|
|
* +++
|
|
*
|
|
* Method: Traverse leaf nodes of the btree. Store BK and running
|
|
* total count of previous keys in the map array.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
INLINE static HMAPBT STDCALL HmapbtCreateHbt(QBTHR qbthr)
|
|
{
|
|
BK bk;
|
|
QCB qcb;
|
|
int wLevel, cBk;
|
|
QMAPBT qb;
|
|
QMAPREC qbT;
|
|
int cKeys;
|
|
|
|
ASSERT(qbthr);
|
|
|
|
// If the btree exists but is empty, return an empty map
|
|
|
|
if ((wLevel = qbthr->bth.cLevels) == 0) {
|
|
qb = (QMAPBT) lcCalloc(LcbFromBk(0));
|
|
qb->cTotalBk = 0;
|
|
return (HMAPBT) qb;
|
|
}
|
|
--wLevel;
|
|
|
|
if (qbthr->pCache == NULL && RcMakeCache(qbthr) != rcSuccess)
|
|
return NULL;
|
|
|
|
qb = (QMAPBT) lcCalloc(LcbFromBk(qbthr->bth.bkEOF));
|
|
if (!qb)
|
|
goto error_return;
|
|
|
|
qbT = qb->table;
|
|
cBk = 0;
|
|
cKeys = 0;
|
|
|
|
#ifdef _X86_
|
|
for (bk = qbthr->bth.bkFirst;; bk = BkNext(qcb)) {
|
|
#else
|
|
for (bk = qbthr->bth.bkFirst;; bk = BkNext(qbthr, qcb)) {
|
|
#endif
|
|
if (bk == bkNil)
|
|
break;
|
|
|
|
if ((qcb = QFromBk((DWORD) bk, wLevel, qbthr)) == NULL) {
|
|
lcFree(qb);
|
|
goto error_return;
|
|
}
|
|
|
|
cBk++;
|
|
qbT->cPreviousKeys = cKeys;
|
|
qbT->bk = bk;
|
|
qbT++;
|
|
cKeys += qcb->db.cKeys;
|
|
}
|
|
|
|
qb->cTotalBk = cBk;
|
|
|
|
return (HMAPBT) lcReAlloc(qb, LcbFromBk(cBk));
|
|
|
|
error_return:
|
|
|
|
rcBtreeError = rcFailure;
|
|
return NULL;
|
|
}
|
|
|
|
INLINE static void STDCALL DestroyHmapbt(HMAPBT hmapbt)
|
|
{
|
|
if (hmapbt != NULL)
|
|
FreeGh(hmapbt);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*
|
|
| Public functions |
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: RcCreateBTMapHfs( hfs, hbt, szName )
|
|
-
|
|
* Purpose: Create and store a btmap index of the btree hbt, putting
|
|
* it into a file called szName in the file system hfs.
|
|
*
|
|
* ASSUMES
|
|
* args IN: hfs - file system where lies the btree
|
|
* hbt - handle of btree to map
|
|
* szName - name of file to store map file in
|
|
*
|
|
* PROMISES
|
|
* returns: rc
|
|
* args OUT: hfs - map file is stored in this file system
|
|
*
|
|
\***************************************************************************/
|
|
|
|
RC STDCALL RcCreateBTMapHfs(HFS hfs, HBT hbt, LPCSTR szName)
|
|
{
|
|
HF hf;
|
|
HMAPBT hmapbt;
|
|
QMAPBT qmapbt;
|
|
BOOL fSuccess;
|
|
LONG lcb;
|
|
|
|
if ((hfs == NULL) || (hbt == NULL))
|
|
return rcBtreeError = rcBadHandle;
|
|
if ((hmapbt = HmapbtCreateHbt(PtrFromGh(hbt))) == NULL)
|
|
return rcBtreeError = rcFailure;
|
|
|
|
hf = HfCreateFileHfs(hfs, szName, fFSOpenReadWrite);
|
|
if (hf == NULL)
|
|
goto error_return;
|
|
qmapbt = (QMAPBT) PtrFromGh(hmapbt);
|
|
|
|
#ifndef _X86_
|
|
{
|
|
QMAPBT qtmapbt;
|
|
lcb = LcbFromBkDisk(qmapbt->cTotalBk);
|
|
qtmapbt = LhAlloc(LMEM_FIXED,lcb);
|
|
if (qtmapbt == NULL)
|
|
goto error_return;
|
|
/* SDFF translation from mem format to disk format: */
|
|
LcbReverseMapSDFF( ISdffFileIdHf( hf ), SE_MAPBT, qtmapbt, qmapbt );
|
|
LSeekHf(hf, 0L, wFSSeekSet);
|
|
fSuccess = (LcbWriteHf(hf, (QV) qtmapbt, lcb) == lcb);
|
|
FreeLh(qtmapbt);
|
|
}
|
|
#else
|
|
lcb = LcbFromBk(qmapbt->cTotalBk);
|
|
|
|
LSeekHf(hf, 0L, wFSSeekSet);
|
|
fSuccess = (LcbWriteHf(hf, (QV) qmapbt, lcb) == lcb);
|
|
#endif
|
|
|
|
if (!fSuccess) {
|
|
RcAbandonHf(hf);
|
|
goto error_return;
|
|
}
|
|
if (RcCloseHf(hf) != rcSuccess) {
|
|
RcUnlinkFileHfs(hfs, szName);
|
|
goto error_return;
|
|
}
|
|
DestroyHmapbt(hmapbt);
|
|
return rcBtreeError = rcSuccess;
|
|
|
|
error_return:
|
|
DestroyHmapbt(hmapbt);
|
|
return rcBtreeError = rcFailure;
|
|
}
|