151 lines
4.1 KiB
C++
151 lines
4.1 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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;
|
|
}
|