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

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 1997, Microsoft Corporation. All Rights Reserved.
  4. //
  5. /////////////////////////////////////////////////////////////////////////////
  6. //#include "stdafx.h"
  7. #include "pch.cxx"
  8. #include "BSDict.h"
  9. #ifdef _INSTRUMENT
  10. #include "clog.h"
  11. #endif
  12. #include "Hash.h"
  13. static CWordHash wordHash;
  14. BYTE CDoubleFileBSDict::lpBuffer[MAX_BUFFER_SIZE];
  15. BYTE *CDoubleFileBSDict::lpCurIndex;
  16. void CDoubleFileBSDict::LoadIndex(HANDLE hInput)
  17. {
  18. DWORD readBytes;
  19. // _ASSERT(hInput != NULL);
  20. // read index header
  21. LoadIndexHeader(hInput);
  22. // Alloc indexes
  23. hIndex = GlobalAlloc(GPTR, GetIndexSize() * GetNumOfBlocks());
  24. Assert( hIndex != NULL );
  25. lpIndex = (BYTE *)GlobalLock(hIndex);
  26. Assert( lpIndex != NULL);
  27. // read indexes
  28. ReadFile(hInput, lpIndex, GetIndexSize() * GetNumOfBlocks(), &readBytes, NULL);
  29. }
  30. void CDoubleFileBSDict::LoadIndexHeader(HANDLE hInput)
  31. {
  32. DWORD readBytes;
  33. ReadFile(hInput, m_pIndexHeader, sizeof(_IndexHeader), &readBytes, NULL);
  34. // _ASSERT(readBytes == sizeof(_IndexHeader));
  35. }
  36. int CDoubleFileBSDict::FindWord(HANDLE hDict, DWORD fpBlock, LPCTSTR lpStr)
  37. {
  38. int indexNum;
  39. BYTE pumsa = 0;
  40. DWORD readBytes;
  41. int numWords, wordNum;
  42. static int curBufferWordLen, curBufIndexNum;
  43. //#ifdef _INSTRUMENT
  44. //numOfComp =0;
  45. //#endif
  46. indexNum = FindIndex(lpStr, 0, GetNumOfBlocks()-1, &pumsa);
  47. if (pumsa) return pumsa;
  48. else {
  49. // Search Cache Block
  50. #ifdef _INSTRUMENT
  51. _Log.IncreaseTotalAccess(lpStr);
  52. #endif
  53. if (wordHash.Find(lpStr, &pumsa)==TRUE) {
  54. #ifdef _INSTRUMENT
  55. _Log.IncreaseHit();
  56. #endif
  57. if (pumsa) // if word found in cache
  58. return pumsa;
  59. else return 0;
  60. } else {
  61. // Check if aleady in buffer
  62. if ( (curBufferWordLen == GetWordLen()) && (curBufIndexNum == indexNum) )
  63. #ifdef _INSTRUMENT
  64. _Log.IncreaseHit();
  65. #else
  66. ;
  67. #endif
  68. else {
  69. // read a candidate block
  70. SetFilePointer(hDict, fpBlock + indexNum*GetBlockSize(), 0, FILE_BEGIN);
  71. ReadFile(hDict, lpBuffer, GetBlockSize(), &readBytes, 0);
  72. curBufferWordLen = GetWordLen(); curBufIndexNum = indexNum;
  73. #ifdef _INSTRUMENT
  74. _Log.IncreaseFail();
  75. #endif
  76. }
  77. }
  78. numWords = *(WORD*)(lpCurIndex+GetIndexSize() - sizeof(WORD));
  79. if ( (wordNum = FindBlock(lpStr, 0, numWords-1))!=-1) {
  80. pumsa = *(lpBuffer+numWords*GetWordByteLen() + wordNum);
  81. //
  82. wordHash.Add(lpStr, pumsa);
  83. //
  84. return pumsa;
  85. }
  86. else {
  87. wordHash.Add(lpStr, pumsa);
  88. return 0;
  89. }
  90. }
  91. return 0;
  92. }
  93. int CDoubleFileBSDict::FindIndex(LPCTSTR lpWord, int left, int right, BYTE *pumsa)
  94. {
  95. int middle, flag;
  96. while (left < right) {
  97. middle = (left+right)>>1;
  98. lpCurIndex = lpIndex + middle * GetIndexSize();
  99. switch ( (flag = Comp(LPCTSTR(lpCurIndex), lpWord)) ) {
  100. case -1 : left = middle + 1;
  101. break;
  102. case 0 : *pumsa = *(lpCurIndex + GetWordByteLen());
  103. return middle;
  104. case 1 : right = middle - 1;
  105. }
  106. }
  107. lpCurIndex = lpIndex + left * GetIndexSize();
  108. if ( (flag = Comp(LPCTSTR(lpCurIndex), lpWord)) == 0) {
  109. *pumsa = *(lpCurIndex + GetWordByteLen());
  110. return left;
  111. }
  112. if (left && flag==1) {
  113. lpCurIndex -= GetIndexSize();
  114. return left-1;
  115. } else
  116. return left;
  117. }
  118. int CDoubleFileBSDict::FindBlock(LPCTSTR lpWord, int left, int right)
  119. {
  120. int middle;
  121. while (left <= right) {
  122. middle = (left+right)>>1;
  123. switch ( Comp(LPCTSTR(lpBuffer+middle*GetWordByteLen()), lpWord) ) {
  124. case -1 : left = middle + 1;
  125. break;
  126. case 0 : return middle;
  127. case 1 : right = middle - 1;
  128. }
  129. }
  130. return -1;
  131. }