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.

181 lines
4.7 KiB

  1. /*****************************************************************************
  2. * *
  3. * BTKTSZ.C *
  4. * *
  5. * Copyright (C) Microsoft Corporation 1990 - 1994. *
  6. * All Rights reserved. *
  7. * *
  8. ******************************************************************************
  9. * *
  10. * Module Intent *
  11. * *
  12. * Functions for SZ (0-terminated string) 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 <misc.h>
  23. #include <iterror.h>
  24. #include <string.h>
  25. #include <wrapstor.h>
  26. #include <_mvutil.h>
  27. /***************************************************************************
  28. *
  29. * @doc INTERNAL
  30. *
  31. * @func BK FAR PASCAL | BkScanSzInternal |
  32. * Scan an internal node for a key and return child BK.
  33. *
  34. * @parm BK | bk |
  35. * BK of internal node to scan
  36. *
  37. * @parm KEY | key |
  38. * key to search for
  39. *
  40. * @parm SHORT | wLevel |
  41. * level of btree bk lives on
  42. *
  43. * @parm QBTHR | qbthr |
  44. * btree header containing cache, and btree specs
  45. *
  46. * @parm QW | qiKey |
  47. * address of an int or NULL to not get it
  48. *
  49. * @rdesc bk of subtree that might contain key; bkNil on error
  50. * args OUT: qbthr->qCache - bk's block will be cached
  51. * qiKey - index into rgbBlock of first key >= key
  52. *
  53. * Side Effects: bk's block will be cached
  54. *
  55. ***************************************************************************/
  56. PUBLIC BK FAR PASCAL BkScanSzInternal(BK bk, KEY key, SHORT wLevel,
  57. QBTHR qbthr, QW qiKey, PHRESULT phr)
  58. {
  59. QCB qcb;
  60. QB q;
  61. SHORT cKeys;
  62. if ((qcb = QFromBk(bk, wLevel, qbthr, phr)) == NULL)
  63. return bkNil;
  64. q = qcb->db.rgbBlock;
  65. cKeys = qcb->db.cKeys;
  66. bk = (BK)GETLONG(q);
  67. q += sizeof(BK);
  68. while (cKeys-- > 0)
  69. {
  70. if (STRCMP((SZ)key, (SZ)q) >= 0)
  71. {
  72. q += lstrlen((SZ)q) + 1;
  73. bk = (BK)GETLONG(q);
  74. q += sizeof(BK);
  75. }
  76. else
  77. break;
  78. }
  79. if (qiKey != NULL)
  80. *qiKey = (WORD)(q - (QB)qcb->db.rgbBlock);
  81. return bk;
  82. }
  83. /***************************************************************************
  84. *
  85. * @doc INTERNAL
  86. *
  87. * @func HRESULT FAR PASCAL | RcScanSzLeaf |
  88. * Scan a leaf node for a key and copy the associated data.
  89. *
  90. * @parm BK | bk |
  91. * the leaf block
  92. *
  93. * @parm KEY | key |
  94. * the key we're looking for
  95. *
  96. * @parm SHORT | wLevel |
  97. * the level of leaves (unnecessary)
  98. *
  99. * @parm QBTHR | qbthr |
  100. * the btree header
  101. *
  102. * @parm QV | qRec |
  103. * if found, record gets copied into this buffer
  104. *
  105. * @parm QTPOS | qbtpos |
  106. * pos of first key >= key goes here
  107. *
  108. * @rdesc ERR_SUCCESS if found; ERR_NOEXIST if not found
  109. * 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. ***************************************************************************/
  114. PUBLIC HRESULT FAR PASCAL RcScanSzLeaf(BK bk, KEY key, SHORT wLevel,
  115. QBTHR qbthr, QV qRec, QBTPOS qbtpos)
  116. {
  117. QCB qcb;
  118. SZ sz;
  119. int w;
  120. SHORT cKey;
  121. QB qb;
  122. HRESULT rc;
  123. HRESULT errb;
  124. if ((qcb = QFromBk(bk, wLevel, qbthr, &errb)) == NULL)
  125. return errb;
  126. rc = E_NOTEXIST;
  127. sz = qcb->db.rgbBlock + 2 * sizeof(BK);
  128. for (cKey = 0; cKey < qcb->db.cKeys; cKey++)
  129. {
  130. w = STRCMP((SZ)key, sz);
  131. if (w > 0) /* still looking for key */
  132. {
  133. sz += STRLEN(sz) + 1;
  134. sz += CbSizeRec(sz, qbthr);
  135. }
  136. else if (w < 0) /* key not found */
  137. break;
  138. else /* matched the key */
  139. {
  140. if (qRec != NULL)
  141. {
  142. qb = (QB)sz + STRLEN(sz) + 1;
  143. QVCOPY(qRec, qb, (LONG)CbSizeRec(qb, qbthr));
  144. }
  145. rc = S_OK;
  146. break;
  147. }
  148. }
  149. if (qbtpos != NULL)
  150. {
  151. qbtpos->bk = bk;
  152. qbtpos->cKey = cKey;
  153. qbtpos->iKey = (int)((QB)sz - (QB)qcb->db.rgbBlock);
  154. }
  155. return rc;;
  156. }
  157. /* EOF */