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.

246 lines
6.7 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 2000.
  5. //
  6. // File: RWEX.HXX
  7. //
  8. // Contents: Relevant word extraction
  9. //
  10. // Classes: CRelevantWord, CRWStore, CRWHeap, CRWIter
  11. //
  12. // History: 25-Apr-94 v-dlee Created.
  13. //
  14. //----------------------------------------------------------------------------
  15. #pragma once
  16. #include <misc.hxx>
  17. const ULONG defRWCount = 6;
  18. struct SRWItem
  19. {
  20. KEYID kKeyId;
  21. LONG lRank;
  22. };
  23. struct SRWHeader
  24. {
  25. WORKID wid;
  26. ULONG cItems;
  27. #pragma warning(disable : 4200) // 0 sized array is non-ansi
  28. SRWItem aItems[0];
  29. #pragma warning(default : 4200)
  30. SRWHeader * Forward(ULONG cItems,ULONG cbRowWidth)
  31. { return (SRWHeader *) ((BYTE *) this + cItems * cbRowWidth); }
  32. SRWHeader * Backward(ULONG cItems,ULONG cbRowWidth)
  33. { return (SRWHeader *) ((BYTE *) this - cItems * cbRowWidth); }
  34. };
  35. //+---------------------------------------------------------------------------
  36. //
  37. // Class: CRWStore
  38. //
  39. // Purpose: A place to put relevant words during calculation
  40. //
  41. // History: 25-Apr-94 v-dlee Created.
  42. //
  43. // Notes: The array of wids/heaps was put at the end of the object
  44. // instead of in a member pointer to ease the fsctl transfer
  45. // of the object.
  46. //
  47. //----------------------------------------------------------------------------
  48. class CRWStore
  49. {
  50. public:
  51. CRWStore(WORKID *pwList,ULONG cWids,ULONG cIds);
  52. ~CRWStore() {}
  53. void * operator new(size_t st,ULONG cWids,ULONG cIds);
  54. #if _MSC_VER >= 1200
  55. void operator delete(void * p)
  56. {
  57. if (p != 0)
  58. {
  59. ::delete (p);
  60. }
  61. }
  62. void operator delete(void * p, ULONG cWids, ULONG cIds);
  63. #endif
  64. ULONG GetWidCount() { return _cWids; }
  65. ULONG GetIdCount() { return _cIds; }
  66. SRWHeader * GetRow(ULONG ul)
  67. { return (SRWHeader *) (_ArrayStart() + ul * _cbRow); }
  68. DWORD GetObjectSize() { return _ObjectSize(_cWids,_cIds); }
  69. static DWORD ComputeObjectSize(ULONG cWids,ULONG cIds)
  70. { return _ObjectSize(cWids,cIds); }
  71. BOOL isTrackedWid(WORKID wid)
  72. { return 0 != _Find(wid,(SRWHeader *) _ArrayStart(),_cWids); }
  73. void Insert(WORKID wid,KEYID keyid, LONG lRank);
  74. void DoneWithKey() { _ulSearchLeftOff = 0; }
  75. private:
  76. static DWORD _ObjectSize(ULONG cWids,ULONG cIds)
  77. { return sizeof(CRWStore) + cWids * _RowSize(cIds); }
  78. static DWORD _RowSize(ULONG cIds)
  79. { return sizeof(SRWHeader) + cIds * sizeof(SRWItem); }
  80. ULONG _HeaderToRow(SRWHeader *ph)
  81. { return (ULONG)((BYTE *) ph - _ArrayStart()) / _cbRow; }
  82. BYTE * _ArrayStart()
  83. { return (BYTE *) this + sizeof(CRWStore); }
  84. SRWHeader *_Find(WORKID wid,SRWHeader *pBase,ULONG cRows);
  85. ULONG _cbRow;
  86. ULONG _cWids;
  87. ULONG _cIds;
  88. ULONG _ulSearchLeftOff;
  89. };
  90. //+---------------------------------------------------------------------------
  91. //
  92. // Class: CRHeap
  93. //
  94. // Purpose: A list of relevant words is computed for each document.
  95. // The words are stored in a heap with the lowest-ranking word
  96. // on top.
  97. //
  98. // History: 25-Apr-94 v-dlee Created.
  99. //
  100. //----------------------------------------------------------------------------
  101. class CRWHeap
  102. {
  103. public:
  104. CRWHeap(SRWHeader *ph,ULONG ulMaxIds) :
  105. _ph(ph), _ulMaxIds(ulMaxIds) {}
  106. ~CRWHeap() {}
  107. void Insert(KEYID kKey, LONG lRank);
  108. KEYID DeQueue();
  109. private:
  110. BOOL _IsValid(ULONG elem)
  111. { return _ph->cItems && (elem < _ph->cItems); }
  112. BOOL _IsLeaf(ULONG elem) { return _Left(elem) >= _ph->cItems; }
  113. ULONG _Parent(ULONG elem)
  114. { return (elem & 0x1) ? (elem >> 1) : ((elem >> 1) - 1); }
  115. ULONG _Left(ULONG elem) { return _Right(elem) - 1; }
  116. ULONG _Right(ULONG elem) { return (elem + 1) << 1; }
  117. ULONG _ulMaxIds;
  118. SRWHeader *_ph;
  119. };
  120. //+---------------------------------------------------------------------------
  121. //
  122. // Class: CRIter
  123. //
  124. // Purpose: Iterates through the documents in a CRWStore and the keyids
  125. // for each document.
  126. //
  127. // Notes: The words are retrieved in opposite order of rank.
  128. // This iterator is destructive.
  129. //
  130. // History: 25-Apr-94 v-dlee Created.
  131. //
  132. //----------------------------------------------------------------------------
  133. class CRWIter
  134. {
  135. public:
  136. CRWIter(CRWStore &store) : _store(store), _ulCur(0) { Advance(); }
  137. ~CRWIter() {}
  138. BOOL AtEnd() { return _ulCur > _store.GetWidCount(); }
  139. void Advance() { _p = _store.GetRow(_ulCur++); }
  140. WORKID GetWid() { return _p->wid; }
  141. ULONG GetRWCount() { return _p->cItems; }
  142. KEYID GetRW()
  143. {
  144. if (_p->cItems != 0)
  145. {
  146. CRWHeap heap(_p,_store.GetIdCount());
  147. return heap.DeQueue();
  148. }
  149. else
  150. {
  151. return kidInvalid;
  152. }
  153. }
  154. private:
  155. CRWStore &_store;
  156. ULONG _ulCur;
  157. SRWHeader *_p;
  158. };
  159. //+---------------------------------------------------------------------------
  160. //
  161. // Class: CRelevantWord
  162. //
  163. // Purpose: Manages the calculation of relevant words
  164. //
  165. // History: 25-Apr-94 v-dlee Created.
  166. //
  167. //----------------------------------------------------------------------------
  168. class CRelevantWord : INHERIT_UNWIND
  169. {
  170. DECLARE_UNWIND
  171. public:
  172. CRelevantWord(WORKID *pwList,ULONG cWids,ULONG cIds);
  173. ~CRelevantWord();
  174. CRWStore * AcquireStore()
  175. {
  176. CRWStore *t = _pstore;
  177. _pstore = 0;
  178. return t;
  179. }
  180. void Add(WORKID wid,ULONG cOcc)
  181. {
  182. _pWidItem[_cWidsAdded].wid = wid;
  183. _pWidItem[_cWidsAdded].cOcc = cOcc;
  184. _cWidsAdded++;
  185. }
  186. void DoneWithKey(KEYID kidKey,ULONG maxWid,ULONG cWids);
  187. BOOL isTrackedWid(WORKID wid)
  188. { return _pstore->isTrackedWid(wid); }
  189. private:
  190. struct SRWWidItem
  191. {
  192. WORKID wid;
  193. ULONG cOcc;
  194. };
  195. void _SetWidInfo(ULONG maxWid,ULONG cWids)
  196. { _widFactor = Log2(maxWid / cWids); }
  197. ULONG _Rank(ULONG occ) { return occ * _widFactor; }
  198. CRWStore *_pstore;
  199. SRWWidItem *_pWidItem;
  200. ULONG _cWidsAdded;
  201. ULONG _widFactor;
  202. };
  203. extern void _SortULongArray(ULONG *pulItems,ULONG cItems);