summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/meta/meta_table.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/wiredtiger/src/meta/meta_table.c')
-rw-r--r--src/third_party/wiredtiger/src/meta/meta_table.c141
1 files changed, 91 insertions, 50 deletions
diff --git a/src/third_party/wiredtiger/src/meta/meta_table.c b/src/third_party/wiredtiger/src/meta/meta_table.c
index e7074a9c1b5..9938cb07a5c 100644
--- a/src/third_party/wiredtiger/src/meta/meta_table.c
+++ b/src/third_party/wiredtiger/src/meta/meta_table.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2014-2015 MongoDB, Inc.
+ * Copyright (c) 2014-2016 MongoDB, Inc.
* Copyright (c) 2008-2014 WiredTiger, Inc.
* All rights reserved.
*
@@ -31,21 +31,28 @@ __metadata_turtle(const char *key)
}
/*
- * __wt_metadata_open --
- * Opens the metadata file, sets session->meta_dhandle.
+ * __wt_metadata_cursor_open --
+ * Opens a cursor on the metadata.
*/
int
-__wt_metadata_open(WT_SESSION_IMPL *session)
+__wt_metadata_cursor_open(
+ WT_SESSION_IMPL *session, const char *config, WT_CURSOR **cursorp)
{
WT_BTREE *btree;
+ WT_DECL_RET;
+ const char *open_cursor_cfg[] = {
+ WT_CONFIG_BASE(session, WT_SESSION_open_cursor), config, NULL };
- if (session->meta_dhandle != NULL)
- return (0);
-
- WT_RET(__wt_session_get_btree(session, WT_METAFILE_URI, NULL, NULL, 0));
+ WT_WITHOUT_DHANDLE(session, ret = __wt_open_cursor(
+ session, WT_METAFILE_URI, NULL, open_cursor_cfg, cursorp));
+ WT_RET(ret);
- session->meta_dhandle = session->dhandle;
- WT_ASSERT(session, session->meta_dhandle != NULL);
+ /*
+ * Retrieve the btree from the cursor, rather than the session because
+ * we don't always switch the metadata handle in to the session before
+ * entering this function.
+ */
+ btree = ((WT_CURSOR_BTREE *)(*cursorp))->btree;
/*
* Set special flags for the metadata file: eviction (the metadata file
@@ -56,7 +63,6 @@ __wt_metadata_open(WT_SESSION_IMPL *session)
* opens (the first update is safe because it's single-threaded from
* wiredtiger_open).
*/
- btree = S2BT(session);
if (!F_ISSET(btree, WT_BTREE_IN_MEMORY))
F_SET(btree, WT_BTREE_IN_MEMORY);
if (!F_ISSET(btree, WT_BTREE_NO_EVICTION))
@@ -64,44 +70,81 @@ __wt_metadata_open(WT_SESSION_IMPL *session)
if (F_ISSET(btree, WT_BTREE_NO_LOGGING))
F_CLR(btree, WT_BTREE_NO_LOGGING);
- /* The metadata handle doesn't need to stay locked -- release it. */
- return (__wt_session_release_btree(session));
+ return (0);
}
/*
* __wt_metadata_cursor --
- * Opens a cursor on the metadata.
+ * Returns the session's cached metadata cursor, unless it's in use, in
+ * which case it opens and returns another metadata cursor.
*/
int
-__wt_metadata_cursor(
- WT_SESSION_IMPL *session, const char *config, WT_CURSOR **cursorp)
+__wt_metadata_cursor(WT_SESSION_IMPL *session, WT_CURSOR **cursorp)
{
- WT_DATA_HANDLE *saved_dhandle;
- WT_DECL_RET;
- bool is_dead;
- const char *cfg[] =
- { WT_CONFIG_BASE(session, WT_SESSION_open_cursor), config, NULL };
+ WT_CURSOR *cursor;
- saved_dhandle = session->dhandle;
- WT_ERR(__wt_metadata_open(session));
+ /*
+ * If we don't have a cached metadata cursor, or it's already in use,
+ * we'll need to open a new one.
+ */
+ cursor = NULL;
+ if (session->meta_cursor == NULL ||
+ F_ISSET(session->meta_cursor, WT_CURSTD_META_INUSE)) {
+ WT_RET(__wt_metadata_cursor_open(session, NULL, &cursor));
+ if (session->meta_cursor == NULL) {
+ session->meta_cursor = cursor;
+ cursor = NULL;
+ }
+ }
- session->dhandle = session->meta_dhandle;
+ /*
+ * If there's no cursor return, we're done, our caller should have just
+ * been triggering the creation of the session's cached cursor. There
+ * should not be an open local cursor in that case, but caution doesn't
+ * cost anything.
+ */
+ if (cursorp == NULL)
+ return (cursor == NULL ? 0 : cursor->close(cursor));
- /*
- * We use the metadata a lot, so we have a handle cached; lock it and
- * increment the in-use counter once the cursor is open.
+ /*
+ * If the cached cursor is in use, return the newly opened cursor, else
+ * mark the cached cursor in use and return it.
*/
- WT_ERR(__wt_session_lock_dhandle(session, 0, &is_dead));
+ if (F_ISSET(session->meta_cursor, WT_CURSTD_META_INUSE))
+ *cursorp = cursor;
+ else {
+ *cursorp = session->meta_cursor;
+ F_SET(session->meta_cursor, WT_CURSTD_META_INUSE);
+ }
+ return (0);
+}
- /* The metadata should never be closed. */
- WT_ASSERT(session, !is_dead);
+/*
+ * __wt_metadata_cursor_release --
+ * Release a metadata cursor.
+ */
+int
+__wt_metadata_cursor_release(WT_SESSION_IMPL *session, WT_CURSOR **cursorp)
+{
+ WT_CURSOR *cursor;
- WT_ERR(__wt_curfile_create(session, NULL, cfg, false, false, cursorp));
- __wt_cursor_dhandle_incr_use(session);
+ WT_UNUSED(session);
- /* Restore the caller's btree. */
-err: session->dhandle = saved_dhandle;
- return (ret);
+ if ((cursor = *cursorp) == NULL)
+ return (0);
+ *cursorp = NULL;
+
+ /*
+ * If using the session's cached metadata cursor, clear the in-use flag
+ * and reset it, otherwise, discard the cursor.
+ */
+ if (F_ISSET(cursor, WT_CURSTD_META_INUSE)) {
+ WT_ASSERT(session, cursor == session->meta_cursor);
+
+ F_CLR(cursor, WT_CURSTD_META_INUSE);
+ return (cursor->reset(cursor));
+ }
+ return (cursor->close(cursor));
}
/*
@@ -124,14 +167,13 @@ __wt_metadata_insert(
WT_RET_MSG(session, EINVAL,
"%s: insert not supported on the turtle file", key);
- WT_RET(__wt_metadata_cursor(session, NULL, &cursor));
+ WT_RET(__wt_metadata_cursor(session, &cursor));
cursor->set_key(cursor, key);
cursor->set_value(cursor, value);
WT_ERR(cursor->insert(cursor));
if (WT_META_TRACKING(session))
WT_ERR(__wt_meta_track_insert(session, key));
-
-err: WT_TRET(cursor->close(cursor));
+err: WT_TRET(__wt_metadata_cursor_release(session, &cursor));
return (ret);
}
@@ -152,7 +194,7 @@ __wt_metadata_update(
__metadata_turtle(key) ? "" : "not "));
if (__metadata_turtle(key)) {
- WT_WITH_TURTLE_LOCK(session,
+ WT_WITH_TURTLE_LOCK(session, ret,
ret = __wt_turtle_update(session, key, value));
return (ret);
}
@@ -160,12 +202,14 @@ __wt_metadata_update(
if (WT_META_TRACKING(session))
WT_RET(__wt_meta_track_update(session, key));
- WT_RET(__wt_metadata_cursor(session, "overwrite", &cursor));
+ WT_RET(__wt_metadata_cursor(session, &cursor));
+ /* This cursor needs to have overwrite semantics. */
+ WT_ASSERT(session, F_ISSET(cursor, WT_CURSTD_OVERWRITE));
+
cursor->set_key(cursor, key);
cursor->set_value(cursor, value);
WT_ERR(cursor->insert(cursor));
-
-err: WT_TRET(cursor->close(cursor));
+err: WT_TRET(__wt_metadata_cursor_release(session, &cursor));
return (ret);
}
@@ -188,14 +232,13 @@ __wt_metadata_remove(WT_SESSION_IMPL *session, const char *key)
WT_RET_MSG(session, EINVAL,
"%s: remove not supported on the turtle file", key);
- WT_RET(__wt_metadata_cursor(session, NULL, &cursor));
+ WT_RET(__wt_metadata_cursor(session, &cursor));
cursor->set_key(cursor, key);
WT_ERR(cursor->search(cursor));
if (WT_META_TRACKING(session))
WT_ERR(__wt_meta_track_update(session, key));
WT_ERR(cursor->remove(cursor));
-
-err: WT_TRET(cursor->close(cursor));
+err: WT_TRET(__wt_metadata_cursor_release(session, &cursor));
return (ret);
}
@@ -205,8 +248,7 @@ err: WT_TRET(cursor->close(cursor));
* The caller is responsible for freeing the allocated memory.
*/
int
-__wt_metadata_search(
- WT_SESSION_IMPL *session, const char *key, char **valuep)
+__wt_metadata_search(WT_SESSION_IMPL *session, const char *key, char **valuep)
{
WT_CURSOR *cursor;
WT_DECL_RET;
@@ -230,7 +272,7 @@ __wt_metadata_search(
* Metadata updates use non-transactional techniques (such as the
* schema and metadata locks) to protect access to in-flight updates.
*/
- WT_RET(__wt_metadata_cursor(session, NULL, &cursor));
+ WT_RET(__wt_metadata_cursor(session, &cursor));
cursor->set_key(cursor, key);
WT_WITH_TXN_ISOLATION(session, WT_ISO_READ_UNCOMMITTED,
ret = cursor->search(cursor));
@@ -238,7 +280,6 @@ __wt_metadata_search(
WT_ERR(cursor->get_value(cursor, &value));
WT_ERR(__wt_strdup(session, value, valuep));
-
-err: WT_TRET(cursor->close(cursor));
+err: WT_TRET(__wt_metadata_cursor_release(session, &cursor));
return (ret);
}