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.

190 lines
5.1 KiB

  1. /*****************************************************************************
  2. * *
  3. * BTKTLONG.C *
  4. * *
  5. * Copyright (C) Microsoft Corporation 1989 - 1994. *
  6. * All Rights reserved. *
  7. * *
  8. ******************************************************************************
  9. * *
  10. * Module Intent *
  11. * *
  12. * Functions for LONG keys. *
  13. * *
  14. ******************************************************************************
  15. * *
  16. * Current Owner: BinhN *
  17. * *
  18. *****************************************************************************/
  19. static char s_aszModule[] = __FILE__; /* For error report */
  20. #include <mvopsys.h>
  21. #include <orkin.h>
  22. #include <iterror.h>
  23. #include <misc.h>
  24. #include <wrapstor.h>
  25. #include <_mvutil.h>
  26. /***************************************************************************
  27. *
  28. * @doc INTERNAL
  29. *
  30. * @func BK FAR PASCAL | BkScanLInternal |
  31. * Scan an internal node for a LONG key and return child BK.
  32. *
  33. * @parm BK | bk |
  34. * BK of internal node to scan
  35. *
  36. * @parm KEY | key |
  37. * key to search for
  38. *
  39. * @parm SHORT | wLevel |
  40. * level of btree bk lives on
  41. *
  42. * @parm QBTHR | qbthr |
  43. * btree header containing cache, and btree specs
  44. *
  45. * @rdesc bk of subtree that might contain key; bkNil on error
  46. * args OUT: qbthr->qCache - bk's block will be cached
  47. *
  48. * Side Effects: bk's block will be cached
  49. *
  50. * @comm Method: Should use binary search. Doesn't, yet.
  51. *
  52. ***************************************************************************/
  53. PUBLIC BK FAR PASCAL BkScanLInternal(BK bk, KEY key, SHORT wLevel,
  54. QBTHR qbthr, QW qiKey, PHRESULT phr)
  55. {
  56. QCB qcb;
  57. QB q;
  58. SHORT cKeys;
  59. LONG dwKeyVal;
  60. dwKeyVal = *(LONG FAR *)key;
  61. if ((qcb = QFromBk(bk, wLevel, qbthr, phr)) == NULL)
  62. {
  63. return bkNil;
  64. }
  65. q = qcb->db.rgbBlock;
  66. cKeys = qcb->db.cKeys;
  67. bk = SWAPLONG(*(LPUL)q);
  68. q += sizeof(BK);
  69. while (cKeys-- > 0)
  70. {
  71. if (dwKeyVal >= (LONG) SWAPLONG(*(LPUL)q))
  72. {
  73. q += sizeof(LONG);
  74. bk = SWAPLONG(*(LPUL)q);
  75. q += sizeof(BK);
  76. }
  77. else
  78. break;
  79. }
  80. if (qiKey != NULL)
  81. {
  82. *qiKey = (WORD)(q - (QB)qcb->db.rgbBlock);
  83. }
  84. return bk;
  85. }
  86. /***************************************************************************
  87. *
  88. * @doc INTERNAL
  89. *
  90. * @func HRESULT FAR PASCAL | RcScanLLeaf |
  91. * Scan a leaf node for a key and copy the associated data.
  92. *
  93. * @parm BK | bk |
  94. * the leaf block
  95. *
  96. * @parm KEY | key |
  97. * the key we're looking for
  98. *
  99. * @parm SHORT | wLevel |
  100. * the level of leaves (unnecessary)
  101. *
  102. * @parm QBTHR | qbthr |
  103. * the btree header
  104. *
  105. * @rdesc ERR_SUCCESS if found; ERR_NOTEXIST if not found
  106. * args OUT: qRec - if found, record gets copied into this buffer
  107. * qbtpos - pos of first key >= key goes here
  108. *
  109. * @comm If we are scanning for a key greater than any key in this
  110. * block, the pos returned will be invalid and will point just
  111. * past the last valid key in this block.
  112. *
  113. * Method: Should use binary search if fixed record size. Doesn't, yet.
  114. *
  115. ***************************************************************************/
  116. PUBLIC HRESULT FAR PASCAL RcScanLLeaf(BK bk, KEY key, SHORT wLevel,
  117. QBTHR qbthr, QV qRec, QBTPOS qbtpos)
  118. {
  119. QCB qcb;
  120. QB qb;
  121. SHORT cKey;
  122. HRESULT rc;
  123. LONG dwKeyVal;
  124. HRESULT errb;
  125. dwKeyVal = *(LONG FAR *)key;
  126. if ((qcb = QFromBk(bk, wLevel, qbthr, &errb)) == NULL)
  127. {
  128. return (errb);
  129. }
  130. rc = E_NOTEXIST;
  131. qb = qcb->db.rgbBlock + 2 * sizeof(BK);
  132. for (cKey = 0; cKey < qcb->db.cKeys; cKey++)
  133. {
  134. LONG dwVal = (LONG)GETLONG ((LPUL)qb);
  135. if (dwKeyVal > dwVal)
  136. {
  137. // still looking for key
  138. qb += sizeof(LONG);
  139. qb += CbSizeRec(qb, qbthr);
  140. }
  141. else if (dwKeyVal < dwVal)
  142. {
  143. // key not found
  144. break;
  145. }
  146. else
  147. {
  148. // matched the key
  149. if (qRec != NULL)
  150. {
  151. qb += sizeof(LONG);
  152. QVCOPY(qRec, qb, (LONG)CbSizeRec(qb, qbthr));
  153. }
  154. rc = S_OK;
  155. break;
  156. }
  157. }
  158. if (qbtpos != NULL)
  159. {
  160. qbtpos->bk = bk;
  161. qbtpos->iKey = (WORD)(qb - (QB)qcb->db.rgbBlock);
  162. qbtpos->cKey = cKey;
  163. }
  164. return rc;
  165. }
  166. /* EOF */