Compare commits

...

21 Commits
1.1.2 ... 1.1.3

Author SHA1 Message Date
Michael Cahill
2698a34aa3 Merge branches 'develop' and 'master' of github.com:wiredtiger/wiredtiger 2012-04-04 09:04:26 +10:00
Michael Cahill
2da36349a2 Don't report range errors for config values that aren't well-formed integers. 2012-04-03 17:29:02 +10:00
Michael Cahill
21386f956e Remove the release tree after creating the tarball. 2012-03-30 22:24:24 +11:00
Michael Cahill
59fddb2109 s_types should check in more directories than just src. 2012-03-30 22:24:21 +11:00
Keith Bostic
a82a65805f When we removed test/config.i, it broke s_types -- simplify s_types,
just do a find on src/.
2012-03-28 11:32:16 +00:00
Keith Bostic
6a7972d8ca We no longer use __wt_buf_swap(), remove it (it's trivial to replace
if it comes back).
2012-03-28 11:26:06 +00:00
Keith Bostic
3c8f54583a move CURDUMP_PASS into the WiredTiger name space, don't complain that
it isn't used.
2012-03-28 11:24:47 +00:00
Michael Cahill
1a2cf3ba21 Remove test/config*, it's obsolete now. 2012-03-28 22:11:36 +11:00
Michael Cahill
405f6a3969 Layer dump cursors on top of any cursor type.
--HG--
extra : rebase_source : a0ddaa6ba4d7ed5fdb7ca8811f2147e3ede0bad3
2012-03-11 10:46:05 +11:00
Michael Cahill
a3de556296 Push handling of "standard" cursor config flags into __wt_cursor_init.
--HG--
extra : rebase_source : dfa07973f66199329fede015f43ac813315bd1f8
2012-03-11 10:46:03 +11:00
Michael Cahill
39fdfd8d48 Remove the CURSTD_FILE and CURSTD_TABLE flags: if we need to look inside a
cursor beyond the public fields, we're breaking layering.

--HG--
extra : rebase_source : 06d12a9724f81743a140a9875f816e857993e405
2012-03-11 10:46:00 +11:00
Michael Cahill
787035cf14 Fix the "exclusive" config for WT_SESSION::create.
1. Make it work for files within a single session.
2. Make it work for files across sessions.
3. Make other data sources consistent with files.
closes #181

--HG--
extra : rebase_source : 29b07b914508b8fcef1a4e4c212d32e5f21dd50e
2012-03-28 22:02:18 +11:00
Michael Cahill
fb9d316b61 Typo in usage method for "wt write".
--HG--
extra : rebase_source : 32fbccc4b5c7c38b685ee00183f2e6f04e31c72c
2012-03-28 16:56:15 +11:00
Keith Bostic
c4db159a08 Add a couple more copyrights. 2012-03-26 21:15:15 +00:00
Keith Bostic
261b6640d4 update a comment, no real change. 2012-03-25 10:34:42 +00:00
Keith Bostic
f977094e54 Don't force the delete percentage to 0 (so salvage runs), if the
configuration says differently.
2012-03-24 18:27:03 +00:00
Keith Bostic
d346eade1e Add a section on replacing the default system memory allocator to the
tuning page.

An example setting the cache to 10MB isn't useful, crank the example
to 500MB.
2012-03-21 19:25:15 +00:00
Michael Cahill
966b216ee8 Merge branch 'master' of github.com:wiredtiger/wiredtiger 2012-03-20 23:35:43 +11:00
Michael Cahill
763fd3c876 Cut release 1.1.2.
--HG--
extra : rebase_source : 2a3ef9165ed9001ebb2b013577652d831140c370
2012-03-20 23:13:44 +11:00
Michael Cahill
99bc3af83b ../../../../ext/compressors/bzip2_compress/bzip2_compress.c:161: warning: implicit conversion shortens 64-bit value into a 32-bit value
--HG--
extra : rebase_source : 67f5d6fe20895f7f2891df98c1062b84a2db85da
2012-03-20 23:12:31 +11:00
Keith Bostic
06b0957920 Don't complain about buffers that weren't discarded yet, it breaks the
test suite.
2012-03-20 08:56:48 +00:00
45 changed files with 527 additions and 454 deletions

57
NEWS
View File

@@ -1,11 +1,51 @@
WiredTiger release 1.1.2, 2012-03-20
------------------------------------
Add public-domain copyright notices to the extension code.
test/format can now run multi-threaded, fixed two bugs it found:
(1) When iterating backwards through a skiplist, we could race with an insert.
(2) If eviction fails for a page, we have to assume that eviction has unlocked
the reference.
Scan row-store leaf pages twice when reading to reduce the overhead of the
index array.
Eviction race fixes:
(1) Call __rec_review with WT_REFs: don't look at the page until we've checked
the state.
(2) Clear the eviction point if we hit it when discarding a child page, not
just the parent.
Eviction tuning changes, particularly for read-only, out-of-cache workloads.
Only notify the eviction server if an application thread doesn't find any pages
to evict, and then only once.
Only spin on the LRU lock if there might be pages in the LRU queue to evict.
Keep the current eviction point in memory and make the eviction walk run
concurrent with LRU eviction.
Every test now has err/out captured, and it is checked to assure it is empty at
the end of every test.
WiredTiger release 1.1.1, 2012-03-12
------------------------------------
Default to a verbose build: that can be switched off by running "configure --enable-silent-rules").
Default to a verbose build: that can be switched off by running "configure
--enable-silent-rules").
Account for all memory allocated when reading a page into cache. Total memory usage is now much closer to the cache size when using many small keys and values.
Account for all memory allocated when reading a page into cache. Total memory
usage is now much closer to the cache size when using many small keys and
values.
Have application threads trigger a retry forced page eviction rather than blocking eviction. This allows rec_evict.c to simply set the WT_REF state to WT_REF_MEM after all failures, and fixes a bug where pages on the forced eviction queue would end up with state WT_REF_MEM, meaning they could be chosen for eviction multiple times.
Have application threads trigger a retry forced page eviction rather than
blocking eviction. This allows rec_evict.c to simply set the WT_REF state to
WT_REF_MEM after all failures, and fixes a bug where pages on the forced
eviction queue would end up with state WT_REF_MEM, meaning they could be chosen
for eviction multiple times.
Grow existing scratch buffers in preference to allocating new ones.
@@ -13,11 +53,16 @@ Fix a race between threads reading in and then modifying a page.
Get rid of the pinned flag: it is no longer used.
Fix a race where btree files weren't completely closed before they could be re-opened. This behavior can be triggered by using a new session on every operation (see the new -S flag to the test/thread program). [#178]
Fix a race where btree files weren't completely closed before they could be
re-opened. This behavior can be triggered by using a new session on every
operation (see the new -S flag to the test/thread program). [#178]
When connections are closed, create a session and discard the btree handles. This fixes a long-standing bug in closing a connection: if for any reason there are btree handles still open, we need a real session handle to close them.
When connections are closed, create a session and discard the btree handles.
This fixes a long-standing bug in closing a connection: if for any reason there
are btree handles still open, we need a real session handle to close them.
Really close btree handles: otherwise we can't safely remove or rename them. Fixes test failures in test_base02 (among others).
Really close btree handles: otherwise we can't safely remove or rename them.
Fixes test failures in test_base02 (among others).
Wait for application threads in LRU eviction to drain before walking a file.

4
README
View File

@@ -1,6 +1,6 @@
WiredTiger 1.1.1: (March 16, 2012)
WiredTiger 1.1.2: (March 20, 2012)
This is version 1.1.1 of WiredTiger.
This is version 1.1.2 of WiredTiger.
WiredTiger documentation can be found at:

View File

@@ -2,8 +2,8 @@ dnl build by dist/s_version
VERSION_MAJOR=1
VERSION_MINOR=1
VERSION_PATCH=1
VERSION_STRING='"WiredTiger 1.1.1: (March 12, 2012)"'
VERSION_PATCH=2
VERSION_STRING='"WiredTiger 1.1.2: (March 20, 2012)"'
AC_SUBST(VERSION_MAJOR)
AC_SUBST(VERSION_MINOR)

View File

@@ -1,2 +1,2 @@
dnl WiredTiger product version for AC_INIT. Maintained by dist/s_version
1.1.1
1.1.2

2
dist/RELEASE vendored
View File

@@ -1,6 +1,6 @@
WIREDTIGER_VERSION_MAJOR=1
WIREDTIGER_VERSION_MINOR=1
WIREDTIGER_VERSION_PATCH=1
WIREDTIGER_VERSION_PATCH=2
WIREDTIGER_VERSION="$WIREDTIGER_VERSION_MAJOR.$WIREDTIGER_VERSION_MINOR.$WIREDTIGER_VERSION_PATCH"
WIREDTIGER_RELEASE_DATE=`date "+%B %e, %Y"`

View File

@@ -12,7 +12,6 @@ skip dist/serial.py
skip dist/stat_data.py
skip dist/stat.py
skip docs/tools/doxypy.py
skip docs/tools/fixlinks.py
skip lang/python/setup.py
skip lang/python/src/wiredtiger/service/constants.py
skip lang/python/src/wiredtiger/service/__init__.py

1
dist/s_funcs.list vendored
View File

@@ -1,4 +1,5 @@
# List of functions that aren't found by s_funcs, but that's OK.
WT_CURDUMP_PASS
__bit_ffs
__bit_nclr
__wt_bm_addr_stderr

2
dist/s_release vendored
View File

@@ -47,3 +47,5 @@ echo "Packing release into $RELEASE_DIR/$PKG.tar.bz2"
echo "Packing documentation into $RELEASE_DIR/$PKG-docs.tar.bz2"
(cd "$RELEASE_DIR" && tar cf - $PKG/[A-Z][A-Z]* $PKG/docs | \
bzip2 -9 > $PKG-docs.tar.bz2)
rm -r $DEST

6
dist/s_types vendored
View File

@@ -3,12 +3,8 @@
t=__wt.$$
trap 'rm -f $t; exit 0' 0 1 2 3 13 15
l="`cd .. && echo src/include/*.[hi] src/include/*.in`"
l="`cd .. && find test -name '*.c' -print`"
l="`cd .. && echo */*.i`"
l="$l `sed -e '/^[a-z]/! d' filelist`"
(cd .. &&
l="`find examples ext src test -name '*.[chi]' -o -name '*.in'`"
egrep 'u_quad|u_int8_t|u_int16_t|u_int32_t|u_int64_t' $l |
sed '/@u_quad_decl@/d') > $t
test -s $t && cat $t && exit 1

View File

@@ -133,6 +133,7 @@ inuse
io
ip
je
jemalloc
jni
json
keyexist
@@ -154,6 +155,7 @@ lsn
lt
mailto
mainpage
malloc
malloc'd
marshalled
marshalling
@@ -255,6 +257,7 @@ subpage
superset
tablename
tcl
tcmalloc
td
th
thang

View File

@@ -9,7 +9,7 @@ function.
The effectiveness of the cache can be measured by reviewing the page
eviction statistics for the database.
An example of setting a cache size to 10MB:
An example of setting a cache size to 500MB:
@snippet ex_config.c configure cache size
@@ -90,6 +90,17 @@ An example of configuring page sizes:
@snippet ex_file.c file create
@section memory Memory allocation
I/O intensive threaded applications, where the working set does not fit
into the available cache, can be dominated by memory allocation because
the WiredTiger engine has to free and re-allocate memory as part of many
queries. Replacing the system's malloc implementation with one that has
better threaded performance (for example, Google's
<a href="http://goog-perftools.sourceforge.net/doc/tcmalloc.html">tcmalloc</a>,
or <a href="http://www.canonware.com/jemalloc">jemalloc</a>),
can dramatically improve throughput.
@section statistics Performance monitoring with statistics
WiredTiger maintains a variety of statistics that can be read with a
@@ -116,5 +127,4 @@ statistics until the cursor returns the end of the list.
Note the raw value of the statistic is available from the \c value
field, as well as a printable string version of the value.
*/

View File

@@ -1,5 +1,30 @@
#!/usr/bin/env python
#
# Copyright (c) 2008-2012 WiredTiger, Inc.
#
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# This Python script is run as part of generating the documentation for the
# WiredTiger Python API. It runs after doxypy, and turns method names in
# comments into references to the corresponding function in the C API.

View File

@@ -1,4 +1,29 @@
#!/bin/sh
#
# Copyright (c) 2008-2012 WiredTiger, Inc.
#
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
tooldir=`dirname $0`

View File

@@ -46,7 +46,7 @@ int main(void)
/*! [configure cache size] */
if ((ret = wiredtiger_open(home, NULL,
"create,cache_size=10M", &conn)) != 0)
"create,cache_size=500M", &conn)) != 0)
fprintf(stderr, "Error connecting to %s: %s\n",
home, wiredtiger_strerror(ret));
/*! [configure cache size] */

View File

@@ -158,9 +158,9 @@ bzip2_compress(WT_COMPRESSOR *compressor, WT_SESSION *session,
return (bzip2_error(session, "BZ2_bzCompressInit", ret));
bz.next_in = (char *)src;
bz.avail_in = src_len;
bz.avail_in = (uint32_t)src_len;
bz.next_out = (char *)dst;
bz.avail_out = dst_len;
bz.avail_out = (uint32_t)dst_len;
if ((ret = BZ2_bzCompress(&bz, BZ_FINISH)) == BZ_STREAM_END) {
*compression_failed = 0;
*result_lenp = dst_len - bz.avail_out;
@@ -193,9 +193,9 @@ bzip2_decompress(WT_COMPRESSOR *compressor, WT_SESSION *session,
return (bzip2_error(session, "BZ2_bzDecompressInit", ret));
bz.next_in = (char *)src;
bz.avail_in = src_len;
bz.avail_in = (uint32_t)src_len;
bz.next_out = (char *)dst;
bz.avail_out = dst_len;
bz.avail_out = (uint32_t)dst_len;
if ((ret = BZ2_bzDecompress(&bz)) == BZ_STREAM_END) {
*result_lenp = dst_len - bz.avail_out;
ret = 0;

View File

@@ -21,7 +21,7 @@ __wt_block_truncate(WT_SESSION_IMPL *session, const char *filename)
int ret;
/* Open the underlying file handle. */
WT_RET(__wt_open(session, filename, 0, 1, &fh));
WT_RET(__wt_open(session, filename, 0, 0, 1, &fh));
/* Truncate the file. */
WT_ERR(__wt_ftruncate(session, fh, (off_t)0));
@@ -43,18 +43,10 @@ int
__wt_block_create(WT_SESSION_IMPL *session, const char *filename)
{
WT_FH *fh;
int exist, ret;
int ret;
/* Check to see if the file exists -- we don't want to overwrite it. */
WT_RET(__wt_exist(session, filename, &exist));
if (exist)
WT_RET_MSG(session, WT_ERROR,
"the file %s already exists; to re-create it, remove it "
"first, then create it",
filename);
/* Open the underlying file handle. */
WT_RET(__wt_open(session, filename, 1, 1, &fh));
/* Create the underlying file and open a handle. */
WT_RET(__wt_open(session, filename, 1, 1, 1, &fh));
/* Write out the file's meta-data. */
ret = __wt_desc_init(session, fh);
@@ -96,7 +88,7 @@ __wt_block_open(WT_SESSION_IMPL *session, const char *filename,
__wt_block_freelist_open(session, block);
/* Open the underlying file handle. */
WT_ERR(__wt_open(session, filename, 1, 1, &block->fh));
WT_ERR(__wt_open(session, filename, 0, 0, 1, &block->fh));
/* Get the allocation size. */
WT_ERR(__wt_config_getones(session, config, "allocation_size", &cval));

View File

@@ -812,8 +812,8 @@ __slvg_col_range_overlap(
* #7 AAAAAAAAAAAAAAAA same as #2
* #8 AAAAAAAAAAAAA same as #3
* #9 AAAAA A is a prefix of B
* #10 AAAAAAAAAA A is a suffix of B
* #11 AAAAAA A is middle of B
* #10 AAAAAA A is middle of B
* #11 AAAAAAAAAA A is a suffix of B
*
* Because the leaf page array was sorted by record number and a_trk
* appears earlier in that array than b_trk, cases #2/7, #10 and #11
@@ -1351,8 +1351,8 @@ __slvg_row_range_overlap(
* #7 AAAAAAAAAAAAAAAA same as #2
* #8 AAAAAAAAAAAAA same as #3
* #9 AAAAA A is a prefix of B
* #10 AAAAAAAAAA A is a suffix of B
* #11 AAAAAA A is middle of B
* #10 AAAAAA A is middle of B
* #11 AAAAAAAAAA A is a suffix of B
*
* Because the leaf page array was sorted by record number and a_trk
* appears earlier in that array than b_trk, cases #2/7, #10 and #11

View File

@@ -356,9 +356,6 @@ __process_value(WT_CONFIG *conf, WT_CONFIG_ITEM *value)
} else if (value->type == ITEM_NUM) {
errno = 0;
value->val = strtoll(value->str, &endptr, 10);
if (errno == ERANGE)
return (
__config_err(conf, "Number out of range", ERANGE));
/* Check any leftover characters. */
while (endptr < value->str + value->len)
@@ -396,7 +393,17 @@ __process_value(WT_CONFIG *conf, WT_CONFIG_ITEM *value)
value->type = ITEM_ID;
break;
}
}
/*
* If we parsed the the whole string but the number is out of
* range, report an error. Don't report an error for strings
* that aren't well-formed integers: if an integer is expected,
* that will be caught by __wt_config_check.
*/
if (value->type == ITEM_NUM && errno == ERANGE)
return (
__config_err(conf, "Number out of range", ERANGE));
}
return (0);
}

View File

@@ -464,7 +464,7 @@ wiredtiger_open(const char *home, WT_EVENT_HANDLER *event_handler,
WT_ERR(__wt_config_gets(session, cfg, "logging", &cval));
if (cval.val != 0)
WT_ERR(__wt_open(
session, WT_LOG_FILENAME, 1, 0, &conn->log_fh));
session, WT_LOG_FILENAME, 1, 0, 0, &conn->log_fh));
/* Configure direct I/O and buffer alignment. */
WT_ERR(__wt_config_gets(session, cfg, "buffer_alignment", &cval));
@@ -606,7 +606,7 @@ __conn_single(WT_CONNECTION_IMPL *conn, const char **cfg)
*/
WT_RET(__wt_config_gets(session, cfg, "create", &cval));
WT_RET(__wt_open(session,
WT_FLAGFILE, cval.val == 0 ? 0 : 1, 0, &conn->lock_fh));
WT_FLAGFILE, cval.val == 0 ? 0 : 1, 0, 0, &conn->lock_fh));
/*
* Lock a byte of the file: if we don't get the lock, some other process
@@ -698,7 +698,7 @@ __conn_config(WT_CONNECTION_IMPL *conn, const char **cfg, WT_ITEM **cbufp)
return (0);
/* Open the configuration file. */
WT_RET(__wt_open(session, WT_CONFIGFILE, 0, 0, &fh));
WT_RET(__wt_open(session, WT_CONFIGFILE, 0, 0, 0, &fh));
WT_ERR(__wt_filesize(session, fh, &size));
if (size == 0)
goto err;

View File

@@ -67,8 +67,7 @@ __wt_curconfig_open(WT_SESSION_IMPL *session,
cursor->key_format = cursor->value_format = "S";
STATIC_ASSERT(offsetof(WT_CURSOR_CONFIG, iface) == 0);
WT_ERR(__wt_cursor_init(cursor, uri, 0, 1, cfg));
*cursorp = cursor;
WT_ERR(__wt_cursor_init(cursor, uri, 0, cfg, cursorp));
if (0) {
err: __wt_free(session, cconfig);

View File

@@ -9,63 +9,36 @@
/*
* __raw_to_dump --
* We have a buffer where the data item contains a raw value, convert it
* to a printable string.
* We have a buffer where the data item contains a raw value,
* convert it to a printable string.
*/
static int
__raw_to_dump(
WT_SESSION_IMPL *session, WT_ITEM *from, WT_ITEM *to, int hexonly)
{
WT_ITEM *tmp;
uint32_t size;
/*
* In the worst case, every character takes up 3 spaces, plus a
* trailing nul byte.
*/
WT_RET(__wt_scr_alloc(session, from->size * 3 + 10, &tmp));
size = from->size;
if (hexonly)
__wt_raw_to_hex(from->data, tmp->mem, &size);
WT_RET(__wt_raw_to_hex(session, from->data, from->size, to));
else
__wt_raw_to_esc_hex(from->data, tmp->mem, &size);
tmp->size = size;
__wt_buf_swap(to, tmp);
__wt_scr_free(&tmp);
WT_RET(
__wt_raw_to_esc_hex(session, from->data, from->size, to));
return (0);
}
/*
* __dump_to_raw --
* We have a scratch buffer where the data item contains a dump string,
* We have a buffer containing a dump string,
* convert it to a raw value.
*/
static int
__dump_to_raw(
WT_SESSION_IMPL *session, const char *src_arg, WT_ITEM *item, int hexonly)
{
uint32_t size;
/*
* XXX
* Overwrite the string in place: the underlying cursor set_key and
* set_value functions are going to use the cursor's key and value
* buffers, which means we can't. This should probably be fixed by
* layering the dump cursor on top of other cursors and then we can
* use the dump cursor's key/value buffers.
*/
if (hexonly)
WT_RET(__wt_hex_to_raw(
session, (void *)src_arg, (void *)src_arg, &size));
WT_RET(__wt_hex_to_raw(session, src_arg, item));
else
WT_RET(__wt_esc_hex_to_raw(
session, (void *)src_arg, (void *)src_arg, &size));
WT_RET(__wt_esc_hex_to_raw(session, src_arg, item));
memset(item, 0, sizeof(WT_ITEM));
item->data = src_arg;
item->size = size;
return (0);
}
@@ -76,26 +49,24 @@ __dump_to_raw(
static int
__curdump_get_key(WT_CURSOR *cursor, ...)
{
WT_CURSOR *child;
WT_CURSOR_DUMP *cdump;
WT_ITEM item, *itemp;
WT_SESSION_IMPL *session;
int ret;
uint64_t recno;
va_list ap;
cdump = (WT_CURSOR_DUMP *)cursor;
child = cdump->child;
CURSOR_API_CALL(cursor, session, get_key, NULL);
if (WT_CURSOR_RECNO(cursor) && !F_ISSET(cursor, WT_CURSTD_RAW)) {
if (F_ISSET(cursor, WT_CURSTD_TABLE))
WT_ERR(__wt_curtable_get_key(cursor, &recno));
else
WT_ERR(__wt_cursor_get_key(cursor, &recno));
WT_ERR(child->get_key(child, &recno));
WT_ERR(__wt_buf_fmt(session, &cursor->key, "%" PRIu64, recno));
} else {
if (F_ISSET(cursor, WT_CURSTD_TABLE))
WT_ERR(__wt_curtable_get_key(cursor, &item));
else
WT_ERR(__wt_cursor_get_key(cursor, &item));
WT_ERR(child->get_key(child, &item));
WT_ERR(__raw_to_dump(session, &item,
&cursor->key, F_ISSET(cursor, WT_CURSTD_DUMP_HEX) ? 1 : 0));
@@ -150,13 +121,16 @@ format: WT_RET_MSG(session, EINVAL, "%s: invalid record number", p);
static void
__curdump_set_key(WT_CURSOR *cursor, ...)
{
WT_ITEM item;
WT_CURSOR_DUMP *cdump;
WT_CURSOR *child;
WT_SESSION_IMPL *session;
uint64_t recno;
va_list ap;
const char *p;
int ret;
cdump = (WT_CURSOR_DUMP *)cursor;
child = cdump->child;
CURSOR_API_CALL(cursor, session, set_key, NULL);
va_start(ap, cursor);
@@ -169,18 +143,12 @@ __curdump_set_key(WT_CURSOR *cursor, ...)
if (WT_CURSOR_RECNO(cursor) && !F_ISSET(cursor, WT_CURSTD_RAW)) {
WT_ERR(str2recno(session, p, &recno));
if (F_ISSET(cursor, WT_CURSTD_TABLE))
__wt_curtable_set_key(cursor, recno);
else
__wt_cursor_set_key(cursor, recno);
child->set_key(child, recno);
} else {
WT_ERR(__dump_to_raw(session,
p, &item, F_ISSET(cursor, WT_CURSTD_DUMP_HEX) ? 1 : 0));
WT_ERR(__dump_to_raw(session, p, &cursor->key,
F_ISSET(cursor, WT_CURSTD_DUMP_HEX) ? 1 : 0));
if (F_ISSET(cursor, WT_CURSTD_TABLE))
__wt_curtable_set_key(cursor, &item);
else
__wt_cursor_set_key(cursor, &item);
child->set_key(child, &cursor->key);
}
if (0) {
@@ -198,17 +166,18 @@ err: cursor->saved_err = ret;
static int
__curdump_get_value(WT_CURSOR *cursor, ...)
{
WT_CURSOR_DUMP *cdump;
WT_CURSOR *child;
WT_ITEM item, *itemp;
WT_SESSION_IMPL *session;
va_list ap;
int ret;
cdump = (WT_CURSOR_DUMP *)cursor;
child = cdump->child;
CURSOR_API_CALL(cursor, session, get_value, NULL);
if (F_ISSET(cursor, WT_CURSTD_TABLE))
WT_ERR(__wt_curtable_get_value(cursor, &item));
else
WT_ERR(__wt_cursor_get_value(cursor, &item));
WT_ERR(child->get_value(child, &item));
WT_ERR(__raw_to_dump(session, &item,
&cursor->value, F_ISSET(cursor, WT_CURSTD_DUMP_HEX) ? 1 : 0));
@@ -233,12 +202,15 @@ err: API_END(session);
static void
__curdump_set_value(WT_CURSOR *cursor, ...)
{
WT_ITEM item;
WT_CURSOR_DUMP *cdump;
WT_CURSOR *child;
WT_SESSION_IMPL *session;
va_list ap;
int ret;
const char *p;
cdump = (WT_CURSOR_DUMP *)cursor;
child = cdump->child;
CURSOR_API_CALL(cursor, session, set_value, NULL);
va_start(ap, cursor);
@@ -249,12 +221,9 @@ __curdump_set_value(WT_CURSOR *cursor, ...)
va_end(ap);
WT_ERR(__dump_to_raw(session,
p, &item, F_ISSET(cursor, WT_CURSTD_DUMP_HEX) ? 1 : 0));
p, &cursor->value, F_ISSET(cursor, WT_CURSTD_DUMP_HEX) ? 1 : 0));
if (F_ISSET(cursor, WT_CURSTD_TABLE))
__wt_curtable_set_value(cursor, &item);
else
__wt_cursor_set_value(cursor, &item);
child->set_value(child, &cursor->value);
if (0) {
err: cursor->saved_err = ret;
@@ -264,15 +233,111 @@ err: cursor->saved_err = ret;
API_END(session);
}
/* Pass through a call to the underlying cursor. */
#define WT_CURDUMP_PASS(op) \
static int \
__curdump_##op(WT_CURSOR *cursor) \
{ \
WT_CURSOR_DUMP *cdump; \
\
cdump = (WT_CURSOR_DUMP *)cursor; \
return (cdump->child->op(cdump->child)); \
}
WT_CURDUMP_PASS(next)
WT_CURDUMP_PASS(prev)
WT_CURDUMP_PASS(reset)
WT_CURDUMP_PASS(search)
static int
__curdump_search_near(WT_CURSOR *cursor, int *exact)
{
WT_CURSOR_DUMP *cdump;
cdump = (WT_CURSOR_DUMP *)cursor;
return (cdump->child->search_near(cdump->child, exact));
}
WT_CURDUMP_PASS(insert)
WT_CURDUMP_PASS(update)
WT_CURDUMP_PASS(remove)
static int
__curdump_close(WT_CURSOR *cursor)
{
WT_CURSOR_DUMP *cdump;
WT_CURSOR *child;
WT_SESSION_IMPL *session;
int ret;
cdump = (WT_CURSOR_DUMP *)cursor;
child = cdump->child;
ret = 0;
CURSOR_API_CALL(cursor, session, get_key, NULL);
if (child != NULL)
WT_TRET(child->close(child));
/* We shared the child's URI. */
cursor->uri = NULL;
WT_TRET(__wt_cursor_close(cursor));
API_END(session);
return (ret);
}
/*
* __wt_curdump_init --
* initialize a dump cursor.
*/
void
__wt_curdump_init(WT_CURSOR *cursor)
int
__wt_curdump_create(WT_CURSOR *child, WT_CURSOR *owner, WT_CURSOR **cursorp)
{
cursor->get_key = __curdump_get_key;
cursor->get_value = __curdump_get_value;
cursor->set_key = __curdump_set_key;
cursor->set_value = __curdump_set_value;
static WT_CURSOR iface = {
NULL,
NULL,
NULL,
NULL,
__curdump_get_key,
__curdump_get_value,
__curdump_set_key,
__curdump_set_value,
NULL,
__curdump_next,
__curdump_prev,
__curdump_reset,
__curdump_search,
__curdump_search_near,
__curdump_insert,
__curdump_update,
__curdump_remove,
__curdump_close,
{ NULL, NULL }, /* TAILQ_ENTRY q */
0, /* recno key */
{ 0 }, /* recno raw buffer */
{ NULL, 0, 0, NULL, 0 },/* WT_ITEM key */
{ NULL, 0, 0, NULL, 0 },/* WT_ITEM value */
0, /* int saved_err */
0 /* uint32_t flags */
};
WT_CURSOR *cursor;
WT_CURSOR_DUMP *cdump;
WT_SESSION_IMPL *session;
const char *cfg[] = API_CONF_DEFAULTS(session, open_cursor, NULL);
session = (WT_SESSION_IMPL *)child->session;
WT_RET(__wt_calloc_def(session, 1, &cdump));
cursor = &cdump->iface;
*cursor = iface;
cursor->session = child->session;
cursor->uri = child->uri;
cursor->key_format = child->key_format;
cursor->value_format = child->value_format;
cdump->child = child;
/* Copy the dump flags from the child cursor. */
F_SET(cursor,
F_ISSET(child, WT_CURSTD_DUMP_PRINT | WT_CURSTD_DUMP_HEX));
WT_RET(__wt_cursor_init(cursor, NULL, owner, cfg, cursorp));
return (0);
}

View File

@@ -197,7 +197,7 @@ __curfile_close(WT_CURSOR *cursor)
*/
int
__wt_curfile_create(WT_SESSION_IMPL *session,
const char *cfg[], WT_CURSOR **cursorp)
WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp)
{
static WT_CURSOR iface = {
NULL,
@@ -260,32 +260,8 @@ __wt_curfile_create(WT_SESSION_IMPL *session,
if (bulk)
WT_ERR(__wt_curbulk_init((WT_CURSOR_BULK *)cbt));
/* The append flag is only relevant to column stores. */
if (WT_CURSOR_RECNO(cursor)) {
WT_ERR(__wt_config_gets(session, cfg, "append", &cval));
if (cval.val != 0)
F_SET(cursor, WT_CURSTD_APPEND);
}
WT_ERR(__wt_config_gets(session, cfg, "dump", &cval));
if (cval.len != 0) {
__wt_curdump_init(cursor);
F_SET(cursor,
strncmp(cval.str, "print", cval.len) == 0 ?
WT_CURSTD_DUMP_PRINT : WT_CURSTD_DUMP_HEX);
}
WT_ERR(__wt_config_gets(session, cfg, "raw", &cval));
if (cval.val != 0)
F_SET(cursor, WT_CURSTD_RAW);
WT_ERR(__wt_config_gets(session, cfg, "overwrite", &cval));
if (cval.val != 0)
F_SET(cursor, WT_CURSTD_OVERWRITE);
STATIC_ASSERT(offsetof(WT_CURSOR_BTREE, iface) == 0);
WT_ERR(__wt_cursor_init(cursor, cursor->uri, 1, 0, cfg));
*cursorp = cursor;
WT_ERR(__wt_cursor_init(cursor, cursor->uri, owner, cfg, cursorp));
if (0) {
err: __wt_free(session, cbt);
@@ -313,5 +289,5 @@ __wt_curfile_open(WT_SESSION_IMPL *session,
else
return (EINVAL);
return (__wt_curfile_create(session, cfg, cursorp));
return (__wt_curfile_create(session, NULL, cfg, cursorp));
}

View File

@@ -319,7 +319,8 @@ __curindex_open_colgroups(
cp[arg] != NULL)
continue;
session->btree = table->colgroup[arg];
WT_RET(__wt_curfile_create(session, cfg, &cp[arg]));
WT_RET(__wt_curfile_create(
session, &cindex->cbt.iface, cfg, &cp[arg]));
}
return (0);
@@ -425,9 +426,7 @@ __wt_curindex_open(WT_SESSION_IMPL *session,
/* Open the column groups needed for this index cursor. */
WT_ERR(__curindex_open_colgroups(session, cindex, cfg));
WT_ERR(__wt_cursor_init(cursor, cursor->uri, 1, 1, cfg));
*cursorp = cursor;
WT_ERR(__wt_cursor_init(cursor, cursor->uri, 0, cfg, cursorp));
if (0) {
err: (void)__curindex_close(cursor);

View File

@@ -309,10 +309,10 @@ __wt_curstat_open(WT_SESSION_IMPL *session,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
__curstat_get_key,
__curstat_get_value,
__curstat_set_key,
__curstat_set_value,
NULL,
__curstat_next,
__curstat_prev,
@@ -338,7 +338,7 @@ __wt_curstat_open(WT_SESSION_IMPL *session,
WT_CURSOR *cursor;
WT_STATS *stats_first;
void (*clear_func)(WT_STATS *);
int clear_on_close, raw, ret, stats_count;
int clear_on_close, ret, stats_count;
btree = NULL;
clear_func = NULL;
@@ -348,9 +348,6 @@ __wt_curstat_open(WT_SESSION_IMPL *session,
WT_RET(__wt_config_gets(session, cfg, "clear_on_close", &cval));
clear_on_close = (cval.val != 0);
WT_RET(__wt_config_gets(session, cfg, "raw", &cval));
raw = (cval.val != 0);
if (!WT_PREFIX_SKIP(uri, "statistics:"))
return (EINVAL);
if (WT_PREFIX_MATCH(uri, "file:")) {
@@ -371,27 +368,9 @@ __wt_curstat_open(WT_SESSION_IMPL *session,
}
WT_ERR(__wt_calloc_def(session, 1, &cst));
cst->stats_first = stats_first;
cst->stats_count = stats_count;
cst->notpositioned = 1;
cst->clear_func = clear_func;
cursor = &cst->iface;
*cursor = iface;
cursor->session = &session->iface;
cursor->get_key = __curstat_get_key;
cursor->set_key = __curstat_set_key;
cursor->get_value = __curstat_get_value;
cursor->set_value = __curstat_set_value;
cst->btree = btree;
if (raw)
F_SET(cursor, WT_CURSTD_RAW);
STATIC_ASSERT(offsetof(WT_CURSOR_STAT, iface) == 0);
WT_ERR(__wt_cursor_init(cursor, uri, 0, 1, cfg));
/*
* We return the statistics field's offset as the key, and a string
* description, a string value, and a uint64_t value as the value
@@ -400,7 +379,14 @@ __wt_curstat_open(WT_SESSION_IMPL *session,
cursor->key_format = "i";
cursor->value_format = "SSq";
*cursorp = cursor;
cst->btree = btree;
cst->stats_first = stats_first;
cst->stats_count = stats_count;
cst->notpositioned = 1;
cst->clear_func = clear_func;
STATIC_ASSERT(offsetof(WT_CURSOR_STAT, iface) == 0);
WT_ERR(__wt_cursor_init(cursor, uri, NULL, cfg, cursorp));
if (0) {
err: __wt_free(session, cst);

View File

@@ -293,10 +293,8 @@ __wt_cursor_close(WT_CURSOR *cursor)
__wt_buf_free(session, &cursor->key);
__wt_buf_free(session, &cursor->value);
if (F_ISSET(cursor, WT_CURSTD_PUBLIC))
TAILQ_REMOVE(&session->public_cursors, cursor, q);
else if (F_ISSET(cursor, WT_CURSTD_FILE))
TAILQ_REMOVE(&session->file_cursors, cursor, q);
if (F_ISSET(cursor, WT_CURSTD_OPEN))
TAILQ_REMOVE(&session->cursors, cursor, q);
__wt_free(session, cursor->uri);
__wt_free(session, cursor);
@@ -373,11 +371,12 @@ err: if (cursor != NULL)
*/
int
__wt_cursor_init(WT_CURSOR *cursor,
const char *uri, int is_file, int is_public, const char *cfg[])
const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp)
{
WT_CURSOR *cdump;
WT_CONFIG_ITEM cval;
WT_SESSION_IMPL *session;
WT_UNUSED(cfg);
session = (WT_SESSION_IMPL *)cursor->session;
if (cursor->get_key == NULL)
@@ -399,14 +398,44 @@ __wt_cursor_init(WT_CURSOR *cursor,
WT_CLEAR(cursor->key);
WT_CLEAR(cursor->value);
if (is_file) {
F_SET(cursor, WT_CURSTD_FILE);
TAILQ_INSERT_HEAD(&session->file_cursors, cursor, q);
} else if (is_public) {
F_SET(cursor, WT_CURSTD_PUBLIC);
TAILQ_INSERT_HEAD(&session->public_cursors, cursor, q);
/* The append flag is only relevant to column stores. */
if (WT_CURSOR_RECNO(cursor)) {
WT_RET(__wt_config_gets(session, cfg, "append", &cval));
if (cval.val != 0)
F_SET(cursor, WT_CURSTD_APPEND);
}
WT_RET(__wt_config_gets(session, cfg, "dump", &cval));
if (cval.len != 0) {
F_SET(cursor, (strncmp(cval.str, "print", cval.len) == 0) ?
WT_CURSTD_DUMP_PRINT : WT_CURSTD_DUMP_HEX);
WT_RET(__wt_curdump_create(cursor, owner, &cdump));
owner = cdump;
} else
cdump = NULL;
WT_RET(__wt_config_gets(session, cfg, "raw", &cval));
if (cval.val != 0)
F_SET(cursor, WT_CURSTD_RAW);
WT_RET(__wt_config_gets(session, cfg, "overwrite", &cval));
if (cval.val != 0)
F_SET(cursor, WT_CURSTD_OVERWRITE);
/*
* Cursors that are internal to some other cursor (such as file cursors
* inside a table cursor) should be closed after the containing cursor.
* Arrange for that to happen by putting internal cursors after their
* owners on the queue.
*/
if (owner != NULL)
TAILQ_INSERT_AFTER(&session->cursors, owner, cursor, q);
else
TAILQ_INSERT_HEAD(&session->cursors, cursor, q);
F_SET(cursor, WT_CURSTD_OPEN);
*cursorp = (cdump != NULL) ? cdump : cursor;
return (0);
}

View File

@@ -464,7 +464,8 @@ __curtable_open_colgroups(WT_CURSOR_TABLE *ctable, const char *cfg[])
i < WT_COLGROUPS(table);
i++, cp++) {
session->btree = table->colgroup[i];
WT_RET(__wt_curfile_create(session, cfg_no_overwrite, cp));
WT_RET(__wt_curfile_create(
session, &ctable->iface, cfg_no_overwrite, cp));
}
return (0);
}
@@ -493,7 +494,7 @@ __curtable_open_indices(WT_CURSOR_TABLE *ctable)
WT_RET(__wt_calloc_def(session, table->nindices, &ctable->idx_cursors));
for (i = 0, cp = ctable->idx_cursors; i < table->nindices; i++, cp++) {
session->btree = table->index[i];
WT_RET(__wt_curfile_create(session, cfg, cp));
WT_RET(__wt_curfile_create(session, &ctable->iface, cfg, cp));
}
return (0);
}
@@ -533,7 +534,6 @@ __wt_curtable_open(WT_SESSION_IMPL *session,
0, /* int saved_err */
0 /* uint32_t flags */
};
WT_CONFIG_ITEM cval;
WT_CURSOR *cursor;
WT_CURSOR_TABLE *ctable;
WT_ITEM fmt, plan;
@@ -571,7 +571,7 @@ __wt_curtable_open(WT_SESSION_IMPL *session,
* table cursor.
*/
session->btree = table->colgroup[0];
return (__wt_curfile_create(session, cfg, cursorp));
return (__wt_curfile_create(session, NULL, cfg, cursorp));
}
WT_RET(__wt_calloc_def(session, 1, &ctable));
@@ -582,7 +582,6 @@ __wt_curtable_open(WT_SESSION_IMPL *session,
cursor->uri = table->name;
cursor->key_format = table->key_format;
cursor->value_format = table->value_format;
F_SET(cursor, WT_CURSTD_TABLE);
ctable->table = table;
ctable->plan = table->plan;
@@ -598,42 +597,22 @@ __wt_curtable_open(WT_SESSION_IMPL *session,
ctable->plan = __wt_buf_steal(session, &plan, NULL);
}
/* The append flag is only relevant to column stores. */
if (WT_CURSOR_RECNO(cursor)) {
WT_ERR(__wt_config_gets(session, cfg, "append", &cval));
if (cval.val != 0)
F_SET(cursor, WT_CURSTD_APPEND);
}
WT_ERR(__wt_config_gets(session, cfg, "dump", &cval));
if (cval.len != 0) {
__wt_curdump_init(cursor);
F_SET(cursor,
strncmp(cval.str, "print", cval.len) == 0 ?
WT_CURSTD_DUMP_PRINT : WT_CURSTD_DUMP_HEX);
}
WT_ERR(__wt_config_gets(session, cfg, "raw", &cval));
if (cval.val != 0)
F_SET(cursor, WT_CURSTD_RAW);
WT_ERR(__wt_config_gets(session, cfg, "overwrite", &cval));
if (cval.val != 0)
F_SET(cursor, WT_CURSTD_OVERWRITE);
STATIC_ASSERT(offsetof(WT_CURSOR_TABLE, iface) == 0);
WT_ERR(__wt_cursor_init(cursor, cursor->uri, NULL, cfg, cursorp));
/*
* Open the colgroup cursors immediately: we're going to need them for
* any operation. We defer opening index cursors until we need them
* for an update.
* for an update. Note that this must come after the call to
* __wt_cursor_init: the table cursor must already be on the list of
* session cursors or we can't work out where to put the colgroup
* cursor(s).
*/
WT_ERR(__curtable_open_colgroups(ctable, cfg));
STATIC_ASSERT(offsetof(WT_CURSOR_TABLE, iface) == 0);
WT_ERR(__wt_cursor_init(cursor, cursor->uri, 0, 1, cfg));
*cursorp = cursor;
if (0) {
err: (void)__curtable_close(cursor);
*cursorp = NULL;
}
return (ret);

View File

@@ -67,10 +67,8 @@ struct __wt_session_impl {
TAILQ_HEAD(__btrees, __wt_btree_session) btrees;
WT_CURSOR *cursor; /* Current cursor */
/* All file cursors */
TAILQ_HEAD(__file_cursors, __wt_cursor) file_cursors;
/* Cursors closed with the session */
TAILQ_HEAD(__public_cursors, __wt_cursor) public_cursors;
TAILQ_HEAD(__cursors, __wt_cursor) cursors;
WT_BTREE *schematab; /* Schema tables */
TAILQ_HEAD(__tables, __wt_table) tables;

View File

@@ -120,6 +120,12 @@ struct __wt_cursor_config {
WT_CURSOR iface;
};
struct __wt_cursor_dump {
WT_CURSOR iface;
WT_CURSOR *child;
};
struct __wt_cursor_index {
WT_CURSOR_BTREE cbt;

View File

@@ -455,8 +455,11 @@ extern int __wt_curconfig_open(WT_SESSION_IMPL *session,
const char *uri,
const char *cfg[],
WT_CURSOR **cursorp);
extern void __wt_curdump_init(WT_CURSOR *cursor);
extern int __wt_curdump_create(WT_CURSOR *child,
WT_CURSOR *owner,
WT_CURSOR **cursorp);
extern int __wt_curfile_create(WT_SESSION_IMPL *session,
WT_CURSOR *owner,
const char *cfg[],
WT_CURSOR **cursorp);
extern int __wt_curfile_open(WT_SESSION_IMPL *session,
@@ -485,9 +488,9 @@ extern int __wt_cursor_dup(WT_SESSION_IMPL *session,
WT_CURSOR **cursorp);
extern int __wt_cursor_init(WT_CURSOR *cursor,
const char *uri,
int is_file,
int is_public,
const char *cfg[]);
WT_CURSOR *owner,
const char *cfg[],
WT_CURSOR **cursorp);
extern int __wt_cursor_kv_not_set(WT_CURSOR *cursor, int key);
extern int __wt_curtable_get_key(WT_CURSOR *cursor, ...);
extern int __wt_curtable_get_value(WT_CURSOR *cursor, ...);
@@ -560,6 +563,7 @@ extern int __wt_rwlock_destroy(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock);
extern int __wt_open(WT_SESSION_IMPL *session,
const char *name,
int ok_create,
int exclusive,
int is_tree,
WT_FH **fhp);
extern int __wt_close(WT_SESSION_IMPL *session, WT_FH *fh);
@@ -617,6 +621,7 @@ extern int __wt_struct_unpack(WT_SESSION_IMPL *session,
extern int __wt_create_file(WT_SESSION_IMPL *session,
const char *name,
const char *fileuri,
int exclusive,
const char *config);
extern int __wt_schema_create( WT_SESSION_IMPL *session,
const char *name,
@@ -769,7 +774,7 @@ extern int __wt_btree_get_root(WT_SESSION_IMPL *session, WT_ITEM *addr);
extern int __wt_btree_free_root(WT_SESSION_IMPL *session);
extern int __wt_btree_set_root(WT_SESSION_IMPL *session,
const char *filename,
uint8_t *addr,
const uint8_t *addr,
uint32_t size);
extern void __wt_eventv(WT_SESSION_IMPL *session,
int msg_event,
@@ -825,16 +830,20 @@ __wt_hazard_set(WT_SESSION_IMPL *session, WT_REF *ref
extern void __wt_hazard_clear(WT_SESSION_IMPL *session, WT_PAGE *page);
extern void __wt_hazard_empty(WT_SESSION_IMPL *session);
extern void __wt_hazard_validate(WT_SESSION_IMPL *session, WT_PAGE *page);
extern void __wt_raw_to_hex(const void *from, void *to, uint32_t *sizep);
extern void __wt_raw_to_esc_hex(const void *from, void *to, uint32_t *sizep);
extern int __wt_hex_to_raw( WT_SESSION_IMPL *session,
void *from,
void *to,
uint32_t *sizep);
extern int __wt_esc_hex_to_raw( WT_SESSION_IMPL *session,
void *from,
void *to,
uint32_t *sizep);
extern int __wt_raw_to_hex(WT_SESSION_IMPL *session,
const uint8_t *from,
uint32_t size,
WT_ITEM *to);
extern int __wt_raw_to_esc_hex(WT_SESSION_IMPL *session,
const uint8_t *from,
size_t size,
WT_ITEM *to);
extern int __wt_hex_to_raw(WT_SESSION_IMPL *session,
const char *from,
WT_ITEM *to);
extern int __wt_esc_hex_to_raw(WT_SESSION_IMPL *session,
const char *from,
WT_ITEM *to);
extern int __wt_huffman_open(WT_SESSION_IMPL *session,
void *symbol_frequency_array,
u_int symcnt,
@@ -872,7 +881,6 @@ extern int __wt_buf_set_printable( WT_SESSION_IMPL *session,
extern void *__wt_buf_steal(WT_SESSION_IMPL *session,
WT_ITEM *buf,
uint32_t *sizep);
extern void __wt_buf_swap(WT_ITEM *a, WT_ITEM *b);
extern void __wt_buf_free(WT_SESSION_IMPL *session, WT_ITEM *buf);
extern int __wt_buf_fmt(WT_SESSION_IMPL *session,
WT_ITEM *buf,

View File

@@ -395,13 +395,11 @@ struct __wt_cursor {
#define WT_CURSTD_APPEND 0x0001
#define WT_CURSTD_DUMP_HEX 0x0002
#define WT_CURSTD_DUMP_PRINT 0x0004
#define WT_CURSTD_FILE 0x0008
#define WT_CURSTD_KEY_SET 0x0010
#define WT_CURSTD_KEY_SET 0x0008
#define WT_CURSTD_OPEN 0x0010
#define WT_CURSTD_OVERWRITE 0x0020
#define WT_CURSTD_PUBLIC 0x0040
#define WT_CURSTD_RAW 0x0080
#define WT_CURSTD_TABLE 0x0100
#define WT_CURSTD_VALUE_SET 0x0200
#define WT_CURSTD_RAW 0x0040
#define WT_CURSTD_VALUE_SET 0x0080
uint32_t flags;
#endif
};

View File

@@ -86,6 +86,8 @@ struct __wt_cursor_bulk;
typedef struct __wt_cursor_bulk WT_CURSOR_BULK;
struct __wt_cursor_config;
typedef struct __wt_cursor_config WT_CURSOR_CONFIG;
struct __wt_cursor_dump;
typedef struct __wt_cursor_dump WT_CURSOR_DUMP;
struct __wt_cursor_index;
typedef struct __wt_cursor_index WT_CURSOR_INDEX;
struct __wt_cursor_stat;

View File

@@ -13,7 +13,7 @@
*/
int
__wt_open(WT_SESSION_IMPL *session,
const char *name, int ok_create, int is_tree, WT_FH **fhp)
const char *name, int ok_create, int exclusive, int is_tree, WT_FH **fhp)
{
const char *path;
WT_CONNECTION_IMPL *conn;
@@ -52,6 +52,8 @@ __wt_open(WT_SESSION_IMPL *session,
#endif
if (ok_create) {
f |= O_CREAT;
if (exclusive)
f |= O_EXCL;
mode = 0666;
} else
mode = 0;

View File

@@ -9,7 +9,7 @@
int
__wt_create_file(WT_SESSION_IMPL *session,
const char *name, const char *fileuri, const char *config)
const char *name, const char *fileuri, int exclusive, const char *config)
{
WT_ITEM *val;
const char *cfg[] = API_CONF_DEFAULTS(session, create, config);
@@ -34,8 +34,12 @@ __wt_create_file(WT_SESSION_IMPL *session,
/* If the file exists, don't try to recreate it. */
if ((ret = __wt_session_get_btree(session, name, fileuri,
is_schema ? config : NULL, NULL, WT_BTREE_NO_LOCK)) != WT_NOTFOUND)
is_schema ? config : NULL,
NULL, WT_BTREE_NO_LOCK)) != WT_NOTFOUND) {
if (ret == 0 && exclusive)
ret = EEXIST;
return (ret);
}
WT_RET(__wt_btree_create(session, filename));
WT_ERR(__wt_schema_table_track_fileop(session, NULL, filename));
@@ -84,8 +88,8 @@ err: __wt_scr_free(&val);
}
static int
__create_colgroup(
WT_SESSION_IMPL *session, const char *name, const char *config)
__create_colgroup(WT_SESSION_IMPL *session,
const char *name, int exclusive, const char *config)
{
WT_CONFIG_ITEM cval;
WT_ITEM fmt, namebuf, uribuf;
@@ -93,11 +97,12 @@ __create_colgroup(
const char *cfg[] = { __wt_confdfl_colgroup_meta, config, NULL, NULL };
const char *filecfg[] = { config, NULL, NULL };
const char **cfgp;
const char *cgconf, *cgname, *fileconf, *filename, *fileuri, *tablename;
const char *cgconf, *cgname, *fileconf, *filename, *fileuri;
const char *oldconf, *tablename;
size_t tlen;
int ret;
cgconf = fileconf = NULL;
cgconf = fileconf = oldconf = NULL;
WT_CLEAR(fmt);
WT_CLEAR(namebuf);
WT_CLEAR(uribuf);
@@ -115,7 +120,7 @@ __create_colgroup(
if ((ret =
__wt_schema_get_table(session, tablename, tlen, &table)) != 0)
WT_RET_MSG(session, (ret == WT_NOTFOUND) ? ENOENT : ret,
"Can't create '%s' for non-existent table %.*s",
"Can't create '%s' for non-existent table '%.*s'",
name, (int)tlen, tablename);
/* Make sure the column group is referenced from the table. */
@@ -167,13 +172,22 @@ __create_colgroup(
WT_ERR(__wt_buf_fmt(session, &uribuf, "file:%s", filename));
fileuri = uribuf.data;
WT_ERR(__wt_schema_table_insert(session, name, cgconf));
WT_ERR(__wt_create_file(session, name, fileuri, fileconf));
if ((ret = __wt_schema_table_insert(session, name, cgconf)) != 0) {
/*
* If the entry already exists in the schema table, we're done.
* This is an error for exclusive creates but okay otherwise.
*/
if (ret == WT_DUPLICATE_KEY)
ret = exclusive ? EEXIST : 0;
goto err;
}
WT_ERR(__wt_create_file(session, name, fileuri, exclusive, fileconf));
WT_ERR(__wt_schema_open_colgroups(session, table));
err: __wt_free(session, cgconf);
__wt_free(session, fileconf);
__wt_free(session, oldconf);
__wt_buf_free(session, &fmt);
__wt_buf_free(session, &namebuf);
__wt_buf_free(session, &uribuf);
@@ -181,7 +195,8 @@ err: __wt_free(session, cgconf);
}
static int
__create_index(WT_SESSION_IMPL *session, const char *name, const char *config)
__create_index(WT_SESSION_IMPL *session,
const char *name, int exclusive, const char *config)
{
WT_CONFIG pkcols;
WT_CONFIG_ITEM ckey, cval, icols;
@@ -266,8 +281,16 @@ __create_index(WT_SESSION_IMPL *session, const char *name, const char *config)
WT_ERR(__wt_buf_fmt(session, &uribuf, "file:%s", filename));
fileuri = uribuf.data;
WT_ERR(__wt_create_file(session, name, fileuri, fileconf));
WT_ERR(__wt_schema_table_insert(session, name, idxconf));
if ((ret = __wt_schema_table_insert(session, name, idxconf)) != 0) {
/*
* If the entry already exists in the schema table, we're done.
* This is an error for exclusive creates but okay otherwise.
*/
if (ret == WT_DUPLICATE_KEY)
ret = exclusive ? EEXIST : 0;
goto err;
}
WT_ERR(__wt_create_file(session, name, fileuri, exclusive, fileconf));
err: __wt_free(session, fileconf);
__wt_free(session, idxconf);
@@ -279,7 +302,8 @@ err: __wt_free(session, fileconf);
}
static int
__create_table(WT_SESSION_IMPL *session, const char *name, const char *config)
__create_table(WT_SESSION_IMPL *session,
const char *name, int exclusive, const char *config)
{
WT_CONFIG conf;
WT_CONFIG_ITEM cgkey, cgval, cval;
@@ -300,10 +324,8 @@ __create_table(WT_SESSION_IMPL *session, const char *name, const char *config)
if ((ret = __wt_schema_get_table(session,
tablename, strlen(tablename), &table)) == 0) {
if (__wt_config_getones(session,
config, "exclusive", &cval) == 0 && cval.val)
WT_RET_MSG(
session, EEXIST, "Table exists: %s", tablename);
if (exclusive)
ret = EEXIST;
return (0);
}
if (ret != WT_NOTFOUND)
@@ -329,7 +351,7 @@ __create_table(WT_SESSION_IMPL *session, const char *name, const char *config)
cgsize = strlen("colgroup:") + strlen(tablename) + 1;
WT_ERR(__wt_calloc_def(session, cgsize, &cgname));
snprintf(cgname, cgsize, "colgroup:%s", tablename);
WT_ERR(__create_colgroup(session, cgname, config));
WT_ERR(__create_colgroup(session, cgname, exclusive, config));
}
if (0) {
@@ -345,12 +367,16 @@ int
__wt_schema_create(
WT_SESSION_IMPL *session, const char *name, const char *config)
{
int ret;
WT_CONFIG_ITEM cval;
int exclusive, ret;
/* Disallow objects in the WiredTiger name space. */
WT_RET(__wt_schema_name_check(session, name));
exclusive = (
__wt_config_getones(session, config, "exclusive", &cval) == 0 &&
cval.val != 0);
/*
* We track rename operations, if we fail in the middle, we want to
* back it all out.
@@ -358,13 +384,13 @@ __wt_schema_create(
WT_RET(__wt_schema_table_track_on(session));
if (WT_PREFIX_MATCH(name, "colgroup:"))
ret = __create_colgroup(session, name, config);
ret = __create_colgroup(session, name, exclusive, config);
else if (WT_PREFIX_MATCH(name, "file:"))
ret = __wt_create_file(session, name, name, config);
ret = __wt_create_file(session, name, name, exclusive, config);
else if (WT_PREFIX_MATCH(name, "index:"))
ret = __create_index(session, name, config);
ret = __create_index(session, name, exclusive, config);
else if (WT_PREFIX_MATCH(name, "table:"))
ret = __create_table(session, name, config);
ret = __create_table(session, name, exclusive, config);
else
ret = __wt_unknown_object_type(session, name);

View File

@@ -36,7 +36,7 @@ __open_schema_table(WT_SESSION_IMPL *session)
__wt_schema_table_track_off(session, 0);
WT_ERR(__wt_create_file(session,
"file:" WT_SCHEMA_FILENAME,
"file:" WT_SCHEMA_FILENAME, schemaconf));
"file:" WT_SCHEMA_FILENAME, 0, schemaconf));
session->schematab = session->btree;
err: __wt_free(session, schemaconf);
if (tracking)
@@ -56,7 +56,7 @@ __wt_schema_table_cursor(
WT_RET(__open_schema_table(session));
session->btree = session->schematab;
return (__wt_curfile_create(session, cfg, cursorp));
return (__wt_curfile_create(session, NULL, cfg, cursorp));
}
/*

View File

@@ -26,15 +26,7 @@ __session_close(WT_SESSION *wt_session, const char *config)
SESSION_API_CALL(session, close, config, cfg);
WT_UNUSED(cfg);
/*
* We first close all public cursors, then all remaining file cursors.
* File cursors are special because the btree code looks inside them
* to work out whether pages are in use.
*/
while ((cursor = TAILQ_FIRST(&session->public_cursors)) != NULL)
WT_TRET(cursor->close(cursor));
while ((cursor = TAILQ_FIRST(&session->file_cursors)) != NULL)
while ((cursor = TAILQ_FIRST(&session->cursors)) != NULL)
WT_TRET(cursor->close(cursor));
while ((btree_session = TAILQ_FIRST(&session->btrees)) != NULL)
@@ -476,8 +468,7 @@ __wt_open_session(WT_CONNECTION_IMPL *conn, int internal,
session_ret->event_handler = session->event_handler;
session_ret->hazard = conn->hazard + slot * conn->hazard_size;
TAILQ_INIT(&session_ret->file_cursors);
TAILQ_INIT(&session_ret->public_cursors);
TAILQ_INIT(&session_ret->cursors);
TAILQ_INIT(&session_ret->btrees);
if (event_handler != NULL)
session_ret->event_handler = event_handler;

View File

@@ -28,7 +28,6 @@ int
__wt_btree_get_root(WT_SESSION_IMPL *session, WT_ITEM *addr)
{
WT_BTREE *btree;
uint32_t size;
int majorv, minorv, ret;
const char *v;
@@ -59,10 +58,8 @@ __wt_btree_get_root(WT_SESSION_IMPL *session, WT_ITEM *addr)
"%s is an unsupported version of a WiredTiger file",
btree->filename);
if (v != NULL && strlen(v) != 0 && strcmp(v, WT_NOADDR) != 0) {
WT_ERR(__wt_hex_to_raw(session, (void *)v, (void *)v, &size));
WT_ERR(__wt_buf_set(session, addr, v, size));
}
if (v != NULL && strlen(v) != 0 && strcmp(v, WT_NOADDR) != 0)
WT_ERR(__wt_hex_to_raw(session, v, addr));
err: if (ret != 0)
__wt_errx(session,
@@ -108,7 +105,7 @@ err: __wt_scr_free(&addr);
*/
int
__wt_btree_set_root(WT_SESSION_IMPL *session,
const char *filename, uint8_t *addr, uint32_t size)
const char *filename, const uint8_t *addr, uint32_t size)
{
WT_ITEM *v;
int ret;
@@ -118,7 +115,7 @@ __wt_btree_set_root(WT_SESSION_IMPL *session,
/*
* Every bytes is encoded as 2 bytes, plus a trailing nul byte,
* and it needs to hold the [NoAddr] string.
* and it needs to hold the "no address" string.
*/
WT_RET(__wt_scr_alloc(
session, size * 2 + 1 + WT_STORE_SIZE(strlen(WT_NOADDR)), &v));
@@ -133,11 +130,8 @@ __wt_btree_set_root(WT_SESSION_IMPL *session,
if (addr == NULL) {
v->data = WT_NOADDR;
v->size = WT_STORE_SIZE(strlen(WT_NOADDR)) + 1;
} else {
__wt_raw_to_hex(addr, v->mem, &size);
v->data = v->mem;
v->size = size;
}
} else
WT_ERR(__wt_raw_to_hex(session, addr, size, v));
WT_ERR(strcmp(filename, WT_SCHEMA_FILENAME) == 0 ?
__btree_set_turtle(session, v) :

View File

@@ -7,44 +7,59 @@
#include "wt_internal.h"
static const u_char hex[] = "0123456789abcdef";
static const char hex[] = "0123456789abcdef";
/*
* __wt_raw_to_hex --
* Convert a chunk of data to a printable hex string.
*/
void
__wt_raw_to_hex(const void *from, void *to, uint32_t *sizep)
int
__wt_raw_to_hex(WT_SESSION_IMPL *session,
const uint8_t *from, uint32_t size, WT_ITEM *to)
{
uint32_t i;
const uint8_t *p;
uint8_t *t, *t_start;
char *t;
for (p = from, t = t_start = to, i = *sizep; i > 0; --i, ++p) {
/*
* In the worst case, every character takes up 2 spaces, plus a
* trailing nul byte.
*/
WT_RET(__wt_buf_init(session, to, size * 2 + 1));
for (p = from, t = to->mem, i = size; i > 0; --i, ++p) {
*t++ = hex[(*p & 0xf0) >> 4];
*t++ = hex[*p & 0x0f];
}
*t++ = '\0';
*sizep = WT_PTRDIFF32(t, t_start);
to->size = WT_PTRDIFF32(t, to->mem);
return (0);
}
/*
* __wt_raw_to_esc_hex --
* Convert a chunk of data to an printable string using escaped hex as
* necessary.
* necessary.
*/
void
__wt_raw_to_esc_hex(const void *from, void *to, uint32_t *sizep)
int
__wt_raw_to_esc_hex(WT_SESSION_IMPL *session,
const uint8_t *from, size_t size, WT_ITEM *to)
{
uint32_t i;
size_t i;
const uint8_t *p;
uint8_t *t, *t_start;
uint8_t *t;
/*
* In the worst case, every character takes up 3 spaces, plus a
* trailing nul byte.
*/
for (p = from, t = t_start = to, i = *sizep; i > 0; --i, ++p)
WT_RET(__wt_buf_init(session, to, size * 3 + 1));
/*
* In the worst case, every character takes up 3 spaces, plus a
* trailing nul byte.
*/
for (p = from, t = to->mem, i = size; i > 0; --i, ++p)
if (isprint((int)*p)) {
if (*p == '\\')
*t++ = '\\';
@@ -55,7 +70,8 @@ __wt_raw_to_esc_hex(const void *from, void *to, uint32_t *sizep)
*t++ = hex[*p & 0x0f];
}
*t++ = '\0';
*sizep = WT_PTRDIFF32(t, t_start);
to->size = WT_PTRDIFF32(t, to->mem);
return (0);
}
/*
@@ -63,7 +79,7 @@ __wt_raw_to_esc_hex(const void *from, void *to, uint32_t *sizep)
* Convert a pair of hex characters into a byte.
*/
static inline int
hex2byte(uint8_t *from, uint8_t *to)
hex2byte(const char *from, uint8_t *to)
{
uint8_t byte;
@@ -123,34 +139,40 @@ __hex_fmterr(WT_SESSION_IMPL *session)
* Convert a printable hex string to a chunk of data.
*/
int
__wt_hex_to_raw(
WT_SESSION_IMPL *session, void *from, void *to, uint32_t *sizep)
__wt_hex_to_raw(WT_SESSION_IMPL *session, const char *from, WT_ITEM *to)
{
uint8_t *p, *t, *t_start;
const char *p;
uint8_t *t;
size_t size;
if (strlen(from) % 2 != 0)
size = strlen(from);
if (size % 2 != 0)
return (__hex_fmterr(session));
for (p = from, t = t_start = to; *p != '\0'; p += 2, ++t)
WT_RET(__wt_buf_init(session, to, size / 2));
for (p = from, t = to->mem; *p != '\0'; p += 2, ++t)
if (hex2byte(p, t))
return (__hex_fmterr(session));
*sizep = WT_PTRDIFF32(t, t_start);
to->size = WT_PTRDIFF32(t, to->mem);
return (0);
}
/*
* __wt_esc_hex_to_raw --
* Convert a printable string using escaped hex as necessary to a chunk
* of data.
* of data.
*/
int
__wt_esc_hex_to_raw(
WT_SESSION_IMPL *session, void *from, void *to, uint32_t *sizep)
__wt_esc_hex_to_raw(WT_SESSION_IMPL *session, const char *from, WT_ITEM *to)
{
uint8_t *p, *t, *t_start;
const char *p;
uint8_t *t;
for (p = from, t = t_start = to; *p != '\0'; ++p, ++t) {
WT_RET(__wt_buf_init(session, to, strlen(from)));
for (p = from, t = to->mem; *p != '\0'; ++p, ++t) {
if ((*t = *p) != '\\')
continue;
++p;
@@ -160,6 +182,6 @@ __wt_esc_hex_to_raw(
++p;
}
}
*sizep = WT_PTRDIFF32(t, t_start);
to->size = WT_PTRDIFF32(t, to->mem);
return (0);
}

View File

@@ -120,19 +120,7 @@ int
__wt_buf_set_printable(
WT_SESSION_IMPL *session, WT_ITEM *buf, const void *from_arg, size_t size)
{
uint32_t u32size;
/*
* In the worst case, every character takes up 3 spaces, plus a
* trailing nul byte.
*/
WT_RET(__wt_buf_init(session, buf, size * 3 + 10));
u32size = (uint32_t)size;
__wt_raw_to_esc_hex(from_arg, buf->mem, &u32size);
buf->size = u32size;
return (0);
return (__wt_raw_to_esc_hex(session, from_arg, size, buf));
}
/*
@@ -177,20 +165,6 @@ __wt_buf_steal(WT_SESSION_IMPL *session, WT_ITEM *buf, uint32_t *sizep)
return (retp);
}
/*
* __wt_buf_swap --
* Swap a pair of buffers.
*/
void
__wt_buf_swap(WT_ITEM *a, WT_ITEM *b)
{
WT_ITEM tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
/*
* __wt_buf_free --
* Free a buffer.
@@ -382,9 +356,11 @@ __wt_scr_discard(WT_SESSION_IMPL *session)
bufp = session->scratch; i < session->scratch_alloc; ++i, ++bufp) {
if (*bufp == NULL)
continue;
#if 0
if (F_ISSET(*bufp, WT_ITEM_INUSE))
__wt_errx(session,
"scratch buffer allocated and never discarded");
#endif
__wt_buf_free(session, *bufp);
__wt_free(session, *bufp);
}

View File

@@ -43,7 +43,7 @@ __wt_session_dump(WT_SESSION_IMPL *session)
session->name == NULL ? "" : " ", session);
first = 0;
TAILQ_FOREACH(cursor, &session->file_cursors, q) {
TAILQ_FOREACH(cursor, &session->cursors, q) {
if (++first == 1)
__wt_msg(session, "\tcursors:");
__wt_msg(session, "\t\t%p", cursor);

View File

@@ -102,7 +102,7 @@ usage(void)
{
(void)fprintf(stderr,
"usage: %s %s "
"read [-ao] uri key ...\n",
"write [-ao] uri key ...\n",
progname, usage_prefix);
return (1);
}

View File

@@ -1,37 +0,0 @@
%module config
%{
#include <wt_internal.h>
%}
typedef struct WT_CONFIG WT_CONFIG;
typedef struct WT_CONFIG_ITEM WT_CONFIG_ITEM;
struct WT_CONFIG
{
char *orig;
char *end;
char *cur;
int depth, top;
void **go;
};
struct WT_CONFIG_ITEM
{
char *str;
size_t len;
uint64_t val;
enum { ITEM_STRING, ITEM_ID, ITEM_NUM, ITEM_STRUCT } type;
};
/*
* XXX: leak, but the string needs to last beyond the call to config_init.
* It should be freed when the WT_CONFIG object is deleted.
*/
%typemap(in) char *confstr {
$1 = strdup(PyString_AsString($input));
}
int config_init(WT_CONFIG *conf, char *confstr, int len);
int config_next(WT_CONFIG *conf, WT_CONFIG_ITEM *key, WT_CONFIG_ITEM *value);

View File

@@ -1,21 +0,0 @@
#include <wt_int.h>
#include <string.h>
int main(int argc, char *argv[])
{
int ret;
WT_CONFIG c;
WT_CONFIG_ITEM k, v;
const char *cstr = "create,cachesize=10MB";
config_init(&c, cstr, strlen(cstr));
while ((ret = config_next(&c, &k, &v)) == 0) {
printf("Got key '%.*s', value '%.*s'\n",
(int)k.len, k.str, (int)v.len, v.str);
}
printf("Last call to config_next failed with %d\n", ret);
return (0);
}

View File

@@ -1,39 +0,0 @@
import config
def parse(s):
print "Parsing '%s':" % s
c = config.WT_CONFIG()
k = config.WT_CONFIG_ITEM()
v = config.WT_CONFIG_ITEM()
config.config_init(c, s, len(s))
ret = config.config_next(c, k, v)
while ret == 0:
print " => '%s' = '%s'" % (k.str[:k.len], v.str[:v.len])
ret = config.config_next(c, k, v)
# XXX hard-coding WT_NOTFOUND until we fix this
if ret != -31801:
print "Last call to config_next failed with %d" % ret
if __name__ == '__main__':
parse("create")
parse("create,cachesize=10MB")
parse('create,cachesize=10MB,path="/foo/bar"')
parse('columns=(first,second, third)')
parse('key_format="S", value_format="5sq", columns=(first,second, third)')
parse('key_columns=(first=S),value_columns=(second="5s", third=q)')
parse(',,columns=(first=S,second="5s", third=q),,')
parse('index.country_year=(country,year),key_format=r,colgroup.population=(population),columns=(id,country,year,population),value_format=5sHQ')
import json
parse(json.dumps({'hello' : 'world', 'columns' : ('one', 'two', 'three')}))
parse(json.dumps({
"key_format" : "r",
"value_format" : "5sHQ",
"columns" : ("id", "country", "year", "population"),
"colgroup.population" : ("population",),
"index.country_year" : ("country","year")
}))

View File

@@ -59,9 +59,18 @@ config_setup(void)
*cp->v = CONF_RAND(cp);
}
/* Periodically, set the delete percentage to 0 so salvage gets run. */
if (!g.replay && g.run_cnt % 10 == 0)
g.c_delete_pct = 0;
/*
* Periodically, set the delete percentage to 0 so salvage gets run,
* as long as the delete percentage isn't nailed down.
*/
if (!g.replay && g.run_cnt % 10 == 0) {
for (cp = c; cp->name != NULL; ++cp)
if (strcmp(cp->name, "delete_pct") == 0)
break;
if (cp->name != NULL &&
!(cp->flags & (C_IGNORE | C_PERM | C_TEMP)))
g.c_delete_pct = 0;
}
}
/*

View File

@@ -70,7 +70,7 @@ class test_schema02(wttest.WiredTigerTestCase):
# bad table name
self.expect_failure_colgroup("nomatch:c", "columns=(S1,i2)",
"/Can't create 'colgroup:nomatch:c'"
" for non-existent table nomatch/")
" for non-existent table 'nomatch'/")
# colgroup not declared in initial create
self.expect_failure_colgroup("main:nomatch", "columns=(S1,i2)",
"/Column group 'nomatch' not found"