Compare commits

...

32 Commits
1.6.2 ... 1.6.3

Author SHA1 Message Date
Alex Gorrod
627b65c877 Cut release 1.6.3 2013-07-12 12:22:06 +10:00
Alex Gorrod
7f6b1057d1 Destroy locks on exit from test/format. 2013-07-12 12:13:36 +10:00
Keith Bostic
8750d87e13 Fix a comment. 2013-07-11 12:37:45 -04:00
Michael Cahill
c495977b9a Fix a race manipulating file descriptors in the test suite. Always close the connection before closing redirected stdout and stderr. Make sure the connection and redirected files are both closed if a test fails. 2013-07-11 16:52:04 +10:00
Keith Bostic
654b9c2b93 Document that setting LC_ALL=C is a good idea when pre-sorting keys for
bulk load.  Reference #590.
2013-07-09 17:28:39 -04:00
Keith Bostic
7580c8186e Update is like insert, once an update is done, bulk-load is no
longer possible.

We were repeating the fixed-size value WT_ITEM size checks, it's
not a performance problem, but there's no reason to do it twice.
2013-07-09 17:04:40 -04:00
Keith Bostic
ba3f0fb597 whitespace 2013-07-09 09:16:56 -04:00
Alex Gorrod
d242c8dae8 Update test/format max page configuration calculation to make it less likely
that we'll pin the entire cache and get stuck.
2013-07-09 18:08:27 +10:00
Michael Cahill
460792842a Another try at portably getting the IFS setting we need. 2013-07-09 16:19:40 +10:00
Michael Cahill
4040f54345 Make IFS more portable: don't export, set explicitly and move to where it is needed. 2013-07-09 15:42:40 +10:00
Michael Cahill
81bc53cd3f Install the Python module as part of "make install". 2013-07-09 15:33:26 +10:00
Michael Cahill
bc32645c8f Insulate scripts from user settings of IFS. 2013-07-09 15:00:56 +10:00
Keith Bostic
77c7fbdf9b typo 2013-07-08 16:31:10 -04:00
Keith Bostic
61e8803c55 Now the 'transactional' keyword is gone, remove uses it in the test suite. 2013-07-08 11:16:22 -04:00
Keith Bostic
38d6fbe214 The 'transactional' keyword is gone, remove uses of the
WT_CONN_TRANSACTIONAL flag.
2013-07-08 10:50:25 -04:00
Keith Bostic
4fe42451ff Remove the 'transactional' keyword, we're always transactional. 2013-07-08 10:40:08 -04:00
Michael Cahill
88f90694a8 Remove "first_id" from the page modify structure. This should have been removed when transaction IDs were switched to 64 bits.
refs #553
2013-07-08 13:50:09 +10:00
Keith Bostic
abcdeca3e9 Dual-license under either GPLv2 or GPLv3. 2013-07-03 08:57:01 -04:00
Keith Bostic
19f977b398 Building on a 9.1 FreeBSD release. 2013-06-19 16:06:04 -04:00
Alex Gorrod
772fd42c8d Update Doxygen script file to be compatible with Doxygen 1.8.4 2013-06-19 15:04:04 +10:00
Michael Cahill
f9f46cf7b5 Merge pull request #512 from wiredtiger/overwrite
Make "overwrite" default true and apply consistently to insert, update and remove operations.
2013-06-18 18:30:07 -07:00
Michael Cahill
d74a2f7f3e typo 2013-06-19 11:28:25 +10:00
Michael Cahill
952389d109 Minor edit to the upgrade wording for the overwrite API change.
refs #512
2013-06-19 10:59:47 +10:00
Keith Bostic
a9eaa81d90 Add an upgrading section on the new overwrite configuration semantics. 2013-06-18 14:37:58 -04:00
Keith Bostic
176d7f7683 Check all of the combinations of record exist/not-exist and overwrite
on/off for the insert, remove and update methods.   Add an LSM test,
it has a different code path.
2013-06-18 11:22:27 -04:00
Keith Bostic
e3ce18298b cursor/cur_std.c: In function ‘__cursor_runtime_config’:
cursor/cur_std.c:402: warning: unused variable ‘ret’
lsm/lsm_cursor.c: In function ‘__wt_clsm_open’:
lsm/lsm_cursor.c:1065: warning: unused variable ‘cval’
2013-06-18 09:51:16 -04:00
Keith Bostic
1983d6f3b9 If overwrite is the default, do the cheap test first, testing to see if
the cursor referenced item is valid is a more expensive test.

Fix a comment.
2013-06-18 09:49:15 -04:00
Michael Cahill
a6fd589669 typo 2013-06-18 17:30:20 +10:00
Michael Cahill
1f52dadddb whitespace 2013-06-18 17:24:16 +10:00
Michael Cahill
ab8eba816d Generalize the cursor "overwrite" configuration to apply to insert, update and remove. Default to true, so LSM is no longer a special case.
refs #512
2013-06-18 17:21:15 +10:00
Michael Cahill
bac863900f Force the release date to be updated when cutting a release.
refs #580
2013-06-18 14:52:55 +10:00
Alex Gorrod
93a1673a4b Bump develop release version. 2013-06-18 14:20:26 +10:00
58 changed files with 413 additions and 302 deletions

10
LICENSE
View File

@@ -2,16 +2,16 @@ Copyright (c) 2008-2013 WiredTiger, Inc.
All rights reserved.
This program is free software: you can redistribute it and/or modify it under
the terms of version 3 of the GNU General Public License as published by the
Free Software Foundation.
the terms of either version 2 or version 3 of the GNU General Public License
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details:
http://www.gnu.org/licenses/gpl-3.0-standalone.html
details.
For a license to use the WiredTiger software under conditions other than those
described by the GNU General Public License, or for technical support for this
software, contact WiredTiger, Inc. at info@wiredtiger.com.
For further information, see the licensing section in the documentation.

13
NEWS
View File

@@ -1,3 +1,16 @@
WiredTiger release 1.6.3, 2013-07-12
------------------------------------
This is a bugfix and performance tuning release. The main changes are:
* Change the default cursor overwrite configuration so that it is consistent
across all data sources. This change may alter the behavior of existing
applications without triggering any compilation or runtime warnings. See
the upgrade documentation for details. [#512]
* Require platform support for 64 bit atomic operations. [#553]
WiredTiger release 1.6.2, 2013-06-18
------------------------------------

6
README
View File

@@ -1,6 +1,6 @@
WiredTiger 1.6.2: (May 31, 2013)
WiredTiger 1.6.3: (July 12, 2013)
This is version 1.6.2 of WiredTiger.
This is version 1.6.3 of WiredTiger.
WiredTiger release packages and documentation can be found at:
@@ -9,7 +9,7 @@ WiredTiger release packages and documentation can be found at:
Information on configuring, building and installing WiredTiger can be
found at:
http://source.wiredtiger.com/1.6.2/install.html
http://source.wiredtiger.com/1.6.3/install.html
WiredTiger licensing information can be found at:

View File

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

View File

@@ -2,8 +2,8 @@ dnl build by dist/s_version
VERSION_MAJOR=1
VERSION_MINOR=6
VERSION_PATCH=2
VERSION_STRING='"WiredTiger 1.6.2: (May 31, 2013)"'
VERSION_PATCH=3
VERSION_STRING='"WiredTiger 1.6.3: (July 12, 2013)"'
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.6.2
1.6.3

View File

@@ -3,6 +3,11 @@
t=/tmp/__configure.$$
trap 'rm -f $t; exit 0' 0 1 2 3 13 15
# Insulate against IFS from the user's env
IFS=' '' ''
'
export IFS
# Allow this script to be run from anywhere
cd "`dirname \"$0\"`"

16
dist/api_data.py vendored
View File

@@ -416,13 +416,16 @@ methods = {
Config('next_random', 'false', r'''
configure the cursor to return a pseudo-random record from
the object; valid only for row-store cursors. Cursors
configured with next_random only support the WT_CURSOR::next
configured with \c next_random only support the WT_CURSOR::next
and WT_CURSOR::close methods. See @ref cursor_random for
details''',
type='boolean'),
Config('overwrite', 'false', r'''
change the behavior of the cursor's insert method to overwrite
previously existing values''',
Config('overwrite', 'true', r'''
configures whether the cursor's insert, update and remove
methods check the existing state of the record. If \c overwrite
is \c false, WT_CURSOR::insert fails with ::WT_DUPLICATE_KEY
if the record exists, WT_CURSOR::update and WT_CURSOR::remove
fail with ::WT_NOTFOUND if the record does not exist''',
type='boolean'),
Config('raw', 'false', r'''
ignore the encodings for the key and value, manage data as if
@@ -521,7 +524,7 @@ methods = {
::wiredtiger_extension_init'''),
Config('prefix', '', r'''
a prefix for all names registered by this extension (e.g., to
make namespaces distinct or during upgrades'''),
make namespaces distinct or during upgrades)'''),
Config('terminate', 'wiredtiger_extension_terminate', r'''
a optional function in the extension that is called before the
extension is unloaded during WT_CONNECTION::close. The signature of
@@ -625,9 +628,6 @@ methods = {
flush files to stable storage when closing or writing
checkpoints''',
type='boolean'),
Config('transactional', 'true', r'''
support transactional semantics''',
type='boolean'),
Config('use_environment_priv', 'false', r'''
use the \c WIREDTIGER_CONFIG and \c WIREDTIGER_HOME environment
variables regardless of whether or not the process is running

1
dist/flags.py vendored
View File

@@ -65,7 +65,6 @@ flags = {
'CONN_PANIC',
'CONN_SERVER_RUN',
'CONN_SYNC',
'CONN_TRANSACTIONAL',
],
'session' : [
'SESSION_INTERNAL',

8
dist/s_all vendored
View File

@@ -29,18 +29,22 @@ run()
echo 'dist/s_all run started...'
force=
reconf=0
while :
do case "$1" in
-A) # Reconfigure the library build.
reconf=1
shift;;
-f) # Force versions to be updated
force="-f"
shift;;
*)
break;;
esac
done
run "sh ./s_version" "Updating files that include the package version"
run "sh ./s_version $force" "Updating files that include the package version"
test "$reconf" -eq 0 || {
(cd ../build_posix &&
@@ -58,7 +62,7 @@ run "python java_doc.py" "building Java documentation index"
run "sh ./s_typedef -b" "building standard typedefs"
run "sh ./s_prototypes" "building function prototypes"
run "sh ./s_readme" "building README file"
run "sh ./s_readme $force" "building README file"
run "sh ./s_tags" "building tags files"
run "sh ./s_copyright" "checking copyright notices"

25
dist/s_readme vendored
View File

@@ -2,16 +2,29 @@
t=__wt.$$
trap 'rm -f $t; exit 0' 0 1 2 3 13 15
f=../README
. ../RELEASE
# If the version number has changed, generate a new README file (don't generate
# a new one just because the date changed, that happens all the time).
cnt=`(sed -e q < $f; echo "$WIREDTIGER_VERSION_STRING") |
sed -e 's/:.*//' | sort -u | wc -l`
test $cnt -eq 1 && exit 0
force=no
while :
do case "$1" in
-f) # Force versions to be updated
force=yes
shift;;
*)
break;;
esac
done
# If the version hasn't changed and we aren't forcing the issue, we're done.
# Don't generate a new README file just because the date changed unless forced:
# that happens all the time.
if test "$force" = no ; then
cnt=`(sed -e q < $f; echo "$WIREDTIGER_VERSION_STRING") |
sed -e 's/:.*//' | sort -u | wc -l`
test $cnt -eq 1 && exit 0
fi
cat << END_TEXT > $t
$WIREDTIGER_VERSION_STRING

8
dist/s_string.ok vendored
View File

@@ -95,6 +95,7 @@ GCC
GIDs
Geoff
Givargis
Google
IEC
IEEE
IFF
@@ -297,6 +298,7 @@ catfmt
cd
cfg
cfkos
change's
checkfrag
checkpointed
checkpointing
@@ -348,6 +350,7 @@ cust
cv
cxa
data's
database's
datalen
datasets
datasource
@@ -480,6 +483,7 @@ infeasible
init
initn
initsize
inline
inmem
insertK
insertV
@@ -615,6 +619,7 @@ pre
preload
prepended
presize
primary's
printf
printlog
priv
@@ -653,6 +658,7 @@ rf
rle
rpc
rref
run's
runlength
runtime
rwlock
@@ -808,6 +814,7 @@ uu
va
valuep
vanishingly
variable's
vcell
verrx
versa
@@ -819,6 +826,7 @@ vsize
vslot
vunpack
vupdate
walk's
wiredtiger
workFactor
wrapup

5
dist/s_typedef vendored
View File

@@ -3,9 +3,12 @@
t=__wt.$$
trap 'rm -f $t; exit 0' 0 1 2 3 13 15
# Insulate against locale-specific sort order
# Insulate against locale-specific sort order and IFS from the user's env
LC_ALL=C
export LC_ALL
IFS=' '' ''
'
export IFS
build() {
# Build the standard typedefs.

16
dist/s_version vendored
View File

@@ -5,7 +5,21 @@
m4dir=../build_posix/aclocal
if test -f $m4dir/version.m4 -a -f $m4dir/version-set.m4 ; then
force=no
while :
do case "$1" in
-f) # Force versions to be updated
force=yes
shift;;
*)
break;;
esac
done
# If the version hasn't changed and we're not forcing the issue, we're done.
if test "$force" = no -a \
-f $m4dir/version.m4 -a \
-f $m4dir/version-set.m4 ; then
eval `grep '^VERSION_[A-Z]*=' $m4dir/version-set.m4`
if test x${WIREDTIGER_VERSION_MAJOR} = x${VERSION_MAJOR} -a \
x${WIREDTIGER_VERSION_MINOR} = x${VERSION_MINOR} -a \

View File

@@ -25,7 +25,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*
* ex_stat.c
* This is an example demonstrating how to query a database's statistics.
* This is an example demonstrating how to query database statistics.
*/
#include <errno.h>

View File

@@ -12,7 +12,11 @@ $(PYSRC)/wiredtiger_wrap.c: $(top_srcdir)/src/include/wiredtiger.in $(PYSRC)/wir
_wiredtiger.so: $(top_builddir)/libwiredtiger.la $(PYSRC)/wiredtiger_wrap.c
$(PYTHON) $(PYSRC)/setup.py build_ext -b . -t . -f $(PY_SETUP_DEBUG)
TESTS = run-ex_access
install-exec-local:
$(PYTHON) $(PYSRC)/setup.py install_lib -b . --skip-build
clean-local:
rm -rf WT_TEST
$(PYTHON) $(PYSRC)/setup.py clean
rm -rf _wiredtiger.so WT_TEST
TESTS = run-ex_access

View File

@@ -283,7 +283,6 @@ retry: WT_RET(__cursor_func_init(cbt, 1));
* maximum possible record number so the search ends on the
* last page. The real record number is assigned by the
* serialized append operation.
* __wt_col_append_serial_func
*/
if (F_ISSET(cursor, WT_CURSTD_APPEND))
cbt->iface.recno = UINT64_MAX;
@@ -294,13 +293,10 @@ retry: WT_RET(__cursor_func_init(cbt, 1));
cbt->iface.recno = 0;
/*
* If WT_CURSTD_OVERWRITE set, insert/update the key/value pair.
*
* If WT_CURSTD_OVERWRITE not set, fail if the key exists, else
* insert the key/value pair. Creating a record past the end
* of the tree in a fixed-length column-store implicitly fills
* the gap with empty records. Fail in that case, the record
* exists.
* If not overwriting, fail if the key exists. Creating a
* record past the end of the tree in a fixed-length
* column-store implicitly fills the gap with empty records.
* Fail in that case, the record exists.
*/
if (!F_ISSET(cursor, WT_CURSTD_OVERWRITE) &&
((cbt->compare == 0 && !__cursor_invalid(cbt)) ||
@@ -312,16 +308,13 @@ retry: WT_RET(__cursor_func_init(cbt, 1));
cbt->iface.recno = cbt->recno;
break;
case BTREE_ROW:
/*
* If WT_CURSTD_OVERWRITE not set, fail if the key exists, else
* insert the key/value pair.
*
* If WT_CURSTD_OVERWRITE set, insert/update the key/value pair.
*/
WT_ERR(__wt_row_search(session, cbt, 1));
if (cbt->compare == 0 &&
!__cursor_invalid(cbt) &&
!F_ISSET(cursor, WT_CURSTD_OVERWRITE))
/*
* If not overwriting, fail if the key exists, else insert the
* key/value pair.
*/
if (!F_ISSET(cursor, WT_CURSTD_OVERWRITE) &&
cbt->compare == 0 && !__cursor_invalid(cbt))
WT_ERR(WT_DUPLICATE_KEY);
ret = __wt_row_modify(session, cbt, 0);
@@ -396,6 +389,12 @@ retry: WT_RET(__cursor_func_init(cbt, 1));
err: if (ret == WT_RESTART)
goto retry;
/*
* If the cursor is configured to overwrite and the record is not
* found, that is exactly what we want.
*/
if (F_ISSET(cursor, WT_CURSTD_OVERWRITE) && ret == WT_NOTFOUND)
ret = 0;
WT_TRET(__cursor_func_resolve(cbt, ret));
return (ret);
}
@@ -424,34 +423,39 @@ __wt_btcur_update(WT_CURSOR_BTREE *cbt)
WT_RET(__cursor_size_chk(session, &cursor->key));
WT_RET(__cursor_size_chk(session, &cursor->value));
/*
* The tree is no longer empty: eviction should pay attention to it,
* and it's no longer possible to bulk-load into it.
*/
btree->bulk_load_ok = 0;
retry: WT_RET(__cursor_func_init(cbt, 1));
switch (btree->type) {
case BTREE_COL_FIX:
if (cursor->value.size != 1)
WT_RET_MSG(session, EINVAL,
"item size of %" PRIu32 " does not match "
"fixed-length file requirement of 1 byte",
cursor->value.size);
/* FALLTHROUGH */
case BTREE_COL_VAR:
WT_ERR(__wt_col_search(session, cbt, 1));
/*
* Update the record if it exists. Creating a record past the
* end of the tree in a fixed-length column-store implicitly
* fills the gap with empty records. Update the record in that
* case, the record exists.
* If not overwriting, fail if the key doesn't exist. Update
* the record if it exists. Creating a record past the end of
* the tree in a fixed-length column-store implicitly fills the
* gap with empty records. Update the record in that case, the
* record exists.
*/
if ((cbt->compare != 0 || __cursor_invalid(cbt)) &&
if (!F_ISSET(cursor, WT_CURSTD_OVERWRITE) &&
(cbt->compare != 0 || __cursor_invalid(cbt)) &&
!__cursor_fix_implicit(btree, cbt))
WT_ERR(WT_NOTFOUND);
ret = __wt_col_modify(session, cbt, 3);
break;
case BTREE_ROW:
/* Update the record if it exists. */
WT_ERR(__wt_row_search(session, cbt, 1));
if (cbt->compare != 0 || __cursor_invalid(cbt))
/*
* If not overwriting, fail if the key does not exist.
*/
if (!F_ISSET(cursor, WT_CURSTD_OVERWRITE) &&
(cbt->compare != 0 || __cursor_invalid(cbt)))
WT_ERR(WT_NOTFOUND);
ret = __wt_row_modify(session, cbt, 0);
break;

View File

@@ -461,10 +461,8 @@ __inmem_row_int(WT_SESSION_IMPL *session, WT_PAGE *page, size_t *sizep)
* page (because it was never deleted, but by definition
* no earlier transaction might need it).
*
* Re-create the WT_REF state of a deleted node, give
* the page a modify structure and set the transaction
* ID for the first update to the page (WT_TXN_NONE
* because the transaction is committed and visible.)
* Re-create the WT_REF state of a deleted node and give
* the page a modify structure.
*
* If the tree is already dirty and so will be written,
* mark the page dirty. (We'd like to free the deleted
@@ -477,7 +475,6 @@ __inmem_row_int(WT_SESSION_IMPL *session, WT_PAGE *page, size_t *sizep)
ref->txnid = WT_TXN_NONE;
WT_ERR(__wt_page_modify_init(session, page));
page->modify->first_id = WT_TXN_NONE;
if (btree->modified)
__wt_page_modify_set(session, page);
}

View File

@@ -22,8 +22,7 @@ __cache_read_row_deleted(
btree = S2BT(session);
/*
* Give the page a modify structure and set the transaction ID for the
* first update to the page.
* Give the page a modify structure.
*
* If the tree is already dirty and so will be written, mark the page
* dirty. (We'd like to free the deleted pages, but if the handle is
@@ -31,7 +30,6 @@ __cache_read_row_deleted(
* able to do so.)
*/
WT_RET(__wt_page_modify_init(session, page));
page->modify->first_id = ref->txnid;
if (btree->modified)
__wt_page_modify_set(session, page);

View File

@@ -81,8 +81,7 @@ __wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, int op)
*/
if (cbt->compare == 0 && cbt->ins != NULL) {
/* Make sure the update can proceed. */
WT_ERR(
__wt_update_check(session, page, old_upd = cbt->ins->upd));
WT_ERR(__wt_update_check(session, old_upd = cbt->ins->upd));
/* Allocate the WT_UPDATE structure and transaction ID. */
WT_ERR(__wt_update_alloc(session, value, &upd, &upd_size));
@@ -99,7 +98,7 @@ __wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, int op)
__wt_update_obsolete_free(session, page, upd_obsolete);
} else {
/* Make sure the update can proceed. */
WT_ERR(__wt_update_check(session, page, NULL));
WT_ERR(__wt_update_check(session, NULL));
/* There may be no insert list, allocate as necessary. */
new_inshead_size = new_inslist_size = 0;

View File

@@ -67,7 +67,7 @@ __wt_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, int is_remove)
upd_entry = &cbt->ins->upd;
/* Make sure the update can proceed. */
WT_ERR(__wt_update_check(session, page, old_upd = *upd_entry));
WT_ERR(__wt_update_check(session, old_upd = *upd_entry));
/* Allocate the WT_UPDATE structure and transaction ID. */
WT_ERR(__wt_update_alloc(session, value, &upd, &upd_size));
@@ -84,7 +84,7 @@ __wt_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, int is_remove)
__wt_update_obsolete_free(session, page, upd_obsolete);
} else {
/* Make sure the update can proceed. */
WT_ERR(__wt_update_check(session, page, NULL));
WT_ERR(__wt_update_check(session, NULL));
/*
* Allocate insert array if necessary, and set the array
@@ -294,26 +294,14 @@ __wt_insert_serial_func(WT_SESSION_IMPL *session, void *args)
/*
* __wt_update_check --
* Check whether an update can proceed, and maintain the first txnid in
* the page->modify structure.
* Check whether an update can proceed.
*/
int
__wt_update_check(WT_SESSION_IMPL *session, WT_PAGE *page, WT_UPDATE *next)
__wt_update_check(WT_SESSION_IMPL *session, WT_UPDATE *next)
{
WT_TXN *txn;
/* Before allocating anything, make sure this update is permitted. */
WT_RET(__wt_txn_update_check(session, next));
/*
* Record the transaction ID for the first update to a page.
* We don't care if this races: there is a buffer built into the
* check for ancient updates.
*/
txn = &session->txn;
if (page->modify->first_id == WT_TXN_NONE && txn->id != WT_TXN_NONE)
page->modify->first_id = txn->id;
return (0);
}
@@ -461,7 +449,7 @@ __wt_update_serial_func(WT_SESSION_IMPL *session, void *args)
*/
WT_RET(__wt_page_write_gen_wrapped_check(page));
if (old_upd != *upd_entry)
WT_RET(__wt_update_check(session, page, *upd_entry));
WT_RET(__wt_update_check(session, *upd_entry));
upd->next = *upd_entry;
/*

View File

@@ -685,30 +685,27 @@ __wt_config_getones(WT_SESSION_IMPL *session,
}
/*
* __wt_config_gets_defno --
* Given a NULL-terminated list of configuration strings, and if the
* application supplied any configuration strings, find the final value for
* a given string key
* __wt_config_gets_def --
* Performance hack: skip parsing config strings by hard-coding defaults.
*
* It's expensive to repeatedly parse configuration strings, so don't do
* it unless it's necessary in performance paths like cursor creation.
* Assume the second configuration string is the application's
* configuration string, and if it's not set (which is true most of the
* time), then use the supplied default value. This makes it faster to
* open cursors when checking for obscure open configuration strings like
* "next_random".
*/
int
__wt_config_gets_defno(WT_SESSION_IMPL *session,
const char **cfg, const char *key, WT_CONFIG_ITEM *value)
__wt_config_gets_def(WT_SESSION_IMPL *session,
const char **cfg, const char *key, int def, WT_CONFIG_ITEM *value)
{
static const WT_CONFIG_ITEM false_value = {
"", 0, 0, WT_CONFIG_ITEM_NUM
};
/*
* This is a performance hack: it's expensive to repeatedly parse
* configuration strings, so don't do it unless it's necessary in
* performance paths like cursor creation. Assume the second
* configuration string is the application's configuration string, and
* if it's not set (which is true most of the time), then assume the
* default answer is "false", and return that. This makes it much
* faster to open cursors when checking for obscure open configuration
* strings like "next_random".
*/
*value = false_value;
value->val = def;
if (cfg == NULL || cfg[0] == NULL || cfg[1] == NULL)
return (0);
else if (cfg[2] == NULL)

View File

@@ -244,7 +244,6 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open[] = {
{ "statistics_log", "category", NULL,
confchk_statistics_log_subconfigs},
{ "sync", "boolean", NULL, NULL},
{ "transactional", "boolean", NULL, NULL},
{ "use_environment_priv", "boolean", NULL, NULL},
{ "verbose", "list",
"choices=[\"block\",\"shared_cache\",\"ckpt\",\"evict\","
@@ -356,7 +355,7 @@ static const WT_CONFIG_ENTRY config_entries[] = {
NULL
},
{ "session.open_cursor",
"append=0,bulk=0,checkpoint=,dump=,next_random=0,overwrite=0,raw=0,"
"append=0,bulk=0,checkpoint=,dump=,next_random=0,overwrite=,raw=0,"
"statistics_clear=0,statistics_fast=0,target=",
confchk_session_open_cursor
},
@@ -400,7 +399,7 @@ static const WT_CONFIG_ENTRY config_entries[] = {
"logging=0,lsm_merge=,mmap=,multiprocess=0,session_max=50,"
"shared_cache=(chunk=10MB,enable=0,name=pool,reserve=0,size=500MB),"
"statistics=0,statistics_log=(clear=,path=\"WiredTigerStat.%H\","
"sources=,timestamp=\"%b %d %H:%M:%S\",wait=0),sync=,transactional=,"
"sources=,timestamp=\"%b %d %H:%M:%S\",wait=0),sync=,"
"use_environment_priv=0,verbose=",
confchk_wiredtiger_open
},

View File

@@ -266,9 +266,8 @@ err: if (ndsrc != NULL) {
}
/*
* __wt_conn_remove_compressor --
* remove compressor added by WT_CONNECTION->add_compressor,
* only used internally.
* __wt_conn_remove_data_source --
* Remove data source added by WT_CONNECTION->add_data_source.
*/
int
__wt_conn_remove_data_source(
@@ -941,10 +940,6 @@ wiredtiger_open(const char *home, WT_EVENT_HANDLER *event_handler,
if (cval.val)
F_SET(conn, WT_CONN_SYNC);
WT_ERR(__wt_config_gets(session, cfg, "transactional", &cval));
if (cval.val)
F_SET(conn, WT_CONN_TRANSACTIONAL);
WT_ERR(__conn_verbose_config(session, cfg));
WT_ERR(__wt_conn_cache_pool_config(session, cfg));

View File

@@ -322,7 +322,7 @@ __wt_curfile_create(WT_SESSION_IMPL *session,
* random_retrieval
* Random retrieval cursors only support next, reset and close.
*/
WT_ERR(__wt_config_gets_defno(session, cfg, "next_random", &cval));
WT_ERR(__wt_config_gets_def(session, cfg, "next_random", 0, &cval));
if (cval.val != 0) {
__wt_cursor_set_notsup(cursor);
cursor->next = __curfile_next_random;
@@ -358,7 +358,7 @@ __wt_curfile_open(WT_SESSION_IMPL *session, const char *uri,
flags = 0;
WT_RET(__wt_config_gets_defno(session, cfg, "bulk", &cval));
WT_RET(__wt_config_gets_def(session, cfg, "bulk", 0, &cval));
if (cval.type == WT_CONFIG_ITEM_BOOL ||
(cval.type == WT_CONFIG_ITEM_NUM &&
(cval.val == 0 || cval.val == 1))) {

View File

@@ -415,10 +415,11 @@ __wt_curstat_open(WT_SESSION_IMPL *session,
cst = NULL;
flags = 0;
WT_RET(__wt_config_gets_defno(session, cfg, "statistics_clear", &cval));
WT_RET(
__wt_config_gets_def(session, cfg, "statistics_clear", 0, &cval));
if (cval.val != 0)
LF_SET(WT_STATISTICS_CLEAR);
WT_RET(__wt_config_gets_defno(session, cfg, "statistics_fast", &cval));
WT_RET(__wt_config_gets_def(session, cfg, "statistics_fast", 0, &cval));
if (cval.val != 0)
LF_SET(WT_STATISTICS_FAST);

View File

@@ -399,7 +399,6 @@ err: API_END(session);
static int
__cursor_runtime_config(WT_CURSOR *cursor, const char *cfg[])
{
WT_DECL_RET;
WT_CONFIG_ITEM cval;
WT_SESSION_IMPL *session;
@@ -412,14 +411,11 @@ __cursor_runtime_config(WT_CURSOR *cursor, const char *cfg[])
* added for data-source cursors, or, this call needs to return an
* error in the case of a data-source cursor.
*/
if ((ret =
__wt_config_gets_defno(session, cfg, "overwrite", &cval)) == 0) {
if (cval.val)
F_SET(cursor, WT_CURSTD_OVERWRITE);
else
F_CLR(cursor, WT_CURSTD_OVERWRITE);
}
WT_RET_NOTFOUND_OK(ret);
WT_RET(__wt_config_gets_def(session, cfg, "overwrite", 1, &cval));
if (cval.val)
F_SET(cursor, WT_CURSTD_OVERWRITE);
else
F_CLR(cursor, WT_CURSTD_OVERWRITE);
return (0);
}
@@ -525,7 +521,7 @@ __wt_cursor_init(WT_CURSOR *cursor,
* The append flag is only relevant to column stores.
*/
if (WT_CURSOR_RECNO(cursor)) {
WT_RET(__wt_config_gets_defno(session, cfg, "append", &cval));
WT_RET(__wt_config_gets_def(session, cfg, "append", 0, &cval));
if (cval.val != 0)
F_SET(cursor, WT_CURSTD_APPEND);
}
@@ -534,7 +530,7 @@ __wt_cursor_init(WT_CURSOR *cursor,
* checkpoint
* Checkpoint cursors are read-only.
*/
WT_RET(__wt_config_gets_defno(session, cfg, "checkpoint", &cval));
WT_RET(__wt_config_gets_def(session, cfg, "checkpoint", 0, &cval));
if (cval.len != 0) {
cursor->insert = __wt_cursor_notsup;
cursor->update = __wt_cursor_notsup;
@@ -542,7 +538,7 @@ __wt_cursor_init(WT_CURSOR *cursor,
}
/* dump */
WT_RET(__wt_config_gets_defno(session, cfg, "dump", &cval));
WT_RET(__wt_config_gets_def(session, cfg, "dump", 0, &cval));
if (cval.len != 0) {
/*
* Dump cursors should not have owners: only the top-level
@@ -559,7 +555,7 @@ __wt_cursor_init(WT_CURSOR *cursor,
cdump = NULL;
/* raw */
WT_RET(__wt_config_gets_defno(session, cfg, "raw", &cval));
WT_RET(__wt_config_gets_def(session, cfg, "raw", 0, &cval));
if (cval.val != 0)
F_SET(cursor, WT_CURSTD_RAW);

View File

@@ -781,7 +781,7 @@ __wt_curtable_open(WT_SESSION_IMPL *session,
* random_retrieval
* Random retrieval cursors only support next, reset and close.
*/
WT_ERR(__wt_config_gets_defno(session, cfg, "next_random", &cval));
WT_ERR(__wt_config_gets_def(session, cfg, "next_random", 0, &cval));
if (cval.val != 0) {
__wt_cursor_set_notsup(cursor);
cursor->next = __curtable_next_random;

View File

@@ -356,22 +356,6 @@ INLINE_SIMPLE_STRUCTS = YES
TYPEDEF_HIDES_STRUCT = YES
# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
# determine which symbols to keep in memory and which to flush to disk.
# When the cache is full, less often used symbols will be written to disk.
# For small to medium size projects (<1000 input files) the default value is
# probably good enough. For larger projects a too small cache size can cause
# doxygen to be busy swapping symbols to and from disk most of the time
# causing a significant performance penalty.
# If the system has enough physical memory increasing the cache will improve the
# performance by keeping more symbols in memory. Note that the value works on
# a logarithmic scale so increasing the size by one will roughly double the
# memory usage. The cache size is given by this formula:
# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
# corresponding to a cache size of 2^16 = 65536 symbols.
SYMBOL_CACHE_SIZE = 0
# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
# their name and scope. Since this can be an expensive process and often the
@@ -1705,7 +1689,7 @@ DOT_NUM_THREADS = 0
# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
# directory containing the font.
DOT_FONTNAME = FreeSans.ttf
DOT_FONTNAME =
# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
# The default size is 10pt.

View File

@@ -12,6 +12,12 @@ WT_CURSOR::close methods.
When bulk-loading row-store objects, keys must be loaded in sorted
order.
When using the \c sort utility on a Linux or other POSIX-like system to
pre-sort keys, the locale specified by the environment affects the sort
order and may not match the default sort order used by WiredTiger. Set
\c LC_ALL=C in the process' environment to configure the traditional sort
order that uses native byte values.
When bulk-loading fixed-length column store objects, the \c bulk
configuration string value \c bitmap allows chunks of a memory resident
bitmap to be loaded directly into an object by passing a WT_ITEM to

View File

@@ -1,15 +1,16 @@
/*! @page license WiredTiger license
The complete WiredTiger software package is Open Source software: you
are welcome to modify and redistribute it under the terms of version 3
of the
are welcome to modify and redistribute it under the terms of
<a href="http://www.gnu.org/licenses/gpl-2.0-standalone.html">
<b>version 2</b></a> or
<a href="http://www.gnu.org/licenses/gpl-3.0-standalone.html">
<b>version 3</b></a> of the
<b>GNU General Public License</b></a>
as published by the Free Software Foundation. This program is
distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the
<a href="http://www.gnu.org/licenses/gpl-3.0-standalone.html">
<b>GNU General Public License</b></a> for details.
For a license to use the WiredTiger software under conditions other than
@@ -19,8 +20,8 @@ contact WiredTiger, Inc. at
@section library 3rd party software included in the WiredTiger library binary
The WiredTiger library binary includes software copyrighted under the
terms of the
The WiredTiger library binary includes the following 3rd party software,
distributed under the terms of the
<a href="http://www.opensource.org/licenses/BSD-3-Clause">
<b>University of California, Berkeley (BSD) 3-Clause License</b></a>
and the
@@ -28,9 +29,6 @@ and the
<b>MIT License</b></a>. Any redistribution should comply with these
copyrights.
The WiredTiger library binary includes the following 3rd party software,
distributed under the following licenses:
<table>
@hrow{Distribution File, License}
@row{src/include/bitstring.i, University of California\, Berkeley (BSD) 3-Clause License}
@@ -54,7 +52,8 @@ redistribution.
@section public_domain Public domain software
Portions of this program are public domain software. Public domain files have
notices releasing the software into the public domain and may be freely used.
Many portions of this program are public domain software. Public domain
files have notices releasing the software into the public domain and may
be freely used and redistributed.
*/

View File

@@ -18,7 +18,10 @@ FreeBSD
GCC
Gawlick
GitHub
Google
Google's
IEC
JavaScript
LDFLAGS
LIBS
LSB
@@ -238,6 +241,7 @@ os
ovfl
pcoll
pdf
petabyte
pget
php
png
@@ -316,6 +320,7 @@ umask
unallocated
unencoded
unescaped
uninstall
untyped
uri
useconds

View File

@@ -6,9 +6,9 @@ WiredTiger is an high performance, scalable, production quality, NoSQL,
@section releases Releases
<table>
@row{<b>WiredTiger 1.6.2</b> (current),
<a href="releases/wiredtiger-1.6.2.tar.bz2"><b>[Release package]</b></a>,
<a href="1.6.2/index.html"><b>[Documentation]</b></a>}
@row{<b>WiredTiger 1.6.3</b> (current),
<a href="releases/wiredtiger-1.6.3.tar.bz2"><b>[Release package]</b></a>,
<a href="1.6.3/index.html"><b>[Documentation]</b></a>}
@row{<b>WiredTiger 1.5.3</b> (previous),
<a href="releases/wiredtiger-1.5.3.tar.bz2"><b>[Release package]</b></a>,
<a href="1.5.3/index.html"><b>[Documentation]</b></a>}

View File

@@ -1,5 +1,37 @@
/*! @page upgrading Upgrading WiredTiger applications
@section version_163 Upgrading to Version 1.6.3
<dl>
<dt>Cursor overwrite configuration</dt>
<dd>
In previous releases, the WT_SESSION::open_cursor \c overwrite configuration
string behaved inconsistently across Btree and LSM data sources. In Btree,
\c overwrite was \c false by default and was limited to the WT_CURSOR::insert
method, changing an insert to succeed regardless of whether or not the record
previously existed. In LSM trees, \c overwrite was \c true by default, and
applied to the WT_CURSOR::insert, WT_CURSOR::remove and WT_CURSOR::update
methods, configuring all three methods to ignore the existing state of the
record.
In the 1.6.3 release, the \c overwrite configuration is consistent across both
Btree and LSM tree data sources. For performance reasons, the default is the
behavior previously described for LSM trees: in other words, \c overwrite is
\c true by default, causing WT_CURSOR::insert, WT_CURSOR::remove and
WT_CURSOR::update to ignore the current state of the record, and these methods
will succeed regardless of whether or not the record previously exists. When
an application configures \c overwrite to \c false, WT_CURSOR::insert will fail
with ::WT_DUPLICATE_KEY if the record previously exists, and WT_CURSOR::update
and WT_CURSOR::remove will fail with ::WT_NOTFOUND if the record does not
previously exist.
<b>This is a potentially serious API change that will not be detected by
compilation.</b> Application cursors should be reviewed to confirm they are
configured for the desired behavior.
</dd>
</dl>
<hr>
@section version_162 Upgrading to Version 1.6.2
<dl>

View File

@@ -37,8 +37,7 @@
#define TXN_API_CALL(s, h, n, cur, bt, config, cfg) do { \
int __autotxn = 0; \
API_CALL(s, h, n, bt, cur, config, cfg); \
__autotxn = F_ISSET(S2C(s), WT_CONN_TRANSACTIONAL) && \
!F_ISSET(&(s)->txn, TXN_RUNNING); \
__autotxn = !F_ISSET(&(s)->txn, TXN_RUNNING); \
if (__autotxn) \
F_SET(&(s)->txn, TXN_AUTOCOMMIT)
@@ -46,8 +45,7 @@
#define TXN_API_CALL_NOCONF(s, h, n, cur, bt) do { \
int __autotxn = 0; \
API_CALL_NOCONF(s, h, n, cur, bt); \
__autotxn = F_ISSET(S2C(s), WT_CONN_TRANSACTIONAL) && \
!F_ISSET(&(s)->txn, TXN_AUTOCOMMIT | TXN_RUNNING); \
__autotxn = !F_ISSET(&(s)->txn, TXN_AUTOCOMMIT | TXN_RUNNING); \
if (__autotxn) \
F_SET(&(s)->txn, TXN_AUTOCOMMIT)

View File

@@ -196,11 +196,6 @@ struct __wt_page_modify {
} *track; /* Array of tracked objects */
uint32_t track_entries; /* Total track slots */
uint64_t first_id; /* Earliest transactional update, used
* to avoid errors from transaction ID
* wraparound.
*/
#define WT_PM_REC_EMPTY 0x01 /* Reconciliation: page empty */
#define WT_PM_REC_REPLACE 0x02 /* Reconciliation: page replaced */
#define WT_PM_REC_SPLIT 0x04 /* Reconciliation: page split */

View File

@@ -439,9 +439,7 @@ extern int __wt_row_insert_alloc(WT_SESSION_IMPL *session,
WT_INSERT **insp,
size_t *ins_sizep);
extern int __wt_insert_serial_func(WT_SESSION_IMPL *session, void *args);
extern int __wt_update_check(WT_SESSION_IMPL *session,
WT_PAGE *page,
WT_UPDATE *next);
extern int __wt_update_check(WT_SESSION_IMPL *session, WT_UPDATE *next);
extern int __wt_update_alloc(WT_SESSION_IMPL *session,
WT_ITEM *value,
WT_UPDATE **updp,
@@ -490,9 +488,10 @@ extern int __wt_config_getones(WT_SESSION_IMPL *session,
const char *config,
const char *key,
WT_CONFIG_ITEM *value);
extern int __wt_config_gets_defno(WT_SESSION_IMPL *session,
extern int __wt_config_gets_def(WT_SESSION_IMPL *session,
const char **cfg,
const char *key,
int def,
WT_CONFIG_ITEM *value);
extern int __wt_config_subgetraw(WT_SESSION_IMPL *session,
WT_CONFIG_ITEM *cfg,

View File

@@ -3,13 +3,12 @@
* flags section: BEGIN
*/
#define WT_CACHE_POOL_RUN 0x00000001
#define WT_CONN_CACHE_POOL 0x00000040
#define WT_CONN_EVICTION_RUN 0x00000020
#define WT_CONN_LSM_MERGE 0x00000010
#define WT_CONN_PANIC 0x00000008
#define WT_CONN_SERVER_RUN 0x00000004
#define WT_CONN_SYNC 0x00000002
#define WT_CONN_TRANSACTIONAL 0x00000001
#define WT_CONN_CACHE_POOL 0x00000020
#define WT_CONN_EVICTION_RUN 0x00000010
#define WT_CONN_LSM_MERGE 0x00000008
#define WT_CONN_PANIC 0x00000004
#define WT_CONN_SERVER_RUN 0x00000002
#define WT_CONN_SYNC 0x00000001
#define WT_EVICTION_SERVER_LOCKED 0x00000004
#define WT_FILE_TYPE_DATA 0x00000002
#define WT_FILE_TYPE_LOG 0x00000001

View File

@@ -17,9 +17,6 @@ __wt_txn_modify(WT_SESSION_IMPL *session, uint64_t *id)
{
WT_TXN *txn;
if (!F_ISSET(S2C(session), WT_CONN_TRANSACTIONAL))
return (0);
txn = &session->txn;
WT_ASSERT(session, F_ISSET(txn, TXN_RUNNING));
WT_RET(__wt_realloc_def(
@@ -39,9 +36,6 @@ __wt_txn_modify_ref(WT_SESSION_IMPL *session, WT_REF *ref)
{
WT_TXN *txn;
if (!F_ISSET(S2C(session), WT_CONN_TRANSACTIONAL))
return (0);
txn = &session->txn;
WT_ASSERT(session, F_ISSET(txn, TXN_RUNNING));
WT_RET(__wt_realloc_def(
@@ -63,9 +57,6 @@ __wt_txn_unmodify(WT_SESSION_IMPL *session)
{
WT_TXN *txn;
if (!F_ISSET(S2C(session), WT_CONN_TRANSACTIONAL))
return;
txn = &session->txn;
if (F_ISSET(txn, TXN_RUNNING)) {
WT_ASSERT(session, txn->mod_count > 0);

View File

@@ -588,12 +588,15 @@ struct __wt_session {
* "hex"\, \c "print"; default empty.}
* @config{next_random, configure the cursor to return a pseudo-random
* record from the object; valid only for row-store cursors. Cursors
* configured with next_random only support the WT_CURSOR::next and
* configured with \c next_random only support the WT_CURSOR::next and
* WT_CURSOR::close methods. See @ref cursor_random for details., a
* boolean flag; default \c false.}
* @config{overwrite, change the behavior of the cursor's insert method
* to overwrite previously existing values., a boolean flag; default \c
* false.}
* @config{overwrite, configures whether the cursor's insert\, update
* and remove methods check the existing state of the record. If \c
* overwrite is \c false\, WT_CURSOR::insert fails with
* ::WT_DUPLICATE_KEY if the record exists\, WT_CURSOR::update and
* WT_CURSOR::remove fail with ::WT_NOTFOUND if the record does not
* exist., a boolean flag; default \c true.}
* @config{raw, ignore the encodings for the key and value\, manage data
* as if the formats were \c "u". See @ref cursor_raw for details., a
* boolean flag; default \c false.}
@@ -1205,7 +1208,7 @@ struct __wt_connection {
* function must match ::wiredtiger_extension_init., a string; default
* \c wiredtiger_extension_init.}
* @config{prefix, a prefix for all names registered by this extension
* (e.g.\, to make namespaces distinct or during upgrades., a string;
* (e.g.\, to make namespaces distinct or during upgrades)., a string;
* default empty.}
* @config{terminate, a optional function in the extension that is
* called before the extension is unloaded during WT_CONNECTION::close.
@@ -1418,8 +1421,6 @@ struct __wt_connection {
* @config{ ),,}
* @config{sync, flush files to stable storage when closing or writing
* checkpoints., a boolean flag; default \c true.}
* @config{transactional, support transactional semantics., a boolean flag;
* default \c true.}
* @config{use_environment_priv, use the \c WIREDTIGER_CONFIG and \c
* WIREDTIGER_HOME environment variables regardless of whether or not the
* process is running with special privileges. See @ref home for more

View File

@@ -1062,7 +1062,6 @@ __wt_clsm_open(WT_SESSION_IMPL *session,
__clsm_update, /* update */
__clsm_remove, /* remove */
__clsm_close); /* close */
WT_CONFIG_ITEM cval;
WT_CURSOR *cursor;
WT_CURSOR_LSM *clsm;
WT_DECL_RET;
@@ -1099,14 +1098,6 @@ __wt_clsm_open(WT_SESSION_IMPL *session,
STATIC_ASSERT(offsetof(WT_CURSOR_LSM, iface) == 0);
WT_ERR(__wt_cursor_init(cursor, cursor->uri, owner, cfg, cursorp));
/*
* LSM cursors default to overwrite: if no setting was supplied, turn
* it on.
*/
if (cfg == NULL || cfg[1] == NULL || __wt_config_getones(
session, cfg[1], "overwrite", &cval) == WT_NOTFOUND)
F_SET(cursor, WT_CURSTD_OVERWRITE);
if (0) {
err: if (lsm_tree != NULL)
__wt_lsm_tree_release(session, lsm_tree);

View File

@@ -165,7 +165,7 @@ __wt_schema_drop(WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
WT_DECL_RET;
int force;
WT_RET(__wt_config_gets_defno(session, cfg, "force", &cval));
WT_RET(__wt_config_gets_def(session, cfg, "force", 0, &cval));
force = (cval.val != 0);
WT_RET(__wt_meta_track_on(session));

View File

@@ -154,18 +154,13 @@ __session_reconfigure(WT_SESSION *wt_session, const char *config)
WT_TRET(__session_reset_cursors(session));
WT_ERR(__wt_config_gets_defno(session, cfg, "isolation", &cval));
if (cval.len != 0) {
if (!F_ISSET(S2C(session), WT_CONN_TRANSACTIONAL))
WT_ERR_MSG(session, EINVAL,
"Database not configured for transactions");
WT_ERR(__wt_config_gets_def(session, cfg, "isolation", 0, &cval));
if (cval.len != 0)
session->isolation = session->txn.isolation =
WT_STRING_MATCH("snapshot", cval.str, cval.len) ?
TXN_ISO_SNAPSHOT :
WT_STRING_MATCH("read-uncommitted", cval.str, cval.len) ?
TXN_ISO_READ_UNCOMMITTED : TXN_ISO_READ_COMMITTED;
}
err: API_END_NOTFOUND_MAP(session, ret);
}
@@ -630,9 +625,6 @@ __session_begin_transaction(WT_SESSION *wt_session, const char *config)
SESSION_API_CALL(session, begin_transaction, config, cfg);
WT_CSTAT_INCR(session, txn_begin);
if (!F_ISSET(S2C(session), WT_CONN_TRANSACTIONAL))
WT_ERR_MSG(session, EINVAL,
"Database not configured for transactions");
if (F_ISSET(&session->txn, TXN_RUNNING))
WT_ERR_MSG(session, EINVAL, "Transaction already running");

View File

@@ -169,7 +169,7 @@ __wt_session_get_btree_ckpt(WT_SESSION_IMPL *session,
* that never open a checkpoint call the underlying function directly.
*/
WT_RET_NOTFOUND_OK(
__wt_config_gets_defno(session, cfg, "checkpoint", &cval));
__wt_config_gets_def(session, cfg, "checkpoint", 0, &cval));
if (cval.len != 0) {
/*
* The internal checkpoint name is special, find the last

View File

@@ -208,7 +208,7 @@ __wt_txn_begin(WT_SESSION_IMPL *session, const char *cfg[])
WT_ASSERT(session, txn_state->id == WT_TXN_NONE);
WT_RET(__wt_config_gets_defno(session, cfg, "isolation", &cval));
WT_RET(__wt_config_gets_def(session, cfg, "isolation", 0, &cval));
if (cval.len == 0)
txn->isolation = session->isolation;
else

View File

@@ -512,7 +512,7 @@ nextprev(WT_CURSOR *cursor, int next, int *notfoundp)
}
if (ret != 0 && ret != WT_NOTFOUND)
die(ret, "%s", which);
*notfoundp = ret == WT_NOTFOUND;
*notfoundp = (ret == WT_NOTFOUND);
if (!SINGLETHREADED)
return;
@@ -790,21 +790,19 @@ row_remove(WT_CURSOR *cursor, WT_ITEM *key, uint64_t keyno, int *notfoundp)
g.wt_api, session, "%-10s%" PRIu64, "remove", keyno);
cursor->set_key(cursor, key);
ret = cursor->remove(cursor);
/* We use the cursor in overwrite mode, check for existence. */
if ((ret = cursor->search(cursor)) == 0)
ret = cursor->remove(cursor);
if (ret != 0 && ret != WT_NOTFOUND)
die(ret, "row_remove: remove %" PRIu64 " by key", keyno);
*notfoundp = ret == WT_NOTFOUND;
*notfoundp = (ret == WT_NOTFOUND);
if (!SINGLETHREADED)
return;
bdb_remove(keyno, &notfound);
/* LSM trees don't check for existence if "overwrite" is set. */
if (strncmp(cursor->uri, "lsm:", 4) == 0)
*notfoundp = notfound;
else
(void)notfound_chk("row_remove", ret, notfound, keyno);
(void)notfound_chk("row_remove", ret, notfound, keyno);
}
/*
@@ -825,10 +823,12 @@ col_remove(WT_CURSOR *cursor, WT_ITEM *key, uint64_t keyno, int *notfoundp)
g.wt_api, session, "%-10s%" PRIu64, "remove", keyno);
cursor->set_key(cursor, keyno);
ret = cursor->remove(cursor);
/* We use the cursor in overwrite mode, check for existence. */
if ((ret = cursor->search(cursor)) == 0)
ret = cursor->remove(cursor);
if (ret != 0 && ret != WT_NOTFOUND)
die(ret, "col_remove: remove %" PRIu64 " by key", keyno);
*notfoundp = ret == WT_NOTFOUND;
*notfoundp = (ret == WT_NOTFOUND);
if (!SINGLETHREADED)
return;

View File

@@ -102,7 +102,7 @@ main(int argc, char *argv[])
if ((ret = pthread_rwlock_init(&g.backup_lock, NULL)) != 0)
die(ret, "pthread_rwlock_init: hot-backup lock");
if ((ret = pthread_rwlock_init(&g.table_extend_lock, NULL)) != 0)
die(ret, "pthread_rwlock_destroy: table_extend lock");
die(ret, "pthread_rwlock_init: table_extend lock");
/* Clean up on signal. */
(void)signal(SIGINT, onint);
@@ -196,6 +196,12 @@ main(int argc, char *argv[])
(void)fclose(g.rand_log);
config_print(0);
if ((ret = pthread_rwlock_destroy(&g.backup_lock)) != 0)
die(ret, "pthread_rwlock_destroy: hot-backup lock");
if ((ret = pthread_rwlock_destroy(&g.table_extend_lock)) != 0)
die(ret, "pthread_rwlock_destroy: table_extend lock");
config_clear();
return (EXIT_SUCCESS);

View File

@@ -135,25 +135,31 @@ wts_create(void)
/*
* Create the underlying store.
*
* Make sure at least 2 internal page per thread can fit in cache.
*/
if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
die(ret, "connection.open_session");
/*
* Ensure that we can service at least one operation per-thread
* concurrently without filling the cache with pinned pages. We
* choose a multiplier of three because the max configurations control
* on disk size and in memory pages are often significantly larger
* than their disk counterparts.
*/
maxintlpage = 1U << g.c_intl_page_max;
while (maxintlpage > 512 &&
2 * g.c_threads * maxintlpage > g.c_cache << 20)
maxintlpage >>= 1;
maxleafpage = 1U << g.c_leaf_page_max;
while (3 * g.c_threads * (maxintlpage + maxleafpage) >
g.c_cache << 20) {
if (maxleafpage <= 512 && maxintlpage <= 512)
break;
if (maxintlpage > 512)
maxintlpage >>= 1;
if (maxleafpage > 512)
maxleafpage >>= 1;
}
maxintlitem = MMRAND(maxintlpage / 50, maxintlpage / 40);
if (maxintlitem < 40)
maxintlitem = 40;
/* Make sure at least two leaf pages per thread can fit in cache. */
maxleafpage = 1U << g.c_leaf_page_max;
while (maxleafpage > 512 &&
2 * g.c_threads * (maxintlpage + maxleafpage) > g.c_cache << 20)
maxleafpage >>= 1;
maxleafitem = MMRAND(maxleafpage / 50, maxleafpage / 40);
if (maxleafitem < 40)
maxleafitem = 40;

View File

@@ -142,14 +142,12 @@ class suite_subprocess:
print "*********************************************"
print "**** Run 'wt' via: run " + " ".join(procargs[3:]) + infilepart + ">" + wtoutname + " 2>" + wterrname
print "*********************************************"
proc = subprocess.Popen(procargs)
subprocess.call(procargs)
elif infilename:
with open(infilename, "r") as wtin:
subprocess.call(procargs, stdin=wtin, stdout=wtout, stderr=wterr)
else:
if infilename != None:
with open(infilename, "r") as wtin:
proc = subprocess.Popen(procargs, stdin=wtin, stdout=wtout, stderr=wterr)
else:
proc = subprocess.Popen(procargs, stdout=wtout, stderr=wterr)
proc.wait()
subprocess.call(procargs, stdout=wtout, stderr=wterr)
if errfilename == None:
self.check_empty_file(wterrname)
if outfilename == None:

View File

@@ -68,7 +68,7 @@ class test_config03(test_base03.test_base03):
config_vars = [ 'cache_size', 'create', 'error_prefix', 'eviction_target',
'eviction_trigger', 'hazard_max', 'logging',
'multiprocess', 'session_max', 'transactional', 'verbose' ]
'multiprocess', 'session_max', 'verbose' ]
all_scenarios = wtscenario.multiply_scenarios('_',
cache_size_scenarios, create_scenarios, error_prefix_scenarios,

View File

@@ -173,7 +173,7 @@ class test_config04(wttest.WiredTigerTestCase):
def test_transactional(self):
# Note: this will have functional tests in the future.
self.common_test('transactional')
self.common_test('')
if __name__ == '__main__':
wttest.run()

View File

@@ -85,7 +85,7 @@ class test_index01(wttest.WiredTigerTestCase):
def insert(self, *cols):
self.pr('insert')
cursor = self.cursor()
cursor = self.cursor(config='overwrite=false')
cursor.set_key(*cols[:2])
cursor.set_value(*cols[2:])
self.assertEqual(cursor.insert(), 0)
@@ -101,7 +101,7 @@ class test_index01(wttest.WiredTigerTestCase):
def update(self, *cols):
self.pr('update')
cursor = self.cursor()
cursor = self.cursor(config='overwrite=false')
cursor.set_key(*cols[:2])
cursor.set_value(*cols[2:])
self.assertEqual(cursor.update(), 0)
@@ -109,7 +109,7 @@ class test_index01(wttest.WiredTigerTestCase):
def update_nonexistent(self, *cols):
self.pr('update')
cursor = self.cursor()
cursor = self.cursor(config='overwrite=false')
cursor.set_key(*cols[:2])
cursor.set_value(*cols[2:])
self.assertEqual(cursor.update(), wiredtiger.WT_NOTFOUND)
@@ -117,7 +117,7 @@ class test_index01(wttest.WiredTigerTestCase):
def remove(self, name, ID):
self.pr('remove')
cursor = self.cursor()
cursor = self.cursor(config='overwrite=false')
cursor.set_key(name, ID)
self.assertEqual(cursor.remove(), 0)
cursor.close()

View File

@@ -27,42 +27,110 @@
import wiredtiger, wttest
from helper import key_populate, simple_populate
from wtscenario import multiply_scenarios, number_scenarios
# test_overwrite.py
# cursor overwrite configuration method
class test_overwrite(wttest.WiredTigerTestCase):
name = 'overwrite'
scenarios = [
('file', dict(uri='file:overwrite',fmt='r')),
('file', dict(uri='file:overwrite',fmt='S')),
('table', dict(uri='table:overwrite',fmt='r')),
('table', dict(uri='table:overwrite',fmt='S'))
]
('file', dict(type='file:',keyfmt='r')),
('file', dict(type='file:',keyfmt='S')),
('lsm', dict(type='lsm:',keyfmt='S')),
('table', dict(type='table:',keyfmt='r')),
('table', dict(type='table:',keyfmt='S')),
]
# Test configuration of a cursor for overwrite.
def test_overwrite(self):
simple_populate(self, self.uri, 'key_format=' + self.fmt, 100)
cursor = self.session.open_cursor(self.uri, None, None)
cursor.set_key(key_populate(cursor, 10))
# Confirm a cursor configured with/without overwrite correctly handles
# non-existent records during insert, remove and update operations.
def test_overwrite_insert(self):
uri = self.type + self.name
simple_populate(self, uri, 'key_format=' + self.keyfmt, 100)
# Insert of an existing record with overwrite off fails.
cursor = self.session.open_cursor(uri, None, "overwrite=false")
cursor.set_key(key_populate(cursor, 5))
cursor.set_value('XXXXXXXXXX')
self.assertRaises(wiredtiger.WiredTigerError, lambda: cursor.insert())
cursor = self.session.open_cursor(self.uri, None, "overwrite")
cursor.set_key(key_populate(cursor, 10))
cursor.set_value('XXXXXXXXXX')
cursor.insert()
# Test duplicating a cursor with overwrite.
def test_overwrite_reconfig(self):
simple_populate(self, self.uri, 'key_format=' + self.fmt, 100)
cursor = self.session.open_cursor(self.uri, None)
cursor.set_key(key_populate(cursor, 10))
cursor.set_value('XXXXXXXXXX')
self.assertRaises(wiredtiger.WiredTigerError, lambda: cursor.insert())
cursor.set_key(key_populate(cursor, 10))
dupc = self.session.open_cursor(None, cursor, "overwrite")
# One additional test for the insert method: duplicate the cursor with
# overwrite configured and then the insert should succeed. This test
# is only for the insert method because the remove and update method
# failure modes are for non-existent records, and you cannot duplicate
# cursor pointing to non-existent records.
dupc = self.session.open_cursor(None, cursor, "overwrite=true")
dupc.set_value('XXXXXXXXXX')
dupc.insert()
self.assertEquals(dupc.insert(), 0)
# Insert of an existing record with overwrite on succeeds.
cursor = self.session.open_cursor(uri, None)
cursor.set_key(key_populate(cursor, 6))
cursor.set_value('XXXXXXXXXX')
self.assertEquals(cursor.insert(), 0)
# Insert of a non-existent record with overwrite off succeeds.
cursor = self.session.open_cursor(uri, None, "overwrite=false")
cursor.set_key(key_populate(cursor, 200))
cursor.set_value('XXXXXXXXXX')
self.assertEquals(cursor.insert(), 0)
# Insert of a non-existent record with overwrite on succeeds.
cursor = self.session.open_cursor(uri, None)
cursor.set_key(key_populate(cursor, 201))
cursor.set_value('XXXXXXXXXX')
self.assertEquals(cursor.insert(), 0)
def test_overwrite_remove(self):
uri = self.type + self.name
simple_populate(self, uri, 'key_format=' + self.keyfmt, 100)
# Remove of an existing record with overwrite off succeeds.
cursor = self.session.open_cursor(uri, None, "overwrite=false")
cursor.set_key(key_populate(cursor, 5))
self.assertEquals(cursor.remove(), 0)
# Remove of an existing record with overwrite on succeeds.
cursor = self.session.open_cursor(uri, None)
cursor.set_key(key_populate(cursor, 6))
self.assertEquals(cursor.remove(), 0)
# Remove of a non-existent record with overwrite off fails.
cursor = self.session.open_cursor(uri, None, "overwrite=false")
cursor.set_key(key_populate(cursor, 200))
self.assertEquals(cursor.remove(), wiredtiger.WT_NOTFOUND)
# Remove of a non-existent record with overwrite on succeeds.
cursor = self.session.open_cursor(uri, None)
cursor.set_key(key_populate(cursor, 201))
self.assertEquals(cursor.remove(), 0)
def test_overwrite_update(self):
uri = self.type + self.name
simple_populate(self, uri, 'key_format=' + self.keyfmt, 100)
# Update of an existing record with overwrite off succeeds.
cursor = self.session.open_cursor(uri, None, "overwrite=false")
cursor.set_key(key_populate(cursor, 5))
cursor.set_value('XXXXXXXXXX')
self.assertEquals(cursor.update(), 0)
# Update of an existing record with overwrite on succeeds.
cursor = self.session.open_cursor(uri, None)
cursor.set_key(key_populate(cursor, 6))
cursor.set_value('XXXXXXXXXX')
self.assertEquals(cursor.update(), 0)
# Update of a non-existent record with overwrite off fails.
cursor = self.session.open_cursor(uri, None, "overwrite=false")
cursor.set_key(key_populate(cursor, 200))
cursor.set_value('XXXXXXXXXX')
self.assertEquals(cursor.update(), wiredtiger.WT_NOTFOUND)
# Update of a non-existent record with overwrite on succeeds.
cursor = self.session.open_cursor(uri, None)
cursor.set_key(key_populate(cursor, 201))
cursor.set_value('XXXXXXXXXX')
self.assertEquals(cursor.update(), 0)
if __name__ == '__main__':

View File

@@ -128,7 +128,7 @@ class test_truncate_fast_delete(wttest.WiredTigerTestCase):
# Optionally add a few overflow records so we block fast delete on
# those pages.
if self.overflow:
cursor = self.session.open_cursor(uri, None)
cursor = self.session.open_cursor(uri, None, 'overwrite=false')
for i in range(1, self.nentries, 3123):
cursor.set_key(key_populate(cursor, i))
cursor.set_value(value_populate(cursor, i))
@@ -140,7 +140,7 @@ class test_truncate_fast_delete(wttest.WiredTigerTestCase):
# Optionally read/write a few rows before truncation.
if self.readbefore or self.writebefore:
cursor = self.session.open_cursor(uri, None)
cursor = self.session.open_cursor(uri, None, 'overwrite=false')
if self.readbefore:
for i in range(1, self.nentries, 737):
cursor.set_key(key_populate(cursor, i))
@@ -164,7 +164,7 @@ class test_truncate_fast_delete(wttest.WiredTigerTestCase):
# Optionally read/write a few rows after truncation.
if self.readafter or self.writeafter:
cursor = self.session.open_cursor(uri, None)
cursor = self.session.open_cursor(uri, None, 'overwrite=false')
if self.readafter:
for i in range(1, self.nentries, 1123):
cursor.set_key(key_populate(cursor, i))

View File

@@ -43,8 +43,7 @@ class test_txn01(wttest.WiredTigerTestCase):
# Overrides WiredTigerTestCase
def setUpConnectionOpen(self, dir):
conn = wiredtiger.wiredtiger_open(dir, 'create,' +
('error_prefix="%s: ",' % self.shortid()) +
'transactional,')
('error_prefix="%s: ",' % self.shortid()))
self.pr(`conn`)
return conn

View File

@@ -75,8 +75,7 @@ class test_txn02(wttest.WiredTigerTestCase):
# Overrides WiredTigerTestCase
def setUpConnectionOpen(self, dir):
conn = wiredtiger.wiredtiger_open(dir, 'create,' +
('error_prefix="%s: ",' % self.shortid()) +
'transactional,')
('error_prefix="%s: ",' % self.shortid()))
self.pr(`conn`)
self.session2 = conn.open_session()
return conn

View File

@@ -48,8 +48,7 @@ class test_txn03(wttest.WiredTigerTestCase):
# Overrides WiredTigerTestCase
def setUpConnectionOpen(self, dir):
conn = wiredtiger.wiredtiger_open(dir, 'create,' +
('error_prefix="%s: ",' % self.shortid()) +
'transactional,')
('error_prefix="%s: ",' % self.shortid()))
self.pr(`conn`)
return conn

View File

@@ -95,7 +95,8 @@ class CapturedFd(object):
in the constructor.
"""
filefd = os.open(self.filename, os.O_RDWR | os.O_CREAT | os.O_APPEND)
os.close(self.targetFd)
if filefd < 0:
raise Exception(self.testdir + ": cannot remove directory")
os.dup2(filefd, self.targetFd)
os.close(filefd)
@@ -103,8 +104,8 @@ class CapturedFd(object):
"""
Stop capturing. Restore the original fd from the duped copy.
"""
os.close(self.targetFd)
os.dup2(self.originalDupedFd, self.targetFd)
if self.originalDupedFd >= 0:
os.dup2(self.originalDupedFd, self.targetFd)
def show(self, pfx=None):
contents = self.readFileFrom(self.filename, 0, 1000)
@@ -264,23 +265,29 @@ class WiredTigerTestCase(unittest.TestCase):
if os.path.exists(self.testdir):
raise Exception(self.testdir + ": cannot remove directory")
os.makedirs(self.testdir)
os.chdir(self.testdir)
self.fdSetUp()
# tearDown needs a conn field, set it here in case the open fails.
self.conn = None
try:
os.chdir(self.testdir)
self.fdSetUp()
self.conn = self.setUpConnectionOpen(".")
self.session = self.setUpSessionOpen(self.conn)
except:
os.chdir(self.origcwd)
self.tearDown()
raise
def tearDown(self):
excinfo = sys.exc_info()
passed = (excinfo == (None, None, None))
self.pr('finishing')
try:
self.close_conn()
except:
pass
try:
self.fdTearDown()
self.pr('finishing')
self.close_conn()
# Only check for unexpected output if the test passed
if passed:
self.captureout.check(self)