Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
627b65c877 | ||
|
|
7f6b1057d1 | ||
|
|
8750d87e13 | ||
|
|
c495977b9a | ||
|
|
654b9c2b93 | ||
|
|
7580c8186e | ||
|
|
ba3f0fb597 | ||
|
|
d242c8dae8 | ||
|
|
460792842a | ||
|
|
4040f54345 | ||
|
|
81bc53cd3f | ||
|
|
bc32645c8f | ||
|
|
77c7fbdf9b | ||
|
|
61e8803c55 | ||
|
|
38d6fbe214 | ||
|
|
4fe42451ff | ||
|
|
88f90694a8 | ||
|
|
abcdeca3e9 | ||
|
|
19f977b398 | ||
|
|
772fd42c8d | ||
|
|
f9f46cf7b5 | ||
|
|
d74a2f7f3e | ||
|
|
952389d109 | ||
|
|
a9eaa81d90 | ||
|
|
176d7f7683 | ||
|
|
e3ce18298b | ||
|
|
1983d6f3b9 | ||
|
|
a6fd589669 | ||
|
|
1f52dadddb | ||
|
|
ab8eba816d | ||
|
|
bac863900f | ||
|
|
93a1673a4b |
10
LICENSE
10
LICENSE
@@ -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
13
NEWS
@@ -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
6
README
@@ -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:
|
||||
|
||||
|
||||
2
RELEASE
2
RELEASE
@@ -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"`
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
dnl WiredTiger product version for AC_INIT. Maintained by dist/s_version
|
||||
1.6.2
|
||||
1.6.3
|
||||
|
||||
@@ -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
16
dist/api_data.py
vendored
@@ -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
1
dist/flags.py
vendored
@@ -65,7 +65,6 @@ flags = {
|
||||
'CONN_PANIC',
|
||||
'CONN_SERVER_RUN',
|
||||
'CONN_SYNC',
|
||||
'CONN_TRANSACTIONAL',
|
||||
],
|
||||
'session' : [
|
||||
'SESSION_INTERNAL',
|
||||
|
||||
8
dist/s_all
vendored
8
dist/s_all
vendored
@@ -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
25
dist/s_readme
vendored
@@ -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
8
dist/s_string.ok
vendored
@@ -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
5
dist/s_typedef
vendored
@@ -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
16
dist/s_version
vendored
@@ -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 \
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
/*
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
},
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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))) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>}
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, ¬found);
|
||||
|
||||
/* 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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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__':
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user