NT4/private/windows/win4help/winhelp/btmapwr.c
2020-09-30 17:12:29 +02:00

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;
}