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.

250 lines
6.4 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 1995.
  5. //
  6. // File: UNIONCUR.CXX
  7. //
  8. // Contents: Merge Cursor. Computes union of multiple cursors.
  9. //
  10. // Classes: CUnionCursor
  11. //
  12. // History: 26-Sep-91 BartoszM Created
  13. // 17-Jun-92 BartoszM Separated from OrCursor
  14. //
  15. //----------------------------------------------------------------------------
  16. #include <pch.cxx>
  17. #pragma hdrstop
  18. #include "unioncur.hxx"
  19. //+---------------------------------------------------------------------------
  20. //
  21. // Member: CUnionCursor::CUnionCursor, public
  22. //
  23. // Synopsis: Create a cursor that merges a number of cursors.
  24. //
  25. // Arguments: [cCursor] -- count of cursors
  26. // [curStack] -- stack of cursors to be merged
  27. //
  28. // History: 26-Sep-91 BartoszM Created
  29. //
  30. // Notes: The cursors and the array will be deleted by destructor.
  31. //
  32. //----------------------------------------------------------------------------
  33. CUnionCursor::CUnionCursor( int cCursor, CCurStack& curStack )
  34. {
  35. // Two step construction of the heap.
  36. // We have to make sure that all cursors have a valid key
  37. int count = 0;
  38. CCursor** aCursor = curStack.AcqStack();
  39. // remove empty cursors
  40. for ( int i = 0; i < cCursor; i++ )
  41. {
  42. ciAssert ( aCursor[i] != 0 );
  43. if ( aCursor[i]->WorkId() == widInvalid )
  44. {
  45. delete aCursor[i];
  46. }
  47. else if ( count != i )
  48. aCursor[count++] = aCursor[i];
  49. else
  50. count++;
  51. }
  52. _widHeap.MakeHeap ( count, aCursor );
  53. if ( !_widHeap.IsEmpty() )
  54. {
  55. _iid = _widHeap.Top()->IndexId();
  56. _pid = _widHeap.Top()->Pid();
  57. }
  58. }
  59. //+---------------------------------------------------------------------------
  60. //
  61. // Member: CUnionCursor::WorkId, public
  62. //
  63. // Synopsis: Get current work id.
  64. //
  65. // History: 26-Sep-91 BartoszM Created
  66. //
  67. //----------------------------------------------------------------------------
  68. WORKID CUnionCursor::WorkId()
  69. {
  70. if ( _widHeap.IsEmpty() )
  71. return widInvalid;
  72. return _widHeap.Top()->WorkId();
  73. }
  74. //+---------------------------------------------------------------------------
  75. //
  76. // Member: CUnionCursor::NextWorkId, public
  77. //
  78. // Synopsis: Move to next work id
  79. //
  80. // Returns: Target work id or widInvalid if no more wid's for current key
  81. //
  82. // Effects: Changes current IndexId.
  83. //
  84. // History: 26-Sep-91 BartoszM Created
  85. //
  86. // Notes: The same work id may be returned multiple times,
  87. // corresponding to multiple indexes. Fresh List
  88. // will filter out the ones that are stale.
  89. //
  90. //----------------------------------------------------------------------------
  91. WORKID CUnionCursor::NextWorkId()
  92. {
  93. if ( _widHeap.IsEmpty() )
  94. return widInvalid;
  95. _widHeap.Top()->NextWorkId();
  96. _widHeap.Reheap();
  97. WORKID wid = _widHeap.Top()->WorkId();
  98. if ( wid != widInvalid )
  99. {
  100. _pid = _widHeap.Top()->Pid();
  101. _iid = _widHeap.Top()->IndexId();
  102. }
  103. else
  104. _pid = pidInvalid;
  105. return wid;
  106. }
  107. //+---------------------------------------------------------------------------
  108. //
  109. // Member: CUnionCursor::RatioFinished, public
  110. //
  111. // Synopsis: return approximate ratio of documents processed to total
  112. // documents.
  113. //
  114. // Notes: The ratio, while approximate, should not return 1/1 until
  115. // all cursors are exhausted.
  116. //
  117. //----------------------------------------------------------------------------
  118. void CUnionCursor::RatioFinished (ULONG& denom, ULONG& num)
  119. {
  120. WORKID widTop = WorkId();
  121. if (widTop == widInvalid)
  122. {
  123. denom = num = 1;
  124. return;
  125. }
  126. CCursor **vector = _widHeap.GetVector();
  127. int count = _widHeap.Count();
  128. denom = 0;
  129. num = 0;
  130. unsigned cValid = 1;
  131. for (int i=0; i < count; i++)
  132. {
  133. ULONG d, n;
  134. vector[i]->RatioFinished(d, n);
  135. denom += d;
  136. num += n;
  137. Win4Assert( denom >= d && d > 0); // overflow?
  138. if (n == d)
  139. {
  140. WORKID widCurrent = vector[i]->WorkId();
  141. if (widCurrent != widInvalid && widCurrent != widTop)
  142. cValid++;
  143. }
  144. }
  145. if (num == denom && cValid > 1)
  146. denom++;
  147. }
  148. //+---------------------------------------------------------------------------
  149. //
  150. // Member: CUnionCursor::WorkIdCount, public
  151. //
  152. // Synopsis: Do nothing
  153. //
  154. // History: 26-Sep-91 BartoszM Created
  155. //
  156. //----------------------------------------------------------------------------
  157. ULONG CUnionCursor::WorkIdCount()
  158. {
  159. ciAssert (( FALSE && "UnionCursor::WorkIdCount called" ));
  160. return(0);
  161. }
  162. //+---------------------------------------------------------------------------
  163. //
  164. // Member: CUnionCursor::HitCount, public
  165. //
  166. // Synopsis: return occurrence count
  167. //
  168. // History: 28-Feb-92 AmyA Created
  169. //
  170. // Notes: returns the occurrence count for the wid on top of _widHeap.
  171. //
  172. //----------------------------------------------------------------------------
  173. ULONG CUnionCursor::HitCount()
  174. {
  175. ciAssert( !_widHeap.IsEmpty() );
  176. return _widHeap.Top()->HitCount();
  177. }
  178. //+---------------------------------------------------------------------------
  179. //
  180. // Member: CUnionCursor::Rank, public
  181. //
  182. // Synopsis: return occurrence count
  183. //
  184. // History: 28-Feb-92 AmyA Created
  185. //
  186. // Notes: returns the occurrence count for the wid on top of _widHeap.
  187. //
  188. //----------------------------------------------------------------------------
  189. LONG CUnionCursor::Rank()
  190. {
  191. ciAssert( !_widHeap.IsEmpty() );
  192. return _widHeap.Top()->Rank();
  193. }
  194. //+-------------------------------------------------------------------------
  195. //
  196. // Member: CUnionCursor::GetRankVector, public
  197. //
  198. // Effects: Returns the weights from a vector cursor. No effect
  199. // for non-vector cursors.
  200. //
  201. // Arguments: [pulVector] -- Pointer to array of ULONG into which the
  202. // vector elements are returned.
  203. //
  204. // Returns: The number of elements stored in [pulVector].
  205. //
  206. // History: 15-Jul-92 KyleP Created
  207. //
  208. //--------------------------------------------------------------------------
  209. ULONG CUnionCursor::GetRankVector( LONG * plVector, ULONG cElements )
  210. {
  211. ciAssert( !_widHeap.IsEmpty() );
  212. return( _widHeap.Top()->GetRankVector( plVector, cElements ) );
  213. }