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.

295 lines
7.2 KiB

  1. /*****************************************************************************
  2. * *
  3. * BTKTEXT.C *
  4. * *
  5. * Copyright (C) Microsoft Corporation 1997. *
  6. * All Rights reserved. *
  7. * *
  8. ******************************************************************************
  9. * *
  10. * Module Intent *
  11. * *
  12. * Functions for external sort keys. *
  13. * *
  14. ******************************************************************************
  15. * *
  16. * Current Owner: BillA *
  17. * *
  18. *****************************************************************************/
  19. static char s_aszModule[] = __FILE__; /* For error report */
  20. #include <mvopsys.h>
  21. #ifdef _MAC
  22. #include <winnls.h>
  23. #endif
  24. #include <orkin.h>
  25. #include <string.h>
  26. #include <misc.h>
  27. #include <iterror.h>
  28. #include <itsort.h>
  29. #include <wrapstor.h>
  30. #include <mvdbcs.h>
  31. #include <mvsearch.h>
  32. #include <_mvutil.h>
  33. #include "common.h"
  34. /***************************************************************************
  35. *
  36. * @doc INTERNAL
  37. *
  38. * @func BK FAR PASCAL | BkScanExtSortInternal |
  39. * Scan an internal node for an external sort key and return child BK.
  40. *
  41. * @parm BK | bk |
  42. * BK of internal node to scan
  43. *
  44. * @parm KEY | key |
  45. * key to search for
  46. *
  47. * @parm SHORT | wLevel |
  48. * level of btree bk lives on
  49. *
  50. * @parm QBTHR | qbthr |
  51. * btree header containing cache, and btree specs
  52. *
  53. * @parm QW | qiKey |
  54. * address of an int or NULL to not get it
  55. *
  56. * @rdesc bk of subtree that might contain key; bkNil on error
  57. * args OUT: qbthr->qCache - bk's block will be cached
  58. * qiKey - index into rgbBlock of first key >= key
  59. *
  60. * Side Effects: bk's block will be cached
  61. *
  62. ***************************************************************************/
  63. PUBLIC BK FAR PASCAL BkScanExtSortInternal(BK bk, KEY key, SHORT wLevel,
  64. QBTHR qbthr, QW qiKey, LPVOID lpv)
  65. {
  66. QCB qcb; // Pointer to cache block
  67. QB qb; // Pointer to block buffer
  68. SHORT cKeys; // Number of keys in the block
  69. if ((qcb = QFromBk(bk, wLevel, qbthr, (PHRESULT) lpv)) == NULL)
  70. {
  71. return bkNil;
  72. }
  73. qb = qcb->db.rgbBlock; // Block buffer
  74. cKeys = qcb->db.cKeys; // Number of keys in the block
  75. bk = (BK)GETLONG(qb); // Get leaf block number
  76. qb += sizeof(DWORD);
  77. while (cKeys-- > 0)
  78. {
  79. LONG lResult;
  80. // NOTE (billa): This won't work on the Mac unless a method is added
  81. // to IITSortKey to swap dwords and words if necessary. Mikkya
  82. // made an explicit decision to omit this from the initial
  83. // version of IITSortKey (6/4/97).
  84. if (qbthr->pITSortKey == NULL ||
  85. FAILED(qbthr->pITSortKey->Compare((LPCVOID) key, (LPCVOID) qb,
  86. &lResult, NULL)))
  87. {
  88. return bkNil;
  89. }
  90. if (lResult >= 0)
  91. {
  92. DWORD cbKey;
  93. if (qbthr->pITSortKey == NULL ||
  94. FAILED(qbthr->pITSortKey->GetSize((LPCVOID) qb, &cbKey)))
  95. {
  96. return bkNil;
  97. }
  98. qb += cbKey;
  99. bk = (BK)GETLONG(qb);
  100. qb += sizeof(DWORD);
  101. }
  102. else
  103. break;
  104. }
  105. if (qiKey != NULL)
  106. {
  107. *qiKey = (WORD)(qb - (QB)qcb->db.rgbBlock);
  108. }
  109. return bk;
  110. }
  111. /***************************************************************************
  112. *
  113. * @doc INTERNAL
  114. *
  115. * @func HRESULT FAR PASCAL | RcScanExtSortLeaf |
  116. * Scan a leaf node for an external sort key and copy the associated data.
  117. *
  118. * @parm BK | bk |
  119. * the leaf block
  120. *
  121. * @parm KEY | key |
  122. * the key we're looking for
  123. *
  124. * @parm SHORT | wLevel |
  125. * the level of leaves (unnecessary)
  126. *
  127. * @parm QBTHR | qbthr |
  128. * the btree header
  129. *
  130. * @parm QV | qRec |
  131. * if found, record gets copied into this buffer
  132. *
  133. * @parm QTPOS | qbtpos |
  134. * pos of first key >= key goes here
  135. *
  136. * @rdesc ERR_SUCESS if found; ERR_NOTEXIST if not found
  137. * If we are scanning for a key greater than any key in this
  138. * block, the pos returned will be invalid and will point just
  139. * past the last valid key in this block.
  140. *
  141. ***************************************************************************/
  142. PUBLIC HRESULT FAR PASCAL RcScanExtSortLeaf(BK bk, KEY key, SHORT wLevel,
  143. QBTHR qbthr, QV qRec, QBTPOS qbtpos)
  144. {
  145. QCB qcb;
  146. QB qb;
  147. HRESULT rc;
  148. SHORT i;
  149. SHORT cKeys; // Number of keys in the block
  150. QB qbSaved = NULL;
  151. DWORD cbLength, cbLengthSaved = 0;
  152. HRESULT errb;
  153. if ((qcb = QFromBk(bk, wLevel, qbthr, &errb)) == NULL)
  154. {
  155. return errb;
  156. }
  157. rc = E_NOTEXIST;
  158. qb = qcb->db.rgbBlock + 2 * sizeof(BK);
  159. cKeys = qcb->db.cKeys;
  160. for (i= 0; i < cKeys; i++)
  161. {
  162. LONG lResult;
  163. // NOTE (billa): This won't work on the Mac unless a method is added
  164. // to IITSortKey to swap dwords and words if necessary. Mikkya
  165. // made an explicit decision to omit this from the initial
  166. // version of IITSortKey (6/4/97).
  167. if (qbthr->pITSortKey == NULL ||
  168. FAILED(qbthr->pITSortKey->GetSize((LPCVOID) qb, &cbLength)) ||
  169. FAILED(qbthr->pITSortKey->Compare((LPCVOID) key, (LPCVOID) qb,
  170. &lResult, NULL)))
  171. {
  172. return rc;
  173. }
  174. if (lResult > 0) /* still looking for key */
  175. {
  176. qb += cbLength;
  177. qb += CbSizeRec(qb, qbthr);
  178. }
  179. else if (lResult < 0) /* key not found */
  180. {
  181. break;
  182. }
  183. else /* matched the key */
  184. {
  185. if (qRec != NULL)
  186. {
  187. qb += cbLength;
  188. QVCOPY(qRec, qb, (LONG)CbSizeRec(qb, qbthr));
  189. }
  190. rc = S_OK;
  191. break;
  192. }
  193. }
  194. if (qbtpos != NULL)
  195. {
  196. qbtpos->bk = bk;
  197. qbtpos->cKey = i;
  198. qbtpos->iKey = (int)(qb - (QB)qcb->db.rgbBlock);
  199. }
  200. return rc;
  201. }
  202. PUBLIC VOID EXPORT_API PASCAL FAR BtreeSetExtSort(HBT hbt,
  203. IITSortKey *pITSortKey)
  204. {
  205. if (hbt != NULL && pITSortKey != NULL)
  206. {
  207. QBTHR qbthr;
  208. qbthr = (QBTHR) _GLOBALLOCK(hbt);
  209. if (qbthr->pITSortKey != NULL)
  210. qbthr->pITSortKey->Release();
  211. (qbthr->pITSortKey = pITSortKey)->AddRef();
  212. _GLOBALUNLOCK(hbt);
  213. }
  214. else
  215. {
  216. ITASSERT(FALSE);
  217. }
  218. }
  219. PUBLIC VOID EXPORT_API PASCAL FAR BtreeGetExtSort(HBT hbt,
  220. IITSortKey **ppITSortKey)
  221. {
  222. if (ppITSortKey != NULL)
  223. {
  224. // Set to NULL in case we can't set it properly because the hbt is NULL.
  225. *ppITSortKey = NULL;
  226. if (hbt != NULL)
  227. {
  228. QBTHR qbthr;
  229. qbthr = (QBTHR) _GLOBALLOCK(hbt);
  230. if ((*ppITSortKey = qbthr->pITSortKey) != NULL)
  231. (*ppITSortKey)->AddRef();
  232. _GLOBALUNLOCK(hbt);
  233. }
  234. else
  235. {
  236. ITASSERT(FALSE);
  237. }
  238. }
  239. else
  240. {
  241. ITASSERT(FALSE);
  242. }
  243. }
  244. /* EOF */