Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
647f83d11a | ||
|
|
7bedb693a6 | ||
|
|
bf6bc01e3f | ||
|
|
a1359905ad | ||
|
|
8246befcd8 | ||
|
|
61e5b885a2 | ||
|
|
f347a3301d | ||
|
|
1e14492ea0 | ||
|
|
a1b08d168e | ||
|
|
a31f708a1c | ||
|
|
e1189da479 | ||
|
|
64c54763f0 | ||
|
|
a5aba41271 | ||
|
|
ac1bd50106 | ||
|
|
bca4607b9e | ||
|
|
57db817d67 | ||
|
|
c507009cee | ||
|
|
c062a33272 | ||
|
|
2bce92c180 | ||
|
|
45c1e2a5a3 | ||
|
|
38591db0fd | ||
|
|
466e7ade5c | ||
|
|
82a6530951 | ||
|
|
9c371c5a84 | ||
|
|
0250344b90 | ||
|
|
6792cd8115 | ||
|
|
8fa690dce6 |
43
NEWS
43
NEWS
@@ -1,3 +1,46 @@
|
||||
WiredTiger release 1.3.6, 2012-11-06
|
||||
------------------------------------
|
||||
|
||||
This is a bugfix and performance tuning release. The changes are as follows:
|
||||
|
||||
* Rename the WiredTiger installed modules to libwiredtiger_XXX. Don't install
|
||||
the nop and reverse collator modules.
|
||||
|
||||
* Replace test/format's bzip configuration string with compression, which can
|
||||
take one of four arguments (none, bzip, ext, snappy), change format to run
|
||||
snappy compression if the library is available.
|
||||
|
||||
* Rename the builtin block compressor names from "bzip2_compress" to "bzip2",
|
||||
and from "snappy_compress" to "snappy".
|
||||
|
||||
* Support multiple LSM merge threads with the "lsm_merge_threads" config key.
|
||||
Use IDs rather than array index to mark the start chunk in a merge, in case
|
||||
we race with another thread.
|
||||
|
||||
* Cache the hash values used for Bloom filter lookups, rather than hashing for
|
||||
each Bloom filter in an LSM tree.
|
||||
|
||||
* Only switch trees in an LSM cursor if the primary chunk is on disk.
|
||||
|
||||
* Add a per-btree cache priority, currently only used to make it more likely
|
||||
for Bloom filter pages to stay in cache.
|
||||
|
||||
* Only evict pages with read generations in the bottom quarter of the range we
|
||||
see. Fix a 32-bit wrapping bug in assigning read generations.
|
||||
|
||||
* For update-only LSM cursors, only open a cursor in the primary chunk.
|
||||
|
||||
* LSM: Report errors from the checkpoint thread.
|
||||
|
||||
* LSM: only save a Bloom URI in the metadata after it is successfully created.
|
||||
|
||||
* LSM: Create missing Bloom filters when reading from an LSM tree if
|
||||
"lsm_bloom_newest"is set.
|
||||
|
||||
* LSM: Include all of the chosen chunks in a merge. Only pin the current chunk
|
||||
in an LSM cursor if it is writeable.
|
||||
|
||||
|
||||
WiredTiger release 1.3.5, 2012-10-26
|
||||
------------------------------------
|
||||
|
||||
|
||||
4
README
4
README
@@ -1,6 +1,6 @@
|
||||
WiredTiger 1.3.5: (October 26, 2012)
|
||||
WiredTiger 1.3.6: (November 6, 2012)
|
||||
|
||||
This is version 1.3.5 of WiredTiger.
|
||||
This is version 1.3.6 of WiredTiger.
|
||||
|
||||
WiredTiger documentation can be found at:
|
||||
|
||||
|
||||
2
RELEASE
2
RELEASE
@@ -1,6 +1,6 @@
|
||||
WIREDTIGER_VERSION_MAJOR=1
|
||||
WIREDTIGER_VERSION_MINOR=3
|
||||
WIREDTIGER_VERSION_PATCH=5
|
||||
WIREDTIGER_VERSION_PATCH=6
|
||||
WIREDTIGER_VERSION="$WIREDTIGER_VERSION_MAJOR.$WIREDTIGER_VERSION_MINOR.$WIREDTIGER_VERSION_PATCH"
|
||||
|
||||
WIREDTIGER_RELEASE_DATE=`date "+%B %e, %Y"`
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
bench/tcbench
|
||||
examples/c
|
||||
ext/collators/reverse
|
||||
ext/compressors/bzip2_compress BZIP2
|
||||
ext/compressors/nop_compress
|
||||
ext/compressors/snappy_compress SNAPPY
|
||||
ext/compressors/bzip2 BZIP2
|
||||
ext/compressors/nop
|
||||
ext/compressors/snappy SNAPPY
|
||||
lang/python PYTHON
|
||||
test/bloom
|
||||
test/fops
|
||||
|
||||
@@ -2,8 +2,8 @@ dnl build by dist/s_version
|
||||
|
||||
VERSION_MAJOR=1
|
||||
VERSION_MINOR=3
|
||||
VERSION_PATCH=5
|
||||
VERSION_STRING='"WiredTiger 1.3.5: (October 26, 2012)"'
|
||||
VERSION_PATCH=6
|
||||
VERSION_STRING='"WiredTiger 1.3.6: (November 6, 2012)"'
|
||||
|
||||
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.3.5
|
||||
1.3.6
|
||||
|
||||
15
dist/api_data.py
vendored
15
dist/api_data.py
vendored
@@ -113,6 +113,9 @@ lsm_config = [
|
||||
Config('lsm_merge_max', '15', r'''
|
||||
the maximum number of chunks to include in a merge operation''',
|
||||
min='2', max='100'),
|
||||
Config('lsm_merge_threads', '1', r'''
|
||||
the number of thread to perform merge operations''',
|
||||
min='1', max='10'), # !!! max must match WT_LSM_MAX_WORKERS
|
||||
]
|
||||
|
||||
# Per-file configuration
|
||||
@@ -462,13 +465,15 @@ methods = {
|
||||
list, such as <code>"direct_io=[data]"</code>''',
|
||||
type='list', choices=['data', 'log']),
|
||||
Config('extensions', '', r'''
|
||||
list of extensions to load. Optional values are passed as the
|
||||
\c config parameter to WT_CONNECTION::load_extension. Complex
|
||||
paths may need quoting, for example,
|
||||
<code>extensions=("/path/to/ext.so"="entry=my_entry")</code>''',
|
||||
list of shared library extensions to load (using dlopen).
|
||||
Optional values are passed as the \c config parameter to
|
||||
WT_CONNECTION::load_extension. Complex paths may require
|
||||
quoting, for example,
|
||||
<code>extensions=("/path/ext.so"="entry=my_entry")</code>''',
|
||||
type='list'),
|
||||
Config('hazard_max', '1000', r'''
|
||||
maximum number of simultaneous hazard references per session handle''',
|
||||
maximum number of simultaneous hazard references per session
|
||||
handle''',
|
||||
min='15'),
|
||||
Config('logging', 'false', r'''
|
||||
enable logging''',
|
||||
|
||||
1
dist/s_funcs.list
vendored
1
dist/s_funcs.list
vendored
@@ -3,6 +3,7 @@ WT_CURDUMP_PASS
|
||||
__bit_ffs
|
||||
__bit_nclr
|
||||
__wt_bloom_drop
|
||||
__wt_bloom_get
|
||||
__wt_bm_addr_stderr
|
||||
__wt_btree_lex_compare
|
||||
__wt_config_getone
|
||||
|
||||
2
dist/s_string.ok
vendored
2
dist/s_string.ok
vendored
@@ -9,6 +9,7 @@ ADDR
|
||||
AJZ
|
||||
API
|
||||
APIs
|
||||
ARGS
|
||||
Alakuijala
|
||||
Alloc
|
||||
Athlon
|
||||
@@ -205,6 +206,7 @@ WinNT
|
||||
WiredTiger
|
||||
WiredTiger's
|
||||
WiredTigerCheckpoint
|
||||
WiredTigerHome
|
||||
WithSeeds
|
||||
Wuninitialized
|
||||
XP
|
||||
|
||||
@@ -395,6 +395,25 @@ session_ops(WT_SESSION *session)
|
||||
"table:mytable", "key_format=S,value_format=S");
|
||||
/*! [Create a table] */
|
||||
|
||||
/*
|
||||
* This example code gets run, and the compression libraries might not
|
||||
* be loaded, causing the create to fail. The documentation requires
|
||||
* the code snippets, use #ifdef's to avoid running it.
|
||||
*/
|
||||
#ifdef MIGHT_NOT_RUN
|
||||
/*! [Create a bzip2 compressed table] */
|
||||
ret = session->create(session,
|
||||
"table:mytable",
|
||||
"block_compressor=bzip2,key_format=S,value_format=S");
|
||||
/*! [Create a bzip2 compressed table] */
|
||||
|
||||
/*! [Create a snappy compressed table] */
|
||||
ret = session->create(session,
|
||||
"table:mytable",
|
||||
"block_compressor=snappy,key_format=S,value_format=S");
|
||||
/*! [Create a snappy compressed table] */
|
||||
#endif
|
||||
|
||||
/*! [Create a cache-resident object] */
|
||||
ret = session->create(session,
|
||||
"table:mytable", "key_format=r,value_format=S,cache_resident=true");
|
||||
@@ -891,16 +910,44 @@ main(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
system("rm -rf WiredTigerHome && mkdir WiredTigerHome");
|
||||
|
||||
{
|
||||
/*! [Open a connection] */
|
||||
WT_CONNECTION *conn;
|
||||
const char *home = "WT_TEST";
|
||||
ret = wiredtiger_open(home, NULL, "create,transactional", &conn);
|
||||
/*! [Open a connection] */
|
||||
|
||||
(void)conn->close(conn, NULL);
|
||||
ret = wiredtiger_open(
|
||||
"WiredTigerHome", NULL, "create,transactional", &conn);
|
||||
/*! [Open a connection] */
|
||||
}
|
||||
|
||||
/*
|
||||
* This example code gets run, and the compression libraries might not
|
||||
* be installed, causing the open to fail. The documentation requires
|
||||
* the code snippets, use #ifdef's to avoid running it.
|
||||
*/
|
||||
#ifdef MIGHT_NOT_RUN
|
||||
{
|
||||
/*! [Configure bzip2 extension] */
|
||||
WT_CONNECTION *conn;
|
||||
|
||||
ret = wiredtiger_open("WiredTigerHome", NULL,
|
||||
"create,"
|
||||
"extensions=[\"/usr/local/lib/wiredtiger_bzip2.so\"]", &conn);
|
||||
/*! [Configure bzip2 extension] */
|
||||
}
|
||||
|
||||
{
|
||||
/*! [Configure snappy extension] */
|
||||
WT_CONNECTION *conn;
|
||||
|
||||
ret = wiredtiger_open("WiredTigerHome", NULL,
|
||||
"create,"
|
||||
"extensions=[\"/usr/local/lib/wiredtiger_snappy.so\"]", &conn);
|
||||
/*! [Configure snappy extension] */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! [Get the WiredTiger library version #1] */
|
||||
printf("WiredTiger version %s\n", wiredtiger_version(NULL, NULL, NULL));
|
||||
/*! [Get the WiredTiger library version #1] */
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)/src/include
|
||||
|
||||
lib_LTLIBRARIES = reverse_collator.la
|
||||
reverse_collator_la_LDFLAGS = -avoid-version -module
|
||||
noinst_LTLIBRARIES = libwiredtiger_reverse_collator.la
|
||||
libwiredtiger_reverse_collator_la_SOURCES = reverse_collator.c
|
||||
|
||||
# libtool hack: noinst_LTLIBRARIES turns off building shared libraries as well
|
||||
# as installation, it will only build static libraries. As far as I can tell,
|
||||
# the "approved" libtool way to turn them back on is by adding -rpath.
|
||||
libwiredtiger_reverse_collator_la_LDFLAGS = \
|
||||
-avoid-version -module -rpath /nowhere
|
||||
|
||||
6
ext/compressors/bzip2/Makefile.am
Normal file
6
ext/compressors/bzip2/Makefile.am
Normal file
@@ -0,0 +1,6 @@
|
||||
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)/src/include
|
||||
|
||||
lib_LTLIBRARIES = libwiredtiger_bzip2.la
|
||||
libwiredtiger_bzip2_la_SOURCES = bzip2_compress.c
|
||||
libwiredtiger_bzip2_la_LDFLAGS = -avoid-version -module
|
||||
libwiredtiger_bzip2_la_LIBADD = -lbz2
|
||||
@@ -72,8 +72,7 @@ wiredtiger_extension_init(
|
||||
wt_api = api;
|
||||
conn = session->connection;
|
||||
|
||||
return (conn->add_compressor(
|
||||
conn, "bzip2_compress", &bzip2_compressor, NULL));
|
||||
return (conn->add_compressor(conn, "bzip2", &bzip2_compressor, NULL));
|
||||
}
|
||||
|
||||
/* Bzip2 WT_COMPRESSOR implementation for WT_CONNECTION::add_compressor. */
|
||||
@@ -1,5 +0,0 @@
|
||||
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)/src/include
|
||||
|
||||
lib_LTLIBRARIES = bzip2_compress.la
|
||||
bzip2_compress_la_LDFLAGS = -avoid-version -module
|
||||
bzip2_compress_la_LIBADD = -lbz2
|
||||
9
ext/compressors/nop/Makefile.am
Normal file
9
ext/compressors/nop/Makefile.am
Normal file
@@ -0,0 +1,9 @@
|
||||
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)/src/include
|
||||
|
||||
noinst_LTLIBRARIES = libwiredtiger_nop.la
|
||||
libwiredtiger_nop_la_SOURCES = nop_compress.c
|
||||
|
||||
# libtool hack: noinst_LTLIBRARIES turns off building shared libraries as well
|
||||
# as installation, it will only build static libraries. As far as I can tell,
|
||||
# the "approved" libtool way to turn them back on is by adding -rpath.
|
||||
libwiredtiger_nop_la_LDFLAGS = -avoid-version -module -rpath /nowhere
|
||||
@@ -55,8 +55,7 @@ wiredtiger_extension_init(
|
||||
wt_api = api;
|
||||
conn = session->connection;
|
||||
|
||||
return (
|
||||
conn->add_compressor(conn, "nop_compress", &nop_compressor, NULL));
|
||||
return (conn->add_compressor(conn, "nop", &nop_compressor, NULL));
|
||||
}
|
||||
|
||||
/* Implementation of WT_COMPRESSOR for WT_CONNECTION::add_compressor. */
|
||||
@@ -1,4 +0,0 @@
|
||||
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)/src/include
|
||||
|
||||
lib_LTLIBRARIES = nop_compress.la
|
||||
nop_compress_la_LDFLAGS = -avoid-version -module
|
||||
6
ext/compressors/snappy/Makefile.am
Normal file
6
ext/compressors/snappy/Makefile.am
Normal file
@@ -0,0 +1,6 @@
|
||||
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)/src/include
|
||||
|
||||
lib_LTLIBRARIES = libwiredtiger_snappy.la
|
||||
libwiredtiger_snappy_la_SOURCES = snappy_compress.c
|
||||
libwiredtiger_snappy_la_LDFLAGS = -avoid-version -module
|
||||
libwiredtiger_snappy_la_LIBADD = -lsnappy
|
||||
@@ -59,8 +59,8 @@ wiredtiger_extension_init(
|
||||
wt_api = api;
|
||||
conn = session->connection;
|
||||
|
||||
return (conn->add_compressor(
|
||||
conn, "snappy_compress", &wt_snappy_compressor, NULL));
|
||||
return (
|
||||
conn->add_compressor(conn, "snappy", &wt_snappy_compressor, NULL));
|
||||
}
|
||||
|
||||
/* Snappy WT_COMPRESSOR for WT_CONNECTION::add_compressor. */
|
||||
@@ -1,5 +0,0 @@
|
||||
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)/src/include
|
||||
|
||||
lib_LTLIBRARIES = snappy_compress.la
|
||||
snappy_compress_la_LDFLAGS = -avoid-version -module
|
||||
snappy_compress_la_LIBADD = -lsnappy
|
||||
@@ -6,7 +6,6 @@
|
||||
*/
|
||||
|
||||
#include "wt_internal.h"
|
||||
#include "bloom.h"
|
||||
|
||||
#define WT_BLOOM_TABLE_CONFIG "key_format=r,value_format=1t,exclusive=true"
|
||||
|
||||
@@ -125,6 +124,10 @@ __wt_bloom_open(WT_SESSION_IMPL *session,
|
||||
/* Find the largest key, to get the size of the filter. */
|
||||
cfg[1] = bloom->config;
|
||||
WT_RET(__wt_open_cursor(session, bloom->uri, owner, cfg, &c));
|
||||
|
||||
/* XXX Layering violation: bump the cache priority for Bloom filters. */
|
||||
session->btree->evict_priority = (1 << 19);
|
||||
|
||||
WT_RET(c->prev(c));
|
||||
WT_RET(c->get_key(c, &size));
|
||||
|
||||
@@ -199,12 +202,27 @@ err: WT_TRET(c->close(c));
|
||||
}
|
||||
|
||||
/*
|
||||
* __wt_bloom_get --
|
||||
* Tests whether the given key is in the Bloom filter.
|
||||
* Returns zero if found, WT_NOTFOUND if not.
|
||||
* __wt_bloom_hash --
|
||||
* Calculate the hash values for a given key.
|
||||
*/
|
||||
int
|
||||
__wt_bloom_get(WT_BLOOM *bloom, WT_ITEM *key)
|
||||
__wt_bloom_hash(WT_BLOOM *bloom, WT_ITEM *key, WT_BLOOM_HASH *bhash)
|
||||
{
|
||||
WT_UNUSED(bloom);
|
||||
|
||||
bhash->h1 = __wt_hash_fnv64(key->data, key->size);
|
||||
bhash->h2 = __wt_hash_city64(key->data, key->size);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* __wt_bloom_hash_get --
|
||||
* Tests whether the key (as given by its hash signature) is in the Bloom
|
||||
* filter. Returns zero if found, WT_NOTFOUND if not.
|
||||
*/
|
||||
int
|
||||
__wt_bloom_hash_get(WT_BLOOM *bloom, WT_BLOOM_HASH *bhash)
|
||||
{
|
||||
WT_CURSOR *c;
|
||||
WT_DECL_RET;
|
||||
@@ -226,24 +244,15 @@ __wt_bloom_get(WT_BLOOM *bloom, WT_ITEM *key)
|
||||
} else
|
||||
c = bloom->c;
|
||||
|
||||
/*
|
||||
* This comparison code is complex to avoid calculating the second
|
||||
* hash if possible.
|
||||
*/
|
||||
h1 = __wt_hash_fnv64(key->data, key->size);
|
||||
h1 = bhash->h1;
|
||||
h2 = bhash->h2;
|
||||
|
||||
/*
|
||||
* Add 1 to the hash because Wired Tiger tables are 1 based, and the
|
||||
* original bitstring array was 0 based.
|
||||
*/
|
||||
c->set_key(c, (h1 % bloom->m) + 1);
|
||||
WT_RET(c->search(c));
|
||||
WT_RET(c->get_value(c, &bit));
|
||||
if (bit == 0)
|
||||
return (WT_NOTFOUND);
|
||||
h2 = __wt_hash_city64(key->data, key->size);
|
||||
result = 0;
|
||||
for (i = 0, h1 += h2; i < bloom->k - 1; i++, h1 += h2) {
|
||||
for (i = 0; i < bloom->k; i++, h1 += h2) {
|
||||
/*
|
||||
* Add 1 to the hash because Wired Tiger tables are 1 based and
|
||||
* the original bitstring array was 0 based.
|
||||
*/
|
||||
c->set_key(c, (h1 % bloom->m) + 1);
|
||||
WT_ERR(c->search(c));
|
||||
WT_ERR(c->get_value(c, &bit));
|
||||
@@ -263,6 +272,20 @@ err: /* Don't return WT_NOTFOUND from a failed search. */
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* __wt_bloom_get --
|
||||
* Tests whether the given key is in the Bloom filter.
|
||||
* Returns zero if found, WT_NOTFOUND if not.
|
||||
*/
|
||||
int
|
||||
__wt_bloom_get(WT_BLOOM *bloom, WT_ITEM *key)
|
||||
{
|
||||
WT_BLOOM_HASH bhash;
|
||||
|
||||
WT_RET(__wt_bloom_hash(bloom, key, &bhash));
|
||||
return (__wt_bloom_hash_get(bloom, &bhash));
|
||||
}
|
||||
|
||||
/*
|
||||
* __wt_bloom_close --
|
||||
* Close the Bloom filter, release any resources.
|
||||
|
||||
@@ -12,7 +12,7 @@ static int __evict_file_request(WT_SESSION_IMPL *, int);
|
||||
static int __evict_file_request_walk(WT_SESSION_IMPL *);
|
||||
static int __evict_lru(WT_SESSION_IMPL *);
|
||||
static int __evict_lru_cmp(const void *, const void *);
|
||||
static int __evict_walk(WT_SESSION_IMPL *);
|
||||
static int __evict_walk(WT_SESSION_IMPL *, uint32_t *);
|
||||
static int __evict_walk_file(WT_SESSION_IMPL *, u_int *);
|
||||
static int __evict_worker(WT_SESSION_IMPL *);
|
||||
|
||||
@@ -20,14 +20,48 @@ static int __evict_worker(WT_SESSION_IMPL *);
|
||||
* Tuning constants: I hesitate to call this tuning, but we want to review some
|
||||
* number of pages from each file's in-memory tree for each page we evict.
|
||||
*/
|
||||
#define WT_EVICT_GROUP 30 /* Consider N pages as LRU candidates */
|
||||
#define WT_EVICT_INT_SKEW (1<<20) /* Prefer leaf pages over internal
|
||||
#define WT_EVICT_INT_SKEW (1<<20) /* Prefer leaf pages over internal
|
||||
pages by this many increments of the
|
||||
read generation. */
|
||||
#define WT_EVICT_WALK_PER_FILE 5 /* Pages to visit per file */
|
||||
#define WT_EVICT_WALK_BASE 50 /* Pages tracked across file visits */
|
||||
#define WT_EVICT_WALK_BASE 100 /* Pages tracked across file visits */
|
||||
#define WT_EVICT_WALK_INCR 100 /* Pages added each walk */
|
||||
|
||||
/*
|
||||
* __evict_read_gen --
|
||||
* Get the adjusted read generation for an eviction entry.
|
||||
*/
|
||||
static inline uint64_t
|
||||
__evict_read_gen(const WT_EVICT_ENTRY *entry)
|
||||
{
|
||||
uint64_t read_gen;
|
||||
|
||||
if (entry->page == NULL)
|
||||
return (UINT64_MAX);
|
||||
|
||||
read_gen = entry->page->read_gen + entry->btree->evict_priority;
|
||||
if (entry->page->type == WT_PAGE_ROW_INT ||
|
||||
entry->page->type == WT_PAGE_COL_INT)
|
||||
read_gen += WT_EVICT_INT_SKEW;
|
||||
|
||||
return (read_gen);
|
||||
}
|
||||
|
||||
/*
|
||||
* __evict_lru_cmp --
|
||||
* Qsort function: sort the eviction array.
|
||||
*/
|
||||
static int
|
||||
__evict_lru_cmp(const void *a, const void *b)
|
||||
{
|
||||
uint64_t a_lru, b_lru;
|
||||
|
||||
a_lru = __evict_read_gen(a);
|
||||
b_lru = __evict_read_gen(b);
|
||||
|
||||
return ((a_lru < b_lru) ? -1 : (a_lru == b_lru) ? 0 : 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* __evict_list_clr --
|
||||
* Clear an entry in the LRU eviction list.
|
||||
@@ -488,16 +522,43 @@ static int
|
||||
__evict_lru(WT_SESSION_IMPL *session)
|
||||
{
|
||||
WT_CACHE *cache;
|
||||
uint64_t cutoff;
|
||||
uint32_t i, candidates;
|
||||
|
||||
cache = S2C(session)->cache;
|
||||
|
||||
/* Get some more pages to consider for eviction. */
|
||||
WT_RET(__evict_walk(session));
|
||||
WT_RET(__evict_walk(session, &candidates));
|
||||
|
||||
/* Sort the list into LRU order and restart. */
|
||||
__wt_spin_lock(session, &cache->evict_lock);
|
||||
while (candidates > 0 && cache->evict[candidates - 1].page == NULL)
|
||||
--candidates;
|
||||
if (candidates == 0) {
|
||||
__wt_spin_unlock(session, &cache->evict_lock);
|
||||
return (0);
|
||||
}
|
||||
|
||||
qsort(cache->evict,
|
||||
cache->evict_entries, sizeof(WT_EVICT_ENTRY), __evict_lru_cmp);
|
||||
candidates, sizeof(WT_EVICT_ENTRY), __evict_lru_cmp);
|
||||
|
||||
/* Find the bottom 25% */
|
||||
while (candidates > 0 && cache->evict[candidates - 1].page == NULL)
|
||||
--candidates;
|
||||
|
||||
cutoff = (3 * __evict_read_gen(&cache->evict[0]) +
|
||||
__evict_read_gen(&cache->evict[candidates - 1])) / 4;
|
||||
|
||||
/*
|
||||
* Don't take more than half, regardless. That said, if there is only
|
||||
* one candidate page, which is normal when populating an empty file,
|
||||
* don't exclude it.
|
||||
*/
|
||||
for (i = 0; i < candidates / 2; i++)
|
||||
if (cache->evict[i].page->read_gen > cutoff)
|
||||
break;
|
||||
cache->evict_candidates = i + 1;
|
||||
|
||||
__evict_list_clr_all(session, WT_EVICT_WALK_BASE);
|
||||
|
||||
cache->evict_current = cache->evict;
|
||||
@@ -515,7 +576,7 @@ __evict_lru(WT_SESSION_IMPL *session)
|
||||
* Fill in the array by walking the next set of pages.
|
||||
*/
|
||||
static int
|
||||
__evict_walk(WT_SESSION_IMPL *session)
|
||||
__evict_walk(WT_SESSION_IMPL *session, u_int *entriesp)
|
||||
{
|
||||
WT_BTREE *btree;
|
||||
WT_CACHE *cache;
|
||||
@@ -586,6 +647,7 @@ retry: file_count = 0;
|
||||
retries++ < WT_EVICT_WALK_INCR / WT_EVICT_WALK_PER_FILE)
|
||||
goto retry;
|
||||
|
||||
*entriesp = i;
|
||||
if (0) {
|
||||
err: __wt_spin_unlock(session, &cache->evict_lock);
|
||||
}
|
||||
@@ -683,7 +745,10 @@ __evict_get_page(
|
||||
*btreep = NULL;
|
||||
*pagep = NULL;
|
||||
|
||||
candidates = (is_app ? WT_EVICT_GROUP : WT_EVICT_GROUP / 2);
|
||||
candidates = cache->evict_candidates;
|
||||
/* The eviction server only considers half of the entries. */
|
||||
if (!is_app)
|
||||
candidates /= 2;
|
||||
|
||||
/*
|
||||
* Avoid the LRU lock if no pages are available. If there are pages
|
||||
@@ -787,44 +852,3 @@ __wt_evict_lru_page(WT_SESSION_IMPL *session, int is_app)
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* __evict_lru_cmp --
|
||||
* Qsort function: sort the eviction array.
|
||||
*/
|
||||
static int
|
||||
__evict_lru_cmp(const void *a, const void *b)
|
||||
{
|
||||
WT_PAGE *a_page, *b_page;
|
||||
uint64_t a_lru, b_lru;
|
||||
|
||||
/*
|
||||
* There may be NULL references in the array; sort them as greater than
|
||||
* anything else so they migrate to the end of the array.
|
||||
*/
|
||||
a_page = ((WT_EVICT_ENTRY *)a)->page;
|
||||
b_page = ((WT_EVICT_ENTRY *)b)->page;
|
||||
if (a_page == NULL)
|
||||
return (b_page == NULL ? 0 : 1);
|
||||
if (b_page == NULL)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Sort by the LRU in ascending order.
|
||||
*
|
||||
* Bias in favor of leaf pages. Otherwise, we can waste time
|
||||
* considering parent pages for eviction while their child pages are
|
||||
* still in memory.
|
||||
*
|
||||
* Bump the LRU generation by a small fixed amount: the idea being that
|
||||
* if we have enough good leaf page candidates, we should evict them
|
||||
* first, but not completely ignore an old internal page.
|
||||
*/
|
||||
a_lru = a_page->read_gen;
|
||||
b_lru = b_page->read_gen;
|
||||
if (a_page->type == WT_PAGE_ROW_INT || a_page->type == WT_PAGE_COL_INT)
|
||||
a_lru += WT_EVICT_INT_SKEW;
|
||||
if (b_page->type == WT_PAGE_ROW_INT || b_page->type == WT_PAGE_COL_INT)
|
||||
b_lru += WT_EVICT_INT_SKEW;
|
||||
return (a_lru > b_lru ? 1 : (a_lru < b_lru ? -1 : 0));
|
||||
}
|
||||
|
||||
@@ -1247,12 +1247,13 @@ __rec_split_row_promote(WT_SESSION_IMPL *session, WT_RECONCILE *r, uint8_t type)
|
||||
* a copy. For a row-store, it's the first key on the page, a variable-
|
||||
* length byte string, get a copy.
|
||||
*
|
||||
* This function is called from __rec_split at each split boundary, but
|
||||
* that means we're not called before the first boundary. It's painful,
|
||||
* but we need to detect that case and copy the key from the page we're
|
||||
* building. We could simplify this by grabbing a copy of the first key
|
||||
* we put on a page, perhaps in the function building keys for a page,
|
||||
* but that's going to be uglier than this.
|
||||
* This function is called from the split code at each split boundary,
|
||||
* but that means we're not called before the first boundary. When we
|
||||
* do the split work at the second boundary, we need to copy the key
|
||||
* for the first boundary from the page we're building. Alternatively,
|
||||
* we could store a copy of the first key we put on a page somewhere,
|
||||
* perhaps while building the keys for a page, but that's likely to be
|
||||
* even uglier.
|
||||
*/
|
||||
if (r->bnd_next == 1) {
|
||||
/*
|
||||
@@ -1270,7 +1271,11 @@ __rec_split_row_promote(WT_SESSION_IMPL *session, WT_RECONCILE *r, uint8_t type)
|
||||
|
||||
/*
|
||||
* For the current slot, take the last key we built, after doing suffix
|
||||
* compression.
|
||||
* compression. The "last key we built" describes some process: before
|
||||
* calling the split code, we must place the last key on the page before
|
||||
* the boundary into the "last" key structure, and the first key on the
|
||||
* page after the boundary into the "current" key structure, we're going
|
||||
* to compare them for suffix compression.
|
||||
*
|
||||
* Suffix compression is a hack to shorten keys on internal pages. We
|
||||
* only need enough bytes in the promoted key to ensure searches go to
|
||||
|
||||
@@ -115,8 +115,9 @@ __wt_confdfl_file_meta =
|
||||
"internal_page_max=2KB,key_format=u,key_gap=10,leaf_item_max=0,"
|
||||
"leaf_page_max=1MB,lsm_bloom=,lsm_bloom_bit_count=8,lsm_bloom_config="
|
||||
",lsm_bloom_hash_count=4,lsm_bloom_newest=0,lsm_bloom_oldest=0,"
|
||||
"lsm_chunk_size=2MB,lsm_merge_max=15,prefix_compression=,split_pct=75"
|
||||
",value_format=u,version=(major=0,minor=0)";
|
||||
"lsm_chunk_size=2MB,lsm_merge_max=15,lsm_merge_threads=1,"
|
||||
"prefix_compression=,split_pct=75,value_format=u,version=(major=0,"
|
||||
"minor=0)";
|
||||
|
||||
WT_CONFIG_CHECK
|
||||
__wt_confchk_file_meta[] = {
|
||||
@@ -146,6 +147,7 @@ __wt_confchk_file_meta[] = {
|
||||
{ "lsm_bloom_oldest", "boolean", NULL },
|
||||
{ "lsm_chunk_size", "int", "min=512K,max=500MB" },
|
||||
{ "lsm_merge_max", "int", "min=2,max=100" },
|
||||
{ "lsm_merge_threads", "int", "min=1,max=10" },
|
||||
{ "prefix_compression", "boolean", NULL },
|
||||
{ "split_pct", "int", "min=25,max=100" },
|
||||
{ "value_format", "format", NULL },
|
||||
@@ -232,8 +234,8 @@ __wt_confdfl_session_create =
|
||||
"key_format=u,key_gap=10,leaf_item_max=0,leaf_page_max=1MB,lsm_bloom="
|
||||
",lsm_bloom_bit_count=8,lsm_bloom_config=,lsm_bloom_hash_count=4,"
|
||||
"lsm_bloom_newest=0,lsm_bloom_oldest=0,lsm_chunk_size=2MB,"
|
||||
"lsm_merge_max=15,prefix_compression=,source=,split_pct=75,type=file,"
|
||||
"value_format=u,value_format=u";
|
||||
"lsm_merge_max=15,lsm_merge_threads=1,prefix_compression=,source=,"
|
||||
"split_pct=75,type=file,value_format=u,value_format=u";
|
||||
|
||||
WT_CONFIG_CHECK
|
||||
__wt_confchk_session_create[] = {
|
||||
@@ -266,6 +268,7 @@ __wt_confchk_session_create[] = {
|
||||
{ "lsm_bloom_oldest", "boolean", NULL },
|
||||
{ "lsm_chunk_size", "int", "min=512K,max=500MB" },
|
||||
{ "lsm_merge_max", "int", "min=2,max=100" },
|
||||
{ "lsm_merge_threads", "int", "min=1,max=10" },
|
||||
{ "prefix_compression", "boolean", NULL },
|
||||
{ "source", "string", NULL },
|
||||
{ "split_pct", "int", "min=25,max=100" },
|
||||
|
||||
@@ -5,22 +5,35 @@ the bzip2 and snappy compression engines.
|
||||
|
||||
@section compression_bzip2 Using bzip2 compression
|
||||
|
||||
To use the builtin support for <a href="http://www.bzip.org/">bzip2</a>
|
||||
To use the builtin support for
|
||||
<a href="http://www.bzip.org/">Julian Seward's bzip2</a>
|
||||
compression, first check that bzip2 is installed in include and library
|
||||
directories searched by the compiler. Once bzip2 is installed, you can
|
||||
enable bzip2 using the \c --enable-bzip2 option to configure.
|
||||
|
||||
If bzip2 is installed in a non-standard location, you'll need to modify
|
||||
the \c CPPFLAGS and \c LDFLAGS to indicate these locations. For example,
|
||||
with the bzip2 includes and libraries installed in \c /usr/local/include
|
||||
and \c /usr/local/lib, you should run configure as follows:
|
||||
If bzip2 is installed in a location not normally searched by the
|
||||
compiler toolchain, you'll need to modify the \c CPPFLAGS and \c LDFLAGS
|
||||
to indicate these locations. For example, with the bzip2 includes and
|
||||
libraries installed in \c /usr/local/include and \c /usr/local/lib, you
|
||||
should run configure as follows:
|
||||
|
||||
@code
|
||||
cd build_posix
|
||||
../dist/configure --enable-bzip2 CPPFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/include"
|
||||
../configure --enable-bzip2 CPPFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/include"
|
||||
@endcode
|
||||
|
||||
After building, you can confirm the compressor is working by running the
|
||||
When opening the WiredTiger database, load the bzip2 shared library as
|
||||
an extension. For example, with the bzip2 library installed in
|
||||
\c /usr/local/lib, you would use the following extension:
|
||||
|
||||
@snippet ex_all.c Configure bzip2 extension
|
||||
|
||||
Finally, when creating the WiredTiger object, set \c block_compressor
|
||||
to \c bzip2:
|
||||
|
||||
@snippet ex_all.c Create a bzip2 compressed table
|
||||
|
||||
If necessary, you can confirm the compressor is working by running the
|
||||
compression part of the test suite:
|
||||
|
||||
@code
|
||||
@@ -33,23 +46,35 @@ was not skipped.
|
||||
|
||||
@section compression_snappy Using snappy compression
|
||||
|
||||
To use the builtin support for Google's
|
||||
<a href="http://code.google.com/p/snappy/">snappy</a> compression, first
|
||||
check that snappy is installed in include and library directories
|
||||
searched by the compiler. Once snappy is installed, you can enable
|
||||
snappy using the \c --enable-snappy option to configure.
|
||||
To use the builtin support for
|
||||
<a href="http://code.google.com/p/snappy/">Google's snappy</a>
|
||||
compression, first check that snappy is installed in include and library
|
||||
directories searched by the compiler. Once snappy is installed, you can
|
||||
enable snappy using the \c --enable-snappy option to configure.
|
||||
|
||||
If snappy is installed in a non-standard location, you'll need to modify
|
||||
the \c CPPFLAGS and \c LDFLAGS to indicate these locations. For example,
|
||||
with the snappy includes and libraries installed in \c /usr/local/include
|
||||
and \c /usr/local/lib, you should run configure as follows:
|
||||
If snappy is installed in a location not normally searched by the
|
||||
compiler toolchain, you'll need to modify the \c CPPFLAGS and \c LDFLAGS
|
||||
to indicate these locations. For example, with the snappy includes and
|
||||
libraries installed in \c /usr/local/include and \c /usr/local/lib, you
|
||||
should run configure as follows:
|
||||
|
||||
@code
|
||||
cd build_posix
|
||||
../dist/configure --enable-snappy CPPFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/include"
|
||||
../configure --enable-snappy CPPFLAGS="-I/usr/local/include" LDFLAGS="-L/usr/local/include"
|
||||
@endcode
|
||||
|
||||
After building, you can confirm the compressor is working by running the
|
||||
When opening the WiredTiger database, load the snappy shared library as
|
||||
an extension. For example, with the snappy library installed in
|
||||
\c /usr/local/lib, you would use the following extension:
|
||||
|
||||
@snippet ex_all.c Configure snappy extension
|
||||
|
||||
Finally, when creating the WiredTiger object, set \c block_compressor
|
||||
to \c snappy:
|
||||
|
||||
@snippet ex_all.c Create a snappy compressed table
|
||||
|
||||
If necessary, you can confirm the compressor is working by running the
|
||||
compression part of the test suite:
|
||||
|
||||
@code
|
||||
|
||||
@@ -13,8 +13,8 @@ DbMultiple
|
||||
EB
|
||||
EmpId
|
||||
FreeBSD
|
||||
Gawlick
|
||||
GCC
|
||||
Gawlick
|
||||
GitHub
|
||||
IEC
|
||||
LDFLAGS
|
||||
@@ -28,6 +28,7 @@ Mewhort
|
||||
NoSQL
|
||||
RepMgr
|
||||
Rrx
|
||||
Seward's
|
||||
URIs
|
||||
Vv
|
||||
WiredTiger
|
||||
@@ -193,6 +194,7 @@ mutexes
|
||||
mutexing
|
||||
mvcc
|
||||
mygcc
|
||||
namespace
|
||||
ndary
|
||||
ndbm
|
||||
newsite
|
||||
|
||||
@@ -13,7 +13,7 @@ To ask questions or discuss issues related to using WiredTiger, visit our
|
||||
|
||||
View the documentation online:
|
||||
|
||||
- <a href="1.3.5/index.html"><b>WiredTiger 1.3.5 (current release)</b></a>
|
||||
- <a href="1.3.6/index.html"><b>WiredTiger 1.3.6 (current release)</b></a>
|
||||
- <a href="1.2.2/index.html"><b>WiredTiger 1.2.2</b></a>
|
||||
- <a href="1.1.5/index.html"><b>WiredTiger 1.1.5</b></a>
|
||||
|
||||
|
||||
@@ -1,9 +1,48 @@
|
||||
/*! @page upgrading Upgrading WiredTiger applications
|
||||
|
||||
@section version_136 Upgrading to Version 1.3.6
|
||||
<dl>
|
||||
|
||||
<dt>Installed library names</dt>
|
||||
<dd>
|
||||
The installed WiredTiger extension library names changed to limit
|
||||
namespace pollution:
|
||||
|
||||
<table>
|
||||
@hrow{Library, Previous Name, New Name}
|
||||
@row{Bzip2 compression, bzip2_compress.a, libwiredtiger_bzip2.a}
|
||||
@row{, bzip2_compress.la, libwiredtiger_bzip2.la}
|
||||
@row{, bzip2_compress.so, libwiredtiger_bzip2.so}
|
||||
@row{Snappy compression, snappy_compress.a, libwiredtiger_snappy.a}
|
||||
@row{, snappy_compress.la, libwiredtiger_snappy.la}
|
||||
@row{, snappy_compress.so, libwiredtiger_snappy.so}
|
||||
@row{No-op compression, nop_compress.a, No longer installed}
|
||||
@row{, nop_compress.la, No longer installed}
|
||||
@row{, nop_compress.so, No longer installed}
|
||||
@row{Reverse order collator, reverse_collator.a, No longer installed}
|
||||
@row{, reverse_collator.la, No longer installed}
|
||||
@row{, reverse_collator.so, No longer installed}
|
||||
</table>
|
||||
</dd>
|
||||
|
||||
<dt>Built-in compression names</dt>
|
||||
<dd>
|
||||
The built-in compression name arguments to the WT_SESSION:create
|
||||
\c block_compressor configuration string changed for consistency:
|
||||
|
||||
<table>
|
||||
@hrow{Extension, Previous Name, New Name}
|
||||
@row{Bzip2 compression, "bzip2_compress", "bzip2"}
|
||||
@row{Snappy compression, "snappy_compress", "snappy"}
|
||||
</table>
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
<hr>
|
||||
@section version_135 Upgrading to Version 1.3.5
|
||||
<dl>
|
||||
|
||||
<dt>Version 1.3.5 file format changes</dt>
|
||||
<dt>File format changes</dt>
|
||||
<dd>
|
||||
The underlying file formats changed in the 1.3.5 release; tables and files
|
||||
should be dumped and re-loaded into a new database.
|
||||
@@ -100,7 +139,7 @@ returns a cursor comparison status (less than 0, equal to 0, or greater than
|
||||
0) depending on the cursors' key order.
|
||||
</dd>
|
||||
|
||||
<dt>Version 1.3 file format changes</dt>
|
||||
<dt>File format changes</dt>
|
||||
<dd>
|
||||
The underlying file formats changed in the 1.3 release; tables and files
|
||||
should be dumped and re-loaded into a new database.
|
||||
|
||||
@@ -22,3 +22,7 @@ struct __wt_bloom {
|
||||
uint64_t m; /* The number of slots in the bit string. */
|
||||
uint64_t n; /* The number of items to be inserted. */
|
||||
};
|
||||
|
||||
struct __wt_bloom_hash {
|
||||
uint64_t h1, h2; /* The two hashes used to calculate bits. */
|
||||
};
|
||||
|
||||
@@ -271,7 +271,7 @@ struct __wt_page {
|
||||
* The read-generation is not declared volatile: read-generation is set
|
||||
* a lot (on every access), and we don't want to write it that much.
|
||||
*/
|
||||
uint64_t read_gen;
|
||||
uint64_t read_gen;
|
||||
|
||||
/*
|
||||
* In-memory pages optionally reference a number of entries originally
|
||||
|
||||
@@ -119,6 +119,7 @@ struct __wt_btree {
|
||||
u_int block_header; /* Block manager header length */
|
||||
|
||||
WT_PAGE *evict_page; /* Eviction thread's location */
|
||||
uint64_t evict_priority; /* Relative priority of cached pages. */
|
||||
volatile uint32_t lru_count; /* Count of threads in LRU eviction */
|
||||
|
||||
WT_BTREE_STATS *stats; /* Btree statistics */
|
||||
|
||||
@@ -34,7 +34,7 @@ struct __wt_cache {
|
||||
/*
|
||||
* Read information.
|
||||
*/
|
||||
uint32_t read_gen; /* Page read generation (LRU) */
|
||||
uint64_t read_gen; /* Page read generation (LRU) */
|
||||
|
||||
/*
|
||||
* Eviction thread information.
|
||||
@@ -52,6 +52,7 @@ struct __wt_cache {
|
||||
WT_EVICT_ENTRY *evict_current; /* LRU current page to be evicted */
|
||||
size_t evict_allocated; /* LRU list bytes allocated */
|
||||
uint32_t evict_entries; /* LRU list eviction slots */
|
||||
uint32_t evict_candidates; /* LRU list pages to evict */
|
||||
u_int evict_file_next; /* LRU: next file to search */
|
||||
|
||||
/*
|
||||
|
||||
@@ -259,6 +259,8 @@ extern int __wt_bloom_open(WT_SESSION_IMPL *session,
|
||||
WT_BLOOM **bloomp);
|
||||
extern int __wt_bloom_insert(WT_BLOOM *bloom, WT_ITEM *key);
|
||||
extern int __wt_bloom_finalize(WT_BLOOM *bloom);
|
||||
extern int __wt_bloom_hash(WT_BLOOM *bloom, WT_ITEM *key, WT_BLOOM_HASH *bhash);
|
||||
extern int __wt_bloom_hash_get(WT_BLOOM *bloom, WT_BLOOM_HASH *bhash);
|
||||
extern int __wt_bloom_get(WT_BLOOM *bloom, WT_ITEM *key);
|
||||
extern int __wt_bloom_close(WT_BLOOM *bloom);
|
||||
extern int __wt_bloom_drop(WT_BLOOM *bloom, const char *config);
|
||||
@@ -704,8 +706,9 @@ extern int __wt_log_printf(WT_SESSION_IMPL *session,
|
||||
2,
|
||||
3)));
|
||||
extern WT_LOGREC_DESC __wt_logdesc_debug;
|
||||
extern int __wt_clsm_init_merge(WT_CURSOR *cursor,
|
||||
extern int __wt_clsm_init_merge( WT_CURSOR *cursor,
|
||||
int start_chunk,
|
||||
uint32_t start_id,
|
||||
int nchunks);
|
||||
extern int __wt_clsm_open(WT_SESSION_IMPL *session,
|
||||
const char *uri,
|
||||
@@ -719,8 +722,9 @@ extern int __wt_lsm_merge_update_tree(WT_SESSION_IMPL *session,
|
||||
int start_chunk,
|
||||
int nchunks,
|
||||
WT_LSM_CHUNK *chunk);
|
||||
extern int __wt_lsm_merge(WT_SESSION_IMPL *session,
|
||||
extern int __wt_lsm_merge( WT_SESSION_IMPL *session,
|
||||
WT_LSM_TREE *lsm_tree,
|
||||
uint32_t id,
|
||||
int stalls);
|
||||
extern int __wt_lsm_meta_read(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree);
|
||||
extern int __wt_lsm_meta_write(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree);
|
||||
@@ -730,15 +734,14 @@ extern int __wt_lsm_stat_init( WT_SESSION_IMPL *session,
|
||||
extern int __wt_lsm_tree_close_all(WT_SESSION_IMPL *session);
|
||||
extern int __wt_lsm_tree_bloom_name( WT_SESSION_IMPL *session,
|
||||
WT_LSM_TREE *lsm_tree,
|
||||
int i,
|
||||
uint32_t id,
|
||||
WT_ITEM *buf);
|
||||
extern int __wt_lsm_tree_chunk_name( WT_SESSION_IMPL *session,
|
||||
WT_LSM_TREE *lsm_tree,
|
||||
int i,
|
||||
uint32_t id,
|
||||
WT_ITEM *buf);
|
||||
extern int __wt_lsm_tree_setup_chunk(WT_SESSION_IMPL *session,
|
||||
WT_LSM_TREE *lsm_tree,
|
||||
int i,
|
||||
WT_LSM_CHUNK *chunk,
|
||||
int create_bloom);
|
||||
extern int __wt_lsm_tree_create(WT_SESSION_IMPL *session,
|
||||
@@ -769,7 +772,7 @@ extern int __wt_lsm_tree_worker(WT_SESSION_IMPL *session,
|
||||
const char *[]),
|
||||
const char *cfg[],
|
||||
uint32_t open_flags);
|
||||
extern void *__wt_lsm_worker(void *arg);
|
||||
extern void *__wt_lsm_worker(void *vargs);
|
||||
extern void *__wt_lsm_checkpoint_worker(void *arg);
|
||||
extern int __wt_lsm_copy_chunks(WT_SESSION_IMPL *session,
|
||||
WT_LSM_TREE *lsm_tree,
|
||||
|
||||
@@ -20,15 +20,15 @@ struct __wt_cursor_lsm {
|
||||
WT_CURSOR **cursors;
|
||||
WT_CURSOR *current; /* The current cursor for iteration */
|
||||
|
||||
WT_LSM_CHUNK *primary_chunk; /* The current primary chunk. */
|
||||
WT_LSM_CHUNK *primary_chunk; /* The current primary chunk */
|
||||
|
||||
#define WT_CLSM_ITERATE_NEXT 0x01 /* Forward iteration */
|
||||
#define WT_CLSM_ITERATE_PREV 0x02 /* Backward iteration */
|
||||
#define WT_CLSM_MERGE 0x04 /* Merge cursor, don't update. */
|
||||
#define WT_CLSM_MINOR_MERGE 0x08 /* Minor merge, include tombstones. */
|
||||
#define WT_CLSM_MERGE 0x04 /* Merge cursor, don't update */
|
||||
#define WT_CLSM_MINOR_MERGE 0x08 /* Minor merge, include tombstones */
|
||||
#define WT_CLSM_MULTIPLE 0x10 /* Multiple cursors have values for the
|
||||
current key */
|
||||
#define WT_CLSM_UPDATED 0x20 /* Cursor has done updates */
|
||||
#define WT_CLSM_OPEN_READ 0x20 /* Open for reads */
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
@@ -37,14 +37,16 @@ struct __wt_cursor_lsm {
|
||||
* A single chunk (file) in an LSM tree.
|
||||
*/
|
||||
struct __wt_lsm_chunk {
|
||||
const char *uri; /* Data source for this chunk. */
|
||||
const char *bloom_uri; /* URI of Bloom filter, if any. */
|
||||
uint64_t count; /* Approximate count of records. */
|
||||
uint32_t generation; /* Merge generation. */
|
||||
uint32_t id; /* ID used to generate URIs */
|
||||
uint32_t generation; /* Merge generation */
|
||||
const char *uri; /* Data source for this chunk */
|
||||
const char *bloom_uri; /* URI of Bloom filter, if any */
|
||||
uint64_t count; /* Approximate count of records */
|
||||
|
||||
uint32_t ncursor; /* Cursors with the chunk as primary. */
|
||||
#define WT_LSM_CHUNK_ONDISK 0x01
|
||||
#define WT_LSM_CHUNK_BLOOM 0x02
|
||||
uint32_t ncursor; /* Cursors with the chunk as primary */
|
||||
#define WT_LSM_CHUNK_BLOOM 0x01
|
||||
#define WT_LSM_CHUNK_MERGING 0x02
|
||||
#define WT_LSM_CHUNK_ONDISK 0x04
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
@@ -59,7 +61,7 @@ struct __wt_lsm_tree {
|
||||
|
||||
WT_COLLATOR *collator;
|
||||
|
||||
int refcnt; /* Number of users of the tree. */
|
||||
int refcnt; /* Number of users of the tree */
|
||||
WT_RWLOCK *rwlock;
|
||||
TAILQ_ENTRY(__wt_lsm_tree) q;
|
||||
|
||||
@@ -74,21 +76,26 @@ struct __wt_lsm_tree {
|
||||
uint32_t bloom_hash_count;
|
||||
uint32_t chunk_size;
|
||||
uint32_t merge_max;
|
||||
uint32_t merge_threads;
|
||||
|
||||
#define WT_LSM_BLOOM_MERGED 0x00000001
|
||||
#define WT_LSM_BLOOM_NEWEST 0x00000002
|
||||
#define WT_LSM_BLOOM_OFF 0x00000004
|
||||
#define WT_LSM_BLOOM_OLDEST 0x00000008
|
||||
uint32_t bloom; /* Bloom creation policy. */
|
||||
uint32_t bloom; /* Bloom creation policy */
|
||||
|
||||
WT_SESSION_IMPL *worker_session;/* Passed to thread_create */
|
||||
pthread_t worker_tid; /* LSM worker thread */
|
||||
#define WT_LSM_MAX_WORKERS 10
|
||||
/* Passed to thread_create */
|
||||
WT_SESSION_IMPL *worker_sessions[WT_LSM_MAX_WORKERS];
|
||||
/* LSM worker thread(s) */
|
||||
pthread_t worker_tids[WT_LSM_MAX_WORKERS];
|
||||
WT_SESSION_IMPL *ckpt_session; /* For checkpoint worker */
|
||||
pthread_t ckpt_tid; /* LSM checkpoint worker thread */
|
||||
|
||||
int nchunks; /* Number of active chunks */
|
||||
int last; /* Last allocated ID. */
|
||||
WT_LSM_CHUNK **chunk; /* Array of active LSM chunks */
|
||||
size_t chunk_alloc; /* Space allocated for chunks */
|
||||
int nchunks; /* Number of active chunks */
|
||||
uint32_t last; /* Last allocated ID */
|
||||
|
||||
WT_LSM_CHUNK **old_chunks; /* Array of old LSM chunks */
|
||||
size_t old_alloc; /* Space allocated for old chunks */
|
||||
@@ -115,7 +122,16 @@ struct __wt_lsm_data_source {
|
||||
* State for an LSM worker thread.
|
||||
*/
|
||||
struct __wt_lsm_worker_cookie {
|
||||
WT_LSM_CHUNK **chunk_array;
|
||||
size_t chunk_alloc;
|
||||
int nchunks;
|
||||
WT_LSM_CHUNK **chunk_array;
|
||||
size_t chunk_alloc;
|
||||
int nchunks;
|
||||
};
|
||||
|
||||
/*
|
||||
* WT_LSM_WORKER_ARGS --
|
||||
* State for an LSM worker thread.
|
||||
*/
|
||||
struct __wt_lsm_worker_args {
|
||||
WT_LSM_TREE *lsm_tree;
|
||||
int id;
|
||||
};
|
||||
|
||||
@@ -685,6 +685,8 @@ struct __wt_session {
|
||||
* LSM tree.,an integer between 512K and 500MB; default \c 2MB.}
|
||||
* @config{lsm_merge_max, the maximum number of chunks to include in a
|
||||
* merge operation.,an integer between 2 and 100; default \c 15.}
|
||||
* @config{lsm_merge_threads, the number of thread to perform merge
|
||||
* operations.,an integer between 1 and 10; default \c 1.}
|
||||
* @config{prefix_compression, configure row-store format key prefix
|
||||
* compression.,a boolean flag; default \c true.}
|
||||
* @config{source, override the default data source URI derived from the
|
||||
@@ -1177,11 +1179,11 @@ struct __wt_connection {
|
||||
* integer between 10 and 99; default \c 80.}
|
||||
* @config{eviction_trigger, trigger eviction when the cache becomes this full
|
||||
* (as a percentage).,an integer between 10 and 99; default \c 95.}
|
||||
* @config{extensions, list of extensions to load. Optional values are passed
|
||||
* as the \c config parameter to WT_CONNECTION::load_extension. Complex paths
|
||||
* may need quoting\, for example\,
|
||||
* <code>extensions=("/path/to/ext.so"="entry=my_entry")</code>.,a list of
|
||||
* strings; default empty.}
|
||||
* @config{extensions, list of shared library extensions to load (using dlopen).
|
||||
* Optional values are passed as the \c config parameter to
|
||||
* WT_CONNECTION::load_extension. Complex paths may require quoting\, for
|
||||
* example\, <code>extensions=("/path/ext.so"="entry=my_entry")</code>.,a list
|
||||
* of strings; default empty.}
|
||||
* @config{hazard_max, maximum number of simultaneous hazard references per
|
||||
* session handle.,an integer greater than or equal to 15; default \c 1000.}
|
||||
* @config{logging, enable logging.,a boolean flag; default \c false.}
|
||||
|
||||
@@ -59,6 +59,8 @@ struct __wt_block_header;
|
||||
typedef struct __wt_block_header WT_BLOCK_HEADER;
|
||||
struct __wt_bloom;
|
||||
typedef struct __wt_bloom WT_BLOOM;
|
||||
struct __wt_bloom_hash;
|
||||
typedef struct __wt_bloom_hash WT_BLOOM_HASH;
|
||||
struct __wt_btree;
|
||||
typedef struct __wt_btree WT_BTREE;
|
||||
struct __wt_btree_session;
|
||||
@@ -137,6 +139,8 @@ struct __wt_lsm_stats;
|
||||
typedef struct __wt_lsm_stats WT_LSM_STATS;
|
||||
struct __wt_lsm_tree;
|
||||
typedef struct __wt_lsm_tree WT_LSM_TREE;
|
||||
struct __wt_lsm_worker_args;
|
||||
typedef struct __wt_lsm_worker_args WT_LSM_WORKER_ARGS;
|
||||
struct __wt_lsm_worker_cookie;
|
||||
typedef struct __wt_lsm_worker_cookie WT_LSM_WORKER_COOKIE;
|
||||
struct __wt_named_collator;
|
||||
@@ -206,6 +210,7 @@ struct __wt_update;
|
||||
#include "stat.h"
|
||||
|
||||
#include "api.h"
|
||||
#include "bloom.h"
|
||||
#include "cursor.h"
|
||||
#include "lsm.h"
|
||||
#include "meta.h"
|
||||
|
||||
@@ -26,22 +26,23 @@
|
||||
#define WT_LSM_ENTER(clsm, cursor, session, n) \
|
||||
clsm = (WT_CURSOR_LSM *)cursor; \
|
||||
CURSOR_API_CALL(cursor, session, n, NULL); \
|
||||
WT_ERR(__clsm_enter(clsm))
|
||||
WT_ERR(__clsm_enter(clsm, 0))
|
||||
|
||||
#define WT_LSM_UPDATE_ENTER(clsm, cursor, session, n) \
|
||||
clsm = (WT_CURSOR_LSM *)cursor; \
|
||||
CURSOR_UPDATE_API_CALL(cursor, session, n, NULL); \
|
||||
WT_ERR(__clsm_enter(clsm))
|
||||
WT_ERR(__clsm_enter(clsm, 1))
|
||||
|
||||
static int __clsm_open_cursors(WT_CURSOR_LSM *, int);
|
||||
static int __clsm_open_cursors(WT_CURSOR_LSM *, int, int, uint32_t);
|
||||
static int __clsm_search(WT_CURSOR *);
|
||||
|
||||
static inline int
|
||||
__clsm_enter(WT_CURSOR_LSM *clsm)
|
||||
__clsm_enter(WT_CURSOR_LSM *clsm, int update)
|
||||
{
|
||||
if (!F_ISSET(clsm, WT_CLSM_MERGE) &&
|
||||
clsm->dsk_gen != clsm->lsm_tree->dsk_gen)
|
||||
WT_RET(__clsm_open_cursors(clsm, 0));
|
||||
(clsm->dsk_gen != clsm->lsm_tree->dsk_gen ||
|
||||
(!update && !F_ISSET(clsm, WT_CLSM_OPEN_READ))))
|
||||
WT_RET(__clsm_open_cursors(clsm, update, 0, 0));
|
||||
|
||||
return (0);
|
||||
}
|
||||
@@ -106,7 +107,8 @@ __clsm_close_cursors(WT_CURSOR_LSM *clsm)
|
||||
* Open cursors for the current set of files.
|
||||
*/
|
||||
static int
|
||||
__clsm_open_cursors(WT_CURSOR_LSM *clsm, int start_chunk)
|
||||
__clsm_open_cursors(
|
||||
WT_CURSOR_LSM *clsm, int update, int start_chunk, uint32_t start_id)
|
||||
{
|
||||
WT_CURSOR *c, **cp;
|
||||
WT_DECL_RET;
|
||||
@@ -124,6 +126,9 @@ __clsm_open_cursors(WT_CURSOR_LSM *clsm, int start_chunk)
|
||||
c = &clsm->iface;
|
||||
chunk = NULL;
|
||||
|
||||
if (!update)
|
||||
F_SET(clsm, WT_CLSM_OPEN_READ);
|
||||
|
||||
/* Copy the key, so we don't lose the cursor position. */
|
||||
if (F_ISSET(c, WT_CURSTD_KEY_SET)) {
|
||||
if (c->key.data != c->key.mem)
|
||||
@@ -135,10 +140,27 @@ __clsm_open_cursors(WT_CURSOR_LSM *clsm, int start_chunk)
|
||||
WT_RET(__clsm_close_cursors(clsm));
|
||||
|
||||
__wt_spin_lock(session, &lsm_tree->lock);
|
||||
|
||||
/* Merge cursors have already figured out how many chunks they need. */
|
||||
if (F_ISSET(clsm, WT_CLSM_MERGE))
|
||||
if (F_ISSET(clsm, WT_CLSM_MERGE)) {
|
||||
nchunks = clsm->nchunks;
|
||||
else
|
||||
|
||||
/*
|
||||
* We may have raced with another merge completing. Check that
|
||||
* we're starting at the right offset in the chunk array.
|
||||
*/
|
||||
if (start_chunk >= lsm_tree->nchunks ||
|
||||
lsm_tree->chunk[start_chunk]->id != start_id)
|
||||
for (start_chunk = 0;
|
||||
start_chunk < lsm_tree->nchunks;
|
||||
start_chunk++) {
|
||||
chunk = lsm_tree->chunk[start_chunk];
|
||||
if (chunk->id == start_id)
|
||||
break;
|
||||
}
|
||||
|
||||
WT_ASSERT(session, start_chunk + nchunks <= lsm_tree->nchunks);
|
||||
} else
|
||||
nchunks = lsm_tree->nchunks;
|
||||
|
||||
if (clsm->cursors == NULL || nchunks > clsm->nchunks) {
|
||||
@@ -150,6 +172,9 @@ __clsm_open_cursors(WT_CURSOR_LSM *clsm, int start_chunk)
|
||||
clsm->nchunks = nchunks;
|
||||
|
||||
for (i = 0, cp = clsm->cursors; i != clsm->nchunks; i++, cp++) {
|
||||
if (!F_ISSET(clsm, WT_CLSM_OPEN_READ) && i < clsm->nchunks - 1)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Read from the checkpoint if the file has been written.
|
||||
* Once all cursors switch, the in-memory tree can be evicted.
|
||||
@@ -182,18 +207,15 @@ __clsm_open_cursors(WT_CURSOR_LSM *clsm, int start_chunk)
|
||||
}
|
||||
|
||||
/* The last chunk is our new primary. */
|
||||
if ((clsm->primary_chunk = chunk) != NULL) {
|
||||
WT_ASSERT(session,
|
||||
!F_ISSET(clsm, WT_CLSM_UPDATED) ||
|
||||
!F_ISSET(chunk, WT_LSM_CHUNK_ONDISK));
|
||||
|
||||
if (chunk != NULL && !F_ISSET(chunk, WT_LSM_CHUNK_ONDISK)) {
|
||||
clsm->primary_chunk = chunk;
|
||||
(void)WT_ATOMIC_ADD(clsm->primary_chunk->ncursor, 1);
|
||||
}
|
||||
|
||||
/* Peek into the btree layer to track the in-memory size. */
|
||||
if (lsm_tree->memsizep == NULL)
|
||||
(void)__wt_btree_get_memsize(
|
||||
session, session->btree, &lsm_tree->memsizep);
|
||||
/* Peek into the btree layer to track the in-memory size. */
|
||||
if (lsm_tree->memsizep == NULL)
|
||||
(void)__wt_btree_get_memsize(
|
||||
session, session->btree, &lsm_tree->memsizep);
|
||||
}
|
||||
|
||||
clsm->dsk_gen = lsm_tree->dsk_gen;
|
||||
err: __wt_spin_unlock(session, &lsm_tree->lock);
|
||||
@@ -204,7 +226,8 @@ err: __wt_spin_unlock(session, &lsm_tree->lock);
|
||||
* Initialize an LSM cursor for a merge.
|
||||
*/
|
||||
int
|
||||
__wt_clsm_init_merge(WT_CURSOR *cursor, int start_chunk, int nchunks)
|
||||
__wt_clsm_init_merge(
|
||||
WT_CURSOR *cursor, int start_chunk, uint32_t start_id, int nchunks)
|
||||
{
|
||||
WT_CURSOR_LSM *clsm;
|
||||
|
||||
@@ -214,7 +237,7 @@ __wt_clsm_init_merge(WT_CURSOR *cursor, int start_chunk, int nchunks)
|
||||
F_SET(clsm, WT_CLSM_MINOR_MERGE);
|
||||
clsm->nchunks = nchunks;
|
||||
|
||||
return (__clsm_open_cursors(clsm, start_chunk));
|
||||
return (__clsm_open_cursors(clsm, 0, start_chunk, start_id));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -502,11 +525,14 @@ static int
|
||||
__clsm_search(WT_CURSOR *cursor)
|
||||
{
|
||||
WT_BLOOM *bloom;
|
||||
WT_BLOOM_HASH bhash;
|
||||
WT_CURSOR *c;
|
||||
WT_CURSOR_LSM *clsm;
|
||||
WT_DECL_RET;
|
||||
WT_SESSION_IMPL *session;
|
||||
int i;
|
||||
int have_hash, i;
|
||||
|
||||
have_hash = 0;
|
||||
|
||||
WT_LSM_ENTER(clsm, cursor, session, search);
|
||||
WT_CURSOR_NEEDKEY(cursor);
|
||||
@@ -526,7 +552,13 @@ __clsm_search(WT_CURSOR *cursor)
|
||||
FORALL_CURSORS(clsm, c, i) {
|
||||
/* If there is a Bloom filter, see if we can skip the read. */
|
||||
if ((bloom = clsm->blooms[i]) != NULL) {
|
||||
ret = __wt_bloom_get(bloom, &cursor->key);
|
||||
if (!have_hash) {
|
||||
WT_ERR(__wt_bloom_hash(
|
||||
bloom, &cursor->key, &bhash));
|
||||
have_hash = 1;
|
||||
}
|
||||
|
||||
ret = __wt_bloom_hash_get(bloom, &bhash);
|
||||
if (ret == WT_NOTFOUND) {
|
||||
WT_STAT_INCR(
|
||||
clsm->lsm_tree->stats, bloom_misses);
|
||||
@@ -748,17 +780,18 @@ __clsm_put(
|
||||
* If this is the first update in this cursor, check if a new in-memory
|
||||
* chunk is needed.
|
||||
*/
|
||||
if (!F_ISSET(clsm, WT_CLSM_UPDATED)) {
|
||||
if (clsm->primary_chunk == NULL) {
|
||||
__wt_spin_lock(session, &lsm_tree->lock);
|
||||
if (clsm->dsk_gen == lsm_tree->dsk_gen)
|
||||
WT_WITH_SCHEMA_LOCK(session,
|
||||
ret = __wt_lsm_tree_switch(session, lsm_tree));
|
||||
__wt_spin_unlock(session, &lsm_tree->lock);
|
||||
WT_RET(ret);
|
||||
F_SET(clsm, WT_CLSM_UPDATED);
|
||||
|
||||
/* We changed the structure, or someone else did: update. */
|
||||
WT_RET(__clsm_enter(clsm));
|
||||
WT_RET(__clsm_enter(clsm, 1));
|
||||
|
||||
WT_ASSERT(session, clsm->primary_chunk != NULL);
|
||||
}
|
||||
|
||||
primary = clsm->cursors[clsm->nchunks - 1];
|
||||
|
||||
@@ -19,6 +19,8 @@ __wt_lsm_merge_update_tree(WT_SESSION_IMPL *session,
|
||||
size_t chunk_sz, chunks_after_merge;
|
||||
int i, j;
|
||||
|
||||
WT_ASSERT(session, start_chunk + nchunks <= lsm_tree->nchunks);
|
||||
|
||||
/* Setup the array of obsolete chunks. */
|
||||
if (nchunks > lsm_tree->old_avail) {
|
||||
chunk_sz = sizeof(*lsm_tree->old_chunks);
|
||||
@@ -61,7 +63,8 @@ __wt_lsm_merge_update_tree(WT_SESSION_IMPL *session,
|
||||
* Merge a set of chunks of an LSM tree.
|
||||
*/
|
||||
int
|
||||
__wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, int stalls)
|
||||
__wt_lsm_merge(
|
||||
WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, uint32_t id, int stalls)
|
||||
{
|
||||
WT_BLOOM *bloom;
|
||||
WT_CURSOR *src, *dest;
|
||||
@@ -71,7 +74,7 @@ __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, int stalls)
|
||||
WT_LSM_CHUNK *chunk;
|
||||
const char *cur_cfg[] =
|
||||
API_CONF_DEFAULTS(session, open_cursor, "bulk,raw");
|
||||
uint32_t generation;
|
||||
uint32_t generation, start_id;
|
||||
uint64_t insert_count, record_count;
|
||||
int create_bloom, dest_id, end_chunk, i;
|
||||
int max_chunks, nchunks, start_chunk;
|
||||
@@ -81,20 +84,13 @@ __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, int stalls)
|
||||
max_chunks = (int)lsm_tree->merge_max;
|
||||
create_bloom = 0;
|
||||
|
||||
/*
|
||||
* Take a copy of the latest chunk id. This value needs to be atomically
|
||||
* read. We need a copy, since other threads may alter the chunk count
|
||||
* while we are doing a merge.
|
||||
*/
|
||||
nchunks = lsm_tree->nchunks;
|
||||
|
||||
/*
|
||||
* If there aren't any chunks to merge, or some of the chunks aren't
|
||||
* yet written, we're done. A non-zero error indicates that the worker
|
||||
* should assume there is no work to do: if there are unwritten chunks,
|
||||
* the worker should write them immediately.
|
||||
*/
|
||||
if (nchunks <= 1)
|
||||
if (lsm_tree->nchunks <= 1)
|
||||
return (WT_NOTFOUND);
|
||||
|
||||
/*
|
||||
@@ -104,10 +100,14 @@ __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, int stalls)
|
||||
*/
|
||||
__wt_spin_lock(session, &lsm_tree->lock);
|
||||
|
||||
/* Only include chunks that are stable on disk. */
|
||||
end_chunk = nchunks - 1;
|
||||
/*
|
||||
* Only include chunks that are stable on disk and not involved in a
|
||||
* merge.
|
||||
*/
|
||||
end_chunk = lsm_tree->nchunks - 1;
|
||||
while (end_chunk > 0 &&
|
||||
!F_ISSET(lsm_tree->chunk[end_chunk], WT_LSM_CHUNK_ONDISK))
|
||||
(!F_ISSET(lsm_tree->chunk[end_chunk], WT_LSM_CHUNK_ONDISK) ||
|
||||
F_ISSET(lsm_tree->chunk[end_chunk], WT_LSM_CHUNK_MERGING)))
|
||||
--end_chunk;
|
||||
|
||||
/*
|
||||
@@ -129,6 +129,10 @@ __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, int stalls)
|
||||
chunk = lsm_tree->chunk[start_chunk - 1];
|
||||
nchunks = end_chunk - start_chunk + 1;
|
||||
|
||||
/* If the chunk is already involved in a merge, stop. */
|
||||
if (F_ISSET(chunk, WT_LSM_CHUNK_MERGING))
|
||||
break;
|
||||
|
||||
/*
|
||||
* If the next chunk is more than double the average size of
|
||||
* the chunks we have so far, stop.
|
||||
@@ -136,23 +140,46 @@ __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, int stalls)
|
||||
if (nchunks > 2 && chunk->count > 2 * record_count / nchunks)
|
||||
break;
|
||||
|
||||
/* Don't do any big merges until we have waited for 10s. */
|
||||
if (nchunks > 0 && stalls < 10 &&
|
||||
chunk->count > lsm_tree->chunk[end_chunk]->count * 2)
|
||||
/*
|
||||
* Never do big merges in the first thread if there are
|
||||
* multiple threads. If there is a single thread, wait for 10
|
||||
* seconds looking for small merges before trying a big one.
|
||||
*/
|
||||
if (id == 0 && nchunks > 0 &&
|
||||
chunk->count > lsm_tree->chunk[end_chunk]->count * 2 &&
|
||||
(lsm_tree->merge_threads > 1 || stalls < 10))
|
||||
break;
|
||||
|
||||
F_SET(chunk, WT_LSM_CHUNK_MERGING);
|
||||
record_count += chunk->count;
|
||||
--start_chunk;
|
||||
|
||||
if (nchunks == max_chunks)
|
||||
if (nchunks == max_chunks) {
|
||||
F_CLR(lsm_tree->chunk[end_chunk], WT_LSM_CHUNK_MERGING);
|
||||
record_count -= lsm_tree->chunk[end_chunk--]->count;
|
||||
}
|
||||
}
|
||||
__wt_spin_unlock(session, &lsm_tree->lock);
|
||||
|
||||
nchunks = end_chunk - start_chunk + 1;
|
||||
WT_ASSERT(session, nchunks <= max_chunks);
|
||||
|
||||
/* Don't do small merges unless we have waited for 2s. */
|
||||
if (nchunks <= 1 || (stalls < 2 && nchunks < max_chunks / 2))
|
||||
if (nchunks <= 1 ||
|
||||
(id == 0 && stalls < 2 && nchunks < max_chunks / 2)) {
|
||||
for (i = start_chunk; i <= end_chunk; i++)
|
||||
F_CLR(lsm_tree->chunk[i], WT_LSM_CHUNK_MERGING);
|
||||
nchunks = 0;
|
||||
}
|
||||
|
||||
/* Find the merge generation. */
|
||||
for (generation = 0, i = 0; i < nchunks; i++)
|
||||
if (lsm_tree->chunk[start_chunk + i]->generation > generation)
|
||||
generation = lsm_tree->chunk[i]->generation;
|
||||
|
||||
start_id = lsm_tree->chunk[start_chunk]->id;
|
||||
__wt_spin_unlock(session, &lsm_tree->lock);
|
||||
|
||||
if (nchunks == 0)
|
||||
return (WT_NOTFOUND);
|
||||
|
||||
/* Allocate an ID for the merge. */
|
||||
@@ -163,17 +190,13 @@ __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, int stalls)
|
||||
start_chunk, end_chunk, dest_id, record_count);
|
||||
|
||||
WT_RET(__wt_calloc_def(session, 1, &chunk));
|
||||
chunk->id = dest_id;
|
||||
|
||||
if (FLD_ISSET(lsm_tree->bloom, WT_LSM_BLOOM_MERGED) &&
|
||||
(FLD_ISSET(lsm_tree->bloom, WT_LSM_BLOOM_OLDEST) ||
|
||||
start_chunk > 0) && record_count > 0)
|
||||
create_bloom = 1;
|
||||
|
||||
/* Find the merge generation. */
|
||||
for (generation = 0, i = start_chunk; i < end_chunk; i++)
|
||||
if (lsm_tree->chunk[i]->generation > generation)
|
||||
generation = lsm_tree->chunk[i]->generation;
|
||||
|
||||
/*
|
||||
* Special setup for the merge cursor:
|
||||
* first, reset to open the dependent cursors;
|
||||
@@ -182,10 +205,10 @@ __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, int stalls)
|
||||
*/
|
||||
WT_ERR(__wt_open_cursor(session, lsm_tree->name, NULL, NULL, &src));
|
||||
F_SET(src, WT_CURSTD_RAW);
|
||||
WT_ERR(__wt_clsm_init_merge(src, start_chunk, nchunks));
|
||||
WT_ERR(__wt_clsm_init_merge(src, start_chunk, start_id, nchunks));
|
||||
|
||||
WT_WITH_SCHEMA_LOCK(session, ret = __wt_lsm_tree_setup_chunk(
|
||||
session, lsm_tree, dest_id, chunk, create_bloom));
|
||||
session, lsm_tree, chunk, create_bloom));
|
||||
WT_ERR(ret);
|
||||
if (create_bloom)
|
||||
WT_ERR(__wt_bloom_create(session, chunk->bloom_uri,
|
||||
@@ -226,6 +249,19 @@ __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, int stalls)
|
||||
WT_ERR(ret);
|
||||
|
||||
__wt_spin_lock(session, &lsm_tree->lock);
|
||||
|
||||
/*
|
||||
* Check whether we raced with another merge, and adjust the chunk
|
||||
* array offset as necessary.
|
||||
*/
|
||||
if (start_chunk >= lsm_tree->nchunks ||
|
||||
lsm_tree->chunk[start_chunk]->id != start_id)
|
||||
for (start_chunk = 0;
|
||||
start_chunk < lsm_tree->nchunks;
|
||||
start_chunk++)
|
||||
if (lsm_tree->chunk[start_chunk]->id == start_id)
|
||||
break;
|
||||
|
||||
ret = __wt_lsm_merge_update_tree(
|
||||
session, lsm_tree, start_chunk, nchunks, chunk);
|
||||
|
||||
|
||||
@@ -17,11 +17,15 @@ __wt_lsm_meta_read(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
|
||||
WT_CONFIG cparser, lparser;
|
||||
WT_CONFIG_ITEM ck, cv, lk, lv;
|
||||
WT_DECL_RET;
|
||||
WT_ITEM buf;
|
||||
WT_LSM_CHUNK *chunk;
|
||||
const char *config;
|
||||
int nchunks;
|
||||
size_t chunk_sz, alloc;
|
||||
|
||||
WT_CLEAR(buf);
|
||||
chunk_sz = sizeof(WT_LSM_CHUNK);
|
||||
|
||||
WT_RET(__wt_metadata_read(session, lsm_tree->name, &config));
|
||||
WT_ERR(__wt_config_init(session, &cparser, config));
|
||||
while ((ret = __wt_config_next(&cparser, &ck, &cv)) == 0) {
|
||||
@@ -55,46 +59,54 @@ __wt_lsm_meta_read(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
|
||||
lsm_tree->chunk_size = (uint32_t)cv.val;
|
||||
else if (WT_STRING_MATCH("lsm_merge_max", ck.str, ck.len))
|
||||
lsm_tree->merge_max = (uint32_t)cv.val;
|
||||
else if (WT_STRING_MATCH("lsm_merge_threads", ck.str, ck.len))
|
||||
lsm_tree->merge_threads = (uint32_t)cv.val;
|
||||
else if (WT_STRING_MATCH("last", ck.str, ck.len))
|
||||
lsm_tree->last = (int)cv.val;
|
||||
else if (WT_STRING_MATCH("chunks", ck.str, ck.len)) {
|
||||
WT_ERR(__wt_config_subinit(session, &lparser, &cv));
|
||||
chunk_sz = sizeof(*lsm_tree->chunk);
|
||||
for (nchunks = 0; (ret =
|
||||
__wt_config_next(&lparser, &lk, &lv)) == 0; ) {
|
||||
if (WT_STRING_MATCH("bloom", lk.str, lk.len)) {
|
||||
WT_ERR(__wt_strndup(session,
|
||||
lv.str, lv.len, &chunk->bloom_uri));
|
||||
if (WT_STRING_MATCH("id", lk.str, lk.len)) {
|
||||
if ((nchunks + 1) * chunk_sz >
|
||||
lsm_tree->chunk_alloc)
|
||||
WT_ERR(__wt_realloc(session,
|
||||
&lsm_tree->chunk_alloc,
|
||||
WT_MAX(10 * chunk_sz,
|
||||
2 * lsm_tree->chunk_alloc),
|
||||
&lsm_tree->chunk));
|
||||
WT_ERR(__wt_calloc_def(
|
||||
session, 1, &chunk));
|
||||
lsm_tree->chunk[nchunks++] = chunk;
|
||||
chunk->id = (uint32_t)lv.val;
|
||||
WT_ERR(__wt_lsm_tree_chunk_name(session,
|
||||
lsm_tree, chunk->id, &buf));
|
||||
chunk->uri =
|
||||
__wt_buf_steal(session, &buf, NULL);
|
||||
F_SET(chunk, WT_LSM_CHUNK_ONDISK);
|
||||
|
||||
} else if (WT_STRING_MATCH(
|
||||
"bloom", lk.str, lk.len)) {
|
||||
WT_ERR(__wt_lsm_tree_bloom_name(session,
|
||||
lsm_tree, chunk->id, &buf));
|
||||
chunk->bloom_uri =
|
||||
__wt_buf_steal(session, &buf, NULL);
|
||||
F_SET(chunk, WT_LSM_CHUNK_BLOOM);
|
||||
continue;
|
||||
}
|
||||
if (WT_STRING_MATCH("count", lk.str, lk.len)) {
|
||||
} else if (WT_STRING_MATCH(
|
||||
"count", lk.str, lk.len)) {
|
||||
chunk->count = lv.val;
|
||||
continue;
|
||||
}
|
||||
if (WT_STRING_MATCH(
|
||||
} else if (WT_STRING_MATCH(
|
||||
"generation", lk.str, lk.len)) {
|
||||
chunk->generation = (uint32_t)lv.val;
|
||||
continue;
|
||||
}
|
||||
if ((nchunks + 1) * chunk_sz >
|
||||
lsm_tree->chunk_alloc)
|
||||
WT_ERR(__wt_realloc(session,
|
||||
&lsm_tree->chunk_alloc,
|
||||
WT_MAX(10 * chunk_sz,
|
||||
2 * lsm_tree->chunk_alloc),
|
||||
&lsm_tree->chunk));
|
||||
WT_ERR(__wt_calloc_def(session, 1, &chunk));
|
||||
lsm_tree->chunk[nchunks++] = chunk;
|
||||
WT_ERR(__wt_strndup(session,
|
||||
lk.str, lk.len, &chunk->uri));
|
||||
F_SET(chunk, WT_LSM_CHUNK_ONDISK);
|
||||
}
|
||||
WT_ERR_NOTFOUND_OK(ret);
|
||||
lsm_tree->nchunks = nchunks;
|
||||
} else if (WT_STRING_MATCH("old_chunks", ck.str, ck.len)) {
|
||||
WT_ERR(__wt_config_subinit(session, &lparser, &cv));
|
||||
chunk_sz = sizeof(*lsm_tree->old_chunks);
|
||||
for (nchunks = 0; (ret =
|
||||
__wt_config_next(&lparser, &lk, &lv)) == 0; ) {
|
||||
if (WT_STRING_MATCH("bloom", lk.str, lk.len)) {
|
||||
@@ -157,20 +169,20 @@ __wt_lsm_meta_write(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
|
||||
lsm_tree->key_format, lsm_tree->value_format));
|
||||
WT_ERR(__wt_buf_catfmt(session, buf,
|
||||
",last=%" PRIu32 ",lsm_chunk_size=%" PRIu64
|
||||
",lsm_merge_max=%" PRIu32 ",lsm_bloom=%" PRIu32
|
||||
",lsm_merge_max=%" PRIu32 ",lsm_merge_threads=%" PRIu32
|
||||
",lsm_bloom=%" PRIu32
|
||||
",lsm_bloom_bit_count=%" PRIu32 ",lsm_bloom_hash_count=%" PRIu32,
|
||||
lsm_tree->last, (uint64_t)lsm_tree->chunk_size,
|
||||
lsm_tree->merge_max, lsm_tree->bloom,
|
||||
lsm_tree->merge_max, lsm_tree->merge_threads, lsm_tree->bloom,
|
||||
lsm_tree->bloom_bit_count, lsm_tree->bloom_hash_count));
|
||||
WT_ERR(__wt_buf_catfmt(session, buf, ",chunks=["));
|
||||
for (i = 0; i < lsm_tree->nchunks; i++) {
|
||||
chunk = lsm_tree->chunk[i];
|
||||
if (i > 0)
|
||||
WT_ERR(__wt_buf_catfmt(session, buf, ","));
|
||||
WT_ERR(__wt_buf_catfmt(session, buf, "\"%s\"", chunk->uri));
|
||||
if (chunk->bloom_uri != NULL)
|
||||
WT_ERR(__wt_buf_catfmt(
|
||||
session, buf, ",bloom=\"%s\"", chunk->bloom_uri));
|
||||
WT_ERR(__wt_buf_catfmt(session, buf, "id=%" PRIu32, chunk->id));
|
||||
if (F_ISSET(chunk, WT_LSM_CHUNK_BLOOM))
|
||||
WT_ERR(__wt_buf_catfmt(session, buf, ",bloom"));
|
||||
if (chunk->count != 0)
|
||||
WT_ERR(__wt_buf_catfmt(
|
||||
session, buf, ",count=%" PRIu64, chunk->count));
|
||||
|
||||
@@ -68,11 +68,15 @@ __lsm_tree_close(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
|
||||
{
|
||||
WT_DECL_RET;
|
||||
WT_SESSION *wt_session;
|
||||
WT_SESSION_IMPL *s;
|
||||
uint32_t i;
|
||||
|
||||
if (F_ISSET(lsm_tree, WT_LSM_TREE_WORKING)) {
|
||||
F_CLR(lsm_tree, WT_LSM_TREE_WORKING);
|
||||
if (F_ISSET(S2C(session), WT_CONN_LSM_MERGE))
|
||||
WT_TRET(__wt_thread_join(lsm_tree->worker_tid));
|
||||
for (i = 0; i < lsm_tree->merge_threads; i++)
|
||||
WT_TRET(__wt_thread_join(
|
||||
lsm_tree->worker_tids[i]));
|
||||
WT_TRET(__wt_thread_join(lsm_tree->ckpt_tid));
|
||||
}
|
||||
|
||||
@@ -83,18 +87,19 @@ __lsm_tree_close(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
|
||||
*
|
||||
* Do this in the main thread to avoid deadlocks.
|
||||
*/
|
||||
if (lsm_tree->worker_session != NULL) {
|
||||
F_SET(lsm_tree->worker_session,
|
||||
F_ISSET(session, WT_SESSION_SCHEMA_LOCKED));
|
||||
|
||||
wt_session = &lsm_tree->worker_session->iface;
|
||||
for (i = 0; i < lsm_tree->merge_threads; i++) {
|
||||
if ((s = lsm_tree->worker_sessions[i]) == NULL)
|
||||
continue;
|
||||
lsm_tree->worker_sessions[i] = NULL;
|
||||
F_SET(s, F_ISSET(session, WT_SESSION_SCHEMA_LOCKED));
|
||||
wt_session = &s->iface;
|
||||
WT_TRET(wt_session->close(wt_session, NULL));
|
||||
|
||||
/*
|
||||
* This is safe after the close because session handles are
|
||||
* not freed, but are managed by the connection.
|
||||
*/
|
||||
__wt_free(NULL, lsm_tree->worker_session->hazard);
|
||||
__wt_free(NULL, s->hazard);
|
||||
}
|
||||
if (lsm_tree->ckpt_session != NULL) {
|
||||
F_SET(lsm_tree->ckpt_session,
|
||||
@@ -137,10 +142,10 @@ __wt_lsm_tree_close_all(WT_SESSION_IMPL *session)
|
||||
*/
|
||||
int
|
||||
__wt_lsm_tree_bloom_name(
|
||||
WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, int i, WT_ITEM *buf)
|
||||
WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, uint32_t id, WT_ITEM *buf)
|
||||
{
|
||||
WT_RET(__wt_buf_fmt(session, buf, "file:%s-%06d.bf",
|
||||
lsm_tree->filename, i));
|
||||
WT_RET(__wt_buf_fmt(session, buf, "file:%s-%06" PRIu32 ".bf",
|
||||
lsm_tree->filename, id));
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -150,10 +155,10 @@ __wt_lsm_tree_bloom_name(
|
||||
*/
|
||||
int
|
||||
__wt_lsm_tree_chunk_name(
|
||||
WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, int i, WT_ITEM *buf)
|
||||
WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, uint32_t id, WT_ITEM *buf)
|
||||
{
|
||||
WT_RET(__wt_buf_fmt(session, buf, "file:%s-%06d.lsm",
|
||||
lsm_tree->filename, i));
|
||||
WT_RET(__wt_buf_fmt(session, buf, "file:%s-%06" PRIu32 ".lsm",
|
||||
lsm_tree->filename, id));
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -163,15 +168,16 @@ __wt_lsm_tree_chunk_name(
|
||||
*/
|
||||
int
|
||||
__wt_lsm_tree_setup_chunk(WT_SESSION_IMPL *session,
|
||||
WT_LSM_TREE *lsm_tree, int i, WT_LSM_CHUNK *chunk, int create_bloom)
|
||||
WT_LSM_TREE *lsm_tree, WT_LSM_CHUNK *chunk, int create_bloom)
|
||||
{
|
||||
WT_DECL_ITEM(buf);
|
||||
WT_DECL_ITEM(bbuf);
|
||||
WT_DECL_RET;
|
||||
WT_ITEM buf;
|
||||
const char *cfg[] = API_CONF_DEFAULTS(session, drop, "force");
|
||||
|
||||
WT_RET(__wt_scr_alloc(session, 0, &buf));
|
||||
WT_ERR(__wt_lsm_tree_chunk_name(session, lsm_tree, i, buf));
|
||||
WT_CLEAR(buf);
|
||||
WT_RET(__wt_lsm_tree_chunk_name(session, lsm_tree, chunk->id, &buf));
|
||||
chunk->uri = __wt_buf_steal(session, &buf, NULL);
|
||||
|
||||
/*
|
||||
* Drop the chunk first - there may be some content hanging over from
|
||||
* an aborted merge.
|
||||
@@ -181,20 +187,16 @@ __wt_lsm_tree_setup_chunk(WT_SESSION_IMPL *session,
|
||||
* things with handle locks and metadata tracking. It can never have
|
||||
* been the result of an interrupted merge, anyway.
|
||||
*/
|
||||
if (i > 1)
|
||||
WT_ERR(__wt_schema_drop(session, buf->data, cfg));
|
||||
WT_ERR(__wt_schema_create(session, buf->data, lsm_tree->file_config));
|
||||
chunk->uri = __wt_buf_steal(session, buf, NULL);
|
||||
if (chunk->id > 1)
|
||||
WT_ERR(__wt_schema_drop(session, chunk->uri, cfg));
|
||||
WT_ERR(__wt_schema_create(session, chunk->uri, lsm_tree->file_config));
|
||||
if (create_bloom) {
|
||||
WT_ERR(__wt_scr_alloc(session, 0, &bbuf));
|
||||
WT_ERR(__wt_lsm_tree_bloom_name(
|
||||
session, lsm_tree, i, bbuf));
|
||||
chunk->bloom_uri = __wt_buf_steal(session, bbuf, NULL);
|
||||
session, lsm_tree, chunk->id, &buf));
|
||||
chunk->bloom_uri = __wt_buf_steal(session, &buf, NULL);
|
||||
}
|
||||
|
||||
err: __wt_scr_free(&buf);
|
||||
__wt_scr_free(&bbuf);
|
||||
return (ret);
|
||||
err: return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -205,12 +207,12 @@ static int
|
||||
__lsm_tree_start_worker(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
|
||||
{
|
||||
WT_CONNECTION *wt_conn;
|
||||
WT_LSM_WORKER_ARGS *wargs;
|
||||
WT_SESSION *wt_session;
|
||||
WT_SESSION_IMPL *s;
|
||||
uint32_t i;
|
||||
|
||||
wt_conn = &S2C(session)->iface;
|
||||
WT_RET(wt_conn->open_session(wt_conn, NULL, NULL, &wt_session));
|
||||
lsm_tree->worker_session = (WT_SESSION_IMPL *)wt_session;
|
||||
F_SET(lsm_tree->worker_session, WT_SESSION_INTERNAL);
|
||||
|
||||
WT_RET(wt_conn->open_session(wt_conn, NULL, NULL, &wt_session));
|
||||
lsm_tree->ckpt_session = (WT_SESSION_IMPL *)wt_session;
|
||||
@@ -220,8 +222,19 @@ __lsm_tree_start_worker(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
|
||||
/* The new thread will rely on the WORKING value being visible. */
|
||||
WT_FULL_BARRIER();
|
||||
if (F_ISSET(S2C(session), WT_CONN_LSM_MERGE))
|
||||
WT_RET(__wt_thread_create(
|
||||
&lsm_tree->worker_tid, __wt_lsm_worker, lsm_tree));
|
||||
for (i = 0; i < lsm_tree->merge_threads; i++) {
|
||||
WT_RET(wt_conn->open_session(
|
||||
wt_conn, NULL, NULL, &wt_session));
|
||||
s = (WT_SESSION_IMPL *)wt_session;
|
||||
F_SET(s, WT_SESSION_INTERNAL);
|
||||
lsm_tree->worker_sessions[i] = s;
|
||||
|
||||
WT_RET(__wt_calloc_def(session, 1, &wargs));
|
||||
wargs->lsm_tree = lsm_tree;
|
||||
wargs->id = i;
|
||||
WT_RET(__wt_thread_create(
|
||||
&lsm_tree->worker_tids[i], __wt_lsm_worker, wargs));
|
||||
}
|
||||
WT_RET(__wt_thread_create(
|
||||
&lsm_tree->ckpt_tid, __wt_lsm_checkpoint_worker, lsm_tree));
|
||||
|
||||
@@ -306,6 +319,10 @@ __wt_lsm_tree_create(WT_SESSION_IMPL *session,
|
||||
lsm_tree->chunk_size = (uint32_t)cval.val;
|
||||
WT_ERR(__wt_config_gets(session, cfg, "lsm_merge_max", &cval));
|
||||
lsm_tree->merge_max = (uint32_t)cval.val;
|
||||
WT_ERR(__wt_config_gets(session, cfg, "lsm_merge_threads", &cval));
|
||||
lsm_tree->merge_threads = (uint32_t)cval.val;
|
||||
/* Sanity check that api_data.py is in sync with lsm.h */
|
||||
WT_ASSERT(session, lsm_tree->merge_threads <= WT_LSM_MAX_WORKERS);
|
||||
|
||||
WT_ERR(__wt_scr_alloc(session, 0, &buf));
|
||||
WT_ERR(__wt_buf_fmt(session, buf,
|
||||
@@ -346,20 +363,21 @@ __lsm_tree_open_check(
|
||||
WT_CONFIG_ITEM cval;
|
||||
const char *cfg[] = API_CONF_DEFAULTS(
|
||||
session, create, lsm_tree->file_config);
|
||||
uint64_t required;
|
||||
uint32_t maxleafpage;
|
||||
uint64_t req;
|
||||
|
||||
WT_RET(__wt_config_gets(
|
||||
session, cfg, "leaf_page_max", &cval));
|
||||
maxleafpage = (uint32_t)cval.val;
|
||||
|
||||
/* Three chunks, plus one page for each participant in a merge. */
|
||||
req = 3 * lsm_tree->chunk_size + (lsm_tree->merge_max * maxleafpage);
|
||||
if (S2C(session)->cache_size < req)
|
||||
required = 3 * lsm_tree->chunk_size +
|
||||
lsm_tree->merge_threads * (lsm_tree->merge_max * maxleafpage);
|
||||
if (S2C(session)->cache_size < required)
|
||||
WT_RET_MSG(session, EINVAL,
|
||||
"The LSM configuration requires a cache size of at least %"
|
||||
PRIu64 ". Configured size is %" PRIu64,
|
||||
req, S2C(session)->cache_size);
|
||||
required, S2C(session)->cache_size);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -433,7 +451,7 @@ __wt_lsm_tree_get(WT_SESSION_IMPL *session,
|
||||
if (exclusive && lsm_tree->refcnt)
|
||||
return (EBUSY);
|
||||
|
||||
WT_ATOMIC_ADD(lsm_tree->refcnt, 1);
|
||||
(void)WT_ATOMIC_ADD(lsm_tree->refcnt, 1);
|
||||
*treep = lsm_tree;
|
||||
return (0);
|
||||
}
|
||||
@@ -453,7 +471,7 @@ void
|
||||
__wt_lsm_tree_release(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
|
||||
{
|
||||
WT_ASSERT(session, lsm_tree->refcnt > 0);
|
||||
WT_ATOMIC_SUB(lsm_tree->refcnt, 1);
|
||||
(void)WT_ATOMIC_SUB(lsm_tree->refcnt, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -466,7 +484,7 @@ __wt_lsm_tree_switch(
|
||||
{
|
||||
WT_DECL_RET;
|
||||
WT_LSM_CHUNK *chunk;
|
||||
int new_id;
|
||||
uint32_t new_id;
|
||||
|
||||
new_id = WT_ATOMIC_ADD(lsm_tree->last, 1);
|
||||
|
||||
@@ -486,9 +504,9 @@ __wt_lsm_tree_switch(
|
||||
&lsm_tree->chunk));
|
||||
|
||||
WT_ERR(__wt_calloc_def(session, 1, &chunk));
|
||||
chunk->id = new_id;
|
||||
lsm_tree->chunk[lsm_tree->nchunks++] = chunk;
|
||||
WT_ERR(__wt_lsm_tree_setup_chunk(
|
||||
session, lsm_tree, new_id, chunk,
|
||||
WT_ERR(__wt_lsm_tree_setup_chunk(session, lsm_tree, chunk,
|
||||
FLD_ISSET(lsm_tree->bloom, WT_LSM_BLOOM_NEWEST) ? 1 : 0));
|
||||
|
||||
++lsm_tree->dsk_gen;
|
||||
@@ -556,14 +574,15 @@ int
|
||||
__wt_lsm_tree_rename(WT_SESSION_IMPL *session,
|
||||
const char *oldname, const char *newname, const char *cfg[])
|
||||
{
|
||||
WT_DECL_ITEM(buf);
|
||||
WT_DECL_RET;
|
||||
WT_ITEM buf;
|
||||
WT_LSM_CHUNK *chunk;
|
||||
WT_LSM_TREE *lsm_tree;
|
||||
const char *old;
|
||||
int i;
|
||||
|
||||
old = NULL;
|
||||
WT_CLEAR(buf);
|
||||
|
||||
/* Get the LSM tree. */
|
||||
WT_RET(__wt_lsm_tree_get(session, oldname, 1, &lsm_tree));
|
||||
@@ -574,8 +593,6 @@ __wt_lsm_tree_rename(WT_SESSION_IMPL *session,
|
||||
/* Prevent any new opens. */
|
||||
WT_RET(__wt_spin_trylock(session, &lsm_tree->lock));
|
||||
|
||||
WT_ERR(__wt_scr_alloc(session, 0, &buf));
|
||||
|
||||
/* Set the new name. */
|
||||
__wt_free(session, lsm_tree->name);
|
||||
WT_ERR(__wt_strdup(session, newname, &lsm_tree->name));
|
||||
@@ -586,16 +603,18 @@ __wt_lsm_tree_rename(WT_SESSION_IMPL *session,
|
||||
old = chunk->uri;
|
||||
chunk->uri = NULL;
|
||||
|
||||
WT_ERR(__wt_lsm_tree_chunk_name(session, lsm_tree, i, buf));
|
||||
chunk->uri = __wt_buf_steal(session, buf, NULL);
|
||||
WT_ERR(__wt_lsm_tree_chunk_name(
|
||||
session, lsm_tree, (uint32_t)i, &buf));
|
||||
chunk->uri = __wt_buf_steal(session, &buf, NULL);
|
||||
WT_ERR(__wt_schema_rename(session, old, chunk->uri, cfg));
|
||||
__wt_free(session, old);
|
||||
|
||||
if ((old = chunk->bloom_uri) != NULL) {
|
||||
if (F_ISSET(chunk, WT_LSM_CHUNK_BLOOM)) {
|
||||
old = chunk->bloom_uri;
|
||||
chunk->bloom_uri = NULL;
|
||||
WT_ERR(__wt_lsm_tree_bloom_name(
|
||||
session, lsm_tree, i, buf));
|
||||
chunk->bloom_uri = __wt_buf_steal(session, buf, NULL);
|
||||
session, lsm_tree, (uint32_t)i, &buf));
|
||||
chunk->bloom_uri = __wt_buf_steal(session, &buf, NULL);
|
||||
F_SET(chunk, WT_LSM_CHUNK_BLOOM);
|
||||
WT_ERR(__wt_schema_rename(
|
||||
session, old, chunk->uri, cfg));
|
||||
@@ -610,7 +629,6 @@ __wt_lsm_tree_rename(WT_SESSION_IMPL *session,
|
||||
if (0) {
|
||||
err: __wt_spin_unlock(session, &lsm_tree->lock);
|
||||
}
|
||||
__wt_scr_free(&buf);
|
||||
if (old != NULL)
|
||||
__wt_free(session, old);
|
||||
__lsm_tree_discard(session, lsm_tree);
|
||||
@@ -640,15 +658,15 @@ __wt_lsm_tree_truncate(
|
||||
/* Prevent any new opens. */
|
||||
WT_RET(__wt_spin_trylock(session, &lsm_tree->lock));
|
||||
|
||||
/* Mark all chunks old. */
|
||||
/* Create the new chunk. */
|
||||
WT_ERR(__wt_calloc_def(session, 1, &chunk));
|
||||
chunk->id = WT_ATOMIC_ADD(lsm_tree->last, 1);
|
||||
WT_ERR(__wt_lsm_tree_setup_chunk(session, lsm_tree, chunk, 0));
|
||||
|
||||
/* Mark all chunks old. */
|
||||
WT_ERR(__wt_lsm_merge_update_tree(
|
||||
session, lsm_tree, 0, lsm_tree->nchunks, chunk));
|
||||
|
||||
/* Create the new chunk. */
|
||||
WT_ERR(__wt_lsm_tree_setup_chunk(
|
||||
session, lsm_tree, WT_ATOMIC_ADD(lsm_tree->last, 1), chunk, 0));
|
||||
|
||||
WT_ERR(__wt_lsm_meta_write(session, lsm_tree));
|
||||
|
||||
WT_ERR(__lsm_tree_start_worker(session, lsm_tree));
|
||||
|
||||
@@ -17,14 +17,18 @@ static int __lsm_free_chunks(WT_SESSION_IMPL *, WT_LSM_TREE *);
|
||||
* trees to disk and merging on-disk trees.
|
||||
*/
|
||||
void *
|
||||
__wt_lsm_worker(void *arg)
|
||||
__wt_lsm_worker(void *vargs)
|
||||
{
|
||||
WT_LSM_WORKER_ARGS *args;
|
||||
WT_LSM_TREE *lsm_tree;
|
||||
WT_SESSION_IMPL *session;
|
||||
int progress, stalls;
|
||||
int id, progress, stalls;
|
||||
|
||||
lsm_tree = arg;
|
||||
session = lsm_tree->worker_session;
|
||||
args = vargs;
|
||||
lsm_tree = args->lsm_tree;
|
||||
id = args->id;
|
||||
session = lsm_tree->worker_sessions[id];
|
||||
__wt_free(session, args);
|
||||
stalls = 0;
|
||||
|
||||
while (F_ISSET(lsm_tree, WT_LSM_TREE_WORKING)) {
|
||||
@@ -34,13 +38,18 @@ __wt_lsm_worker(void *arg)
|
||||
session->btree = NULL;
|
||||
|
||||
/* Report stalls to merge in seconds. */
|
||||
if (__wt_lsm_merge(session, lsm_tree, stalls / 1000) == 0)
|
||||
if (__wt_lsm_merge(session, lsm_tree, id, stalls / 1000) == 0)
|
||||
progress = 1;
|
||||
|
||||
/* Clear any state from previous worker thread iterations. */
|
||||
session->btree = NULL;
|
||||
|
||||
if (lsm_tree->nold_chunks != lsm_tree->old_avail &&
|
||||
/*
|
||||
* Only have one thread freeing old chunks, and only if there
|
||||
* are chunks to free.
|
||||
*/
|
||||
if (id == 0 &&
|
||||
lsm_tree->nold_chunks != lsm_tree->old_avail &&
|
||||
__lsm_free_chunks(session, lsm_tree) == 0)
|
||||
progress = 1;
|
||||
|
||||
@@ -82,14 +91,23 @@ __wt_lsm_checkpoint_worker(void *arg)
|
||||
/* Write checkpoints in all completed files. */
|
||||
for (i = 0, j = 0; i < cookie.nchunks; i++) {
|
||||
chunk = cookie.chunk_array[i];
|
||||
if (F_ISSET(chunk, WT_LSM_CHUNK_ONDISK))
|
||||
continue;
|
||||
/* Stop if a thread is still active in the chunk. */
|
||||
if (chunk->ncursor != 0)
|
||||
if (chunk->ncursor != 0 ||
|
||||
(i == cookie.nchunks - 1 &&
|
||||
!F_ISSET(chunk, WT_LSM_CHUNK_ONDISK)))
|
||||
break;
|
||||
|
||||
WT_ERR(__lsm_bloom_create(
|
||||
session, lsm_tree, chunk));
|
||||
if (!F_ISSET(chunk, WT_LSM_CHUNK_BLOOM) &&
|
||||
(ret = __lsm_bloom_create(
|
||||
session, lsm_tree, chunk)) != 0) {
|
||||
(void)__wt_err(
|
||||
session, ret, "bloom creation failed");
|
||||
break;
|
||||
}
|
||||
|
||||
if (F_ISSET(chunk, WT_LSM_CHUNK_ONDISK))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* NOTE: we pass a non-NULL config, because otherwise
|
||||
* __wt_checkpoint thinks we're closing the file.
|
||||
@@ -101,14 +119,18 @@ __wt_lsm_checkpoint_worker(void *arg)
|
||||
++j;
|
||||
__wt_spin_lock(session, &lsm_tree->lock);
|
||||
F_SET(chunk, WT_LSM_CHUNK_ONDISK);
|
||||
lsm_tree->dsk_gen++;
|
||||
++lsm_tree->dsk_gen;
|
||||
__wt_spin_unlock(session, &lsm_tree->lock);
|
||||
WT_VERBOSE_ERR(session, lsm,
|
||||
"LSM worker checkpointed %d.", i);
|
||||
} else {
|
||||
(void)__wt_err(
|
||||
session, ret, "LSM checkpoint failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == 0)
|
||||
__wt_sleep(0, 10);
|
||||
__wt_sleep(0, 1000);
|
||||
}
|
||||
err: __wt_free(session, cookie.chunk_array);
|
||||
|
||||
@@ -136,12 +158,9 @@ __wt_lsm_copy_chunks(WT_SESSION_IMPL *session,
|
||||
/* The actual error value is ignored. */
|
||||
return (WT_ERROR);
|
||||
}
|
||||
/*
|
||||
* Take a copy of the current state of the LSM tree. Skip
|
||||
* the last chunk - since it is the active one and not relevant
|
||||
* to merge operations.
|
||||
*/
|
||||
nchunks = lsm_tree->nchunks - 1;
|
||||
|
||||
/* Take a copy of the current state of the LSM tree. */
|
||||
nchunks = lsm_tree->nchunks;
|
||||
|
||||
/*
|
||||
* If the tree array of active chunks is larger than our current buffer,
|
||||
@@ -173,7 +192,7 @@ __lsm_bloom_create(WT_SESSION_IMPL *session,
|
||||
WT_BLOOM *bloom;
|
||||
WT_CURSOR *src;
|
||||
WT_DECL_RET;
|
||||
WT_ITEM key;
|
||||
WT_ITEM buf, key;
|
||||
const char *cur_cfg[] = API_CONF_DEFAULTS(session, open_cursor, "raw");
|
||||
uint64_t insert_count;
|
||||
|
||||
@@ -181,11 +200,21 @@ __lsm_bloom_create(WT_SESSION_IMPL *session,
|
||||
chunk->count == 0)
|
||||
return (0);
|
||||
|
||||
WT_ASSERT(session, chunk->bloom_uri != NULL);
|
||||
/*
|
||||
* Normally, the Bloom URI is populated when the chunk struct is
|
||||
* allocated. After an open, however, it may not have been.
|
||||
* Deal with that here.
|
||||
*/
|
||||
if (chunk->bloom_uri == NULL) {
|
||||
WT_CLEAR(buf);
|
||||
WT_RET(__wt_lsm_tree_bloom_name(
|
||||
session, lsm_tree, chunk->id, &buf));
|
||||
chunk->bloom_uri = __wt_buf_steal(session, &buf, NULL);
|
||||
}
|
||||
|
||||
bloom = NULL;
|
||||
|
||||
WT_ERR(__wt_bloom_create(session, chunk->bloom_uri,
|
||||
WT_RET(__wt_bloom_create(session, chunk->bloom_uri,
|
||||
lsm_tree->bloom_config, chunk->count,
|
||||
lsm_tree->bloom_bit_count, lsm_tree->bloom_hash_count, &bloom));
|
||||
|
||||
@@ -236,17 +265,15 @@ __lsm_free_chunks(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
|
||||
* An EBUSY return is acceptable - a cursor may still
|
||||
* be positioned on this old chunk.
|
||||
*/
|
||||
if (ret == 0) {
|
||||
progress = 1;
|
||||
F_CLR(chunk, WT_LSM_CHUNK_BLOOM);
|
||||
__wt_free(session, chunk->bloom_uri);
|
||||
chunk->bloom_uri = NULL;
|
||||
} else if (ret != EBUSY)
|
||||
goto err;
|
||||
if (ret == EBUSY)
|
||||
if (ret == EBUSY) {
|
||||
WT_VERBOSE_ERR(session, lsm,
|
||||
"LSM worker bloom drop busy: %s.",
|
||||
chunk->bloom_uri);
|
||||
continue;
|
||||
} else
|
||||
WT_ERR(ret);
|
||||
|
||||
F_CLR(chunk, WT_LSM_CHUNK_BLOOM);
|
||||
}
|
||||
if (chunk->uri != NULL) {
|
||||
WT_WITH_SCHEMA_LOCK(session, ret =
|
||||
@@ -255,19 +282,20 @@ __lsm_free_chunks(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
|
||||
* An EBUSY return is acceptable - a cursor may still
|
||||
* be positioned on this old chunk.
|
||||
*/
|
||||
if (ret == 0) {
|
||||
progress = 1;
|
||||
__wt_free(session, chunk->uri);
|
||||
chunk->uri = NULL;
|
||||
} else if (ret != EBUSY)
|
||||
goto err;
|
||||
if (ret == EBUSY) {
|
||||
WT_VERBOSE_ERR(session, lsm,
|
||||
"LSM worker drop busy: %s.",
|
||||
chunk->uri);
|
||||
continue;
|
||||
} else
|
||||
WT_ERR(ret);
|
||||
}
|
||||
|
||||
if (chunk->uri == NULL &&
|
||||
!F_ISSET(chunk, WT_LSM_CHUNK_BLOOM)) {
|
||||
__wt_free(session, lsm_tree->old_chunks[i]);
|
||||
++lsm_tree->old_avail;
|
||||
}
|
||||
progress = 1;
|
||||
__wt_free(session, chunk->bloom_uri);
|
||||
__wt_free(session, chunk->uri);
|
||||
__wt_free(session, lsm_tree->old_chunks[i]);
|
||||
++lsm_tree->old_avail;
|
||||
}
|
||||
if (locked) {
|
||||
err: WT_TRET(__wt_lsm_meta_write(session, lsm_tree));
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#define BDB 1 /* Berkeley DB header files */
|
||||
|
||||
@@ -1,16 +1,36 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "format.h"
|
||||
#include "config.h"
|
||||
|
||||
static const char *config_file_type(int);
|
||||
static const char *config_file_type(u_int);
|
||||
static CONFIG *config_find(const char *, size_t);
|
||||
static uint32_t config_translate(const char *);
|
||||
static u_int config_translate(const char *);
|
||||
|
||||
/*
|
||||
* config_setup --
|
||||
@@ -20,6 +40,7 @@ void
|
||||
config_setup(void)
|
||||
{
|
||||
CONFIG *cp;
|
||||
const char *cstr;
|
||||
|
||||
/* Clear any temporary values. */
|
||||
config_clear();
|
||||
@@ -30,7 +51,7 @@ config_setup(void)
|
||||
* them.
|
||||
*/
|
||||
cp = config_find("data_source", strlen("data_source"));
|
||||
if (!(cp->flags & C_PERM)) {
|
||||
if (!(cp->flags & C_PERM))
|
||||
switch (MMRAND(0, 2)) {
|
||||
case 0:
|
||||
config_single("data_source=file", 0);
|
||||
@@ -44,7 +65,6 @@ config_setup(void)
|
||||
config_single("data_source=table", 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cp = config_find("file_type", strlen("file_type"));
|
||||
if (!(cp->flags & C_PERM)) {
|
||||
@@ -62,8 +82,8 @@ config_setup(void)
|
||||
config_single("file_type=row", 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
g.type = (int)config_translate(g.c_file_type);
|
||||
}
|
||||
g.type = config_translate(g.c_file_type);
|
||||
|
||||
/*
|
||||
* If data_source and file_type were both "permanent", we may still
|
||||
@@ -76,6 +96,48 @@ config_setup(void)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compression: choose something if compression wasn't specified,
|
||||
* otherwise confirm the appropriate shared library is available.
|
||||
*/
|
||||
cp = config_find("compression", strlen("compression"));
|
||||
if (!(cp->flags & C_PERM)) {
|
||||
cstr = "compression=none";
|
||||
switch (MMRAND(0, 9)) {
|
||||
case 0: /* 10% */
|
||||
break;
|
||||
case 1: case 2: case 3: case 4: /* 40% */
|
||||
if (access(BZIP_PATH, R_OK) == 0)
|
||||
cstr = "compression=bzip";
|
||||
break;
|
||||
case 5: /* 10% */
|
||||
#if 0
|
||||
cstr = "compression=ext";
|
||||
#endif
|
||||
break;
|
||||
case 6: case 7: case 8: case 9: /* 40% */
|
||||
if (access(SNAPPY_PATH, R_OK) == 0)
|
||||
cstr = "compression=snappy";
|
||||
break;
|
||||
}
|
||||
config_single(cstr, 0);
|
||||
}
|
||||
g.compression = config_translate(g.c_compression);
|
||||
if (cp->flags & C_PERM) {
|
||||
if (g.compression == COMPRESS_BZIP &&
|
||||
access(BZIP_PATH, R_OK) != 0) {
|
||||
fprintf(stderr,
|
||||
"bzip library not found or not readable\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (g.compression == COMPRESS_SNAPPY &&
|
||||
access(SNAPPY_PATH, R_OK) != 0) {
|
||||
fprintf(stderr,
|
||||
"snappy library not found or not readable\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Build the object name. */
|
||||
if ((g.uri = malloc(
|
||||
strlen(g.c_data_source) + strlen(WT_NAME) + 2)) == NULL)
|
||||
@@ -274,7 +336,9 @@ config_single(const char *s, int perm)
|
||||
}
|
||||
else if (strncmp(s, "file_type", strlen("file_type")) == 0)
|
||||
*cp->vstr = strdup(
|
||||
config_file_type((int)config_translate(ep)));
|
||||
config_file_type(config_translate(ep)));
|
||||
else if (strncmp(s, "compression", strlen("compression")) == 0)
|
||||
*cp->vstr = strdup(ep);
|
||||
if (*cp->vstr == NULL)
|
||||
syserr("strdup");
|
||||
return;
|
||||
@@ -299,25 +363,35 @@ config_single(const char *s, int perm)
|
||||
* config_translate --
|
||||
* Return an integer value representing the argument.
|
||||
*/
|
||||
static uint32_t
|
||||
static u_int
|
||||
config_translate(const char *s)
|
||||
{
|
||||
/* If it's already a integer value, we're done. */
|
||||
if (isdigit(s[0]))
|
||||
return (uint32_t)atoi(s);
|
||||
return ((u_int)atoi(s));
|
||||
|
||||
/* Currently, all we translate are the file type names. */
|
||||
/* File type names. */
|
||||
if (strcmp(s, "fix") == 0 ||
|
||||
strcmp(s, "flcs") == 0 || /* Deprecated */
|
||||
strcmp(s, "fixed-length column-store") == 0)
|
||||
return ((uint32_t)FIX);
|
||||
return (FIX);
|
||||
if (strcmp(s, "var") == 0 ||
|
||||
strcmp(s, "vlcs") == 0 || /* Deprecated */
|
||||
strcmp(s, "variable-length column-store") == 0)
|
||||
return ((uint32_t)VAR);
|
||||
return (VAR);
|
||||
if (strcmp(s, "row") == 0 ||
|
||||
strcmp(s, "row-store") == 0)
|
||||
return ((uint32_t)ROW);
|
||||
return (ROW);
|
||||
|
||||
/* Compression type names. */
|
||||
if (strcmp(s, "none") == 0)
|
||||
return (COMPRESS_NONE);
|
||||
if (strcmp(s, "bzip") == 0)
|
||||
return (COMPRESS_BZIP);
|
||||
if (strcmp(s, "ext") == 0)
|
||||
return (COMPRESS_EXT);
|
||||
if (strcmp(s, "snappy") == 0)
|
||||
return (COMPRESS_SNAPPY);
|
||||
|
||||
fprintf(stderr, "%s: %s: unknown configuration value\n", g.progname, s);
|
||||
exit(EXIT_FAILURE);
|
||||
@@ -347,7 +421,7 @@ config_find(const char *s, size_t len)
|
||||
* Return the file type as a string.
|
||||
*/
|
||||
static const char *
|
||||
config_file_type(int type)
|
||||
config_file_type(u_int type)
|
||||
{
|
||||
switch (type) {
|
||||
case FIX:
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -39,7 +59,7 @@ typedef struct {
|
||||
|
||||
uint32_t min; /* Minimum value */
|
||||
uint32_t max; /* Maximum value */
|
||||
uint32_t *v; /* Value for this run */
|
||||
u_int *v; /* Value for this run */
|
||||
char **vstr; /* Value for string options */
|
||||
} CONFIG;
|
||||
|
||||
@@ -54,14 +74,14 @@ static CONFIG c[] = {
|
||||
"number of bits for fixed-length column-store files",
|
||||
C_FIX, 0, 1, 8, &g.c_bitcnt, NULL },
|
||||
|
||||
{ "bzip",
|
||||
"if blocks are BZIP2 encoded", /* 80% */
|
||||
0, C_BOOL, 80, 0, &g.c_bzip, NULL },
|
||||
|
||||
{ "cache",
|
||||
"size of the cache in MB",
|
||||
0, 0, 1, 100, &g.c_cache, NULL },
|
||||
|
||||
{ "compression",
|
||||
"type of compression (none | bzip | ext | snappy)",
|
||||
0, C_IGNORE|C_STRING, 1, 4, NULL, &g.c_compression },
|
||||
|
||||
{ "data_source",
|
||||
"type of data source to create (file | table | lsm)",
|
||||
0, C_IGNORE | C_STRING, 0, 0, NULL, &g.c_data_source },
|
||||
|
||||
@@ -1,12 +1,33 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
@@ -26,6 +47,14 @@
|
||||
#include <wiredtiger.h>
|
||||
#endif
|
||||
|
||||
#define EXTPATH "../../ext/" /* Extensions path */
|
||||
#define BZIP_PATH \
|
||||
EXTPATH "compressors/bzip2/.libs/libwiredtiger_bzip2.so"
|
||||
#define SNAPPY_PATH \
|
||||
EXTPATH "compressors/snappy/.libs/libwiredtiger_snappy.so"
|
||||
#define REVERSE_PATH \
|
||||
EXTPATH "collators/reverse/.libs/libwiredtiger_reverse_collator.so"
|
||||
|
||||
#define M(v) ((v) * 1000000) /* Million */
|
||||
#define UNUSED(var) (void)(var) /* Quiet unused var warnings */
|
||||
|
||||
@@ -59,37 +88,44 @@ typedef struct {
|
||||
int replay; /* Replaying a run. */
|
||||
int track; /* Track progress */
|
||||
|
||||
char *uri; /* Object name */
|
||||
|
||||
#define FIX 1 /* File types */
|
||||
#define ROW 2
|
||||
#define VAR 3
|
||||
int type; /* File type */
|
||||
char *uri; /* Object name */
|
||||
u_int type; /* File type */
|
||||
|
||||
#define COMPRESS_NONE 1
|
||||
#define COMPRESS_BZIP 2
|
||||
#define COMPRESS_EXT 3
|
||||
#define COMPRESS_SNAPPY 4
|
||||
u_int compression; /* Compression type */
|
||||
|
||||
char *config_open; /* Command-line configuration */
|
||||
|
||||
uint32_t c_bitcnt; /* Config values */
|
||||
uint32_t c_bzip;
|
||||
uint32_t c_cache;
|
||||
char *c_data_source;
|
||||
uint32_t c_delete_pct;
|
||||
uint32_t c_dictionary;
|
||||
char *c_file_type;
|
||||
uint32_t c_huffman_key;
|
||||
uint32_t c_huffman_value;
|
||||
uint32_t c_insert_pct;
|
||||
uint32_t c_intl_page_max;
|
||||
uint32_t c_key_max;
|
||||
uint32_t c_key_min;
|
||||
uint32_t c_leaf_page_max;
|
||||
uint32_t c_ops;
|
||||
uint32_t c_repeat_data_pct;
|
||||
uint32_t c_reverse;
|
||||
uint32_t c_rows;
|
||||
uint32_t c_runs;
|
||||
uint32_t c_threads;
|
||||
uint32_t c_value_max;
|
||||
uint32_t c_value_min;
|
||||
uint32_t c_write_pct;
|
||||
u_int c_bitcnt; /* Config values */
|
||||
u_int c_cache;
|
||||
char *c_compression;
|
||||
char *c_data_source;
|
||||
u_int c_delete_pct;
|
||||
u_int c_dictionary;
|
||||
char *c_file_type;
|
||||
u_int c_huffman_key;
|
||||
u_int c_huffman_value;
|
||||
u_int c_insert_pct;
|
||||
u_int c_intl_page_max;
|
||||
u_int c_key_max;
|
||||
u_int c_key_min;
|
||||
u_int c_leaf_page_max;
|
||||
u_int c_ops;
|
||||
u_int c_repeat_data_pct;
|
||||
u_int c_reverse;
|
||||
u_int c_rows;
|
||||
u_int c_runs;
|
||||
u_int c_threads;
|
||||
u_int c_value_max;
|
||||
u_int c_value_min;
|
||||
u_int c_write_pct;
|
||||
|
||||
uint32_t key_cnt; /* Keys loaded so far */
|
||||
uint32_t rows; /* Total rows */
|
||||
|
||||
@@ -32,13 +32,16 @@ if test $# -ne 0; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
revext="$top/ext/collators/reverse/.libs/reverse_collator.so"
|
||||
bzext="$top/ext/compressors/bzip2_compress/.libs/bzip2_compress.so"
|
||||
if test -e $bzext ; then
|
||||
ext="\"$revext\",\"$bzext\""
|
||||
else
|
||||
ext="\"$revext\""
|
||||
ext="\"$top/ext/collators/reverse/.libs/libwiredtiger_reverse_collator.so\""
|
||||
bz_ext="$top/ext/compressors/bzip2/.libs/libwiredtiger_bzip2.so"
|
||||
if test -e $bz_ext ; then
|
||||
ext="$ext,\"$bz_ext\""
|
||||
fi
|
||||
sn_ext="$top/ext/compressors/snappy/.libs/libwiredtiger_snappy.so"
|
||||
if test -e $sn_ext ; then
|
||||
ext="$ext,\"$sn_ext\""
|
||||
fi
|
||||
|
||||
config='extensions=['$ext']'
|
||||
|
||||
$top/wt -h RUNDIR -C "$config" dump $wt_name |
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "format.h"
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "format.h"
|
||||
@@ -183,9 +203,17 @@ track(const char *tag, uint64_t cnt, TINFO *tinfo)
|
||||
uint32_t
|
||||
wts_rand(void)
|
||||
{
|
||||
struct timeval t;
|
||||
char buf[64];
|
||||
uint32_t r;
|
||||
|
||||
/* If it's not a replay, seed the random number generator. */
|
||||
if (!g.replay) {
|
||||
if (gettimeofday(&t, NULL) != 0)
|
||||
die(errno, "gettimeofday");
|
||||
srand((u_int)(0xdeadbeef ^ (u_int)t.tv_usec));
|
||||
}
|
||||
|
||||
/* If we're threaded, it's not repeatable, ignore the log. */
|
||||
if (!SINGLETHREADED)
|
||||
return ((uint32_t)rand());
|
||||
@@ -202,10 +230,8 @@ wts_rand(void)
|
||||
if ((g.rand_log =
|
||||
fopen("RUNDIR/rand", g.replay ? "r" : "w")) == NULL)
|
||||
die(errno, "fopen: RUNDIR/rand");
|
||||
if (!g.replay) {
|
||||
srand((u_int)(0xdeadbeef ^ (u_int)time(NULL)));
|
||||
if (!g.replay)
|
||||
(void)setvbuf(g.rand_log, NULL, _IOLBF, 0);
|
||||
}
|
||||
}
|
||||
if (g.replay) {
|
||||
if (fgets(buf, sizeof(buf), g.rand_log) == NULL) {
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "format.h"
|
||||
@@ -45,44 +65,45 @@ wts_open(void)
|
||||
WT_SESSION *session;
|
||||
uint32_t maxintlpage, maxintlitem, maxleafpage, maxleafitem;
|
||||
int ret;
|
||||
const char *ext1, *ext2;
|
||||
char config[512], *end, *p;
|
||||
|
||||
/* If the bzip2 compression module has been built, use it. */
|
||||
#define EXTPATH "../../ext"
|
||||
ext1 = EXTPATH "compressors/bzip2_compress/.libs/bzip2_compress.so";
|
||||
if (access(ext1, R_OK) != 0) {
|
||||
ext1 = "";
|
||||
g.c_bzip = 0;
|
||||
}
|
||||
ext2 = EXTPATH "/collators/reverse/.libs/reverse_collator.so";
|
||||
char config[1024], *end, *p;
|
||||
|
||||
/*
|
||||
* Open configuration -- put command line configuration options at the
|
||||
* end so they can override "standard" configuration.
|
||||
* Open configuration.
|
||||
*
|
||||
* Put command line configuration options at the end so they override
|
||||
* the standard configuration.
|
||||
*/
|
||||
snprintf(config, sizeof(config),
|
||||
"create,error_prefix=\"%s\",cache_size=%" PRIu32 "MB,sync=false,"
|
||||
"extensions=[\"%s\",\"%s\"],%s",
|
||||
g.progname, g.c_cache, ext1, ext2,
|
||||
"extensions=[\"%s\",\"%s\", \"%s\"],%s",
|
||||
g.progname, g.c_cache,
|
||||
access(BZIP_PATH, R_OK) == 0 ? BZIP_PATH : "",
|
||||
access(SNAPPY_PATH, R_OK) == 0 ? SNAPPY_PATH : "",
|
||||
REVERSE_PATH,
|
||||
g.config_open == NULL ? "" : g.config_open);
|
||||
|
||||
if ((ret =
|
||||
wiredtiger_open("RUNDIR", &event_handler, config, &conn)) != 0)
|
||||
die(ret, "wiredtiger_open");
|
||||
g.wts_conn = conn;
|
||||
|
||||
if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0)
|
||||
die(ret, "connection.open_session");
|
||||
|
||||
/*
|
||||
* Create the object.
|
||||
*
|
||||
* Make sure at least 2 internal page per thread can fit in cache.
|
||||
*/
|
||||
maxintlpage = 1U << g.c_intl_page_max;
|
||||
/* Make sure at least 2 internal page per thread can fit in cache. */
|
||||
while (2 * g.c_threads * maxintlpage > g.c_cache << 20)
|
||||
maxintlpage >>= 1;
|
||||
maxintlitem = MMRAND(maxintlpage / 50, maxintlpage / 40);
|
||||
if (maxintlitem < 40)
|
||||
maxintlitem = 40;
|
||||
maxleafpage = 1U << g.c_leaf_page_max;
|
||||
|
||||
/* Make sure at least one leaf page per thread can fit in cache. */
|
||||
maxleafpage = 1U << g.c_leaf_page_max;
|
||||
while (g.c_threads * (maxintlpage + maxleafpage) > g.c_cache << 20)
|
||||
maxleafpage >>= 1;
|
||||
maxleafitem = MMRAND(maxleafpage / 50, maxleafpage / 40);
|
||||
@@ -98,10 +119,6 @@ wts_open(void)
|
||||
(g.type == ROW) ? "u" : "r",
|
||||
maxintlpage, maxintlitem, maxleafpage, maxleafitem);
|
||||
|
||||
if (g.c_bzip)
|
||||
p += snprintf(p, (size_t)(end - p),
|
||||
",block_compressor=\"bzip2_compress\"");
|
||||
|
||||
switch (g.type) {
|
||||
case FIX:
|
||||
p += snprintf(p, (size_t)(end - p),
|
||||
@@ -125,13 +142,27 @@ wts_open(void)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Configure compression. */
|
||||
switch (g.compression) {
|
||||
case COMPRESS_NONE:
|
||||
break;
|
||||
case COMPRESS_BZIP:
|
||||
p += snprintf(p, (size_t)(end - p),
|
||||
",block_compressor=\"bzip2\"");
|
||||
break;
|
||||
case COMPRESS_EXT:
|
||||
break;
|
||||
case COMPRESS_SNAPPY:
|
||||
p += snprintf(p, (size_t)(end - p),
|
||||
",block_compressor=\"snappy\"");
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ret = session->create(session, g.uri, config)) != 0)
|
||||
die(ret, "session.create: %s", g.uri);
|
||||
|
||||
if ((ret = session->close(session, NULL)) != 0)
|
||||
die(ret, "session.close");
|
||||
|
||||
g.wts_conn = conn;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "format.h"
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "format.h"
|
||||
@@ -120,8 +140,11 @@ ops(void *arg)
|
||||
memset(&value, 0, sizeof(value));
|
||||
val_gen_setup(&valbuf);
|
||||
|
||||
/* Each thread does its share of the total operations. */
|
||||
thread_ops = g.c_ops / g.c_threads;
|
||||
/*
|
||||
* Each thread does its share of the total operations, and make sure
|
||||
* that it's not 0 (testing runs: threads might be larger than ops).
|
||||
*/
|
||||
thread_ops = g.c_threads + g.c_ops / g.c_threads;
|
||||
|
||||
/* Pick a period for re-opening the session and cursors. */
|
||||
session = NULL;
|
||||
|
||||
@@ -1,3 +1,30 @@
|
||||
/*-
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
@@ -1,3 +1,30 @@
|
||||
/*-
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
@@ -1,3 +1,30 @@
|
||||
/*-
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "wt_internal.h"
|
||||
|
||||
@@ -97,7 +97,8 @@ class test_compress01_base(wttest.WiredTigerTestCase):
|
||||
testdir = os.path.dirname(__file__)
|
||||
import run
|
||||
extdir = os.path.join(run.wt_builddir, 'ext/compressors')
|
||||
extfile = os.path.join(extdir, name, '.libs', name + '.so')
|
||||
extfile = os.path.join(
|
||||
extdir, name, '.libs', 'libwiredtiger_' + name + '.so')
|
||||
if not os.path.exists(extfile):
|
||||
self.skipTest('Extension "' + extfile + '" not built')
|
||||
return 'extensions=["' + extfile + '"]'
|
||||
@@ -130,15 +131,15 @@ class compress01_tests(object):
|
||||
|
||||
class test_compress01_1_nop(test_compress01_base, compress01_tests):
|
||||
def __init__(self, testname):
|
||||
test_compress01_base.__init__(self, testname, 'nop_compress', 'nop')
|
||||
test_compress01_base.__init__(self, testname, 'nop', 'nop')
|
||||
|
||||
class test_compress01_2_bz(test_compress01_base, compress01_tests):
|
||||
def __init__(self, testname):
|
||||
test_compress01_base.__init__(self, testname, 'bzip2_compress', 'bz')
|
||||
test_compress01_base.__init__(self, testname, 'bzip2', 'bz')
|
||||
|
||||
class test_compress01_3_sn(test_compress01_base, compress01_tests):
|
||||
def __init__(self, testname):
|
||||
test_compress01_base.__init__(self, testname, 'snappy_compress', 'sn')
|
||||
test_compress01_base.__init__(self, testname, 'snappy', 'sn')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "thread.h"
|
||||
|
||||
@@ -1,8 +1,28 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2012 WiredTiger, Inc.
|
||||
* All rights reserved.
|
||||
* Public Domain 2008-2012 WiredTiger, Inc.
|
||||
*
|
||||
* See the file LICENSE for redistribution information.
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
Reference in New Issue
Block a user