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

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1998-2002
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char revid[] = "$Id: db_am.c,v 11.96 2002/08/27 15:17:32 bostic 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/hash.h"
  20. #include "dbinc/lock.h"
  21. #include "dbinc/log.h"
  22. #include "dbinc/mp.h"
  23. #include "dbinc/qam.h"
  24. static int __db_append_primary __P((DBC *, DBT *, DBT *));
  25. static int __db_secondary_get __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
  26. static int __db_secondary_close __P((DB *, u_int32_t));
  27. #ifdef DEBUG
  28. static int __db_cprint_item __P((DBC *));
  29. #endif
  30. /*
  31.  * __db_cursor --
  32.  * Allocate and return a cursor.
  33.  *
  34.  * PUBLIC: int __db_cursor __P((DB *, DB_TXN *, DBC **, u_int32_t));
  35.  */
  36. int
  37. __db_cursor(dbp, txn, dbcp, flags)
  38. DB *dbp;
  39. DB_TXN *txn;
  40. DBC **dbcp;
  41. u_int32_t flags;
  42. {
  43. DB_ENV *dbenv;
  44. DBC *dbc;
  45. db_lockmode_t mode;
  46. u_int32_t op;
  47. int ret;
  48. dbenv = dbp->dbenv;
  49. PANIC_CHECK(dbenv);
  50. DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->cursor");
  51. /* Validate arguments. */
  52. if ((ret = __db_cursorchk(dbp, flags)) != 0)
  53. return (ret);
  54. /*
  55.  * Check for consistent transaction usage.  For now, assume that
  56.  * this cursor might be used for read operations only (in which
  57.  * case it may not require a txn).  We'll check more stringently
  58.  * in c_del and c_put.  (Note that this all means that the
  59.  * read-op txn tests have to be a subset of the write-op ones.)
  60.  */
  61. if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 1)) != 0)
  62. return (ret);
  63. if ((ret = __db_icursor(dbp,
  64.     txn, dbp->type, PGNO_INVALID, 0, DB_LOCK_INVALIDID, dbcp)) != 0)
  65. return (ret);
  66. dbc = *dbcp;
  67. /*
  68.  * If this is CDB, do all the locking in the interface, which is
  69.  * right here.
  70.  */
  71. if (CDB_LOCKING(dbenv)) {
  72. op = LF_ISSET(DB_OPFLAGS_MASK);
  73. mode = (op == DB_WRITELOCK) ? DB_LOCK_WRITE :
  74.     ((op == DB_WRITECURSOR) ? DB_LOCK_IWRITE : DB_LOCK_READ);
  75. if ((ret = dbenv->lock_get(dbenv, dbc->locker, 0,
  76.     &dbc->lock_dbt, mode, &dbc->mylock)) != 0) {
  77. (void)__db_c_close(dbc);
  78. return (ret);
  79. }
  80. if (op == DB_WRITECURSOR)
  81. F_SET(dbc, DBC_WRITECURSOR);
  82. if (op == DB_WRITELOCK)
  83. F_SET(dbc, DBC_WRITER);
  84. }
  85. if (LF_ISSET(DB_DIRTY_READ) ||
  86.     (txn != NULL && F_ISSET(txn, TXN_DIRTY_READ)))
  87. F_SET(dbc, DBC_DIRTY_READ);
  88. return (0);
  89. }
  90. /*
  91.  * __db_icursor --
  92.  * Internal version of __db_cursor.  If dbcp is
  93.  * non-NULL it is assumed to point to an area to
  94.  * initialize as a cursor.
  95.  *
  96.  * PUBLIC: int __db_icursor
  97.  * PUBLIC:     __P((DB *, DB_TXN *, DBTYPE, db_pgno_t, int, u_int32_t, DBC **));
  98.  */
  99. int
  100. __db_icursor(dbp, txn, dbtype, root, is_opd, lockerid, dbcp)
  101. DB *dbp;
  102. DB_TXN *txn;
  103. DBTYPE dbtype;
  104. db_pgno_t root;
  105. int is_opd;
  106. u_int32_t lockerid;
  107. DBC **dbcp;
  108. {
  109. DBC *dbc, *adbc;
  110. DBC_INTERNAL *cp;
  111. DB_ENV *dbenv;
  112. int allocated, ret;
  113. dbenv = dbp->dbenv;
  114. allocated = 0;
  115. /*
  116.  * Take one from the free list if it's available.  Take only the
  117.  * right type.  With off page dups we may have different kinds
  118.  * of cursors on the queue for a single database.
  119.  */
  120. MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
  121. for (dbc = TAILQ_FIRST(&dbp->free_queue);
  122.     dbc != NULL; dbc = TAILQ_NEXT(dbc, links))
  123. if (dbtype == dbc->dbtype) {
  124. TAILQ_REMOVE(&dbp->free_queue, dbc, links);
  125. F_CLR(dbc, ~DBC_OWN_LID);
  126. break;
  127. }
  128. MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
  129. if (dbc == NULL) {
  130. if ((ret = __os_calloc(dbp->dbenv, 1, sizeof(DBC), &dbc)) != 0)
  131. return (ret);
  132. allocated = 1;
  133. dbc->flags = 0;
  134. dbc->dbp = dbp;
  135. /* Set up locking information. */
  136. if (LOCKING_ON(dbenv)) {
  137. /*
  138.  * If we are not threaded, then there is no need to
  139.  * create new locker ids.  We know that no one else
  140.  * is running concurrently using this DB, so we can
  141.  * take a peek at any cursors on the active queue.
  142.  */
  143. if (!DB_IS_THREADED(dbp) &&
  144.     (adbc = TAILQ_FIRST(&dbp->active_queue)) != NULL)
  145. dbc->lid = adbc->lid;
  146. else {
  147. if ((ret =
  148.     dbenv->lock_id(dbenv, &dbc->lid)) != 0)
  149. goto err;
  150. F_SET(dbc, DBC_OWN_LID);
  151. }
  152. /*
  153.  * In CDB, secondary indices should share a lock file
  154.  * ID with the primary;  otherwise we're susceptible to
  155.  * deadlocks.  We also use __db_icursor rather
  156.  * than sdbp->cursor to create secondary update
  157.  * cursors in c_put and c_del;  these won't
  158.  * acquire a new lock.
  159.  *
  160.  * !!!
  161.  * Since this is in the one-time cursor allocation
  162.  * code, we need to be sure to destroy, not just
  163.  * close, all cursors in the secondary when we
  164.  * associate.
  165.  */
  166. if (CDB_LOCKING(dbp->dbenv) &&
  167.     F_ISSET(dbp, DB_AM_SECONDARY))
  168. memcpy(dbc->lock.fileid,
  169.     dbp->s_primary->fileid, DB_FILE_ID_LEN);
  170. else
  171. memcpy(dbc->lock.fileid,
  172.     dbp->fileid, DB_FILE_ID_LEN);
  173. if (CDB_LOCKING(dbenv)) {
  174. if (F_ISSET(dbenv, DB_ENV_CDB_ALLDB)) {
  175. /*
  176.  * If we are doing a single lock per
  177.  * environment, set up the global
  178.  * lock object just like we do to
  179.  * single thread creates.
  180.  */
  181. DB_ASSERT(sizeof(db_pgno_t) ==
  182.     sizeof(u_int32_t));
  183. dbc->lock_dbt.size = sizeof(u_int32_t);
  184. dbc->lock_dbt.data = &dbc->lock.pgno;
  185. dbc->lock.pgno = 0;
  186. } else {
  187. dbc->lock_dbt.size = DB_FILE_ID_LEN;
  188. dbc->lock_dbt.data = dbc->lock.fileid;
  189. }
  190. } else {
  191. dbc->lock.type = DB_PAGE_LOCK;
  192. dbc->lock_dbt.size = sizeof(dbc->lock);
  193. dbc->lock_dbt.data = &dbc->lock;
  194. }
  195. }
  196. /* Init the DBC internal structure. */
  197. switch (dbtype) {
  198. case DB_BTREE:
  199. case DB_RECNO:
  200. if ((ret = __bam_c_init(dbc, dbtype)) != 0)
  201. goto err;
  202. break;
  203. case DB_HASH:
  204. if ((ret = __ham_c_init(dbc)) != 0)
  205. goto err;
  206. break;
  207. case DB_QUEUE:
  208. if ((ret = __qam_c_init(dbc)) != 0)
  209. goto err;
  210. break;
  211. default:
  212. ret = __db_unknown_type(dbp->dbenv,
  213.     "__db_icursor", dbtype);
  214. goto err;
  215. }
  216. cp = dbc->internal;
  217. }
  218. /* Refresh the DBC structure. */
  219. dbc->dbtype = dbtype;
  220. RESET_RET_MEM(dbc);
  221. if ((dbc->txn = txn) == NULL) {
  222. /*
  223.  * There are certain cases in which we want to create a
  224.  * new cursor with a particular locker ID that is known
  225.  * to be the same as (and thus not conflict with) an
  226.  * open cursor.
  227.  *
  228.  * The most obvious case is cursor duplication;  when we
  229.  * call DBC->c_dup or __db_c_idup, we want to use the original
  230.  * cursor's locker ID.
  231.  *
  232.  * Another case is when updating secondary indices.  Standard
  233.  * CDB locking would mean that we might block ourself:  we need
  234.  * to open an update cursor in the secondary while an update
  235.  * cursor in the primary is open, and when the secondary and
  236.  * primary are subdatabases or we're using env-wide locking,
  237.  * this is disastrous.
  238.  *
  239.  * In these cases, our caller will pass a nonzero locker ID
  240.  * into this function.  Use this locker ID instead of dbc->lid
  241.  * as the locker ID for our new cursor.
  242.  */
  243. if (lockerid != DB_LOCK_INVALIDID)
  244. dbc->locker = lockerid;
  245. else
  246. dbc->locker = dbc->lid;
  247. } else {
  248. dbc->locker = txn->txnid;
  249. txn->cursors++;
  250. }
  251. /*
  252.  * These fields change when we are used as a secondary index, so
  253.  * if the DB is a secondary, make sure they're set properly just
  254.  * in case we opened some cursors before we were associated.
  255.  *
  256.  * __db_c_get is used by all access methods, so this should be safe.
  257.  */
  258. if (F_ISSET(dbp, DB_AM_SECONDARY))
  259. dbc->c_get = __db_c_secondary_get;
  260. if (is_opd)
  261. F_SET(dbc, DBC_OPD);
  262. if (F_ISSET(dbp, DB_AM_RECOVER))
  263. F_SET(dbc, DBC_RECOVER);
  264. if (F_ISSET(dbp, DB_AM_COMPENSATE))
  265. F_SET(dbc, DBC_COMPENSATE);
  266. /* Refresh the DBC internal structure. */
  267. cp = dbc->internal;
  268. cp->opd = NULL;
  269. cp->indx = 0;
  270. cp->page = NULL;
  271. cp->pgno = PGNO_INVALID;
  272. cp->root = root;
  273. switch (dbtype) {
  274. case DB_BTREE:
  275. case DB_RECNO:
  276. if ((ret = __bam_c_refresh(dbc)) != 0)
  277. goto err;
  278. break;
  279. case DB_HASH:
  280. case DB_QUEUE:
  281. break;
  282. default:
  283. ret = __db_unknown_type(dbp->dbenv, "__db_icursor", dbp->type);
  284. goto err;
  285. }
  286. MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
  287. TAILQ_INSERT_TAIL(&dbp->active_queue, dbc, links);
  288. F_SET(dbc, DBC_ACTIVE);
  289. MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
  290. *dbcp = dbc;
  291. return (0);
  292. err: if (allocated)
  293. __os_free(dbp->dbenv, dbc);
  294. return (ret);
  295. }
  296. #ifdef DEBUG
  297. /*
  298.  * __db_cprint --
  299.  * Display the cursor active and free queues.
  300.  *
  301.  * PUBLIC: int __db_cprint __P((DB *));
  302.  */
  303. int
  304. __db_cprint(dbp)
  305. DB *dbp;
  306. {
  307. DBC *dbc;
  308. int ret, t_ret;
  309. ret = 0;
  310. MUTEX_THREAD_LOCK(dbp->dbenv, dbp->mutexp);
  311. fprintf(stderr, "Active queue:n");
  312. for (dbc = TAILQ_FIRST(&dbp->active_queue);
  313.     dbc != NULL; dbc = TAILQ_NEXT(dbc, links))
  314. if ((t_ret = __db_cprint_item(dbc)) != 0 && ret == 0)
  315. ret = t_ret;
  316. fprintf(stderr, "Free queue:n");
  317. for (dbc = TAILQ_FIRST(&dbp->free_queue);
  318.     dbc != NULL; dbc = TAILQ_NEXT(dbc, links))
  319. if ((t_ret = __db_cprint_item(dbc)) != 0 && ret == 0)
  320. ret = t_ret;
  321. MUTEX_THREAD_UNLOCK(dbp->dbenv, dbp->mutexp);
  322. return (ret);
  323. }
  324. static
  325. int __db_cprint_item(dbc)
  326. DBC *dbc;
  327. {
  328. static const FN fn[] = {
  329. { DBC_ACTIVE, "active" },
  330. { DBC_COMPENSATE, "compensate" },
  331. { DBC_OPD, "off-page-dup" },
  332. { DBC_RECOVER, "recover" },
  333. { DBC_RMW, "read-modify-write" },
  334. { DBC_TRANSIENT, "transient" },
  335. { DBC_WRITECURSOR, "write cursor" },
  336. { DBC_WRITEDUP, "internally dup'ed write cursor" },
  337. { DBC_WRITER, "short-term write cursor" },
  338. { 0, NULL }
  339. };
  340. DB *dbp;
  341. DBC_INTERNAL *cp;
  342. const char *s;
  343. dbp = dbc->dbp;
  344. cp = dbc->internal;
  345. s = __db_dbtype_to_string(dbc->dbtype);
  346. if (strcmp(s, "UNKNOWN TYPE") == 0) {
  347. DB_ASSERT(0);
  348. return (1);
  349. }
  350. fprintf(stderr, "%s/%#0lx: opd: %#0lxn",
  351.     s, P_TO_ULONG(dbc), P_TO_ULONG(cp->opd));
  352. fprintf(stderr, "ttxn: %#0lx lid: %lu locker: %lun",
  353.     P_TO_ULONG(dbc->txn), (u_long)dbc->lid, (u_long)dbc->locker);
  354. fprintf(stderr, "troot: %lu page/index: %lu/%lu",
  355.     (u_long)cp->root, (u_long)cp->pgno, (u_long)cp->indx);
  356. __db_prflags(dbc->flags, fn, stderr);
  357. fprintf(stderr, "n");
  358. switch (dbp->type) {
  359. case DB_BTREE:
  360. __bam_cprint(dbc);
  361. break;
  362. case DB_HASH:
  363. __ham_cprint(dbc);
  364. break;
  365. default:
  366. break;
  367. }
  368. return (0);
  369. }
  370. #endif /* DEBUG */
  371. /*
  372.  * db_fd --
  373.  * Return a file descriptor for flock'ing.
  374.  *
  375.  * PUBLIC: int __db_fd __P((DB *, int *));
  376.  */
  377. int
  378. __db_fd(dbp, fdp)
  379. DB *dbp;
  380. int *fdp;
  381. {
  382. DB_FH *fhp;
  383. int ret;
  384. PANIC_CHECK(dbp->dbenv);
  385. DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->fd");
  386. /*
  387.  * XXX
  388.  * Truly spectacular layering violation.
  389.  */
  390. if ((ret = __mp_xxx_fh(dbp->mpf, &fhp)) != 0)
  391. return (ret);
  392. if (F_ISSET(fhp, DB_FH_VALID)) {
  393. *fdp = fhp->fd;
  394. return (0);
  395. } else {
  396. *fdp = -1;
  397. __db_err(dbp->dbenv, "DB does not have a valid file handle");
  398. return (ENOENT);
  399. }
  400. }
  401. /*
  402.  * __db_get --
  403.  * Return a key/data pair.
  404.  *
  405.  * PUBLIC: int __db_get __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
  406.  */
  407. int
  408. __db_get(dbp, txn, key, data, flags)
  409. DB *dbp;
  410. DB_TXN *txn;
  411. DBT *key, *data;
  412. u_int32_t flags;
  413. {
  414. DBC *dbc;
  415. int mode, ret, t_ret;
  416. PANIC_CHECK(dbp->dbenv);
  417. DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get");
  418. if ((ret = __db_getchk(dbp, key, data, flags)) != 0)
  419. return (ret);
  420. /* Check for consistent transaction usage. */
  421. if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 1)) != 0)
  422. return (ret);
  423. mode = 0;
  424. if (LF_ISSET(DB_DIRTY_READ)) {
  425. mode = DB_DIRTY_READ;
  426. LF_CLR(DB_DIRTY_READ);
  427. }
  428. else if (flags == DB_CONSUME || flags == DB_CONSUME_WAIT)
  429. mode = DB_WRITELOCK;
  430. if ((ret = dbp->cursor(dbp, txn, &dbc, mode)) != 0)
  431. return (ret);
  432. DEBUG_LREAD(dbc, txn, "__db_get", key, NULL, flags);
  433. /*
  434.  * The DBC_TRANSIENT flag indicates that we're just doing a
  435.  * single operation with this cursor, and that in case of
  436.  * error we don't need to restore it to its old position--we're
  437.  * going to close it right away.  Thus, we can perform the get
  438.  * without duplicating the cursor, saving some cycles in this
  439.  * common case.
  440.  *
  441.  * SET_RET_MEM indicates that if key and/or data have no DBT
  442.  * flags set and DB manages the returned-data memory, that memory
  443.  * will belong to this handle, not to the underlying cursor.
  444.  */
  445. F_SET(dbc, DBC_TRANSIENT);
  446. SET_RET_MEM(dbc, dbp);
  447. if (LF_ISSET(~(DB_RMW | DB_MULTIPLE)) == 0)
  448. LF_SET(DB_SET);
  449. ret = dbc->c_get(dbc, key, data, flags);
  450. if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
  451. ret = t_ret;
  452. return (ret);
  453. }
  454. /*
  455.  * __db_put --
  456.  * Store a key/data pair.
  457.  *
  458.  * PUBLIC: int __db_put __P((DB *, DB_TXN *, DBT *, DBT *, u_int32_t));
  459.  */
  460. int
  461. __db_put(dbp, txn, key, data, flags)
  462. DB *dbp;
  463. DB_TXN *txn;
  464. DBT *key, *data;
  465. u_int32_t flags;
  466. {
  467. DBC *dbc;
  468. DBT tdata;
  469. DB_ENV *dbenv;
  470. int ret, t_ret, txn_local;
  471. dbc = NULL;
  472. dbenv = dbp->dbenv;
  473. txn_local = 0;
  474. PANIC_CHECK(dbenv);
  475. DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->put");
  476. /* Validate arguments. */
  477. if ((ret = __db_putchk(dbp, key, data,
  478.     flags, F_ISSET(dbp, DB_AM_DUP) || F_ISSET(key, DB_DBT_DUPOK))) != 0)
  479. return (ret);
  480. /* Create local transaction as necessary. */
  481. if (IS_AUTO_COMMIT(dbenv, txn, flags)) {
  482. if ((ret = __db_txn_auto(dbp, &txn)) != 0)
  483. return (ret);
  484. txn_local = 1;
  485. LF_CLR(DB_AUTO_COMMIT);
  486. }
  487. /* Check for consistent transaction usage. */
  488. if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0)
  489. goto err;
  490. if ((ret = dbp->cursor(dbp, txn, &dbc, DB_WRITELOCK)) != 0)
  491. goto err;
  492. DEBUG_LWRITE(dbc, txn, "db_put", key, data, flags);
  493. SET_RET_MEM(dbc, dbp);
  494. /*
  495.  * See the comment in __db_get().
  496.  *
  497.  * Note that the c_get in the DB_NOOVERWRITE case is safe to
  498.  * do with this flag set;  if it errors in any way other than
  499.  * DB_NOTFOUND, we're going to close the cursor without doing
  500.  * anything else, and if it returns DB_NOTFOUND then it's safe
  501.  * to do a c_put(DB_KEYLAST) even if an access method moved the
  502.  * cursor, since that's not position-dependent.
  503.  */
  504. F_SET(dbc, DBC_TRANSIENT);
  505. switch (flags) {
  506. case DB_APPEND:
  507. /*
  508.  * If there is an append callback, the value stored in
  509.  * data->data may be replaced and then freed.  To avoid
  510.  * passing a freed pointer back to the user, just operate
  511.  * on a copy of the data DBT.
  512.  */
  513. tdata = *data;
  514. /*
  515.  * Append isn't a normal put operation;  call the appropriate
  516.  * access method's append function.
  517.  */
  518. switch (dbp->type) {
  519. case DB_QUEUE:
  520. if ((ret = __qam_append(dbc, key, &tdata)) != 0)
  521. goto err;
  522. break;
  523. case DB_RECNO:
  524. if ((ret = __ram_append(dbc, key, &tdata)) != 0)
  525. goto err;
  526. break;
  527. default:
  528. /* The interface should prevent this. */
  529. DB_ASSERT(0);
  530. ret = __db_ferr(dbenv, "__db_put", flags);
  531. goto err;
  532. }
  533. /*
  534.  * Secondary indices:  since we've returned zero from
  535.  * an append function, we've just put a record, and done
  536.  * so outside __db_c_put.  We know we're not a secondary--
  537.  * the interface prevents puts on them--but we may be a
  538.  * primary.  If so, update our secondary indices
  539.  * appropriately.
  540.  */
  541. DB_ASSERT(!F_ISSET(dbp, DB_AM_SECONDARY));
  542. if (LIST_FIRST(&dbp->s_secondaries) != NULL)
  543. ret = __db_append_primary(dbc, key, &tdata);
  544. /*
  545.  * The append callback, if one exists, may have allocated
  546.  * a new tdata.data buffer.  If so, free it.
  547.  */
  548. FREE_IF_NEEDED(dbp, &tdata);
  549. /* No need for a cursor put;  we're done. */
  550. goto err;
  551. case DB_NOOVERWRITE:
  552. flags = 0;
  553. /*
  554.  * Set DB_DBT_USERMEM, this might be a threaded application and
  555.  * the flags checking will catch us.  We don't want the actual
  556.  * data, so request a partial of length 0.
  557.  */
  558. memset(&tdata, 0, sizeof(tdata));
  559. F_SET(&tdata, DB_DBT_USERMEM | DB_DBT_PARTIAL);
  560. /*
  561.  * If we're doing page-level locking, set the read-modify-write
  562.  * flag, we're going to overwrite immediately.
  563.  */
  564. if ((ret = dbc->c_get(dbc, key, &tdata,
  565.     DB_SET | (STD_LOCKING(dbc) ? DB_RMW : 0))) == 0)
  566. ret = DB_KEYEXIST;
  567. else if (ret == DB_NOTFOUND || ret == DB_KEYEMPTY)
  568. ret = 0;
  569. break;
  570. default:
  571. /* Fall through to normal cursor put. */
  572. break;
  573. }
  574. if (ret == 0)
  575. ret = dbc->c_put(dbc,
  576.     key, data, flags == 0 ? DB_KEYLAST : flags);
  577. err: /* Close the cursor. */
  578. if (dbc != NULL && (t_ret = __db_c_close(dbc)) != 0 && ret == 0)
  579. ret = t_ret;
  580. /* Commit for DB_AUTO_COMMIT. */
  581. if (txn_local) {
  582. if (ret == 0)
  583. ret = txn->commit(txn, 0);
  584. else
  585. if ((t_ret = txn->abort(txn)) != 0)
  586. ret = __db_panic(dbenv, t_ret);
  587. }
  588. return (ret);
  589. }
  590. /*
  591.  * __db_delete --
  592.  * Delete the items referenced by a key.
  593.  *
  594.  * PUBLIC: int __db_delete __P((DB *, DB_TXN *, DBT *, u_int32_t));
  595.  */
  596. int
  597. __db_delete(dbp, txn, key, flags)
  598. DB *dbp;
  599. DB_TXN *txn;
  600. DBT *key;
  601. u_int32_t flags;
  602. {
  603. DBC *dbc;
  604. DBT data, lkey;
  605. DB_ENV *dbenv;
  606. u_int32_t f_init, f_next;
  607. int ret, t_ret, txn_local;
  608. dbc = NULL;
  609. dbenv = dbp->dbenv;
  610. txn_local = 0;
  611. PANIC_CHECK(dbenv);
  612. DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->del");
  613. /* Check for invalid flags. */
  614. if ((ret = __db_delchk(dbp, key, flags)) != 0)
  615. return (ret);
  616. /* Create local transaction as necessary. */
  617. if (IS_AUTO_COMMIT(dbenv, txn, flags)) {
  618. if ((ret = __db_txn_auto(dbp, &txn)) != 0)
  619. return (ret);
  620. txn_local = 1;
  621. LF_CLR(DB_AUTO_COMMIT);
  622. }
  623. /* Check for consistent transaction usage. */
  624. if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0)
  625. goto err;
  626. /* Allocate a cursor. */
  627. if ((ret = dbp->cursor(dbp, txn, &dbc, DB_WRITELOCK)) != 0)
  628. goto err;
  629. DEBUG_LWRITE(dbc, txn, "db_delete", key, NULL, flags);
  630. /*
  631.  * Walk a cursor through the key/data pairs, deleting as we go.  Set
  632.  * the DB_DBT_USERMEM flag, as this might be a threaded application
  633.  * and the flags checking will catch us.  We don't actually want the
  634.  * keys or data, so request a partial of length 0.
  635.  */
  636. memset(&lkey, 0, sizeof(lkey));
  637. F_SET(&lkey, DB_DBT_USERMEM | DB_DBT_PARTIAL);
  638. memset(&data, 0, sizeof(data));
  639. F_SET(&data, DB_DBT_USERMEM | DB_DBT_PARTIAL);
  640. /*
  641.  * If locking (and we haven't already acquired CDB locks), set the
  642.  * read-modify-write flag.
  643.  */
  644. f_init = DB_SET;
  645. f_next = DB_NEXT_DUP;
  646. if (STD_LOCKING(dbc)) {
  647. f_init |= DB_RMW;
  648. f_next |= DB_RMW;
  649. }
  650. /* Walk through the set of key/data pairs, deleting as we go. */
  651. if ((ret = dbc->c_get(dbc, key, &data, f_init)) != 0)
  652. goto err;
  653. /*
  654.  * Hash permits an optimization in DB->del:  since on-page
  655.  * duplicates are stored in a single HKEYDATA structure, it's
  656.  * possible to delete an entire set of them at once, and as
  657.  * the HKEYDATA has to be rebuilt and re-put each time it
  658.  * changes, this is much faster than deleting the duplicates
  659.  * one by one.  Thus, if we're not pointing at an off-page
  660.  * duplicate set, and we're not using secondary indices (in
  661.  * which case we'd have to examine the items one by one anyway),
  662.  * let hash do this "quick delete".
  663.  *
  664.  * !!!
  665.  * Note that this is the only application-executed delete call in
  666.  * Berkeley DB that does not go through the __db_c_del function.
  667.  * If anything other than the delete itself (like a secondary index
  668.  * update) has to happen there in a particular situation, the
  669.  * conditions here should be modified not to call __ham_quick_delete.
  670.  * The ordinary AM-independent alternative will work just fine with
  671.  * a hash;  it'll just be slower.
  672.  */
  673. if (dbp->type == DB_HASH) {
  674. if (LIST_FIRST(&dbp->s_secondaries) == NULL &&
  675.     !F_ISSET(dbp, DB_AM_SECONDARY) &&
  676.     dbc->internal->opd == NULL) {
  677. ret = __ham_quick_delete(dbc);
  678. goto err;
  679. }
  680. }
  681. for (;;) {
  682. if ((ret = dbc->c_del(dbc, 0)) != 0)
  683. goto err;
  684. if ((ret = dbc->c_get(dbc, &lkey, &data, f_next)) != 0) {
  685. if (ret == DB_NOTFOUND) {
  686. ret = 0;
  687. break;
  688. }
  689. goto err;
  690. }
  691. }
  692. err: /* Discard the cursor. */
  693. if (dbc != NULL && (t_ret = dbc->c_close(dbc)) != 0 && ret == 0)
  694. ret = t_ret;
  695. /* Commit for DB_AUTO_COMMIT. */
  696. if (txn_local) {
  697. if (ret == 0)
  698. ret = txn->commit(txn, 0);
  699. else
  700. if ((t_ret = txn->abort(txn)) != 0)
  701. ret = __db_panic(dbenv, t_ret);
  702. }
  703. return (ret);
  704. }
  705. /*
  706.  * __db_sync --
  707.  * Flush the database cache.
  708.  *
  709.  * PUBLIC: int __db_sync __P((DB *, u_int32_t));
  710.  */
  711. int
  712. __db_sync(dbp, flags)
  713. DB *dbp;
  714. u_int32_t flags;
  715. {
  716. int ret, t_ret;
  717. PANIC_CHECK(dbp->dbenv);
  718. DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->sync");
  719. if ((ret = __db_syncchk(dbp, flags)) != 0)
  720. return (ret);
  721. /* Read-only trees never need to be sync'd. */
  722. if (F_ISSET(dbp, DB_AM_RDONLY))
  723. return (0);
  724. /* If it's a Recno tree, write the backing source text file. */
  725. if (dbp->type == DB_RECNO)
  726. ret = __ram_writeback(dbp);
  727. /* If the tree was never backed by a database file, we're done. */
  728. if (F_ISSET(dbp, DB_AM_INMEM))
  729. return (0);
  730. /* Flush any dirty pages from the cache to the backing file. */
  731. if ((t_ret = dbp->mpf->sync(dbp->mpf)) != 0 && ret == 0)
  732. ret = t_ret;
  733. return (ret);
  734. }
  735. /*
  736.  * __db_associate --
  737.  * Associate another database as a secondary index to this one.
  738.  *
  739.  * PUBLIC: int __db_associate __P((DB *, DB_TXN *, DB *,
  740.  * PUBLIC:     int (*)(DB *, const DBT *, const DBT *, DBT *), u_int32_t));
  741.  */
  742. int
  743. __db_associate(dbp, txn, sdbp, callback, flags)
  744. DB *dbp, *sdbp;
  745. DB_TXN *txn;
  746. int (*callback) __P((DB *, const DBT *, const DBT *, DBT *));
  747. u_int32_t flags;
  748. {
  749. DB_ENV *dbenv;
  750. DBC *pdbc, *sdbc;
  751. DBT skey, key, data;
  752. int build, ret, t_ret, txn_local;
  753. dbenv = dbp->dbenv;
  754. PANIC_CHECK(dbenv);
  755. txn_local = 0;
  756. pdbc = NULL;
  757. memset(&key, 0, sizeof(DBT));
  758. memset(&data, 0, sizeof(DBT));
  759. memset(&skey, 0, sizeof(DBT));
  760. if ((ret = __db_associatechk(dbp, sdbp, callback, flags)) != 0)
  761. return (ret);
  762. /*
  763.  * Create a local transaction as necessary, check for consistent
  764.  * transaction usage, and, if we have no transaction but do have
  765.  * locking on, acquire a locker id for the handle lock acquisition.
  766.  */
  767. if (IS_AUTO_COMMIT(dbenv, txn, flags)) {
  768. if ((ret = __db_txn_auto(dbp, &txn)) != 0)
  769. return (ret);
  770. txn_local = 1;
  771. } else if (txn != NULL && !TXN_ON(dbenv))
  772. return (__db_not_txn_env(dbenv));
  773. /*
  774.  * Check that if an open transaction is in progress, we're in it,
  775.  * for other common transaction errors, and for concurrent associates.
  776.  */
  777. if ((ret = __db_check_txn(dbp, txn, DB_LOCK_INVALIDID, 0)) != 0)
  778. return (ret);
  779. sdbp->s_callback = callback;
  780. sdbp->s_primary = dbp;
  781. sdbp->stored_get = sdbp->get;
  782. sdbp->get = __db_secondary_get;
  783. sdbp->stored_close = sdbp->close;
  784. sdbp->close = __db_secondary_close;
  785. /*
  786.  * Secondary cursors may have the primary's lock file ID, so we
  787.  * need to make sure that no older cursors are lying around
  788.  * when we make the transition.
  789.  */
  790. if (TAILQ_FIRST(&sdbp->active_queue) != NULL ||
  791.     TAILQ_FIRST(&sdbp->join_queue) != NULL) {
  792. __db_err(dbenv,
  793.     "Databases may not become secondary indices while cursors are open");
  794. ret = EINVAL;
  795. goto err;
  796. }
  797. while ((sdbc = TAILQ_FIRST(&sdbp->free_queue)) != NULL)
  798. if ((ret = __db_c_destroy(sdbc)) != 0)
  799. goto err;
  800. F_SET(sdbp, DB_AM_SECONDARY);
  801. /*
  802.  * Check to see if the secondary is empty--and thus if we should
  803.  * build it--before we link it in and risk making it show up in
  804.  * other threads.
  805.  */
  806. build = 0;
  807. if (LF_ISSET(DB_CREATE)) {
  808. if ((ret = sdbp->cursor(sdbp, txn, &sdbc, 0)) != 0)
  809. goto err;
  810. memset(&key, 0, sizeof(DBT));
  811. memset(&data, 0, sizeof(DBT));
  812. /*
  813.  * We don't care about key or data;  we're just doing
  814.  * an existence check.
  815.  */
  816. F_SET(&key, DB_DBT_PARTIAL | DB_DBT_USERMEM);
  817. F_SET(&data, DB_DBT_PARTIAL | DB_DBT_USERMEM);
  818. if ((ret = sdbc->c_real_get(sdbc, &key, &data,
  819.     (STD_LOCKING(sdbc) ? DB_RMW : 0) |
  820.     DB_FIRST)) == DB_NOTFOUND) {
  821. build = 1;
  822. ret = 0;
  823. }
  824. /*
  825.  * Secondary cursors have special refcounting close
  826.  * methods.  Be careful.
  827.  */
  828. if ((t_ret = __db_c_close(sdbc)) != 0)
  829. ret = t_ret;
  830. if (ret != 0)
  831. goto err;
  832. }
  833. /*
  834.  * Add the secondary to the list on the primary.  Do it here
  835.  * so that we see any updates that occur while we're walking
  836.  * the primary.
  837.  */
  838. MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);
  839. /* See __db_s_next for an explanation of secondary refcounting. */
  840. DB_ASSERT(sdbp->s_refcnt == 0);
  841. sdbp->s_refcnt = 1;
  842. LIST_INSERT_HEAD(&dbp->s_secondaries, sdbp, s_links);
  843. MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);
  844. if (build) {
  845. /*
  846.  * We loop through the primary, putting each item we
  847.  * find into the new secondary.
  848.  *
  849.  * If we're using CDB, opening these two cursors puts us
  850.  * in a bit of a locking tangle:  CDB locks are done on the
  851.  * primary, so that we stay deadlock-free, but that means
  852.  * that updating the secondary while we have a read cursor
  853.  * open on the primary will self-block.  To get around this,
  854.  * we force the primary cursor to use the same locker ID
  855.  * as the secondary, so they won't conflict.  This should
  856.  * be harmless even if we're not using CDB.
  857.  */
  858. if ((ret = sdbp->cursor(sdbp, txn, &sdbc,
  859.     CDB_LOCKING(sdbp->dbenv) ? DB_WRITECURSOR : 0)) != 0)
  860. goto err;
  861. if ((ret = __db_icursor(dbp,
  862.     txn, dbp->type, PGNO_INVALID, 0, sdbc->locker, &pdbc)) != 0)
  863. goto err;
  864. /* Lock out other threads, now that we have a locker ID. */
  865. dbp->associate_lid = sdbc->locker;
  866. memset(&key, 0, sizeof(DBT));
  867. memset(&data, 0, sizeof(DBT));
  868. while ((ret = pdbc->c_get(pdbc, &key, &data, DB_NEXT)) == 0) {
  869. memset(&skey, 0, sizeof(DBT));
  870. if ((ret = callback(sdbp, &key, &data, &skey)) != 0) {
  871. if (ret == DB_DONOTINDEX)
  872. continue;
  873. else
  874. goto err;
  875. }
  876. if ((ret = sdbc->c_put(sdbc,
  877.     &skey, &key, DB_UPDATE_SECONDARY)) != 0) {
  878. FREE_IF_NEEDED(sdbp, &skey);
  879. goto err;
  880. }
  881. FREE_IF_NEEDED(sdbp, &skey);
  882. }
  883. if (ret == DB_NOTFOUND)
  884. ret = 0;
  885. if ((ret = sdbc->c_close(sdbc)) != 0)
  886. goto err;
  887. }
  888. err: if (pdbc != NULL && (t_ret = pdbc->c_close(pdbc)) != 0 && ret == 0)
  889. ret = t_ret;
  890. dbp->associate_lid = DB_LOCK_INVALIDID;
  891. if (txn_local) {
  892. if (ret == 0)
  893. ret = txn->commit(txn, 0);
  894. else
  895. if ((t_ret = txn->abort(txn)) != 0)
  896. ret = __db_panic(dbenv, t_ret);
  897. }
  898. return (ret);
  899. }
  900. /*
  901.  * __db_pget --
  902.  * Return a primary key/data pair given a secondary key.
  903.  *
  904.  * PUBLIC: int __db_pget __P((DB *, DB_TXN *, DBT *, DBT *, DBT *, u_int32_t));
  905.  */
  906. int
  907. __db_pget(dbp, txn, skey, pkey, data, flags)
  908. DB *dbp;
  909. DB_TXN *txn;
  910. DBT *skey, *pkey, *data;
  911. u_int32_t flags;
  912. {
  913. DBC *dbc;
  914. int ret, t_ret;
  915. PANIC_CHECK(dbp->dbenv);
  916. DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->pget");
  917. if ((ret = __db_pgetchk(dbp, skey, pkey, data, flags)) != 0)
  918. return (ret);
  919. if ((ret = dbp->cursor(dbp, txn, &dbc, 0)) != 0)
  920. return (ret);
  921. SET_RET_MEM(dbc, dbp);
  922. /*
  923.  * The underlying cursor pget will fill in a default DBT for null
  924.  * pkeys, and use the cursor's returned-key memory internally to
  925.  * store any intermediate primary keys.  However, we've just set
  926.  * the returned-key memory to the DB handle's key memory, which
  927.  * is unsafe to use if the DB handle is threaded.  If the pkey
  928.  * argument is NULL, use the DBC-owned returned-key memory
  929.  * instead;  it'll go away when we close the cursor before we
  930.  * return, but in this case that's just fine, as we're not
  931.  * returning the primary key.
  932.  */
  933. if (pkey == NULL)
  934. dbc->rkey = &dbc->my_rkey;
  935. DEBUG_LREAD(dbc, txn, "__db_pget", skey, NULL, flags);
  936. /*
  937.  * The cursor is just a perfectly ordinary secondary database
  938.  * cursor.  Call its c_pget() method to do the dirty work.
  939.  */
  940. if (flags == 0 || flags == DB_RMW)
  941. flags |= DB_SET;
  942. ret = dbc->c_pget(dbc, skey, pkey, data, flags);
  943. if ((t_ret = __db_c_close(dbc)) != 0 && ret == 0)
  944. ret = t_ret;
  945. return (ret);
  946. }
  947. /*
  948.  * __db_secondary_get --
  949.  * This wrapper function for DB->pget() is the DB->get() function
  950.  * on a database which has been made into a secondary index.
  951.  */
  952. static int
  953. __db_secondary_get(sdbp, txn, skey, data, flags)
  954. DB *sdbp;
  955. DB_TXN *txn;
  956. DBT *skey, *data;
  957. u_int32_t flags;
  958. {
  959. DB_ASSERT(F_ISSET(sdbp, DB_AM_SECONDARY));
  960. return (sdbp->pget(sdbp, txn, skey, NULL, data, flags));
  961. }
  962. /*
  963.  * __db_secondary_close --
  964.  * Wrapper function for DB->close() which we use on secondaries to
  965.  * manage refcounting and make sure we don't close them underneath
  966.  * a primary that is updating.
  967.  */
  968. static int
  969. __db_secondary_close(sdbp, flags)
  970. DB *sdbp;
  971. u_int32_t flags;
  972. {
  973. DB *primary;
  974. int doclose;
  975. doclose = 0;
  976. primary = sdbp->s_primary;
  977. MUTEX_THREAD_LOCK(primary->dbenv, primary->mutexp);
  978. /*
  979.  * Check the refcount--if it was at 1 when we were called, no
  980.  * thread is currently updating this secondary through the primary,
  981.  * so it's safe to close it for real.
  982.  *
  983.  * If it's not safe to do the close now, we do nothing;  the
  984.  * database will actually be closed when the refcount is decremented,
  985.  * which can happen in either __db_s_next or __db_s_done.
  986.  */
  987. DB_ASSERT(sdbp->s_refcnt != 0);
  988. if (--sdbp->s_refcnt == 0) {
  989. LIST_REMOVE(sdbp, s_links);
  990. /* We don't want to call close while the mutex is held. */
  991. doclose = 1;
  992. }
  993. MUTEX_THREAD_UNLOCK(primary->dbenv, primary->mutexp);
  994. /*
  995.  * sdbp->close is this function;  call the real one explicitly if
  996.  * need be.
  997.  */
  998. return (doclose ? __db_close(sdbp, flags) : 0);
  999. }
  1000. /*
  1001.  * __db_append_primary --
  1002.  * Perform the secondary index updates necessary to put(DB_APPEND)
  1003.  * a record to a primary database.
  1004.  */
  1005. static int
  1006. __db_append_primary(dbc, key, data)
  1007. DBC *dbc;
  1008. DBT *key, *data;
  1009. {
  1010. DB *dbp, *sdbp;
  1011. DBC *sdbc, *pdbc;
  1012. DBT oldpkey, pkey, pdata, skey;
  1013. int cmp, ret, t_ret;
  1014. dbp = dbc->dbp;
  1015. sdbp = NULL;
  1016. ret = 0;
  1017. /*
  1018.  * Worrying about partial appends seems a little like worrying
  1019.  * about Linear A character encodings.  But we support those
  1020.  * too if your application understands them.
  1021.  */
  1022. pdbc = NULL;
  1023. if (F_ISSET(data, DB_DBT_PARTIAL) || F_ISSET(key, DB_DBT_PARTIAL)) {
  1024. /*
  1025.  * The dbc we were passed is all set to pass things
  1026.  * back to the user;  we can't safely do a call on it.
  1027.  * Dup the cursor, grab the real data item (we don't
  1028.  * care what the key is--we've been passed it directly),
  1029.  * and use that instead of the data DBT we were passed.
  1030.  *
  1031.  * Note that we can get away with this simple get because
  1032.  * an appended item is by definition new, and the
  1033.  * correctly-constructed full data item from this partial
  1034.  * put is on the page waiting for us.
  1035.  */
  1036. if ((ret = __db_c_idup(dbc, &pdbc, DB_POSITIONI)) != 0)
  1037. return (ret);
  1038. memset(&pkey, 0, sizeof(DBT));
  1039. memset(&pdata, 0, sizeof(DBT));
  1040. if ((ret = pdbc->c_get(pdbc, &pkey, &pdata, DB_CURRENT)) != 0)
  1041. goto err;
  1042. key = &pkey;
  1043. data = &pdata;
  1044. }
  1045. /*
  1046.  * Loop through the secondary indices, putting a new item in
  1047.  * each that points to the appended item.
  1048.  *
  1049.  * This is much like the loop in "step 3" in __db_c_put, so
  1050.  * I'm not commenting heavily here;  it was unclean to excerpt
  1051.  * just that section into a common function, but the basic
  1052.  * overview is the same here.
  1053.  */
  1054. for (sdbp = __db_s_first(dbp);
  1055.     sdbp != NULL && ret == 0; ret = __db_s_next(&sdbp)) {
  1056. memset(&skey, 0, sizeof(DBT));
  1057. if ((ret = sdbp->s_callback(sdbp, key, data, &skey)) != 0) {
  1058. if (ret == DB_DONOTINDEX)
  1059. continue;
  1060. else
  1061. goto err;
  1062. }
  1063. if ((ret = __db_icursor(sdbp, dbc->txn, sdbp->type,
  1064.     PGNO_INVALID, 0, dbc->locker, &sdbc)) != 0) {
  1065. FREE_IF_NEEDED(sdbp, &skey);
  1066. goto err;
  1067. }
  1068. if (CDB_LOCKING(sdbp->dbenv)) {
  1069. DB_ASSERT(sdbc->mylock.off == LOCK_INVALID);
  1070. F_SET(sdbc, DBC_WRITER);
  1071. }
  1072. /*
  1073.  * Since we know we have a new primary key, it can't be a
  1074.  * duplicate duplicate in the secondary.  It can be a
  1075.  * duplicate in a secondary that doesn't support duplicates,
  1076.  * however, so we need to be careful to avoid an overwrite
  1077.  * (which would corrupt our index).
  1078.  */
  1079. if (!F_ISSET(sdbp, DB_AM_DUP)) {
  1080. memset(&oldpkey, 0, sizeof(DBT));
  1081. F_SET(&oldpkey, DB_DBT_MALLOC);
  1082. ret = sdbc->c_real_get(sdbc, &skey, &oldpkey,
  1083.     DB_SET | (STD_LOCKING(dbc) ? DB_RMW : 0));
  1084. if (ret == 0) {
  1085. cmp = __bam_defcmp(sdbp, &oldpkey, key);
  1086. /*
  1087.  * XXX
  1088.  * This needs to use the right free function
  1089.  * as soon as this is possible.
  1090.  */
  1091. __os_ufree(sdbp->dbenv,
  1092.     oldpkey.data);
  1093. if (cmp != 0) {
  1094. __db_err(sdbp->dbenv, "%s%s",
  1095.     "Append results in a non-unique secondary key in",
  1096.     " an index not configured to support duplicates");
  1097. ret = EINVAL;
  1098. goto err1;
  1099. }
  1100. } else if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY)
  1101. goto err1;
  1102. }
  1103. ret = sdbc->c_put(sdbc, &skey, key, DB_UPDATE_SECONDARY);
  1104. err1: FREE_IF_NEEDED(sdbp, &skey);
  1105. if ((t_ret = sdbc->c_close(sdbc)) != 0 && ret == 0)
  1106. ret = t_ret;
  1107. if (ret != 0)
  1108. goto err;
  1109. }
  1110. err: if (pdbc != NULL && (t_ret = pdbc->c_close(pdbc)) != 0 && ret == 0)
  1111. ret = t_ret;
  1112. if (sdbp != NULL && (t_ret = __db_s_done(sdbp)) != 0 && ret == 0)
  1113. ret = t_ret;
  1114. return (ret);
  1115. }