Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

150 lines
4.1 KiB

/////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 1997, Microsoft Corporation. All Rights Reserved.
//
/////////////////////////////////////////////////////////////////////////////
//#include "stdafx.h"
#include "pch.cxx"
#include "BSDict.h"
#ifdef _INSTRUMENT
#include "clog.h"
#endif
#include "Hash.h"
static CWordHash wordHash;
BYTE CDoubleFileBSDict::lpBuffer[MAX_BUFFER_SIZE];
BYTE *CDoubleFileBSDict::lpCurIndex;
void CDoubleFileBSDict::LoadIndex(HANDLE hInput)
{
DWORD readBytes;
// _ASSERT(hInput != NULL);
// read index header
LoadIndexHeader(hInput);
// Alloc indexes
hIndex = GlobalAlloc(GPTR, GetIndexSize() * GetNumOfBlocks());
Assert( hIndex != NULL );
lpIndex = (BYTE *)GlobalLock(hIndex);
Assert( lpIndex != NULL);
// read indexes
ReadFile(hInput, lpIndex, GetIndexSize() * GetNumOfBlocks(), &readBytes, NULL);
}
void CDoubleFileBSDict::LoadIndexHeader(HANDLE hInput)
{
DWORD readBytes;
ReadFile(hInput, m_pIndexHeader, sizeof(_IndexHeader), &readBytes, NULL);
// _ASSERT(readBytes == sizeof(_IndexHeader));
}
int CDoubleFileBSDict::FindWord(HANDLE hDict, DWORD fpBlock, LPCTSTR lpStr)
{
int indexNum;
BYTE pumsa = 0;
DWORD readBytes;
int numWords, wordNum;
static int curBufferWordLen, curBufIndexNum;
//#ifdef _INSTRUMENT
//numOfComp =0;
//#endif
indexNum = FindIndex(lpStr, 0, GetNumOfBlocks()-1, &pumsa);
if (pumsa) return pumsa;
else {
// Search Cache Block
#ifdef _INSTRUMENT
_Log.IncreaseTotalAccess(lpStr);
#endif
if (wordHash.Find(lpStr, &pumsa)==TRUE) {
#ifdef _INSTRUMENT
_Log.IncreaseHit();
#endif
if (pumsa) // if word found in cache
return pumsa;
else return 0;
} else {
// Check if aleady in buffer
if ( (curBufferWordLen == GetWordLen()) && (curBufIndexNum == indexNum) )
#ifdef _INSTRUMENT
_Log.IncreaseHit();
#else
;
#endif
else {
// read a candidate block
SetFilePointer(hDict, fpBlock + indexNum*GetBlockSize(), 0, FILE_BEGIN);
ReadFile(hDict, lpBuffer, GetBlockSize(), &readBytes, 0);
curBufferWordLen = GetWordLen(); curBufIndexNum = indexNum;
#ifdef _INSTRUMENT
_Log.IncreaseFail();
#endif
}
}
numWords = *(WORD*)(lpCurIndex+GetIndexSize() - sizeof(WORD));
if ( (wordNum = FindBlock(lpStr, 0, numWords-1))!=-1) {
pumsa = *(lpBuffer+numWords*GetWordByteLen() + wordNum);
//
wordHash.Add(lpStr, pumsa);
//
return pumsa;
}
else {
wordHash.Add(lpStr, pumsa);
return 0;
}
}
return 0;
}
int CDoubleFileBSDict::FindIndex(LPCTSTR lpWord, int left, int right, BYTE *pumsa)
{
int middle, flag;
while (left < right) {
middle = (left+right)>>1;
lpCurIndex = lpIndex + middle * GetIndexSize();
switch ( (flag = Comp(LPCTSTR(lpCurIndex), lpWord)) ) {
case -1 : left = middle + 1;
break;
case 0 : *pumsa = *(lpCurIndex + GetWordByteLen());
return middle;
case 1 : right = middle - 1;
}
}
lpCurIndex = lpIndex + left * GetIndexSize();
if ( (flag = Comp(LPCTSTR(lpCurIndex), lpWord)) == 0) {
*pumsa = *(lpCurIndex + GetWordByteLen());
return left;
}
if (left && flag==1) {
lpCurIndex -= GetIndexSize();
return left-1;
} else
return left;
}
int CDoubleFileBSDict::FindBlock(LPCTSTR lpWord, int left, int right)
{
int middle;
while (left <= right) {
middle = (left+right)>>1;
switch ( Comp(LPCTSTR(lpBuffer+middle*GetWordByteLen()), lpWord) ) {
case -1 : left = middle + 1;
break;
case 0 : return middle;
case 1 : right = middle - 1;
}
}
return -1;
}