bt_cursor.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:72k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1996-2002
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char revid[] = "$Id: bt_cursor.c,v 11.147 2002/08/13 20:46:07 ubell Exp $";
  10. #endif /* not lint */
  11. #ifndef NO_SYSTEM_INCLUDES
  12. #include <sys/types.h>
  13. #include <string.h>
  14. #endif
  15. #include "db_int.h"
  16. #include "dbinc/db_page.h"
  17. #include "dbinc/db_shash.h"
  18. #include "dbinc/btree.h"
  19. #include "dbinc/lock.h"
  20. static int  __bam_bulk __P((DBC *, DBT *, u_int32_t));
  21. static int  __bam_c_close __P((DBC *, db_pgno_t, int *));
  22. static int  __bam_c_del __P((DBC *));
  23. static int  __bam_c_destroy __P((DBC *));
  24. static int  __bam_c_first __P((DBC *));
  25. static int  __bam_c_get __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
  26. static int  __bam_c_getstack __P((DBC *));
  27. static int  __bam_c_last __P((DBC *));
  28. static int  __bam_c_next __P((DBC *, int, int));
  29. static int  __bam_c_physdel __P((DBC *));
  30. static int  __bam_c_prev __P((DBC *));
  31. static int  __bam_c_put __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *));
  32. static int  __bam_c_search __P((DBC *,
  33. db_pgno_t, const DBT *, u_int32_t, int *));
  34. static int  __bam_c_writelock __P((DBC *));
  35. static int  __bam_getboth_finddatum __P((DBC *, DBT *, u_int32_t));
  36. static int  __bam_getbothc __P((DBC *, DBT *));
  37. static int  __bam_get_prev __P((DBC *));
  38. static int  __bam_isopd __P((DBC *, db_pgno_t *));
  39. /*
  40.  * Acquire a new page/lock.  If we hold a page/lock, discard the page, and
  41.  * lock-couple the lock.
  42.  *
  43.  * !!!
  44.  * We have to handle both where we have a lock to lock-couple and where we
  45.  * don't -- we don't duplicate locks when we duplicate cursors if we are
  46.  * running in a transaction environment as there's no point if locks are
  47.  * never discarded.  This means that the cursor may or may not hold a lock.
  48.  * In the case where we are decending the tree we always want to
  49.  * unlock the held interior page so we use ACQUIRE_COUPLE.
  50.  */
  51. #undef ACQUIRE
  52. #define ACQUIRE(dbc, mode, lpgno, lock, fpgno, pagep, ret) {
  53. DB_MPOOLFILE *__mpf = (dbc)->dbp->mpf;
  54. if ((pagep) != NULL) {
  55. ret = __mpf->put(__mpf, pagep, 0);
  56. pagep = NULL;
  57. } else
  58. ret = 0;
  59. if ((ret) == 0 && STD_LOCKING(dbc))
  60. ret = __db_lget(dbc, LCK_COUPLE, lpgno, mode, 0, &(lock));
  61. if ((ret) == 0)
  62. ret = __mpf->get(__mpf, &(fpgno), 0, &(pagep));
  63. }
  64. #undef ACQUIRE_COUPLE
  65. #define ACQUIRE_COUPLE(dbc, mode, lpgno, lock, fpgno, pagep, ret) {
  66. DB_MPOOLFILE *__mpf = (dbc)->dbp->mpf;
  67. if ((pagep) != NULL) {
  68. ret = __mpf->put(__mpf, pagep, 0);
  69. pagep = NULL;
  70. } else
  71. ret = 0;
  72. if ((ret) == 0 && STD_LOCKING(dbc))
  73. ret = __db_lget(dbc,
  74.     LCK_COUPLE_ALWAYS, lpgno, mode, 0, &(lock));
  75. if ((ret) == 0)
  76. ret = __mpf->get(__mpf, &(fpgno), 0, &(pagep));
  77. }
  78. /* Acquire a new page/lock for a cursor. */
  79. #undef ACQUIRE_CUR
  80. #define ACQUIRE_CUR(dbc, mode, p, ret) {
  81. BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal;
  82. ACQUIRE(dbc, mode, p, __cp->lock, p, __cp->page, ret);
  83. if ((ret) == 0) {
  84. __cp->pgno = p;
  85. __cp->lock_mode = (mode);
  86. }
  87. }
  88. /*
  89.  * Acquire a new page/lock for a cursor and release the previous.
  90.  * This is typically used when decending a tree and we do not
  91.  * want to hold the interior nodes locked.
  92.  */
  93. #undef ACQUIRE_CUR_COUPLE
  94. #define ACQUIRE_CUR_COUPLE(dbc, mode, p, ret) {
  95. BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal;
  96. ACQUIRE_COUPLE(dbc, mode, p, __cp->lock, p, __cp->page, ret);
  97. if ((ret) == 0) {
  98. __cp->pgno = p;
  99. __cp->lock_mode = (mode);
  100. }
  101. }
  102. /*
  103.  * Acquire a write lock if we don't already have one.
  104.  *
  105.  * !!!
  106.  * See ACQUIRE macro on why we handle cursors that don't have locks.
  107.  */
  108. #undef ACQUIRE_WRITE_LOCK
  109. #define ACQUIRE_WRITE_LOCK(dbc, ret) {
  110. BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal;
  111. ret = 0;
  112. if (STD_LOCKING(dbc) &&
  113.     __cp->lock_mode != DB_LOCK_WRITE &&
  114.     ((ret) = __db_lget(dbc,
  115.     LOCK_ISSET(__cp->lock) ? LCK_COUPLE : 0,
  116.     __cp->pgno, DB_LOCK_WRITE, 0, &__cp->lock)) == 0)
  117. __cp->lock_mode = DB_LOCK_WRITE;
  118. }
  119. /* Discard the current page/lock. */
  120. #undef DISCARD
  121. #define DISCARD(dbc, ldiscard, lock, pagep, ret) {
  122. DB_MPOOLFILE *__mpf = (dbc)->dbp->mpf;
  123. int __t_ret;
  124. if ((pagep) != NULL) {
  125. ret = __mpf->put(__mpf, pagep, 0);
  126. pagep = NULL;
  127. } else
  128. ret = 0;
  129. if (ldiscard)
  130. __t_ret = __LPUT((dbc), lock);
  131. else
  132. __t_ret = __TLPUT((dbc), lock);
  133. if (__t_ret != 0 && (ret) == 0)
  134. ret = __t_ret;
  135. }
  136. /* Discard the current page/lock for a cursor. */
  137. #undef DISCARD_CUR
  138. #define DISCARD_CUR(dbc, ret) {
  139. BTREE_CURSOR *__cp = (BTREE_CURSOR *)(dbc)->internal;
  140. DISCARD(dbc, 0, __cp->lock, __cp->page, ret);
  141. if ((ret) == 0)
  142. __cp->lock_mode = DB_LOCK_NG;
  143. }
  144. /* If on-page item is a deleted record. */
  145. #undef IS_DELETED
  146. #define IS_DELETED(dbp, page, indx)
  147. B_DISSET(GET_BKEYDATA(dbp, page,
  148.     (indx) + (TYPE(page) == P_LBTREE ? O_INDX : 0))->type)
  149. #undef IS_CUR_DELETED
  150. #define IS_CUR_DELETED(dbc)
  151. IS_DELETED((dbc)->dbp, (dbc)->internal->page, (dbc)->internal->indx)
  152. /*
  153.  * Test to see if two cursors could point to duplicates of the same key.
  154.  * In the case of off-page duplicates they are they same, as the cursors
  155.  * will be in the same off-page duplicate tree.  In the case of on-page
  156.  * duplicates, the key index offsets must be the same.  For the last test,
  157.  * as the original cursor may not have a valid page pointer, we use the
  158.  * current cursor's.
  159.  */
  160. #undef IS_DUPLICATE
  161. #define IS_DUPLICATE(dbc, i1, i2)
  162.     (P_INP((dbc)->dbp,((PAGE *)(dbc)->internal->page))[i1] ==
  163.      P_INP((dbc)->dbp,((PAGE *)(dbc)->internal->page))[i2])
  164. #undef IS_CUR_DUPLICATE
  165. #define IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx)
  166. (F_ISSET(dbc, DBC_OPD) ||
  167.     (orig_pgno == (dbc)->internal->pgno &&
  168.     IS_DUPLICATE(dbc, (dbc)->internal->indx, orig_indx)))
  169. /*
  170.  * __bam_c_init --
  171.  * Initialize the access private portion of a cursor
  172.  *
  173.  * PUBLIC: int __bam_c_init __P((DBC *, DBTYPE));
  174.  */
  175. int
  176. __bam_c_init(dbc, dbtype)
  177. DBC *dbc;
  178. DBTYPE dbtype;
  179. {
  180. DB_ENV *dbenv;
  181. int ret;
  182. dbenv = dbc->dbp->dbenv;
  183. /* Allocate/initialize the internal structure. */
  184. if (dbc->internal == NULL && (ret =
  185.     __os_malloc(dbenv, sizeof(BTREE_CURSOR), &dbc->internal)) != 0)
  186. return (ret);
  187. /* Initialize methods. */
  188. dbc->c_close = __db_c_close;
  189. dbc->c_count = __db_c_count;
  190. dbc->c_del = __db_c_del;
  191. dbc->c_dup = __db_c_dup;
  192. dbc->c_get = dbc->c_real_get = __db_c_get;
  193. dbc->c_pget = __db_c_pget;
  194. dbc->c_put = __db_c_put;
  195. if (dbtype == DB_BTREE) {
  196. dbc->c_am_bulk = __bam_bulk;
  197. dbc->c_am_close = __bam_c_close;
  198. dbc->c_am_del = __bam_c_del;
  199. dbc->c_am_destroy = __bam_c_destroy;
  200. dbc->c_am_get = __bam_c_get;
  201. dbc->c_am_put = __bam_c_put;
  202. dbc->c_am_writelock = __bam_c_writelock;
  203. } else {
  204. dbc->c_am_bulk = __bam_bulk;
  205. dbc->c_am_close = __bam_c_close;
  206. dbc->c_am_del = __ram_c_del;
  207. dbc->c_am_destroy = __bam_c_destroy;
  208. dbc->c_am_get = __ram_c_get;
  209. dbc->c_am_put = __ram_c_put;
  210. dbc->c_am_writelock = __bam_c_writelock;
  211. }
  212. return (0);
  213. }
  214. /*
  215.  * __bam_c_refresh
  216.  * Set things up properly for cursor re-use.
  217.  *
  218.  * PUBLIC: int __bam_c_refresh __P((DBC *));
  219.  */
  220. int
  221. __bam_c_refresh(dbc)
  222. DBC *dbc;
  223. {
  224. BTREE *t;
  225. BTREE_CURSOR *cp;
  226. DB *dbp;
  227. dbp = dbc->dbp;
  228. t = dbp->bt_internal;
  229. cp = (BTREE_CURSOR *)dbc->internal;
  230. /*
  231.  * If our caller set the root page number, it's because the root was
  232.  * known.  This is always the case for off page dup cursors.  Else,
  233.  * pull it out of our internal information.
  234.  */
  235. if (cp->root == PGNO_INVALID)
  236. cp->root = t->bt_root;
  237. LOCK_INIT(cp->lock);
  238. cp->lock_mode = DB_LOCK_NG;
  239. cp->sp = cp->csp = cp->stack;
  240. cp->esp = cp->stack + sizeof(cp->stack) / sizeof(cp->stack[0]);
  241. /*
  242.  * The btree leaf page data structures require that two key/data pairs
  243.  * (or four items) fit on a page, but other than that there's no fixed
  244.  * requirement.  The btree off-page duplicates only require two items,
  245.  * to be exact, but requiring four for them as well seems reasonable.
  246.  *
  247.  * Recno uses the btree bt_ovflsize value -- it's close enough.
  248.  */
  249. cp->ovflsize = B_MINKEY_TO_OVFLSIZE(
  250.     dbp,  F_ISSET(dbc, DBC_OPD) ? 2 : t->bt_minkey, dbp->pgsize);
  251. cp->recno = RECNO_OOB;
  252. cp->order = INVALID_ORDER;
  253. cp->flags = 0;
  254. /* Initialize for record numbers. */
  255. if (F_ISSET(dbc, DBC_OPD) ||
  256.     dbc->dbtype == DB_RECNO || F_ISSET(dbp, DB_AM_RECNUM)) {
  257. F_SET(cp, C_RECNUM);
  258. /*
  259.  * All btrees that support record numbers, optionally standard
  260.  * recno trees, and all off-page duplicate recno trees have
  261.  * mutable record numbers.
  262.  */
  263. if ((F_ISSET(dbc, DBC_OPD) && dbc->dbtype == DB_RECNO) ||
  264.     F_ISSET(dbp, DB_AM_RECNUM | DB_AM_RENUMBER))
  265. F_SET(cp, C_RENUMBER);
  266. }
  267. return (0);
  268. }
  269. /*
  270.  * __bam_c_close --
  271.  * Close down the cursor.
  272.  */
  273. static int
  274. __bam_c_close(dbc, root_pgno, rmroot)
  275. DBC *dbc;
  276. db_pgno_t root_pgno;
  277. int *rmroot;
  278. {
  279. BTREE_CURSOR *cp, *cp_opd, *cp_c;
  280. DB *dbp;
  281. DBC *dbc_opd, *dbc_c;
  282. DB_MPOOLFILE *mpf;
  283. PAGE *h;
  284. int cdb_lock, ret, t_ret;
  285. dbp = dbc->dbp;
  286. mpf = dbp->mpf;
  287. cp = (BTREE_CURSOR *)dbc->internal;
  288. cp_opd = (dbc_opd = cp->opd) == NULL ?
  289.     NULL : (BTREE_CURSOR *)dbc_opd->internal;
  290. cdb_lock = ret = 0;
  291. /*
  292.  * There are 3 ways this function is called:
  293.  *
  294.  * 1. Closing a primary cursor: we get called with a pointer to a
  295.  *    primary cursor that has a NULL opd field.  This happens when
  296.  *    closing a btree/recno database cursor without an associated
  297.  *    off-page duplicate tree.
  298.  *
  299.  * 2. Closing a primary and an off-page duplicate cursor stack: we
  300.  *    get called with a pointer to the primary cursor which has a
  301.  *    non-NULL opd field.  This happens when closing a btree cursor
  302.  *    into database with an associated off-page btree/recno duplicate
  303.  *    tree. (It can't be a primary recno database, recno databases
  304.  *    don't support duplicates.)
  305.  *
  306.  * 3. Closing an off-page duplicate cursor stack: we get called with
  307.  *    a pointer to the off-page duplicate cursor.  This happens when
  308.  *    closing a non-btree database that has an associated off-page
  309.  *    btree/recno duplicate tree or for a btree database when the
  310.  *    opd tree is not empty (root_pgno == PGNO_INVALID).
  311.  *
  312.  * If either the primary or off-page duplicate cursor deleted a btree
  313.  * key/data pair, check to see if the item is still referenced by a
  314.  * different cursor.  If it is, confirm that cursor's delete flag is
  315.  * set and leave it to that cursor to do the delete.
  316.  *
  317.  * NB: The test for == 0 below is correct.  Our caller already removed
  318.  * our cursor argument from the active queue, we won't find it when we
  319.  * search the queue in __bam_ca_delete().
  320.  * NB: It can't be true that both the primary and off-page duplicate
  321.  * cursors have deleted a btree key/data pair.  Either the primary
  322.  * cursor may have deleted an item and there's no off-page duplicate
  323.  * cursor, or there's an off-page duplicate cursor and it may have
  324.  * deleted an item.
  325.  *
  326.  * Primary recno databases aren't an issue here.  Recno keys are either
  327.  * deleted immediately or never deleted, and do not have to be handled
  328.  * here.
  329.  *
  330.  * Off-page duplicate recno databases are an issue here, cases #2 and
  331.  * #3 above can both be off-page recno databases.  The problem is the
  332.  * same as the final problem for off-page duplicate btree databases.
  333.  * If we no longer need the off-page duplicate tree, we want to remove
  334.  * it.  For off-page duplicate btrees, we are done with the tree when
  335.  * we delete the last item it contains, i.e., there can be no further
  336.  * references to it when it's empty.  For off-page duplicate recnos,
  337.  * we remove items from the tree as the application calls the remove
  338.  * function, so we are done with the tree when we close the last cursor
  339.  * that references it.
  340.  *
  341.  * We optionally take the root page number from our caller.  If the
  342.  * primary database is a btree, we can get it ourselves because dbc
  343.  * is the primary cursor.  If the primary database is not a btree,
  344.  * the problem is that we may be dealing with a stack of pages.  The
  345.  * cursor we're using to do the delete points at the bottom of that
  346.  * stack and we need the top of the stack.
  347.  */
  348. if (F_ISSET(cp, C_DELETED)) {
  349. dbc_c = dbc;
  350. switch (dbc->dbtype) {
  351. case DB_BTREE: /* Case #1, #3. */
  352. if (__bam_ca_delete(dbp, cp->pgno, cp->indx, 1) == 0)
  353. goto lock;
  354. goto done;
  355. case DB_RECNO:
  356. if (!F_ISSET(dbc, DBC_OPD)) /* Case #1. */
  357. goto done;
  358. /* Case #3. */
  359. if (__ram_ca_delete(dbp, cp->root) == 0)
  360. goto lock;
  361. goto done;
  362. default:
  363. return (__db_unknown_type(dbp->dbenv,
  364. "__bam_c_close", dbc->dbtype));
  365. }
  366. }
  367. if (dbc_opd == NULL)
  368. goto done;
  369. if (F_ISSET(cp_opd, C_DELETED)) { /* Case #2. */
  370. /*
  371.  * We will not have been provided a root page number.  Acquire
  372.  * one from the primary database.
  373.  */
  374. if ((ret = mpf->get(mpf, &cp->pgno, 0, &h)) != 0)
  375. goto err;
  376. root_pgno = GET_BOVERFLOW(dbp, h, cp->indx + O_INDX)->pgno;
  377. if ((ret = mpf->put(mpf, h, 0)) != 0)
  378. goto err;
  379. dbc_c = dbc_opd;
  380. switch (dbc_opd->dbtype) {
  381. case DB_BTREE:
  382. if (__bam_ca_delete(
  383.     dbp, cp_opd->pgno, cp_opd->indx, 1) == 0)
  384. goto lock;
  385. goto done;
  386. case DB_RECNO:
  387. if (__ram_ca_delete(dbp, cp_opd->root) == 0)
  388. goto lock;
  389. goto done;
  390. default:
  391. return (__db_unknown_type(dbp->dbenv,
  392. "__bam_c_close", dbc->dbtype));
  393. }
  394. }
  395. goto done;
  396. lock: cp_c = (BTREE_CURSOR *)dbc_c->internal;
  397. /*
  398.  * If this is CDB, upgrade the lock if necessary.  While we acquired
  399.  * the write lock to logically delete the record, we released it when
  400.  * we returned from that call, and so may not be holding a write lock
  401.  * at the moment.  NB: to get here in CDB we must either be holding a
  402.  * write lock or be the only cursor that is permitted to acquire write
  403.  * locks.  The reason is that there can never be more than a single CDB
  404.  * write cursor (that cursor cannot be dup'd), and so that cursor must
  405.  * be closed and the item therefore deleted before any other cursor
  406.  * could acquire a reference to this item.
  407.  *
  408.  * Note that dbc may be an off-page dup cursor;  this is the sole
  409.  * instance in which an OPD cursor does any locking, but it's necessary
  410.  * because we may be closed by ourselves without a parent cursor
  411.  * handy, and we have to do a lock upgrade on behalf of somebody.
  412.  * If this is the case, the OPD has been given the parent's locking
  413.  * info in __db_c_get--the OPD is also a WRITEDUP.
  414.  */
  415. if (CDB_LOCKING(dbp->dbenv)) {
  416. if (F_ISSET(dbc, DBC_WRITEDUP | DBC_WRITECURSOR)) {
  417. if ((ret = dbp->dbenv->lock_get(
  418.     dbp->dbenv, dbc->locker, DB_LOCK_UPGRADE,
  419.     &dbc->lock_dbt, DB_LOCK_WRITE, &dbc->mylock)) != 0)
  420. goto err;
  421. cdb_lock = 1;
  422. }
  423. if ((ret = mpf->get(mpf, &cp_c->pgno, 0, &cp_c->page)) != 0)
  424. goto err;
  425. goto delete;
  426. }
  427. /*
  428.  * The variable dbc_c has been initialized to reference the cursor in
  429.  * which we're going to do the delete.  Initialize the cursor's page
  430.  * and lock structures as necessary.
  431.  *
  432.  * First, we may not need to acquire any locks.  If we're in case #3,
  433.  * that is, the primary database isn't a btree database, our caller
  434.  * is responsible for acquiring any necessary locks before calling us.
  435.  */
  436. if (F_ISSET(dbc, DBC_OPD)) {
  437. if ((ret = mpf->get(mpf, &cp_c->pgno, 0, &cp_c->page)) != 0)
  438. goto err;
  439. goto delete;
  440. }
  441. /*
  442.  * Otherwise, acquire a write lock.  If the cursor that did the initial
  443.  * logical deletion (and which had a write lock) is not the same as the
  444.  * cursor doing the physical deletion (which may have only ever had a
  445.  * read lock on the item), we need to upgrade.  The confusion comes as
  446.  * follows:
  447.  *
  448.  * C1 created, acquires item read lock
  449.  * C2 dup C1, create C2, also has item read lock.
  450.  * C1 acquire write lock, delete item
  451.  * C1 close
  452.  * C2 close, needs a write lock to physically delete item.
  453.  *
  454.  * If we're in a TXN, we know that C2 will be able to acquire the write
  455.  * lock, because no locker other than the one shared by C1 and C2 can
  456.  * acquire a write lock -- the original write lock C1 acquire was never
  457.  * discarded.
  458.  *
  459.  * If we're not in a TXN, it's nastier.  Other cursors might acquire
  460.  * read locks on the item after C1 closed, discarding its write lock,
  461.  * and such locks would prevent C2 from acquiring a read lock.  That's
  462.  * OK, though, we'll simply wait until we can acquire a read lock, or
  463.  * we'll deadlock.  (Which better not happen, since we're not in a TXN.)
  464.  *
  465.  * Lock the primary database page, regardless of whether we're deleting
  466.  * an item on a primary database page or an off-page duplicates page.
  467.  */
  468. ACQUIRE(dbc, DB_LOCK_WRITE,
  469.     cp->pgno, cp_c->lock, cp_c->pgno, cp_c->page, ret);
  470. if (ret != 0)
  471. goto err;
  472. delete: /*
  473.  * If the delete occurred in a btree, delete the on-page physical item
  474.  * referenced by the cursor.
  475.  */
  476. if (dbc_c->dbtype == DB_BTREE && (ret = __bam_c_physdel(dbc_c)) != 0)
  477. goto err;
  478. /*
  479.  * If we're not working in an off-page duplicate tree, then we're
  480.  * done.
  481.  */
  482. if (!F_ISSET(dbc_c, DBC_OPD) || root_pgno == PGNO_INVALID)
  483. goto done;
  484. /*
  485.  * We may have just deleted the last element in the off-page duplicate
  486.  * tree, and closed the last cursor in the tree.  For an off-page btree
  487.  * there are no other cursors in the tree by definition, if the tree is
  488.  * empty.  For an off-page recno we know we have closed the last cursor
  489.  * in the tree because the __ram_ca_delete call above returned 0 only
  490.  * in that case.  So, if the off-page duplicate tree is empty at this
  491.  * point, we want to remove it.
  492.  */
  493. if ((ret = mpf->get(mpf, &root_pgno, 0, &h)) != 0)
  494. goto err;
  495. if (NUM_ENT(h) == 0) {
  496. if ((ret = __db_free(dbc, h)) != 0)
  497. goto err;
  498. } else {
  499. if ((ret = mpf->put(mpf, h, 0)) != 0)
  500. goto err;
  501. goto done;
  502. }
  503. /*
  504.  * When removing the tree, we have to do one of two things.  If this is
  505.  * case #2, that is, the primary tree is a btree, delete the key that's
  506.  * associated with the tree from the btree leaf page.  We know we are
  507.  * the only reference to it and we already have the correct lock.  We
  508.  * detect this case because the cursor that was passed to us references
  509.  * an off-page duplicate cursor.
  510.  *
  511.  * If this is case #3, that is, the primary tree isn't a btree, pass
  512.  * the information back to our caller, it's their job to do cleanup on
  513.  * the primary page.
  514.  */
  515. if (dbc_opd != NULL) {
  516. if ((ret = mpf->get(mpf, &cp->pgno, 0, &cp->page)) != 0)
  517. goto err;
  518. if ((ret = __bam_c_physdel(dbc)) != 0)
  519. goto err;
  520. } else
  521. *rmroot = 1;
  522. err:
  523. done: /*
  524.  * Discard the page references and locks, and confirm that the stack
  525.  * has been emptied.
  526.  */
  527. if (dbc_opd != NULL) {
  528. DISCARD_CUR(dbc_opd, t_ret);
  529. if (t_ret != 0 && ret == 0)
  530. ret = t_ret;
  531. }
  532. DISCARD_CUR(dbc, t_ret);
  533. if (t_ret != 0 && ret == 0)
  534. ret = t_ret;
  535. /* Downgrade any CDB lock we acquired. */
  536. if (cdb_lock)
  537. (void)__lock_downgrade(
  538.     dbp->dbenv, &dbc->mylock, DB_LOCK_IWRITE, 0);
  539. return (ret);
  540. }
  541. /*
  542.  * __bam_c_destroy --
  543.  * Close a single cursor -- internal version.
  544.  */
  545. static int
  546. __bam_c_destroy(dbc)
  547. DBC *dbc;
  548. {
  549. /* Discard the structures. */
  550. __os_free(dbc->dbp->dbenv, dbc->internal);
  551. return (0);
  552. }
  553. /*
  554.  * __bam_c_count --
  555.  * Return a count of on and off-page duplicates.
  556.  *
  557.  * PUBLIC: int __bam_c_count __P((DBC *, db_recno_t *));
  558.  */
  559. int
  560. __bam_c_count(dbc, recnop)
  561. DBC *dbc;
  562. db_recno_t *recnop;
  563. {
  564. BTREE_CURSOR *cp;
  565. DB *dbp;
  566. DB_MPOOLFILE *mpf;
  567. db_indx_t indx, top;
  568. db_recno_t recno;
  569. int ret;
  570. dbp = dbc->dbp;
  571. mpf = dbp->mpf;
  572. cp = (BTREE_CURSOR *)dbc->internal;
  573. /*
  574.  * Called with the top-level cursor that may reference an off-page
  575.  * duplicates page.  If it's a set of on-page duplicates, get the
  576.  * page and count.  Otherwise, get the root page of the off-page
  577.  * duplicate tree, and use the count.  We don't have to acquire any
  578.  * new locks, we have to have a read lock to even get here.
  579.  */
  580. if (cp->opd == NULL) {
  581. if ((ret = mpf->get(mpf, &cp->pgno, 0, &cp->page)) != 0)
  582. return (ret);
  583. /*
  584.  * Move back to the beginning of the set of duplicates and
  585.  * then count forward.
  586.  */
  587. for (indx = cp->indx;; indx -= P_INDX)
  588. if (indx == 0 ||
  589.     !IS_DUPLICATE(dbc, indx, indx - P_INDX))
  590. break;
  591. for (recno = 1, top = NUM_ENT(cp->page) - P_INDX;
  592.     indx < top; ++recno, indx += P_INDX)
  593. if (!IS_DUPLICATE(dbc, indx, indx + P_INDX))
  594. break;
  595. *recnop = recno;
  596. } else {
  597. if ((ret =
  598.     mpf->get(mpf, &cp->opd->internal->root, 0, &cp->page)) != 0)
  599. return (ret);
  600. *recnop = RE_NREC(cp->page);
  601. }
  602. ret = mpf->put(mpf, cp->page, 0);
  603. cp->page = NULL;
  604. return (ret);
  605. }
  606. /*
  607.  * __bam_c_del --
  608.  * Delete using a cursor.
  609.  */
  610. static int
  611. __bam_c_del(dbc)
  612. DBC *dbc;
  613. {
  614. BTREE_CURSOR *cp;
  615. DB *dbp;
  616. DB_MPOOLFILE *mpf;
  617. int ret, t_ret;
  618. dbp = dbc->dbp;
  619. mpf = dbp->mpf;
  620. cp = (BTREE_CURSOR *)dbc->internal;
  621. ret = 0;
  622. /* If the item was already deleted, return failure. */
  623. if (F_ISSET(cp, C_DELETED))
  624. return (DB_KEYEMPTY);
  625. /*
  626.  * This code is always called with a page lock but no page.
  627.  */
  628. DB_ASSERT(cp->page == NULL);
  629. /*
  630.  * We don't physically delete the record until the cursor moves, so
  631.  * we have to have a long-lived write lock on the page instead of a
  632.  * a long-lived read lock.  Note, we have to have a read lock to even
  633.  * get here.
  634.  *
  635.  * If we're maintaining record numbers, we lock the entire tree, else
  636.  * we lock the single page.
  637.  */
  638. if (F_ISSET(cp, C_RECNUM)) {
  639. if ((ret = __bam_c_getstack(dbc)) != 0)
  640. goto err;
  641. cp->page = cp->csp->page;
  642. } else {
  643. ACQUIRE_CUR(dbc, DB_LOCK_WRITE, cp->pgno, ret);
  644. if (ret != 0)
  645. goto err;
  646. }
  647. /* Log the change. */
  648. if (DBC_LOGGING(dbc)) {
  649. if ((ret = __bam_cdel_log(dbp, dbc->txn, &LSN(cp->page), 0,
  650.     PGNO(cp->page), &LSN(cp->page), cp->indx)) != 0)
  651. goto err;
  652. } else
  653. LSN_NOT_LOGGED(LSN(cp->page));
  654. /* Set the intent-to-delete flag on the page. */
  655. if (TYPE(cp->page) == P_LBTREE)
  656. B_DSET(GET_BKEYDATA(dbp, cp->page, cp->indx + O_INDX)->type);
  657. else
  658. B_DSET(GET_BKEYDATA(dbp, cp->page, cp->indx)->type);
  659. /* Mark the page dirty. */
  660. ret = mpf->set(mpf, cp->page, DB_MPOOL_DIRTY);
  661. err: /*
  662.  * If we've been successful so far and the tree has record numbers,
  663.  * adjust the record counts.  Either way, release acquired page(s).
  664.  */
  665. if (F_ISSET(cp, C_RECNUM)) {
  666. if (ret == 0)
  667. ret = __bam_adjust(dbc, -1);
  668. (void)__bam_stkrel(dbc, 0);
  669. } else
  670. if (cp->page != NULL &&
  671.     (t_ret = mpf->put(mpf, cp->page, 0)) != 0 && ret == 0)
  672. ret = t_ret;
  673. cp->page = NULL;
  674. /* Update the cursors last, after all chance of failure is past. */
  675. if (ret == 0)
  676. (void)__bam_ca_delete(dbp, cp->pgno, cp->indx, 1);
  677. return (ret);
  678. }
  679. /*
  680.  * __bam_c_dup --
  681.  * Duplicate a btree cursor, such that the new one holds appropriate
  682.  * locks for the position of the original.
  683.  *
  684.  * PUBLIC: int __bam_c_dup __P((DBC *, DBC *));
  685.  */
  686. int
  687. __bam_c_dup(orig_dbc, new_dbc)
  688. DBC *orig_dbc, *new_dbc;
  689. {
  690. BTREE_CURSOR *orig, *new;
  691. int ret;
  692. orig = (BTREE_CURSOR *)orig_dbc->internal;
  693. new = (BTREE_CURSOR *)new_dbc->internal;
  694. /*
  695.  * If we're holding a lock we need to acquire a copy of it, unless
  696.  * we're in a transaction.  We don't need to copy any lock we're
  697.  * holding inside a transaction because all the locks are retained
  698.  * until the transaction commits or aborts.
  699.  */
  700. if (LOCK_ISSET(orig->lock) && orig_dbc->txn == NULL) {
  701. if ((ret = __db_lget(new_dbc,
  702.     0, new->pgno, new->lock_mode, 0, &new->lock)) != 0)
  703. return (ret);
  704. }
  705. new->ovflsize = orig->ovflsize;
  706. new->recno = orig->recno;
  707. new->flags = orig->flags;
  708. return (0);
  709. }
  710. /*
  711.  * __bam_c_get --
  712.  * Get using a cursor (btree).
  713.  */
  714. static int
  715. __bam_c_get(dbc, key, data, flags, pgnop)
  716. DBC *dbc;
  717. DBT *key, *data;
  718. u_int32_t flags;
  719. db_pgno_t *pgnop;
  720. {
  721. BTREE_CURSOR *cp;
  722. DB *dbp;
  723. DB_MPOOLFILE *mpf;
  724. db_pgno_t orig_pgno;
  725. db_indx_t orig_indx;
  726. int exact, newopd, ret;
  727. dbp = dbc->dbp;
  728. mpf = dbp->mpf;
  729. cp = (BTREE_CURSOR *)dbc->internal;
  730. orig_pgno = cp->pgno;
  731. orig_indx = cp->indx;
  732. newopd = 0;
  733. switch (flags) {
  734. case DB_CURRENT:
  735. /* It's not possible to return a deleted record. */
  736. if (F_ISSET(cp, C_DELETED)) {
  737. ret = DB_KEYEMPTY;
  738. goto err;
  739. }
  740. /*
  741.  * Acquire the current page.  We have at least a read-lock
  742.  * already.  The caller may have set DB_RMW asking for a
  743.  * write lock, but upgrading to a write lock has no better
  744.  * chance of succeeding now instead of later, so don't try.
  745.  */
  746. if ((ret = mpf->get(mpf, &cp->pgno, 0, &cp->page)) != 0)
  747. goto err;
  748. break;
  749. case DB_FIRST:
  750. newopd = 1;
  751. if ((ret = __bam_c_first(dbc)) != 0)
  752. goto err;
  753. break;
  754. case DB_GET_BOTH:
  755. case DB_GET_BOTH_RANGE:
  756. /*
  757.  * There are two ways to get here based on DBcursor->c_get
  758.  * with the DB_GET_BOTH/DB_GET_BOTH_RANGE flags set:
  759.  *
  760.  * 1. Searching a sorted off-page duplicate tree: do a tree
  761.  * search.
  762.  *
  763.  * 2. Searching btree: do a tree search.  If it returns a
  764.  * reference to off-page duplicate tree, return immediately
  765.  * and let our caller deal with it.  If the search doesn't
  766.  * return a reference to off-page duplicate tree, continue
  767.  * with an on-page search.
  768.  */
  769. if (F_ISSET(dbc, DBC_OPD)) {
  770. if ((ret = __bam_c_search(
  771.     dbc, PGNO_INVALID, data, flags, &exact)) != 0)
  772. goto err;
  773. if (flags == DB_GET_BOTH) {
  774. if (!exact) {
  775. ret = DB_NOTFOUND;
  776. goto err;
  777. }
  778. break;
  779. }
  780. /*
  781.  * We didn't require an exact match, so the search may
  782.  * may have returned an entry past the end of the page,
  783.  * or we may be referencing a deleted record.  If so,
  784.  * move to the next entry.
  785.  */
  786. if ((cp->indx == NUM_ENT(cp->page) ||
  787.     IS_CUR_DELETED(dbc)) &&
  788.     (ret = __bam_c_next(dbc, 1, 0)) != 0)
  789. goto err;
  790. } else {
  791. if ((ret = __bam_c_search(
  792.     dbc, PGNO_INVALID, key, flags, &exact)) != 0)
  793. return (ret);
  794. if (!exact) {
  795. ret = DB_NOTFOUND;
  796. goto err;
  797. }
  798. if (pgnop != NULL && __bam_isopd(dbc, pgnop)) {
  799. newopd = 1;
  800. break;
  801. }
  802. if ((ret =
  803.     __bam_getboth_finddatum(dbc, data, flags)) != 0)
  804. goto err;
  805. }
  806. break;
  807. case DB_GET_BOTHC:
  808. if ((ret = __bam_getbothc(dbc, data)) != 0)
  809. goto err;
  810. break;
  811. case DB_LAST:
  812. newopd = 1;
  813. if ((ret = __bam_c_last(dbc)) != 0)
  814. goto err;
  815. break;
  816. case DB_NEXT:
  817. newopd = 1;
  818. if (cp->pgno == PGNO_INVALID) {
  819. if ((ret = __bam_c_first(dbc)) != 0)
  820. goto err;
  821. } else
  822. if ((ret = __bam_c_next(dbc, 1, 0)) != 0)
  823. goto err;
  824. break;
  825. case DB_NEXT_DUP:
  826. if ((ret = __bam_c_next(dbc, 1, 0)) != 0)
  827. goto err;
  828. if (!IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx)) {
  829. ret = DB_NOTFOUND;
  830. goto err;
  831. }
  832. break;
  833. case DB_NEXT_NODUP:
  834. newopd = 1;
  835. if (cp->pgno == PGNO_INVALID) {
  836. if ((ret = __bam_c_first(dbc)) != 0)
  837. goto err;
  838. } else
  839. do {
  840. if ((ret = __bam_c_next(dbc, 1, 0)) != 0)
  841. goto err;
  842. } while (IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx));
  843. break;
  844. case DB_PREV:
  845. newopd = 1;
  846. if (cp->pgno == PGNO_INVALID) {
  847. if ((ret = __bam_c_last(dbc)) != 0)
  848. goto err;
  849. } else
  850. if ((ret = __bam_c_prev(dbc)) != 0)
  851. goto err;
  852. break;
  853. case DB_PREV_NODUP:
  854. newopd = 1;
  855. if (cp->pgno == PGNO_INVALID) {
  856. if ((ret = __bam_c_last(dbc)) != 0)
  857. goto err;
  858. } else
  859. do {
  860. if ((ret = __bam_c_prev(dbc)) != 0)
  861. goto err;
  862. } while (IS_CUR_DUPLICATE(dbc, orig_pgno, orig_indx));
  863. break;
  864. case DB_SET:
  865. case DB_SET_RECNO:
  866. newopd = 1;
  867. if ((ret = __bam_c_search(dbc,
  868.     PGNO_INVALID, key, flags, &exact)) != 0)
  869. goto err;
  870. break;
  871. case DB_SET_RANGE:
  872. newopd = 1;
  873. if ((ret = __bam_c_search(dbc,
  874.     PGNO_INVALID, key, flags, &exact)) != 0)
  875. goto err;
  876. /*
  877.  * As we didn't require an exact match, the search function
  878.  * may have returned an entry past the end of the page.  Or,
  879.  * we may be referencing a deleted record.  If so, move to
  880.  * the next entry.
  881.  */
  882. if (cp->indx == NUM_ENT(cp->page) || IS_CUR_DELETED(dbc))
  883. if ((ret = __bam_c_next(dbc, 0, 0)) != 0)
  884. goto err;
  885. break;
  886. default:
  887. ret = __db_unknown_flag(dbp->dbenv, "__bam_c_get", flags);
  888. goto err;
  889. }
  890. /*
  891.  * We may have moved to an off-page duplicate tree.  Return that
  892.  * information to our caller.
  893.  */
  894. if (newopd && pgnop != NULL)
  895. (void)__bam_isopd(dbc, pgnop);
  896. /*
  897.  * Don't return the key, it was passed to us (this is true even if the
  898.  * application defines a compare function returning equality for more
  899.  * than one key value, since in that case which actual value we store
  900.  * in the database is undefined -- and particularly true in the case of
  901.  * duplicates where we only store one key value).
  902.  */
  903. if (flags == DB_GET_BOTH ||
  904.     flags == DB_GET_BOTH_RANGE || flags == DB_SET)
  905. F_SET(key, DB_DBT_ISSET);
  906. err: /*
  907.  * Regardless of whether we were successful or not, if the cursor
  908.  * moved, clear the delete flag, DBcursor->c_get never references
  909.  * a deleted key, if it moved at all.
  910.  */
  911. if (F_ISSET(cp, C_DELETED) &&
  912.     (cp->pgno != orig_pgno || cp->indx != orig_indx))
  913. F_CLR(cp, C_DELETED);
  914. return (ret);
  915. }
  916. static int
  917. __bam_get_prev(dbc)
  918. DBC *dbc;
  919. {
  920. BTREE_CURSOR *cp;
  921. DBT key, data;
  922. db_pgno_t pgno;
  923. int ret;
  924. if ((ret = __bam_c_prev(dbc)) != 0)
  925. return (ret);
  926. if (__bam_isopd(dbc, &pgno)) {
  927. cp = (BTREE_CURSOR *)dbc->internal;
  928. if ((ret = __db_c_newopd(dbc, pgno, cp->opd, &cp->opd)) != 0)
  929. return (ret);
  930. if ((ret = cp->opd->c_am_get(cp->opd,
  931.     &key, &data, DB_LAST, NULL)) != 0)
  932. return (ret);
  933. }
  934. return (0);
  935. }
  936. /*
  937.  * __bam_bulk -- Return bulk data from a btree.
  938.  */
  939. static int
  940. __bam_bulk(dbc, data, flags)
  941. DBC *dbc;
  942. DBT *data;
  943. u_int32_t flags;
  944. {
  945. BKEYDATA *bk;
  946. BOVERFLOW *bo;
  947. BTREE_CURSOR *cp;
  948. PAGE *pg;
  949. db_indx_t *inp, indx, pg_keyoff;
  950. int32_t  *endp, key_off, *offp, *saveoffp;
  951. u_int8_t *dbuf, *dp, *np;
  952. u_int32_t key_size, size, space;
  953. int adj, is_key, need_pg, next_key, no_dup;
  954. int pagesize, rec_key, ret;
  955. ret = 0;
  956. key_off = 0;
  957. size = 0;
  958. pagesize = dbc->dbp->pgsize;
  959. cp = (BTREE_CURSOR *)dbc->internal;
  960. /*
  961.  * dp tracks the beginging of the page in the buffer.
  962.  * np is the next place to copy things into the buffer.
  963.  * dbuf always stays at the beging of the buffer.
  964.  */
  965. dbuf = data->data;
  966. np = dp = dbuf;
  967. /* Keep track of space that is left.  There is a termination entry */
  968. space = data->ulen;
  969. space -= sizeof(*offp);
  970. /* Build the offset/size table from the end up. */
  971. endp = (int32_t *)((u_int8_t *)dbuf + data->ulen);
  972. endp--;
  973. offp = endp;
  974. key_size = 0;
  975. /*
  976.  * Distinguish between BTREE and RECNO.
  977.  * There are no keys in RECNO.  If MULTIPLE_KEY is specified
  978.  * then we return the record numbers.
  979.  * is_key indicates that multiple btree keys are returned.
  980.  * rec_key is set if we are returning record numbers.
  981.  * next_key is set if we are going after the next key rather than dup.
  982.  */
  983. if (dbc->dbtype == DB_BTREE) {
  984. is_key = LF_ISSET(DB_MULTIPLE_KEY) ? 1: 0;
  985. rec_key = 0;
  986. next_key = is_key && LF_ISSET(DB_OPFLAGS_MASK) != DB_NEXT_DUP;
  987. adj = 2;
  988. } else {
  989. is_key = 0;
  990. rec_key = LF_ISSET(DB_MULTIPLE_KEY) ? 1 : 0;
  991. next_key = LF_ISSET(DB_OPFLAGS_MASK) != DB_NEXT_DUP;
  992. adj = 1;
  993. }
  994. no_dup = LF_ISSET(DB_OPFLAGS_MASK) == DB_NEXT_NODUP;
  995. next_pg:
  996. indx = cp->indx;
  997. pg = cp->page;
  998. inp = P_INP(dbc->dbp, pg);
  999. /* The current page is not yet in the buffer. */
  1000. need_pg = 1;
  1001. /*
  1002.  * Keep track of the offset of the current key on the page.
  1003.  * If we are returning keys, set it to 0 first so we force
  1004.  * the copy of the key to the buffer.
  1005.  */
  1006. pg_keyoff = 0;
  1007. if (is_key == 0)
  1008. pg_keyoff = inp[indx];
  1009. do {
  1010. if (IS_DELETED(dbc->dbp, pg, indx)) {
  1011. if (dbc->dbtype != DB_RECNO)
  1012. continue;
  1013. cp->recno++;
  1014. /*
  1015.  * If we are not returning recnos then we
  1016.  * need to fill in every slot so the user
  1017.  * can calculate the record numbers.
  1018.  */
  1019. if (rec_key != 0)
  1020. continue;
  1021. space -= 2 * sizeof(*offp);
  1022. /* Check if space as underflowed. */
  1023. if (space > data->ulen)
  1024. goto back_up;
  1025. /* Just mark the empty recno slots. */
  1026. *offp-- = 0;
  1027. *offp-- = 0;
  1028. continue;
  1029. }
  1030. /*
  1031.  * Check to see if we have a new key.
  1032.  * If so, then see if we need to put the
  1033.  * key on the page.  If its already there
  1034.  * then we just point to it.
  1035.  */
  1036. if (is_key && pg_keyoff != inp[indx]) {
  1037. bk = GET_BKEYDATA(dbc->dbp, pg, indx);
  1038. if (B_TYPE(bk->type) == B_OVERFLOW) {
  1039. bo = (BOVERFLOW *)bk;
  1040. size = key_size = bo->tlen;
  1041. if (key_size > space)
  1042. goto get_key_space;
  1043. if ((ret = __bam_bulk_overflow(dbc,
  1044.     bo->tlen, bo->pgno, np)) != 0)
  1045. return (ret);
  1046. space -= key_size;
  1047. key_off = (int32_t)(np - dbuf);
  1048. np += key_size;
  1049. } else {
  1050. if (need_pg) {
  1051. dp = np;
  1052. size = pagesize - HOFFSET(pg);
  1053. if (space < size) {
  1054. get_key_space:
  1055. /* Nothing added, then error. */
  1056. if (offp == endp) {
  1057. data->size =
  1058.     ALIGN(size +
  1059.     pagesize,
  1060.     sizeof(u_int32_t));
  1061. return (ENOMEM);
  1062. }
  1063. /*
  1064.  * We need to back up to the
  1065.  * last record put into the
  1066.  * buffer so that it is
  1067.  * CURRENT.
  1068.  */
  1069. if (indx != 0)
  1070. indx -= P_INDX;
  1071. else {
  1072. if ((ret =
  1073.     __bam_get_prev(
  1074.     dbc)) != 0)
  1075. return (ret);
  1076. indx = cp->indx;
  1077. pg = cp->page;
  1078. }
  1079. break;
  1080. }
  1081. /*
  1082.  * Move the data part of the page
  1083.  * to the buffer.
  1084.  */
  1085. memcpy(dp,
  1086.    (u_int8_t *)pg + HOFFSET(pg), size);
  1087. need_pg = 0;
  1088. space -= size;
  1089. np += size;
  1090. }
  1091. key_size = bk->len;
  1092. key_off = (int32_t)(inp[indx] - HOFFSET(pg)
  1093.     + dp - dbuf + SSZA(BKEYDATA, data));
  1094. pg_keyoff = inp[indx];
  1095. }
  1096. }
  1097. /*
  1098.  * Reserve space for the pointers and sizes.
  1099.  * Either key/data pair or just for a data item.
  1100.  */
  1101. space -= (is_key ? 4 : 2) * sizeof(*offp);
  1102. if (rec_key)
  1103. space -= sizeof(*offp);
  1104. /* Check to see if space has underflowed. */
  1105. if (space > data->ulen)
  1106. goto back_up;
  1107. /*
  1108.  * Determine if the next record is in the
  1109.  * buffer already or if it needs to be copied in.
  1110.  * If we have an off page dup, then copy as many
  1111.  * as will fit into the buffer.
  1112.  */
  1113. bk = GET_BKEYDATA(dbc->dbp, pg, indx + adj - 1);
  1114. if (B_TYPE(bk->type) == B_DUPLICATE) {
  1115. bo = (BOVERFLOW *)bk;
  1116. if (is_key) {
  1117. *offp-- = key_off;
  1118. *offp-- = key_size;
  1119. }
  1120. /*
  1121.  * We pass the offset of the current key.
  1122.  * On return we check to see if offp has
  1123.  * moved to see if any data fit.
  1124.  */
  1125. saveoffp = offp;
  1126. if ((ret = __bam_bulk_duplicates(dbc, bo->pgno,
  1127.     dbuf, is_key ? offp + P_INDX : NULL,
  1128.     &offp, &np, &space, no_dup)) != 0) {
  1129. if (ret == ENOMEM) {
  1130. size = space;
  1131. /* If nothing was added, then error. */
  1132. if (offp == saveoffp) {
  1133. offp += 2;
  1134. goto back_up;
  1135. }
  1136. goto get_space;
  1137. }
  1138. return (ret);
  1139. }
  1140. } else if (B_TYPE(bk->type) == B_OVERFLOW) {
  1141. bo = (BOVERFLOW *)bk;
  1142. size = bo->tlen;
  1143. if (size > space)
  1144. goto back_up;
  1145. if ((ret =
  1146.     __bam_bulk_overflow(dbc,
  1147. bo->tlen, bo->pgno, np)) != 0)
  1148. return (ret);
  1149. space -= size;
  1150. if (is_key) {
  1151. *offp-- = key_off;
  1152. *offp-- = key_size;
  1153. } else if (rec_key)
  1154. *offp-- = cp->recno;
  1155. *offp-- = (int32_t)(np - dbuf);
  1156. np += size;
  1157. *offp-- = size;
  1158. } else {
  1159. if (need_pg) {
  1160. dp = np;
  1161. size = pagesize - HOFFSET(pg);
  1162. if (space < size) {
  1163. back_up:
  1164. /*
  1165.  * Back up the index so that the
  1166.  * last record in the buffer is CURRENT
  1167.  */
  1168. if (indx >= adj)
  1169. indx -= adj;
  1170. else {
  1171. if ((ret =
  1172.     __bam_get_prev(dbc)) != 0 &&
  1173.     ret != DB_NOTFOUND)
  1174. return (ret);
  1175. indx = cp->indx;
  1176. pg = cp->page;
  1177. }
  1178. if (dbc->dbtype == DB_RECNO)
  1179. cp->recno--;
  1180. get_space:
  1181. /*
  1182.  * See if we put anything in the
  1183.  * buffer or if we are doing a DBP->get
  1184.  * did we get all of the data.
  1185.  */
  1186. if (offp >=
  1187.     (is_key ? &endp[-1] : endp) ||
  1188.     F_ISSET(dbc, DBC_TRANSIENT)) {
  1189. data->size = ALIGN(size +
  1190.     data->ulen - space,
  1191.     sizeof(u_int32_t));
  1192. return (ENOMEM);
  1193. }
  1194. break;
  1195. }
  1196. memcpy(dp, (u_int8_t *)pg + HOFFSET(pg), size);
  1197. need_pg = 0;
  1198. space -= size;
  1199. np += size;
  1200. }
  1201. /*
  1202.  * Add the offsets and sizes to the end of the buffer.
  1203.  * First add the key info then the data info.
  1204.  */
  1205. if (is_key) {
  1206. *offp-- = key_off;
  1207. *offp-- = key_size;
  1208. } else if (rec_key)
  1209. *offp-- = cp->recno;
  1210. *offp-- = (int32_t)(inp[indx + adj - 1] - HOFFSET(pg)
  1211.     + dp - dbuf + SSZA(BKEYDATA, data));
  1212. *offp-- = bk->len;
  1213. }
  1214. if (dbc->dbtype == DB_RECNO)
  1215. cp->recno++;
  1216. else if (no_dup) {
  1217. while (indx + adj < NUM_ENT(pg) &&
  1218.     pg_keyoff == inp[indx + adj])
  1219. indx += adj;
  1220. }
  1221. /*
  1222.  * Stop when we either run off the page or we
  1223.  * move to the next key and we are not returning mulitple keys.
  1224.  */
  1225. } while ((indx += adj) < NUM_ENT(pg) &&
  1226.     (next_key || pg_keyoff == inp[indx]));
  1227. /* If we are off the page then try to the next page. */
  1228. if (ret == 0 && next_key && indx >= NUM_ENT(pg)) {
  1229. cp->indx = indx;
  1230. ret = __bam_c_next(dbc, 0, 1);
  1231. if (ret == 0)
  1232. goto next_pg;
  1233. if (ret != DB_NOTFOUND)
  1234. return (ret);
  1235. }
  1236. /*
  1237.  * If we did a DBP->get we must error if we did not return
  1238.  * all the data for the current key because there is
  1239.  * no way to know if we did not get it all, nor any
  1240.  * interface to fetch the balance.
  1241.  */
  1242. if (ret == 0 &&
  1243.     F_ISSET(dbc, DBC_TRANSIENT) && pg_keyoff == inp[indx]) {
  1244. data->size = (data->ulen - space) + size;
  1245. return (ENOMEM);
  1246. }
  1247. /*
  1248.  * Must leave the index pointing at the last record fetched.
  1249.  * If we are not fetching keys, we may have stepped to the
  1250.  * next key.
  1251.  */
  1252. if (next_key || pg_keyoff == inp[indx])
  1253. cp->indx = indx;
  1254. else
  1255. cp->indx = indx - P_INDX;
  1256. if (rec_key == 1)
  1257. *offp = (u_int32_t) RECNO_OOB;
  1258. else
  1259. *offp = (u_int32_t) -1;
  1260. return (0);
  1261. }
  1262. /*
  1263.  * __bam_bulk_overflow --
  1264.  * Dump overflow record into the buffer.
  1265.  * The space requirements have already been checked.
  1266.  * PUBLIC: int __bam_bulk_overflow
  1267.  * PUBLIC:    __P((DBC *, u_int32_t, db_pgno_t, u_int8_t *));
  1268.  */
  1269. int
  1270. __bam_bulk_overflow(dbc, len, pgno, dp)
  1271. DBC *dbc;
  1272. u_int32_t len;
  1273. db_pgno_t pgno;
  1274. u_int8_t *dp;
  1275. {
  1276. DBT dbt;
  1277. memset(&dbt, 0, sizeof(dbt));
  1278. F_SET(&dbt, DB_DBT_USERMEM);
  1279. dbt.ulen = len;
  1280. dbt.data = (void *)dp;
  1281. return (__db_goff(dbc->dbp, &dbt, len, pgno, NULL, NULL));
  1282. }
  1283. /*
  1284.  * __bam_bulk_duplicates --
  1285.  * Put as many off page duplicates as will fit into the buffer.
  1286.  * This routine will adjust the cursor to reflect the position in
  1287.  * the overflow tree.
  1288.  * PUBLIC: int __bam_bulk_duplicates __P((DBC *,
  1289.  * PUBLIC:       db_pgno_t, u_int8_t *, int32_t *,
  1290.  * PUBLIC:  int32_t **, u_int8_t **, u_int32_t *, int));
  1291.  */
  1292. int
  1293. __bam_bulk_duplicates(dbc, pgno, dbuf, keyoff, offpp, dpp, spacep, no_dup)
  1294. DBC *dbc;
  1295. db_pgno_t pgno;
  1296. u_int8_t *dbuf;
  1297. int32_t *keyoff, **offpp;
  1298. u_int8_t **dpp;
  1299. u_int32_t *spacep;
  1300. int no_dup;
  1301. {
  1302. DB *dbp;
  1303. BKEYDATA *bk;
  1304. BOVERFLOW *bo;
  1305. BTREE_CURSOR *cp;
  1306. DBC *opd;
  1307. DBT key, data;
  1308. PAGE *pg;
  1309. db_indx_t indx, *inp;
  1310. int32_t *offp;
  1311. u_int32_t size, space;
  1312. u_int8_t *dp, *np;
  1313. int first, need_pg, pagesize, ret, t_ret;
  1314. ret = 0;
  1315. dbp = dbc->dbp;
  1316. cp = (BTREE_CURSOR *)dbc->internal;
  1317. opd = cp->opd;
  1318. if (opd == NULL) {
  1319. if ((ret = __db_c_newopd(dbc, pgno, NULL, &opd)) != 0)
  1320. return (ret);
  1321. cp->opd = opd;
  1322. if ((ret = opd->c_am_get(opd,
  1323.     &key, &data, DB_FIRST, NULL)) != 0)
  1324. return (ret);
  1325. }
  1326. pagesize = opd->dbp->pgsize;
  1327. cp = (BTREE_CURSOR *)opd->internal;
  1328. space = *spacep;
  1329. /* Get current offset slot. */
  1330. offp = *offpp;
  1331. /*
  1332.  * np is the next place to put data.
  1333.  * dp is the begining of the current page in the buffer.
  1334.  */
  1335. np = dp = *dpp;
  1336. first = 1;
  1337. indx = cp->indx;
  1338. do {
  1339. /* Fetch the current record.  No initial move. */
  1340. if ((ret = __bam_c_next(opd, 0, 0)) != 0)
  1341. break;
  1342. pg = cp->page;
  1343. indx = cp->indx;
  1344. inp = P_INP(dbp, pg);
  1345. /* We need to copy the page to the buffer. */
  1346. need_pg = 1;
  1347. do {
  1348. if (IS_DELETED(dbp, pg, indx))
  1349. goto contin;
  1350. bk = GET_BKEYDATA(dbp, pg, indx);
  1351. space -= 2 * sizeof(*offp);
  1352. /* Allocate space for key if needed. */
  1353. if (first == 0 && keyoff != NULL)
  1354. space -= 2 * sizeof(*offp);
  1355. /* Did space underflow? */
  1356. if (space > *spacep) {
  1357. ret = ENOMEM;
  1358. if (first == 1) {
  1359. space = *spacep + -(int32_t)space;
  1360. if (need_pg)
  1361. space += pagesize - HOFFSET(pg);
  1362. }
  1363. break;
  1364. }
  1365. if (B_TYPE(bk->type) == B_OVERFLOW) {
  1366. bo = (BOVERFLOW *)bk;
  1367. size = bo->tlen;
  1368. if (size > space) {
  1369. ret = ENOMEM;
  1370. if (first == 1) {
  1371. space = *spacep + size;
  1372. }
  1373. break;
  1374. }
  1375. if (first == 0 && keyoff != NULL) {
  1376. *offp-- = keyoff[0];
  1377. *offp-- = keyoff[-1];
  1378. }
  1379. if ((ret = __bam_bulk_overflow(dbc,
  1380.     bo->tlen, bo->pgno, np)) != 0)
  1381. return (ret);
  1382. space -= size;
  1383. *offp-- = (int32_t)(np - dbuf);
  1384. np += size;
  1385. } else {
  1386. if (need_pg) {
  1387. dp = np;
  1388. size = pagesize - HOFFSET(pg);
  1389. if (space < size) {
  1390. ret = ENOMEM;
  1391. /* Return space required. */
  1392. if (first == 1) {
  1393. space = *spacep + size;
  1394. }
  1395. break;
  1396. }
  1397. memcpy(dp,
  1398.     (u_int8_t *)pg + HOFFSET(pg), size);
  1399. need_pg = 0;
  1400. space -= size;
  1401. np += size;
  1402. }
  1403. if (first == 0 && keyoff != NULL) {
  1404. *offp-- = keyoff[0];
  1405. *offp-- = keyoff[-1];
  1406. }
  1407. size = bk->len;
  1408. *offp-- = (int32_t)(inp[indx] - HOFFSET(pg)
  1409.     + dp - dbuf + SSZA(BKEYDATA, data));
  1410. }
  1411. *offp-- = size;
  1412. first = 0;
  1413. if (no_dup)
  1414. break;
  1415. contin:
  1416. indx++;
  1417. if (opd->dbtype == DB_RECNO)
  1418. cp->recno++;
  1419. } while (indx < NUM_ENT(pg));
  1420. if (no_dup)
  1421. break;
  1422. cp->indx = indx;
  1423. } while (ret == 0);
  1424. /* Return the updated information. */
  1425. *spacep = space;
  1426. *offpp = offp;
  1427. *dpp = np;
  1428. /*
  1429.  * If we ran out of space back up the pointer.
  1430.  * If we did not return any dups or reached the end, close the opd.
  1431.  */
  1432. if (ret == ENOMEM) {
  1433. if (opd->dbtype == DB_RECNO) {
  1434. if (--cp->recno == 0)
  1435. goto close_opd;
  1436. } else if (indx != 0)
  1437. cp->indx--;
  1438. else {
  1439. t_ret = __bam_c_prev(opd);
  1440. if (t_ret == DB_NOTFOUND)
  1441. goto close_opd;
  1442. if (t_ret != 0)
  1443. ret = t_ret;
  1444. }
  1445. } else if (keyoff == NULL && ret == DB_NOTFOUND) {
  1446. cp->indx--;
  1447. if (opd->dbtype == DB_RECNO)
  1448. --cp->recno;
  1449. } else if (indx == 0 || ret == DB_NOTFOUND) {
  1450. close_opd:
  1451. opd->c_close(opd);
  1452. ((BTREE_CURSOR *)dbc->internal)->opd = NULL;
  1453. }
  1454. if (ret == DB_NOTFOUND)
  1455. ret = 0;
  1456. return (ret);
  1457. }
  1458. /*
  1459.  * __bam_getbothc --
  1460.  * Search for a matching data item on a join.
  1461.  */
  1462. static int
  1463. __bam_getbothc(dbc, data)
  1464. DBC *dbc;
  1465. DBT *data;
  1466. {
  1467. BTREE_CURSOR *cp;
  1468. DB *dbp;
  1469. DB_MPOOLFILE *mpf;
  1470. int cmp, exact, ret;
  1471. dbp = dbc->dbp;
  1472. mpf = dbp->mpf;
  1473. cp = (BTREE_CURSOR *)dbc->internal;
  1474. /*
  1475.  * Acquire the current page.  We have at least a read-lock
  1476.  * already.  The caller may have set DB_RMW asking for a
  1477.  * write lock, but upgrading to a write lock has no better
  1478.  * chance of succeeding now instead of later, so don't try.
  1479.  */
  1480. if ((ret = mpf->get(mpf, &cp->pgno, 0, &cp->page)) != 0)
  1481. return (ret);
  1482. /*
  1483.  * An off-page duplicate cursor.  Search the remaining duplicates
  1484.  * for one which matches (do a normal btree search, then verify
  1485.  * that the retrieved record is greater than the original one).
  1486.  */
  1487. if (F_ISSET(dbc, DBC_OPD)) {
  1488. /*
  1489.  * Check to make sure the desired item comes strictly after
  1490.  * the current position;  if it doesn't, return DB_NOTFOUND.
  1491.  */
  1492. if ((ret = __bam_cmp(dbp, data, cp->page, cp->indx,
  1493.     dbp->dup_compare == NULL ? __bam_defcmp : dbp->dup_compare,
  1494.     &cmp)) != 0)
  1495. return (ret);
  1496. if (cmp <= 0)
  1497. return (DB_NOTFOUND);
  1498. /* Discard the current page, we're going to do a full search. */
  1499. if ((ret = mpf->put(mpf, cp->page, 0)) != 0)
  1500. return (ret);
  1501. cp->page = NULL;
  1502. return (__bam_c_search(dbc,
  1503.     PGNO_INVALID, data, DB_GET_BOTH, &exact));
  1504. }
  1505. /*
  1506.  * We're doing a DBC->c_get(DB_GET_BOTHC) and we're already searching
  1507.  * a set of on-page duplicates (either sorted or unsorted).  Continue
  1508.  * a linear search from after the current position.
  1509.  *
  1510.  * (Note that we could have just finished a "set" of one duplicate,
  1511.  * i.e. not a duplicate at all, but the following check will always
  1512.  * return DB_NOTFOUND in this case, which is the desired behavior.)
  1513.  */
  1514. if (cp->indx + P_INDX >= NUM_ENT(cp->page) ||
  1515.     !IS_DUPLICATE(dbc, cp->indx, cp->indx + P_INDX))
  1516. return (DB_NOTFOUND);
  1517. cp->indx += P_INDX;
  1518. return (__bam_getboth_finddatum(dbc, data, DB_GET_BOTH));
  1519. }
  1520. /*
  1521.  * __bam_getboth_finddatum --
  1522.  * Find a matching on-page data item.
  1523.  */
  1524. static int
  1525. __bam_getboth_finddatum(dbc, data, flags)
  1526. DBC *dbc;
  1527. DBT *data;
  1528. u_int32_t flags;
  1529. {
  1530. BTREE_CURSOR *cp;
  1531. DB *dbp;
  1532. db_indx_t base, lim, top;
  1533. int cmp, ret;
  1534. dbp = dbc->dbp;
  1535. cp = (BTREE_CURSOR *)dbc->internal;
  1536. /*
  1537.  * Called (sometimes indirectly) from DBC->get to search on-page data
  1538.  * item(s) for a matching value.  If the original flag was DB_GET_BOTH
  1539.  * or DB_GET_BOTH_RANGE, the cursor is set to the first undeleted data
  1540.  * item for the key.  If the original flag was DB_GET_BOTHC, the cursor
  1541.  * argument is set to the first data item we can potentially return.
  1542.  * In both cases, there may or may not be additional duplicate data
  1543.  * items to search.
  1544.  *
  1545.  * If the duplicates are not sorted, do a linear search.
  1546.  */
  1547. if (dbp->dup_compare == NULL) {
  1548. for (;; cp->indx += P_INDX) {
  1549. if (!IS_CUR_DELETED(dbc) &&
  1550.     (ret = __bam_cmp(dbp, data, cp->page,
  1551.     cp->indx + O_INDX, __bam_defcmp, &cmp)) != 0)
  1552. return (ret);
  1553. if (cmp == 0)
  1554. return (0);
  1555. if (cp->indx + P_INDX >= NUM_ENT(cp->page) ||
  1556.     !IS_DUPLICATE(dbc, cp->indx, cp->indx + P_INDX))
  1557. break;
  1558. }
  1559. return (DB_NOTFOUND);
  1560. }
  1561. /*
  1562.  * If the duplicates are sorted, do a binary search.  The reason for
  1563.  * this is that large pages and small key/data pairs result in large
  1564.  * numbers of on-page duplicates before they get pushed off-page.
  1565.  *
  1566.  * Find the top and bottom of the duplicate set.  Binary search
  1567.  * requires at least two items, don't loop if there's only one.
  1568.  */
  1569. for (base = top = cp->indx; top < NUM_ENT(cp->page); top += P_INDX)
  1570. if (!IS_DUPLICATE(dbc, cp->indx, top))
  1571. break;
  1572. if (base == (top - P_INDX)) {
  1573. if  ((ret = __bam_cmp(dbp, data,
  1574.     cp->page, cp->indx + O_INDX, dbp->dup_compare, &cmp)) != 0)
  1575. return (ret);
  1576. return (cmp == 0 ||
  1577.     (cmp < 0 && flags == DB_GET_BOTH_RANGE) ? 0 : DB_NOTFOUND);
  1578. }
  1579. for (lim = (top - base) / (db_indx_t)P_INDX; lim != 0; lim >>= 1) {
  1580. cp->indx = base + ((lim >> 1) * P_INDX);
  1581. if ((ret = __bam_cmp(dbp, data, cp->page,
  1582.     cp->indx + O_INDX, dbp->dup_compare, &cmp)) != 0)
  1583. return (ret);
  1584. if (cmp == 0) {
  1585. /*
  1586.  * XXX
  1587.  * No duplicate duplicates in sorted duplicate sets,
  1588.  * so there can be only one.
  1589.  */
  1590. if (!IS_CUR_DELETED(dbc))
  1591. return (0);
  1592. break;
  1593. }
  1594. if (cmp > 0) {
  1595. base = cp->indx + P_INDX;
  1596. --lim;
  1597. }
  1598. }
  1599. /* No match found; if we're looking for an exact match, we're done. */
  1600. if (flags == DB_GET_BOTH)
  1601. return (DB_NOTFOUND);
  1602. /*
  1603.  * Base is the smallest index greater than the data item, may be zero
  1604.  * or a last + O_INDX index, and may be deleted.  Find an undeleted
  1605.  * item.
  1606.  */
  1607. cp->indx = base;
  1608. while (cp->indx < top && IS_CUR_DELETED(dbc))
  1609. cp->indx += P_INDX;
  1610. return (cp->indx < top ? 0 : DB_NOTFOUND);
  1611. }
  1612. /*
  1613.  * __bam_c_put --
  1614.  * Put using a cursor.
  1615.  */
  1616. static int
  1617. __bam_c_put(dbc, key, data, flags, pgnop)
  1618. DBC *dbc;
  1619. DBT *key, *data;
  1620. u_int32_t flags;
  1621. db_pgno_t *pgnop;
  1622. {
  1623. BTREE_CURSOR *cp;
  1624. DB *dbp;
  1625. DBT dbt;
  1626. DB_MPOOLFILE *mpf;
  1627. db_pgno_t root_pgno;
  1628. u_int32_t iiop;
  1629. int cmp, exact, ret, stack;
  1630. void *arg;
  1631. dbp = dbc->dbp;
  1632. mpf = dbp->mpf;
  1633. cp = (BTREE_CURSOR *)dbc->internal;
  1634. root_pgno = cp->root;
  1635. split: ret = stack = 0;
  1636. switch (flags) {
  1637. case DB_AFTER:
  1638. case DB_BEFORE:
  1639. case DB_CURRENT:
  1640. iiop = flags;
  1641. /*
  1642.  * If the Btree has record numbers (and we're not replacing an
  1643.  * existing record), we need a complete stack so that we can
  1644.  * adjust the record counts.  The check for flags == DB_CURRENT
  1645.  * is superfluous but left in for clarity.  (If C_RECNUM is set
  1646.  * we know that flags must be DB_CURRENT, as DB_AFTER/DB_BEFORE
  1647.  * are illegal in a Btree unless it's configured for duplicates
  1648.  * and you cannot configure a Btree for both record renumbering
  1649.  * and duplicates.)
  1650.  */
  1651. if (flags == DB_CURRENT &&
  1652.     F_ISSET(cp, C_RECNUM) && F_ISSET(cp, C_DELETED)) {
  1653. if ((ret = __bam_c_getstack(dbc)) != 0)
  1654. goto err;
  1655. /*
  1656.  * Initialize the cursor from the stack.  Don't take
  1657.  * the page number or page index, they should already
  1658.  * be set.
  1659.  */
  1660. cp->page = cp->csp->page;
  1661. cp->lock = cp->csp->lock;
  1662. cp->lock_mode = cp->csp->lock_mode;
  1663. stack = 1;
  1664. break;
  1665. }
  1666. /* Acquire the current page with a write lock. */
  1667. ACQUIRE_WRITE_LOCK(dbc, ret);
  1668. if (ret != 0)
  1669. goto err;
  1670. if ((ret = mpf->get(mpf, &cp->pgno, 0, &cp->page)) != 0)
  1671. goto err;
  1672. break;
  1673. case DB_KEYFIRST:
  1674. case DB_KEYLAST:
  1675. case DB_NODUPDATA:
  1676. /*
  1677.  * Searching off-page, sorted duplicate tree: do a tree search
  1678.  * for the correct item; __bam_c_search returns the smallest
  1679.  * slot greater than the key, use it.
  1680.  *
  1681.  * See comment below regarding where we can start the search.
  1682.  */
  1683. if (F_ISSET(dbc, DBC_OPD)) {
  1684. if ((ret = __bam_c_search(dbc,
  1685.     F_ISSET(cp, C_RECNUM) ? cp->root : root_pgno,
  1686.     data, flags, &exact)) != 0)
  1687. goto err;
  1688. stack = 1;
  1689. /* Disallow "sorted" duplicate duplicates. */
  1690. if (exact) {
  1691. if (IS_DELETED(dbp, cp->page, cp->indx)) {
  1692. iiop = DB_CURRENT;
  1693. break;
  1694. }
  1695. ret = __db_duperr(dbp, flags);
  1696. goto err;
  1697. }
  1698. iiop = DB_BEFORE;
  1699. break;
  1700. }
  1701. /*
  1702.  * Searching a btree.
  1703.  *
  1704.  * If we've done a split, we can start the search from the
  1705.  * parent of the split page, which __bam_split returned
  1706.  * for us in root_pgno, unless we're in a Btree with record
  1707.  * numbering.  In that case, we'll need the true root page
  1708.  * in order to adjust the record count.
  1709.  */
  1710. if ((ret = __bam_c_search(dbc,
  1711.     F_ISSET(cp, C_RECNUM) ? cp->root : root_pgno, key,
  1712.     flags == DB_KEYFIRST || dbp->dup_compare != NULL ?
  1713.     DB_KEYFIRST : DB_KEYLAST, &exact)) != 0)
  1714. goto err;
  1715. stack = 1;
  1716. /*
  1717.  * If we don't have an exact match, __bam_c_search returned
  1718.  * the smallest slot greater than the key, use it.
  1719.  */
  1720. if (!exact) {
  1721. iiop = DB_KEYFIRST;
  1722. break;
  1723. }
  1724. /*
  1725.  * If duplicates aren't supported, replace the current item.
  1726.  * (If implementing the DB->put function, our caller already
  1727.  * checked the DB_NOOVERWRITE flag.)
  1728.  */
  1729. if (!F_ISSET(dbp, DB_AM_DUP)) {
  1730. iiop = DB_CURRENT;
  1731. break;
  1732. }
  1733. /*
  1734.  * If we find a matching entry, it may be an off-page duplicate
  1735.  * tree.  Return the page number to our caller, we need a new
  1736.  * cursor.
  1737.  */
  1738. if (pgnop != NULL && __bam_isopd(dbc, pgnop))
  1739. goto done;
  1740. /* If the duplicates aren't sorted, move to the right slot. */
  1741. if (dbp->dup_compare == NULL) {
  1742. if (flags == DB_KEYFIRST)
  1743. iiop = DB_BEFORE;
  1744. else
  1745. for (;; cp->indx += P_INDX)
  1746. if (cp->indx + P_INDX >=
  1747.     NUM_ENT(cp->page) ||
  1748.     !IS_DUPLICATE(dbc, cp->indx,
  1749.     cp->indx + P_INDX)) {
  1750. iiop = DB_AFTER;
  1751. break;
  1752. }
  1753. break;
  1754. }
  1755. /*
  1756.  * We know that we're looking at the first of a set of sorted
  1757.  * on-page duplicates.  Walk the list to find the right slot.
  1758.  */
  1759. for (;; cp->indx += P_INDX) {
  1760. if ((ret = __bam_cmp(dbp, data, cp->page,
  1761.     cp->indx + O_INDX, dbp->dup_compare, &cmp)) != 0)
  1762. goto err;
  1763. if (cmp < 0) {
  1764. iiop = DB_BEFORE;
  1765. break;
  1766. }
  1767. /* Disallow "sorted" duplicate duplicates. */
  1768. if (cmp == 0) {
  1769. if (IS_DELETED(dbp, cp->page, cp->indx)) {
  1770. iiop = DB_CURRENT;
  1771. break;
  1772. }
  1773. ret = __db_duperr(dbp, flags);
  1774. goto err;
  1775. }
  1776. if (cp->indx + P_INDX >= NUM_ENT(cp->page) ||
  1777.     P_INP(dbp, ((PAGE *)cp->page))[cp->indx] !=
  1778.     P_INP(dbp, ((PAGE *)cp->page))[cp->indx + P_INDX]) {
  1779. iiop = DB_AFTER;
  1780. break;
  1781. }
  1782. }
  1783. break;
  1784. default:
  1785. ret = __db_unknown_flag(dbp->dbenv, "__bam_c_put", flags);
  1786. goto err;
  1787. }
  1788. switch (ret = __bam_iitem(dbc, key, data, iiop, 0)) {
  1789. case 0:
  1790. break;
  1791. case DB_NEEDSPLIT:
  1792. /*
  1793.  * To split, we need a key for the page.  Either use the key
  1794.  * argument or get a copy of the key from the page.
  1795.  */
  1796. if (flags == DB_AFTER ||
  1797.     flags == DB_BEFORE || flags == DB_CURRENT) {
  1798. memset(&dbt, 0, sizeof(DBT));
  1799. if ((ret = __db_ret(dbp, cp->page, 0, &dbt,
  1800.     &dbc->rkey->data, &dbc->rkey->ulen)) != 0)
  1801. goto err;
  1802. arg = &dbt;
  1803. } else
  1804. arg = F_ISSET(dbc, DBC_OPD) ? data : key;
  1805. /*
  1806.  * Discard any locks and pinned pages (the locks are discarded
  1807.  * even if we're running with transactions, as they lock pages
  1808.  * that we're sorry we ever acquired).  If stack is set and the
  1809.  * cursor entries are valid, they point to the same entries as
  1810.  * the stack, don't free them twice.
  1811.  */
  1812. if (stack)
  1813. ret = __bam_stkrel(dbc, STK_CLRDBC | STK_NOLOCK);
  1814. else
  1815. DISCARD_CUR(dbc, ret);
  1816. if (ret != 0)
  1817. goto err;
  1818. /* Split the tree. */
  1819. if ((ret = __bam_split(dbc, arg, &root_pgno)) != 0)
  1820. return (ret);
  1821. goto split;
  1822. default:
  1823. goto err;
  1824. }
  1825. err:
  1826. done: /*
  1827.  * Discard any pages pinned in the tree and their locks, except for
  1828.  * the leaf page.  Note, the leaf page participated in any stack we
  1829.  * acquired, and so we have to adjust the stack as necessary.  If
  1830.  * there was only a single page on the stack, we don't have to free
  1831.  * further stack pages.
  1832.  */
  1833. if (stack && BT_STK_POP(cp) != NULL)
  1834. (void)__bam_stkrel(dbc, 0);
  1835. /*
  1836.  * Regardless of whether we were successful or not, clear the delete
  1837.  * flag.  If we're successful, we either moved the cursor or the item
  1838.  * is no longer deleted.  If we're not successful, then we're just a
  1839.  * copy, no need to have the flag set.
  1840.  */
  1841. F_CLR(cp, C_DELETED);
  1842. return (ret);
  1843. }
  1844. /*
  1845.  * __bam_c_rget --
  1846.  * Return the record number for a cursor.
  1847.  *
  1848.  * PUBLIC: int __bam_c_rget __P((DBC *, DBT *));
  1849.  */
  1850. int
  1851. __bam_c_rget(dbc, data)
  1852. DBC *dbc;
  1853. DBT *data;
  1854. {
  1855. BTREE_CURSOR *cp;
  1856. DB *dbp;
  1857. DBT dbt;
  1858. DB_MPOOLFILE *mpf;
  1859. db_recno_t recno;
  1860. int exact, ret;
  1861. dbp = dbc->dbp;
  1862. mpf = dbp->mpf;
  1863. cp = (BTREE_CURSOR *)dbc->internal;
  1864. /*
  1865.  * Get the page with the current item on it.
  1866.  * Get a copy of the key.
  1867.  * Release the page, making sure we don't release it twice.
  1868.  */
  1869. if ((ret = mpf->get(mpf, &cp->pgno, 0, &cp->page)) != 0)
  1870. return (ret);
  1871. memset(&dbt, 0, sizeof(DBT));
  1872. if ((ret = __db_ret(dbp, cp->page,
  1873.     cp->indx, &dbt, &dbc->rkey->data, &dbc->rkey->ulen)) != 0)
  1874. goto err;
  1875. ret = mpf->put(mpf, cp->page, 0);
  1876. cp->page = NULL;
  1877. if (ret != 0)
  1878. return (ret);
  1879. if ((ret = __bam_search(dbc, PGNO_INVALID, &dbt,
  1880.     F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND,
  1881.     1, &recno, &exact)) != 0)
  1882. goto err;
  1883. ret = __db_retcopy(dbp->dbenv, data,
  1884.     &recno, sizeof(recno), &dbc->rdata->data, &dbc->rdata->ulen);
  1885. /* Release the stack. */
  1886. err: __bam_stkrel(dbc, 0);
  1887. return (ret);
  1888. }
  1889. /*
  1890.  * __bam_c_writelock --
  1891.  * Upgrade the cursor to a write lock.
  1892.  */
  1893. static int
  1894. __bam_c_writelock(dbc)
  1895. DBC *dbc;
  1896. {
  1897. BTREE_CURSOR *cp;
  1898. int ret;
  1899. cp = (BTREE_CURSOR *)dbc->internal;
  1900. if (cp->lock_mode == DB_LOCK_WRITE)
  1901. return (0);
  1902. /*
  1903.  * When writing to an off-page duplicate tree, we need to have the
  1904.  * appropriate page in the primary tree locked.  The general DBC
  1905.  * code calls us first with the primary cursor so we can acquire the
  1906.  * appropriate lock.
  1907.  */
  1908. ACQUIRE_WRITE_LOCK(dbc, ret);
  1909. return (ret);
  1910. }
  1911. /*
  1912.  * __bam_c_first --
  1913.  * Return the first record.
  1914.  */
  1915. static int
  1916. __bam_c_first(dbc)
  1917. DBC *dbc;
  1918. {
  1919. BTREE_CURSOR *cp;
  1920. db_pgno_t pgno;
  1921. int ret;
  1922. cp = (BTREE_CURSOR *)dbc->internal;
  1923. ret = 0;
  1924. /* Walk down the left-hand side of the tree. */
  1925. for (pgno = cp->root;;) {
  1926. ACQUIRE_CUR_COUPLE(dbc, DB_LOCK_READ, pgno, ret);
  1927. if (ret != 0)
  1928. return (ret);
  1929. /* If we find a leaf page, we're done. */
  1930. if (ISLEAF(cp->page))
  1931. break;
  1932. pgno = GET_BINTERNAL(dbc->dbp, cp->page, 0)->pgno;
  1933. }
  1934. /* If we want a write lock instead of a read lock, get it now. */
  1935. if (F_ISSET(dbc, DBC_RMW)) {
  1936. ACQUIRE_WRITE_LOCK(dbc, ret);
  1937. if (ret != 0)
  1938. return (ret);
  1939. }
  1940. cp->indx = 0;
  1941. /* If on an empty page or a deleted record, move to the next one. */
  1942. if (NUM_ENT(cp->page) == 0 || IS_CUR_DELETED(dbc))
  1943. if ((ret = __bam_c_next(dbc, 0, 0)) != 0)
  1944. return (ret);
  1945. return (0);
  1946. }
  1947. /*
  1948.  * __bam_c_last --
  1949.  * Return the last record.
  1950.  */
  1951. static int
  1952. __bam_c_last(dbc)
  1953. DBC *dbc;
  1954. {
  1955. BTREE_CURSOR *cp;
  1956. db_pgno_t pgno;
  1957. int ret;
  1958. cp = (BTREE_CURSOR *)dbc->internal;
  1959. ret = 0;
  1960. /* Walk down the right-hand side of the tree. */
  1961. for (pgno = cp->root;;) {
  1962. ACQUIRE_CUR_COUPLE(dbc, DB_LOCK_READ, pgno, ret);
  1963. if (ret != 0)
  1964. return (ret);
  1965. /* If we find a leaf page, we're done. */
  1966. if (ISLEAF(cp->page))
  1967. break;
  1968. pgno = GET_BINTERNAL(dbc->dbp, cp->page,
  1969.     NUM_ENT(cp->page) - O_INDX)->pgno;
  1970. }
  1971. /* If we want a write lock instead of a read lock, get it now. */
  1972. if (F_ISSET(dbc, DBC_RMW)) {
  1973. ACQUIRE_WRITE_LOCK(dbc, ret);
  1974. if (ret != 0)
  1975. return (ret);
  1976. }
  1977. cp->indx = NUM_ENT(cp->page) == 0 ? 0 :
  1978.     NUM_ENT(cp->page) -
  1979.     (TYPE(cp->page) == P_LBTREE ? P_INDX : O_INDX);
  1980. /* If on an empty page or a deleted record, move to the previous one. */
  1981. if (NUM_ENT(cp->page) == 0 || IS_CUR_DELETED(dbc))
  1982. if ((ret = __bam_c_prev(dbc)) != 0)
  1983. return (ret);
  1984. return (0);
  1985. }
  1986. /*
  1987.  * __bam_c_next --
  1988.  * Move to the next record.
  1989.  */
  1990. static int
  1991. __bam_c_next(dbc, initial_move, deleted_okay)
  1992. DBC *dbc;
  1993. int initial_move, deleted_okay;
  1994. {
  1995. BTREE_CURSOR *cp;
  1996. db_indx_t adjust;
  1997. db_lockmode_t lock_mode;
  1998. db_pgno_t pgno;
  1999. int ret;
  2000. cp = (BTREE_CURSOR *)dbc->internal;
  2001. ret = 0;
  2002. /*
  2003.  * We're either moving through a page of duplicates or a btree leaf
  2004.  * page.
  2005.  *
  2006.  * !!!
  2007.  * This code handles empty pages and pages with only deleted entries.
  2008.  */
  2009. if (F_ISSET(dbc, DBC_OPD)) {
  2010. adjust = O_INDX;
  2011. lock_mode = DB_LOCK_NG;
  2012. } else {
  2013. adjust = dbc->dbtype == DB_BTREE ? P_INDX : O_INDX;
  2014. lock_mode =
  2015.     F_ISSET(dbc, DBC_RMW) ? DB_LOCK_WRITE : DB_LOCK_READ;
  2016. }
  2017. if (cp->page == NULL) {
  2018. ACQUIRE_CUR(dbc, lock_mode, cp->pgno, ret);
  2019. if (ret != 0)
  2020. return (ret);
  2021. }
  2022. if (initial_move)
  2023. cp->indx += adjust;
  2024. for (;;) {
  2025. /*
  2026.  * If at the end of the page, move to a subsequent page.
  2027.  *
  2028.  * !!!
  2029.  * Check for >= NUM_ENT.  If the original search landed us on
  2030.  * NUM_ENT, we may have incremented indx before the test.
  2031.  */
  2032. if (cp->indx >= NUM_ENT(cp->page)) {
  2033. if ((pgno
  2034.     = NEXT_PGNO(cp->page)) == PGNO_INVALID)
  2035. return (DB_NOTFOUND);
  2036. ACQUIRE_CUR(dbc, lock_mode, pgno, ret);
  2037. if (ret != 0)
  2038. return (ret);
  2039. cp->indx = 0;
  2040. continue;
  2041. }
  2042. if (!deleted_okay && IS_CUR_DELETED(dbc)) {
  2043. cp->indx += adjust;
  2044. continue;
  2045. }
  2046. break;
  2047. }
  2048. return (0);
  2049. }
  2050. /*
  2051.  * __bam_c_prev --
  2052.  * Move to the previous record.
  2053.  */
  2054. static int
  2055. __bam_c_prev(dbc)
  2056. DBC *dbc;
  2057. {
  2058. BTREE_CURSOR *cp;
  2059. db_indx_t adjust;
  2060. db_lockmode_t lock_mode;
  2061. db_pgno_t pgno;
  2062. int ret;
  2063. cp = (BTREE_CURSOR *)dbc->internal;
  2064. ret = 0;
  2065. /*
  2066.  * We're either moving through a page of duplicates or a btree leaf
  2067.  * page.
  2068.  *
  2069.  * !!!
  2070.  * This code handles empty pages and pages with only deleted entries.
  2071.  */
  2072. if (F_ISSET(dbc, DBC_OPD)) {
  2073. adjust = O_INDX;
  2074. lock_mode = DB_LOCK_NG;
  2075. } else {
  2076. adjust = dbc->dbtype == DB_BTREE ? P_INDX : O_INDX;
  2077. lock_mode =
  2078.     F_ISSET(dbc, DBC_RMW) ? DB_LOCK_WRITE : DB_LOCK_READ;
  2079. }
  2080. if (cp->page == NULL) {
  2081. ACQUIRE_CUR(dbc, lock_mode, cp->pgno, ret);
  2082. if (ret != 0)
  2083. return (ret);
  2084. }
  2085. for (;;) {
  2086. /* If at the beginning of the page, move to a previous one. */
  2087. if (cp->indx == 0) {
  2088. if ((pgno =
  2089.     PREV_PGNO(cp->page)) == PGNO_INVALID)
  2090. return (DB_NOTFOUND);
  2091. ACQUIRE_CUR(dbc, lock_mode, pgno, ret);
  2092. if (ret != 0)
  2093. return (ret);
  2094. if ((cp->indx = NUM_ENT(cp->page)) == 0)
  2095. continue;
  2096. }
  2097. /* Ignore deleted records. */
  2098. cp->indx -= adjust;
  2099. if (IS_CUR_DELETED(dbc))
  2100. continue;
  2101. break;
  2102. }
  2103. return (0);
  2104. }
  2105. /*
  2106.  * __bam_c_search --
  2107.  * Move to a specified record.
  2108.  */
  2109. static int
  2110. __bam_c_search(dbc, root_pgno, key, flags, exactp)
  2111. DBC *dbc;
  2112. db_pgno_t root_pgno;
  2113. const DBT *key;
  2114. u_int32_t flags;
  2115. int *exactp;
  2116. {
  2117. BTREE *t;
  2118. BTREE_CURSOR *cp;
  2119. DB *dbp;
  2120. PAGE *h;
  2121. db_indx_t indx, *inp;
  2122. db_pgno_t bt_lpgno;
  2123. db_recno_t recno;
  2124. u_int32_t sflags;
  2125. int cmp, ret;
  2126. dbp = dbc->dbp;
  2127. cp = (BTREE_CURSOR *)dbc->internal;
  2128. t = dbp->bt_internal;
  2129. ret = 0;
  2130. /*
  2131.  * Find an entry in the database.  Discard any lock we currently hold,
  2132.  * we're going to search the tree.
  2133.  */
  2134. DISCARD_CUR(dbc, ret);
  2135. if (ret != 0)
  2136. return (ret);
  2137. switch (flags) {
  2138. case DB_SET_RECNO:
  2139. if ((ret = __ram_getno(dbc, key, &recno, 0)) != 0)
  2140. return (ret);
  2141. sflags = (F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND) | S_EXACT;
  2142. if ((ret = __bam_rsearch(dbc, &recno, sflags, 1, exactp)) != 0)
  2143. return (ret);
  2144. break;
  2145. case DB_SET:
  2146. case DB_GET_BOTH:
  2147. sflags = (F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND) | S_EXACT;
  2148. goto search;
  2149. case DB_GET_BOTH_RANGE:
  2150. sflags = (F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND);
  2151. goto search;
  2152. case DB_SET_RANGE:
  2153. sflags =
  2154.     (F_ISSET(dbc, DBC_RMW) ? S_WRITE : S_READ) | S_DUPFIRST;
  2155. goto search;
  2156. case DB_KEYFIRST:
  2157. sflags = S_KEYFIRST;
  2158. goto fast_search;
  2159. case DB_KEYLAST:
  2160. case DB_NODUPDATA:
  2161. sflags = S_KEYLAST;
  2162. fast_search: /*
  2163.  * If the application has a history of inserting into the first
  2164.  * or last pages of the database, we check those pages first to
  2165.  * avoid doing a full search.
  2166.  *
  2167.  * If the tree has record numbers, we need a complete stack so
  2168.  * that we can adjust the record counts, so fast_search isn't
  2169.  * possible.
  2170.  */
  2171. if (F_ISSET(cp, C_RECNUM))
  2172. goto search;
  2173. /*
  2174.  * !!!
  2175.  * We do not mutex protect the t->bt_lpgno field, which means
  2176.  * that it can only be used in an advisory manner.  If we find
  2177.  * page we can use, great.  If we don't, we don't care, we do
  2178.  * it the slow way instead.  Regardless, copy it into a local
  2179.  * variable, otherwise we might acquire a lock for a page and
  2180.  * then read a different page because it changed underfoot.
  2181.  */
  2182. bt_lpgno = t->bt_lpgno;
  2183. /*
  2184.  * If the tree has no history of insertion, do it the slow way.
  2185.  */
  2186. if (bt_lpgno == PGNO_INVALID)
  2187. goto search;
  2188. /* Lock and retrieve the page on which we last inserted. */
  2189. h = NULL;
  2190. ACQUIRE(dbc,
  2191.     DB_LOCK_WRITE, bt_lpgno, cp->lock, bt_lpgno, h, ret);
  2192. if (ret != 0)
  2193. goto fast_miss;
  2194. inp = P_INP(dbp, h);
  2195. /*
  2196.  * It's okay if the page type isn't right or it's empty, it
  2197.  * just means that the world changed.
  2198.  */
  2199. if (TYPE(h) != P_LBTREE || NUM_ENT(h) == 0)
  2200. goto fast_miss;
  2201. /*
  2202.  * What we do here is test to see if we're at the beginning or
  2203.  * end of the tree and if the new item sorts before/after the
  2204.  * first/last page entry.  We don't try and catch inserts into
  2205.  * the middle of the tree (although we could, as long as there
  2206.  * were two keys on the page and we saved both the index and
  2207.  * the page number of the last insert).
  2208.  */
  2209. if (h->next_pgno == PGNO_INVALID) {
  2210. indx = NUM_ENT(h) - P_INDX;
  2211. if ((ret = __bam_cmp(dbp,
  2212.     key, h, indx, t->bt_compare, &cmp)) != 0)
  2213. return (ret);
  2214. if (cmp < 0)
  2215. goto try_begin;
  2216. if (cmp > 0) {
  2217. indx += P_INDX;
  2218. goto fast_hit;
  2219. }
  2220. /*
  2221.  * Found a duplicate.  If doing DB_KEYLAST, we're at
  2222.  * the correct position, otherwise, move to the first
  2223.  * of the duplicates.  If we're looking at off-page
  2224.  * duplicates, duplicate duplicates aren't permitted,
  2225.  * so we're done.
  2226.  */
  2227. if (flags == DB_KEYLAST)
  2228. goto fast_hit;
  2229. for (;
  2230.     indx > 0 && inp[indx - P_INDX] == inp[indx];
  2231.     indx -= P_INDX)
  2232. ;
  2233. goto fast_hit;
  2234. }
  2235. try_begin: if (h->prev_pgno == PGNO_INVALID) {
  2236. indx = 0;
  2237. if ((ret = __bam_cmp(dbp,
  2238.     key, h, indx, t->bt_compare, &cmp)) != 0)
  2239. return (ret);
  2240. if (cmp > 0)
  2241. goto fast_miss;
  2242. if (cmp < 0)
  2243. goto fast_hit;
  2244. /*
  2245.  * Found a duplicate.  If doing DB_KEYFIRST, we're at
  2246.  * the correct position, otherwise, move to the last
  2247.  * of the duplicates.  If we're looking at off-page
  2248.  * duplicates, duplicate duplicates aren't permitted,
  2249.  * so we're done.
  2250.  */
  2251. if (flags == DB_KEYFIRST)
  2252. goto fast_hit;
  2253. for (;
  2254.     indx < (db_indx_t)(NUM_ENT(h) - P_INDX) &&
  2255.     inp[indx] == inp[indx + P_INDX];
  2256.     indx += P_INDX)
  2257. ;
  2258. goto fast_hit;
  2259. }
  2260. goto fast_miss;
  2261. fast_hit: /* Set the exact match flag, we may have found a duplicate. */
  2262. *exactp = cmp == 0;
  2263. /*
  2264.  * Insert the entry in the stack.  (Our caller is likely to
  2265.  * call __bam_stkrel() after our return.)
  2266.  */
  2267. BT_STK_CLR(cp);
  2268. BT_STK_ENTER(dbp->dbenv,
  2269.     cp, h, indx, cp->lock, cp->lock_mode, ret);
  2270. if (ret != 0)
  2271. return (ret);
  2272. break;
  2273. fast_miss: /*
  2274.  * This was not the right page, so we do not need to retain
  2275.  * the lock even in the presence of transactions.
  2276.  */
  2277. DISCARD(dbc, 1, cp->lock, h, ret);
  2278. if (ret != 0)
  2279. return (ret);
  2280. search: if ((ret = __bam_search(dbc, root_pgno,
  2281.     key, sflags, 1, NULL, exactp)) != 0)
  2282. return (ret);
  2283. break;
  2284. default:
  2285. return (__db_unknown_flag(dbp->dbenv, "__bam_c_search", flags));
  2286. }
  2287. /* Initialize the cursor from the stack. */
  2288. cp->page = cp->csp->page;
  2289. cp->pgno = cp->csp->page->pgno;
  2290. cp->indx = cp->csp->indx;
  2291. cp->lock = cp->csp->lock;
  2292. cp->lock_mode = cp->csp->lock_mode;
  2293. /*
  2294.  * If we inserted a key into the first or last slot of the tree,
  2295.  * remember where it was so we can do it more quickly next time.
  2296.  * If there are duplicates and we are inserting into the last slot,
  2297.  * the cursor will point _to_ the last item, not after it, which
  2298.  * is why we subtract P_INDX below.
  2299.  */
  2300. if (TYPE(cp->page) == P_LBTREE &&
  2301.     (flags == DB_KEYFIRST || flags == DB_KEYLAST))
  2302. t->bt_lpgno =
  2303.     (NEXT_PGNO(cp->page) == PGNO_INVALID &&
  2304.     cp->indx >= NUM_ENT(cp->page) - P_INDX) ||
  2305.     (PREV_PGNO(cp->page) == PGNO_INVALID &&
  2306.     cp->indx == 0) ? cp->pgno : PGNO_INVALID;
  2307. return (0);
  2308. }
  2309. /*
  2310.  * __bam_c_physdel --
  2311.  * Physically remove an item from the page.
  2312.  */
  2313. static int
  2314. __bam_c_physdel(dbc)
  2315. DBC *dbc;
  2316. {
  2317. BTREE_CURSOR *cp;
  2318. DB *dbp;
  2319. DBT key;
  2320. DB_LOCK lock;
  2321. DB_MPOOLFILE *mpf;
  2322. PAGE *h;
  2323. db_pgno_t pgno;
  2324. int delete_page, empty_page, exact, level, ret;
  2325. dbp = dbc->dbp;
  2326. mpf = dbp->mpf;
  2327. cp = (BTREE_CURSOR *)dbc->internal;
  2328. delete_page = empty_page = ret = 0;
  2329. /* If the page is going to be emptied, consider deleting it. */
  2330. delete_page = empty_page =
  2331.     NUM_ENT(cp->page) == (TYPE(cp->page) == P_LBTREE ? 2 : 1);
  2332. /*
  2333.  * Check if the application turned off reverse splits.  Applications
  2334.  * can't turn off reverse splits in off-page duplicate trees, that
  2335.  * space will never be reused unless the exact same key is specified.
  2336.  */
  2337. if (delete_page &&
  2338.     !F_ISSET(dbc, DBC_OPD) && F_ISSET(dbp, DB_AM_REVSPLITOFF))
  2339. delete_page = 0;
  2340. /*
  2341.  * We never delete the last leaf page.  (Not really true -- we delete
  2342.  * the last leaf page of off-page duplicate trees, but that's handled
  2343.  * by our caller, not down here.)
  2344.  */
  2345. if (delete_page && cp->pgno == cp->root)
  2346. delete_page = 0;
  2347. /*
  2348.  * To delete a leaf page other than an empty root page, we need a
  2349.  * copy of a key from the page.  Use the 0th page index since it's
  2350.  * the last key the page held.
  2351.  *
  2352.  * !!!
  2353.  * Note that because __bam_c_physdel is always called from a cursor
  2354.  * close, it should be safe to use the cursor's own "my_rkey" memory
  2355.  * to temporarily hold this key.  We shouldn't own any returned-data
  2356.  * memory of interest--if we do, we're in trouble anyway.
  2357.  */
  2358. if (delete_page) {
  2359. memset(&key, 0, sizeof(DBT));
  2360. if ((ret = __db_ret(dbp, cp->page,
  2361.     0, &key, &dbc->my_rkey.data, &dbc->my_rkey.ulen)) != 0)
  2362. return (ret);
  2363. }
  2364. /*
  2365.  * Delete the items.  If page isn't empty, we adjust the cursors.
  2366.  *
  2367.  * !!!
  2368.  * The following operations to delete a page may deadlock.  The easy
  2369.  * scenario is if we're deleting an item because we're closing cursors
  2370.  * because we've already deadlocked and want to call txn->abort.  If
  2371.  * we fail due to deadlock, we'll leave a locked, possibly empty page
  2372.  * in the tree, which won't be empty long because we'll undo the delete
  2373.  * when we undo the transaction's modifications.
  2374.  *
  2375.  * !!!
  2376.  * Delete the key item first, otherwise the on-page duplicate checks
  2377.  * in __bam_ditem() won't work!
  2378.  */
  2379. if (TYPE(cp->page) == P_LBTREE) {
  2380. if ((ret = __bam_ditem(dbc, cp->page, cp->indx)) != 0)
  2381. return (ret);
  2382. if (!empty_page)
  2383. if ((ret = __bam_ca_di(dbc,
  2384.     PGNO(cp->page), cp->indx, -1)) != 0)
  2385. return (ret);
  2386. }
  2387. if ((ret = __bam_ditem(dbc, cp->page, cp->indx)) != 0)
  2388. return (ret);
  2389. if (!empty_page)
  2390. if ((ret = __bam_ca_di(dbc, PGNO(cp->page), cp->indx, -1)) != 0)
  2391. return (ret);
  2392. /* If we're not going to try and delete the page, we're done. */
  2393. if (!delete_page)
  2394. return (0);
  2395. /*
  2396.  * Call __bam_search to reacquire the empty leaf page, but this time
  2397.  * get both the leaf page and it's parent, locked.  Jump back up the
  2398.  * tree, until we have the top pair of pages that we want to delete.
  2399.  * Once we have the top page that we want to delete locked, lock the
  2400.  * underlying pages and check to make sure they're still empty.  If
  2401.  * they are, delete them.
  2402.  */
  2403. for (level = LEAFLEVEL;; ++level) {
  2404. /* Acquire a page and its parent, locked. */
  2405. if ((ret = __bam_search(dbc, PGNO_INVALID,
  2406.     &key, S_WRPAIR, level, NULL, &exact)) != 0)
  2407. return (ret);
  2408. /*
  2409.  * If we reach the root or the parent page isn't going to be
  2410.  * empty when we delete one record, stop.
  2411.  */
  2412. h = cp->csp[-1].page;
  2413. if (h->pgno == cp->root || NUM_ENT(h) != 1)
  2414. break;
  2415. /* Discard the stack, retaining no locks. */
  2416. (void)__bam_stkrel(dbc, STK_NOLOCK);
  2417. }
  2418. /*
  2419.  * Move the stack pointer one after the last entry, we may be about
  2420.  * to push more items onto the page stack.
  2421.  */
  2422. ++cp->csp;
  2423. /*
  2424.  * cp->csp[-2].page is now the parent page, which we may or may not be
  2425.  * going to delete, and cp->csp[-1].page is the first page we know we
  2426.  * are going to delete.  Walk down the chain of pages, acquiring pages
  2427.  * until we've acquired a leaf page.  Generally, this shouldn't happen;
  2428.  * we should only see a single internal page with one item and a single
  2429.  * leaf page with no items.  The scenario where we could see something
  2430.  * else is if reverse splits were turned off for awhile and then turned
  2431.  * back on.  That could result in all sorts of strangeness, e.g., empty
  2432.  * pages in the tree, trees that looked like linked lists, and so on.
  2433.  *
  2434.  * !!!
  2435.  * Sheer paranoia: if we find any pages that aren't going to be emptied
  2436.  * by the delete, someone else added an item while we were walking the
  2437.  * tree, and we discontinue the delete.  Shouldn't be possible, but we
  2438.  * check regardless.
  2439.  */
  2440. for (h = cp->csp[-1].page;;) {
  2441. if (ISLEAF(h)) {
  2442. if (NUM_ENT(h) != 0)
  2443. break;
  2444. break;
  2445. } else
  2446. if (NUM_ENT(h) != 1)
  2447. break;
  2448. /*
  2449.  * Get the next page, write lock it and push it onto the stack.
  2450.  * We know it's index 0, because it can only have one element.
  2451.  */
  2452. switch (TYPE(h)) {
  2453. case P_IBTREE:
  2454. pgno = GET_BINTERNAL(dbp, h, 0)->pgno;
  2455. break;
  2456. case P_IRECNO:
  2457. pgno = GET_RINTERNAL(dbp, h, 0)->pgno;
  2458. break;
  2459. default:
  2460. return (__db_pgfmt(dbp->dbenv, PGNO(h)));
  2461. }
  2462. if ((ret =
  2463.     __db_lget(dbc, 0, pgno, DB_LOCK_WRITE, 0, &lock)) != 0)
  2464. break;
  2465. if ((ret = mpf->get(mpf, &pgno, 0, &h)) != 0)
  2466. break;
  2467. BT_STK_PUSH(dbp->dbenv, cp, h, 0, lock, DB_LOCK_WRITE, ret);
  2468. if (ret != 0)
  2469. break;
  2470. }
  2471. /* Adjust the cursor stack to reference the last page on the stack. */
  2472. BT_STK_POP(cp);
  2473. /*
  2474.  * If everything worked, delete the stack, otherwise, release the
  2475.  * stack and page locks without further damage.
  2476.  */
  2477. if (ret == 0)
  2478. ret = __bam_dpages(dbc, cp->sp);
  2479. else
  2480. (void)__bam_stkrel(dbc, 0);
  2481. return (ret);
  2482. }
  2483. /*
  2484.  * __bam_c_getstack --
  2485.  * Acquire a full stack for a cursor.
  2486.  */
  2487. static int
  2488. __bam_c_getstack(dbc)
  2489. DBC *dbc;
  2490. {
  2491. BTREE_CURSOR *cp;
  2492. DB *dbp;
  2493. DBT dbt;
  2494. DB_MPOOLFILE *mpf;
  2495. PAGE *h;
  2496. int exact, ret, t_ret;
  2497. dbp = dbc->dbp;
  2498. mpf = dbp->mpf;
  2499. cp = (BTREE_CURSOR *)dbc->internal;
  2500. /*
  2501.  * Get the page with the current item on it.  The caller of this
  2502.  * routine has to already hold a read lock on the page, so there
  2503.  * is no additional lock to acquire.
  2504.  */
  2505. if ((ret = mpf->get(mpf, &cp->pgno, 0, &h)) != 0)
  2506. return (ret);
  2507. /* Get a copy of a key from the page. */
  2508. memset(&dbt, 0, sizeof(DBT));
  2509. if ((ret = __db_ret(dbp,
  2510.     h, 0, &dbt, &dbc->rkey->data, &dbc->rkey->ulen)) != 0)
  2511. goto err;
  2512. /* Get a write-locked stack for the page. */
  2513. exact = 0;
  2514. ret = __bam_search(dbc, PGNO_INVALID,
  2515.     &dbt, S_KEYFIRST, 1, NULL, &exact);
  2516. err: /* Discard the key and the page. */
  2517. if ((t_ret = mpf->put(mpf, h, 0)) != 0 && ret == 0)
  2518. ret = t_ret;
  2519. return (ret);
  2520. }
  2521. /*
  2522.  * __bam_isopd --
  2523.  * Return if the cursor references an off-page duplicate tree via its
  2524.  * page number.
  2525.  */
  2526. static int
  2527. __bam_isopd(dbc, pgnop)
  2528. DBC *dbc;
  2529. db_pgno_t *pgnop;
  2530. {
  2531. BOVERFLOW *bo;
  2532. if (TYPE(dbc->internal->page) != P_LBTREE)
  2533. return (0);
  2534. bo = GET_BOVERFLOW(dbc->dbp,
  2535.     dbc->internal->page, dbc->internal->indx + O_INDX);
  2536. if (B_TYPE(bo->type) == B_DUPLICATE) {
  2537. *pgnop = bo->pgno;
  2538. return (1);
  2539. }
  2540. return (0);
  2541. }