summaryrefslogtreecommitdiff
path: root/src/qam/qam.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/qam/qam.c')
-rw-r--r--src/qam/qam.c102
1 files changed, 71 insertions, 31 deletions
diff --git a/src/qam/qam.c b/src/qam/qam.c
index e81d4795..0c71fd0d 100644
--- a/src/qam/qam.c
+++ b/src/qam/qam.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -260,7 +260,7 @@ __qamc_put(dbc, key, data, flags, pgnop)
}
if (exact != 0 && flags == DB_NOOVERWRITE)
- ret = DB_KEYEXIST;
+ ret = DBC_ERR(dbc, DB_KEYEXIST);
else
/* Put the item on the page. */
ret = __qam_pitem(dbc,
@@ -526,7 +526,7 @@ __qamc_del(dbc, flags)
return (ret);
if (QAM_NOT_VALID(meta, cp->recno)) {
- ret = DB_NOTFOUND;
+ ret = DBC_ERR(dbc, DB_NOTFOUND);
goto err;
}
first = meta->first_recno;
@@ -549,7 +549,7 @@ __qamc_del(dbc, flags)
goto err;
if (!exact) {
- ret = DB_NOTFOUND;
+ ret = DBC_ERR(dbc, DB_NOTFOUND);
goto err;
}
@@ -636,9 +636,9 @@ __qamc_get(dbc, key, data, flags, pgnop)
QUEUE_CURSOR *cp;
db_lockmode_t lock_mode;
db_pgno_t metapno;
- db_recno_t first;
+ db_recno_t first, old_first;
int exact, inorder, is_first, ret, t_ret, wait, with_delete;
- int retrying;
+ int retrying, stay;
u_int32_t skip, meta_mode;
dbp = dbc->dbp;
@@ -652,7 +652,9 @@ __qamc_get(dbc, key, data, flags, pgnop)
meta = NULL;
*pgnop = 0;
pg = NULL;
- retrying = t_ret = wait = with_delete = 0;
+ retrying = t_ret = wait = with_delete = 0;
+ stay = 1;
+ old_first = RECNO_OOB;
if (flags == DB_CONSUME_WAIT) {
wait = 1;
@@ -676,25 +678,25 @@ __qamc_get(dbc, key, data, flags, pgnop)
t = (QUEUE *)dbp->q_internal;
metapno = t->q_meta;
- /*
- * Get the meta page first
- */
- if ((ret = __memp_fget(mpf, &metapno,
- dbc->thread_info, dbc->txn, meta_mode, &meta)) != 0)
- return (ret);
-
/* Release any previous lock if not in a transaction. */
if ((ret = __TLPUT(dbc, cp->lock)) != 0)
goto err;
skip = 0;
-retry: /* Update the record number. */
+retry:
+ /*
+ * Get the meta page first
+ */
+ if (meta == NULL && (ret = __memp_fget(mpf, &metapno,
+ dbc->thread_info, dbc->txn, meta_mode, &meta)) != 0)
+ return (ret); /* Update the record number. */
+
switch (flags) {
case DB_CURRENT:
break;
case DB_NEXT_DUP:
case DB_PREV_DUP:
- ret = DB_NOTFOUND;
+ ret = DBC_ERR(dbc, DB_NOTFOUND);
goto err;
/* NOTREACHED */
case DB_NEXT:
@@ -711,7 +713,7 @@ retry: /* Update the record number. */
if (QAM_AFTER_CURRENT(meta, cp->recno)) {
pg = NULL;
if (!wait) {
- ret = DB_NOTFOUND;
+ ret = DBC_ERR(dbc, DB_NOTFOUND);
goto err;
}
/*
@@ -774,6 +776,7 @@ retry: /* Update the record number. */
DB_LOCK_UPGRADE, &metalock)) != 0) {
if (ret == DB_LOCK_DEADLOCK)
ret = DB_LOCK_NOTGRANTED;
+ (void)DBC_ERR(dbc, ret);
goto err;
}
@@ -792,6 +795,8 @@ retry: /* Update the record number. */
/* get the first record number */
cp->recno = first = meta->first_recno;
+ if (old_first == RECNO_OOB)
+ old_first = first;
break;
case DB_PREV:
@@ -799,7 +804,7 @@ retry: /* Update the record number. */
if (cp->recno != RECNO_OOB) {
if (cp->recno == meta->first_recno ||
QAM_BEFORE_FIRST(meta, cp->recno)) {
- ret = DB_NOTFOUND;
+ ret = DBC_ERR(dbc, DB_NOTFOUND);
goto err;
}
QAM_DEC_RECNO(cp->recno);
@@ -808,7 +813,7 @@ retry: /* Update the record number. */
/* FALLTHROUGH */
case DB_LAST:
if (meta->first_recno == meta->cur_recno) {
- ret = DB_NOTFOUND;
+ ret = DBC_ERR(dbc, DB_NOTFOUND);
goto err;
}
cp->recno = meta->cur_recno;
@@ -892,11 +897,11 @@ dolock: if (!with_delete || inorder || retrying) {
LOCK_INIT(lock);
goto release_retry;
}
- ret = DB_NOTFOUND;
+ ret = DBC_ERR(dbc, DB_NOTFOUND);
goto lerr;
}
if (QAM_AFTER_CURRENT(meta, cp->recno)) {
- ret = DB_NOTFOUND;
+ ret = DBC_ERR(dbc, DB_NOTFOUND);
goto lerr;
}
}
@@ -951,9 +956,37 @@ release_retry: /* Release locks and retry, if possible. */
case DB_NEXT_NODUP:
if (!with_delete)
is_first = 0;
- else if (first == cp->recno)
+ else if (first == cp->recno) {
/* we have verified that this record is gone. */
QAM_INC_RECNO(first);
+ /*
+ * If we are reading in order and the first
+ * record was not there, we need to reflect
+ * this in the meta page, so that we can
+ * avoid checking this record again and again.
+ */
+ if (inorder && cp->recno == meta->first_recno) {
+ if (DBC_LOGGING(dbc)) {
+#ifdef QDEBUG
+ (void)__log_printf(
+ dbp->env, dbc->txn,
+ "Queue O: %x %u %u %u",
+ dbc->locker ?
+ dbc->locker->id : 0,
+ cp->recno, first,
+ meta->cur_recno);
+#endif
+ if ((ret = __qam_incfirst_log(
+ dbp, dbc->txn,
+ &meta->dbmeta.lsn, 0,
+ cp->recno,
+ PGNO_BASE_MD)) != 0)
+ goto err;
+ } else
+ LSN_NOT_LOGGED(meta->dbmeta.lsn);
+ meta->first_recno = first;
+ }
+ }
if (QAM_BEFORE_FIRST(meta, cp->recno) &&
DONT_NEED_LOCKS(dbc))
flags = DB_FIRST;
@@ -979,7 +1012,7 @@ release_retry: /* Release locks and retry, if possible. */
default:
/* this is for the SET and GET_BOTH cases */
- ret = DB_KEYEMPTY;
+ ret = DBC_ERR(dbc, DB_KEYEMPTY);
goto err1;
}
retrying = 0;
@@ -1031,10 +1064,10 @@ release_retry: /* Release locks and retry, if possible. */
*/
tmp.data = qp->data;
tmp.size = t->re_len;
- if ((ret = __bam_defcmp(dbp, data, &tmp)) != 0) {
+ if ((ret = __bam_defcmp(dbp, data, &tmp, NULL)) != 0) {
if (flags == DB_GET_BOTH_RANGE)
goto release_retry;
- ret = DB_NOTFOUND;
+ ret = DBC_ERR(dbc, DB_NOTFOUND);
goto err1;
}
}
@@ -1139,14 +1172,17 @@ release_retry: /* Release locks and retry, if possible. */
* If we deleted the first record we checked then we moved
* the first pointer properly.
*/
-
- if (first == cp->recno && (skip = (first % t->rec_page)) != 0)
+ if (((QUEUE *)dbp->q_internal)->page_ext != 0)
+ stay = (QAM_RECNO_EXTENT(dbp, old_first) ==
+ QAM_RECNO_EXTENT(dbp, first));
+ if (stay && first == cp->recno &&
+ (skip = (first % t->rec_page)) != 0)
goto done;
if (meta == NULL &&
(ret = __memp_fget(mpf, &metapno,
dbc->thread_info, dbc->txn, 0, &meta)) != 0)
goto err;
- if (skip && !QAM_BEFORE_FIRST(meta, first))
+ if (stay && skip && !QAM_BEFORE_FIRST(meta, first))
goto done;
#ifdef QDEBUG
@@ -1156,7 +1192,11 @@ release_retry: /* Release locks and retry, if possible. */
dbc->locker ? dbc->locker->id : 0,
cp->recno, first, meta->first_recno);
#endif
- ret = __qam_consume(dbc, meta, first);
+ if (stay) {
+ ret = __qam_consume(dbc, meta, first);
+ } else {
+ ret = __qam_consume(dbc, meta, old_first);
+ }
}
err1: if (cp->page != NULL) {
@@ -1272,8 +1312,8 @@ __qam_consume(dbc, meta, first)
*/
if (rec_extent != 0 &&
((exact = (first % rec_extent == 0)) ||
- (first % meta->rec_page == 0) ||
- first == UINT32_MAX)) {
+ (exact = (first == UINT32_MAX)) ||
+ (first % meta->rec_page == 0))) {
#ifdef QDEBUG
if (DBC_LOGGING(dbc))
(void)__log_printf(dbp->env, dbc->txn,