summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@mongodb.com>2016-03-17 16:36:52 +1100
committerMichael Cahill <michael.cahill@mongodb.com>2016-03-17 16:36:52 +1100
commit1fdc632a101d822e14000077a60294fa973d3643 (patch)
treeffeb6421238026fb0f98d0066588d6e13dfa521a
parent3d91b967d46e4d4d51b5a2ebf9fb1d3fad50053d (diff)
parent689f3f95534c9f1f67478f8c702303274d988594 (diff)
downloadmongo-1fdc632a101d822e14000077a60294fa973d3643.tar.gz
Merge pull request #2596 from wiredtiger/wt-2414-join-extractor-lt
WT-2414 Avoid main table reads and extractions for the first index
-rw-r--r--src/cursor/cur_join.c66
-rw-r--r--src/include/cursor.h3
2 files changed, 42 insertions, 27 deletions
diff --git a/src/cursor/cur_join.c b/src/cursor/cur_join.c
index 33e4f2580b6..5f873812c11 100644
--- a/src/cursor/cur_join.c
+++ b/src/cursor/cur_join.c
@@ -95,18 +95,20 @@ __curjoin_pack_recno(WT_SESSION_IMPL *session, uint64_t r, uint8_t *buf,
}
/*
- * __curjoin_copy_primary_key --
+ * __curjoin_split_key --
* Copy the primary key from a cursor (either main table or index)
- * to another cursory.
+ * to another cursor. When copying from an index file, the index
+ * key is also returned.
*
*/
static int
-__curjoin_copy_primary_key(WT_SESSION_IMPL *session, WT_CURSOR_JOIN *cjoin,
- WT_CURSOR *tocur, WT_CURSOR *fromcur, const char *repack_fmt, bool isindex)
+__curjoin_split_key(WT_SESSION_IMPL *session, WT_CURSOR_JOIN *cjoin,
+ WT_ITEM *idxkey, WT_CURSOR *tocur, WT_CURSOR *fromcur,
+ const char *repack_fmt, bool isindex)
{
WT_CURSOR *firstcg_cur;
WT_CURSOR_INDEX *cindex;
- WT_ITEM key, *keyp;
+ WT_ITEM *keyp;
const uint8_t *p;
if (isindex) {
@@ -118,14 +120,14 @@ __curjoin_copy_primary_key(WT_SESSION_IMPL *session, WT_CURSOR_JOIN *cjoin,
*/
WT_RET(__wt_struct_repack(session, cindex->child->key_format,
repack_fmt != NULL ? repack_fmt : cindex->iface.key_format,
- &cindex->child->key, &key));
- WT_ASSERT(session, cindex->child->key.size > key.size);
- key.data = (uint8_t *)key.data + key.size;
- key.size = cindex->child->key.size - key.size;
- WT_ITEM_SET(tocur->key, key);
+ &cindex->child->key, idxkey));
+ WT_ASSERT(session, cindex->child->key.size > idxkey->size);
+ tocur->key.data = (uint8_t *)idxkey->data + idxkey->size;
+ tocur->key.size = cindex->child->key.size - idxkey->size;
if (WT_CURSOR_RECNO(tocur)) {
- p = (const uint8_t *)key.data;
- WT_RET(__wt_vunpack_uint(&p, key.size, &tocur->recno));
+ p = (const uint8_t *)tocur->key.data;
+ WT_RET(__wt_vunpack_uint(&p, tocur->key.size,
+ &tocur->recno));
} else
tocur->recno = 0;
} else {
@@ -141,6 +143,8 @@ __curjoin_copy_primary_key(WT_SESSION_IMPL *session, WT_CURSOR_JOIN *cjoin,
WT_ITEM_SET(tocur->key, *keyp);
tocur->recno = 0;
}
+ idxkey->data = NULL;
+ idxkey->size = 0;
}
return (0);
}
@@ -162,8 +166,8 @@ __curjoin_entry_iter_next(WT_CURSOR_JOIN_ITER *iter, WT_CURSOR *cursor)
* Set our key to the primary key, we'll also need this
* to check membership.
*/
- WT_RET(__curjoin_copy_primary_key(iter->session, iter->cjoin, cursor,
- iter->cursor, iter->entry->repack_format,
+ WT_RET(__curjoin_split_key(iter->session, iter->cjoin, &iter->idxkey,
+ cursor, iter->cursor, iter->entry->repack_format,
iter->entry->index != NULL));
iter->curkey = &cursor->key;
iter->entry->stats.actual_count++;
@@ -691,20 +695,30 @@ __curjoin_entry_member(WT_SESSION_IMPL *session, WT_CURSOR_JOIN *cjoin,
bloom_found = true;
}
if (entry->index != NULL) {
- memset(&v, 0, sizeof(v)); /* Keep lint quiet. */
- c = entry->main;
- c->set_key(c, key);
- if ((ret = c->search(c)) == 0)
- ret = c->get_value(c, &v);
- else if (ret == WT_NOTFOUND)
- WT_ERR_MSG(session, WT_ERROR,
- "main table for join is missing entry");
- WT_TRET(c->reset(c));
- WT_ERR(ret);
+ /*
+ * If this entry is used by the iterator, then we already
+ * have the index key, and we won't have to do any extraction
+ * either.
+ */
+ if (entry == cjoin->iter->entry)
+ WT_ITEM_SET(v, cjoin->iter->idxkey);
+ else {
+ memset(&v, 0, sizeof(v)); /* Keep lint quiet. */
+ c = entry->main;
+ c->set_key(c, key);
+ if ((ret = c->search(c)) == 0)
+ ret = c->get_value(c, &v);
+ else if (ret == WT_NOTFOUND)
+ WT_ERR_MSG(session, WT_ERROR,
+ "main table for join is missing entry");
+ WT_TRET(c->reset(c));
+ WT_ERR(ret);
+ }
} else
- v = *key;
+ WT_ITEM_SET(v, *key);
- if ((idx = entry->index) != NULL && idx->extractor != NULL) {
+ if ((idx = entry->index) != NULL && idx->extractor != NULL &&
+ entry != cjoin->iter->entry) {
WT_CLEAR(extract_cursor);
extract_cursor.iface = iface;
extract_cursor.iface.session = &session->iface;
diff --git a/src/include/cursor.h b/src/include/cursor.h
index a2110465355..7ce0159c608 100644
--- a/src/include/cursor.h
+++ b/src/include/cursor.h
@@ -289,7 +289,8 @@ struct __wt_cursor_join_iter {
WT_CURSOR_JOIN_ENTRY *entry;
WT_CURSOR *cursor; /* has null projection */
WT_CURSOR *main; /* main table with projection */
- WT_ITEM *curkey;
+ WT_ITEM *curkey; /* primary key */
+ WT_ITEM idxkey;
bool positioned;
bool isequal; /* advancing means we're done */
};