diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2015-02-04 12:27:46 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2015-02-04 12:27:46 +1100 |
commit | 5adbba6cb1a4e87ac7c4faa5c5b0dbada30f8c66 (patch) | |
tree | 7e8025d5d82573272af3293d01509882279235d4 | |
parent | 0ac6575b5e2f88a8bbfbad9fc17ada5e9247145b (diff) | |
parent | ecf5849f9b489d916104df01b48440b6cb6129ee (diff) | |
download | mongo-5adbba6cb1a4e87ac7c4faa5c5b0dbada30f8c66.tar.gz |
Merge branch 'develop' into discard-dirty
-rw-r--r-- | src/btree/bt_cursor.c | 4 | ||||
-rw-r--r-- | src/btree/bt_debug.c | 4 | ||||
-rw-r--r-- | src/btree/bt_huffman.c | 27 | ||||
-rw-r--r-- | src/btree/bt_slvg.c | 12 | ||||
-rw-r--r-- | src/btree/bt_split.c | 51 | ||||
-rw-r--r-- | src/btree/bt_stat.c | 7 | ||||
-rw-r--r-- | src/btree/col_srch.c | 1 | ||||
-rw-r--r-- | src/btree/row_srch.c | 3 | ||||
-rw-r--r-- | src/conn/conn_sweep.c | 8 | ||||
-rw-r--r-- | src/include/btmem.h | 13 | ||||
-rw-r--r-- | src/include/btree.i | 3 | ||||
-rw-r--r-- | src/include/connection.h | 2 | ||||
-rw-r--r-- | src/include/cursor.i | 5 | ||||
-rw-r--r-- | src/reconcile/rec_write.c | 8 | ||||
-rw-r--r-- | test/suite/test_huffman01.py | 76 | ||||
-rw-r--r-- | test/suite/test_huffman02.py | 67 |
16 files changed, 248 insertions, 43 deletions
diff --git a/src/btree/bt_cursor.c b/src/btree/bt_cursor.c index c115e44e573..1960e4605ef 100644 --- a/src/btree/bt_cursor.c +++ b/src/btree/bt_cursor.c @@ -782,7 +782,9 @@ __wt_btcur_next_random(WT_CURSOR_BTREE *cbt) WT_RET(__cursor_func_init(cbt, 1)); - WT_ERR(__wt_row_random(session, cbt)); + WT_WITH_PAGE_INDEX(session, + ret = __wt_row_random(session, cbt)); + WT_ERR(ret); if (__cursor_valid(cbt, &upd)) WT_ERR(__wt_kv_return(session, cbt, upd)); else diff --git a/src/btree/bt_debug.c b/src/btree/bt_debug.c index 5a3342e62a9..e84a63695f9 100644 --- a/src/btree/bt_debug.c +++ b/src/btree/bt_debug.c @@ -548,7 +548,9 @@ __debug_page(WT_DBG *ds, WT_PAGE *page, uint32_t flags) session = ds->session; /* Dump the page metadata. */ - WT_RET(__debug_page_metadata(ds, page)); + WT_WITH_PAGE_INDEX(session, + ret = __debug_page_metadata(ds, page)); + WT_RET(ret); /* Dump the page. */ switch (page->type) { diff --git a/src/btree/bt_huffman.c b/src/btree/bt_huffman.c index c1cf3431c3b..c31b3f2fdf1 100644 --- a/src/btree/bt_huffman.c +++ b/src/btree/bt_huffman.c @@ -128,6 +128,30 @@ static const struct __wt_huffman_table __wt_huffman_nytenglish[] = { static int __wt_huffman_read(WT_SESSION_IMPL *, WT_CONFIG_ITEM *, struct __wt_huffman_table **, u_int *, u_int *); +#define WT_HUFFMAN_CONFIG_VALID(str, len) \ + (WT_STRING_CASE_MATCH("english", (str), (len)) || \ + WT_PREFIX_MATCH((str), "utf8") || WT_PREFIX_MATCH((str), "utf16")) + +/* + * __btree_huffman_config -- + * Verify the key or value strings passed in. + */ +static int +__btree_huffman_config(WT_SESSION_IMPL *session, + WT_CONFIG_ITEM *key_conf, WT_CONFIG_ITEM *value_conf) +{ + if (key_conf->len != 0 && + !WT_HUFFMAN_CONFIG_VALID(key_conf->str, key_conf->len)) + WT_RET_MSG( + session, EINVAL, "illegal Huffman key configuration"); + if (value_conf->len != 0 && + !WT_HUFFMAN_CONFIG_VALID(value_conf->str, value_conf->len)) + WT_RET_MSG( + session, EINVAL, "illegal Huffman value configuration"); + return (0); + +} + /* * __wt_btree_huffman_open -- * Configure Huffman encoding for the tree. @@ -150,6 +174,7 @@ __wt_btree_huffman_open(WT_SESSION_IMPL *session) __wt_config_gets_none(session, cfg, "huffman_value", &value_conf)); if (key_conf.len == 0 && value_conf.len == 0) return (0); + WT_RET(__btree_huffman_config(session, &key_conf, &value_conf)); switch (btree->type) { /* Check file type compatibility. */ case BTREE_COL_FIX: @@ -311,6 +336,8 @@ __wt_huffman_read(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *ip, tp->frequency = (uint32_t)frequency; } + if (ret == EOF) + ret = 0; *entriesp = lineno - 1; *tablep = table; diff --git a/src/btree/bt_slvg.c b/src/btree/bt_slvg.c index fbc3890f23b..1cf616a2f6b 100644 --- a/src/btree/bt_slvg.c +++ b/src/btree/bt_slvg.c @@ -294,12 +294,16 @@ __wt_bt_salvage(WT_SESSION_IMPL *session, WT_CKPT *ckptbase, const char *cfg[]) switch (ss->page_type) { case WT_PAGE_COL_FIX: case WT_PAGE_COL_VAR: - WT_ERR( - __slvg_col_build_internal(session, leaf_cnt, ss)); + WT_WITH_PAGE_INDEX(session, + ret = __slvg_col_build_internal( + session, leaf_cnt, ss)); + WT_ERR(ret); break; case WT_PAGE_ROW_LEAF: - WT_ERR( - __slvg_row_build_internal(session, leaf_cnt, ss)); + WT_WITH_PAGE_INDEX(session, + ret = __slvg_row_build_internal( + session, leaf_cnt, ss)); + WT_ERR(ret); break; } diff --git a/src/btree/bt_split.c b/src/btree/bt_split.c index 5b6aa9a3be0..05af1a2f885 100644 --- a/src/btree/bt_split.c +++ b/src/btree/bt_split.c @@ -42,7 +42,8 @@ __split_oldest_gen(WT_SESSION_IMPL *session) * Add a new entry into the session's split stash list. */ static int -__split_stash_add(WT_SESSION_IMPL *session, void *p, size_t len) +__split_stash_add( + WT_SESSION_IMPL *session, uint64_t split_gen, void *p, size_t len) { WT_SPLIT_STASH *stash; @@ -53,7 +54,7 @@ __split_stash_add(WT_SESSION_IMPL *session, void *p, size_t len) session->split_stash_cnt + 1, &session->split_stash)); stash = session->split_stash + session->split_stash_cnt++; - stash->split_gen = WT_ATOMIC_ADD8(S2C(session)->split_gen, 1); + stash->split_gen = split_gen; stash->p = p; stash->len = len; @@ -143,14 +144,14 @@ __wt_split_stash_discard_all( * it to be freed otherwise. */ static int -__split_safe_free(WT_SESSION_IMPL *session, int exclusive, void *p, size_t s) +__split_safe_free(WT_SESSION_IMPL *session, + uint64_t split_gen, int exclusive, void *p, size_t s) { /* * We have swapped something in a page: if we don't have exclusive * access, check whether there are other threads in the same tree. */ - if (!exclusive && - __split_oldest_gen(session) == S2C(session)->split_gen + 1) + if (!exclusive && __split_oldest_gen(session) > split_gen) exclusive = 1; if (exclusive) { @@ -158,7 +159,7 @@ __split_safe_free(WT_SESSION_IMPL *session, int exclusive, void *p, size_t s) return (0); } - return (__split_stash_add(session, p, s)); + return (__split_stash_add(session, split_gen, p, s)); } /* @@ -380,6 +381,7 @@ __split_deepen(WT_SESSION_IMPL *session, WT_PAGE *parent, uint32_t children) WT_REF **alloc_refp; WT_REF *child_ref, **child_refp, *parent_ref, **parent_refp, *ref; size_t child_incr, parent_decr, parent_incr, size; + uint64_t split_gen; uint32_t chunk, i, j, remain, slots; int panic; void *p; @@ -514,6 +516,7 @@ __split_deepen(WT_SESSION_IMPL *session, WT_PAGE *parent, uint32_t children) * needs to be paid. */ WT_INTL_INDEX_SET(parent, alloc_index); + split_gen = WT_ATOMIC_ADD8(S2C(session)->split_gen, 1); panic = 1; #ifdef HAVE_DIAGNOSTIC @@ -583,7 +586,7 @@ __split_deepen(WT_SESSION_IMPL *session, WT_PAGE *parent, uint32_t children) * be using the new index. */ size = sizeof(WT_PAGE_INDEX) + pindex->entries * sizeof(WT_REF *); - WT_ERR(__split_safe_free(session, 0, pindex, size)); + WT_ERR(__split_safe_free(session, split_gen, 0, pindex, size)); parent_decr += size; /* @@ -784,7 +787,7 @@ __wt_multi_to_ref(WT_SESSION_IMPL *session, static int __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new, uint32_t new_entries, size_t parent_decr, size_t parent_incr, - int exclusive, int ref_discard) + int exclusive, int ref_discard, uint64_t *split_genp) { WT_DECL_RET; WT_IKEY *ikey; @@ -792,6 +795,7 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new, WT_PAGE_INDEX *alloc_index, *pindex; WT_REF **alloc_refp, *next_ref, *parent_ref; size_t size; + uint64_t split_gen; uint32_t children, i, j; uint32_t deleted_entries, parent_entries, result_entries; int complete, hazard, locked; @@ -898,6 +902,7 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new, * to threads descending the tree. */ WT_INTL_INDEX_SET(parent, alloc_index); + split_gen = *split_genp = WT_ATOMIC_ADD8(S2C(session)->split_gen, 1); alloc_index = NULL; #ifdef HAVE_DIAGNOSTIC @@ -944,7 +949,7 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new, if (ikey != NULL) { size = sizeof(WT_IKEY) + ikey->size; WT_TRET(__split_safe_free( - session, 0, ikey, size)); + session, split_gen, 0, ikey, size)); parent_decr += size; } /* @@ -962,7 +967,7 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new, } WT_TRET(__split_safe_free( - session, 0, next_ref, sizeof(WT_REF))); + session, split_gen, 0, next_ref, sizeof(WT_REF))); parent_decr += sizeof(WT_REF); } } @@ -972,7 +977,7 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new, * Add it to the session discard list, to be freed when it's safe. */ size = sizeof(WT_PAGE_INDEX) + pindex->entries * sizeof(WT_REF *); - WT_TRET(__split_safe_free(session, exclusive, pindex, size)); + WT_TRET(__split_safe_free(session, split_gen, exclusive, pindex, size)); parent_decr += size; /* @@ -1027,8 +1032,7 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new, */ uint64_t __a, __b; __a = parent->memory_footprint; - WT_WITH_PAGE_INDEX(session, - ret = __split_deepen(session, parent, children)); + ret = __split_deepen(session, parent, children); __b = parent->memory_footprint; if (__b * 2 >= __a) F_SET_ATOMIC(parent, WT_PAGE_REFUSE_DEEPEN); @@ -1076,6 +1080,7 @@ __wt_split_insert(WT_SESSION_IMPL *session, WT_REF *ref, int *splitp) WT_PAGE *page, *right; WT_REF *child, *split_ref[2] = { NULL, NULL }; size_t page_decr, parent_decr, parent_incr, right_incr; + uint64_t split_gen; int i; *splitp = 0; @@ -1328,8 +1333,8 @@ __wt_split_insert(WT_SESSION_IMPL *session, WT_REF *ref, int *splitp) * longer locked, so we cannot safely look at it. */ page = NULL; - if ((ret = __split_parent( - session, ref, split_ref, 2, parent_decr, parent_incr, 0, 0)) != 0) { + if ((ret = __split_parent(session, ref, split_ref, 2, + parent_decr, parent_incr, 0, 0, &split_gen)) != 0) { /* * Move the insert list element back to the original page list. * For simplicity, the previous skip list pointers originally @@ -1366,8 +1371,8 @@ __wt_split_insert(WT_SESSION_IMPL *session, WT_REF *ref, int *splitp) */ if (ikey != NULL) WT_TRET(__split_safe_free( - session, 0, ikey, sizeof(WT_IKEY) + ikey->size)); - WT_TRET(__split_safe_free(session, 0, ref, sizeof(WT_REF))); + session, split_gen, 0, ikey, sizeof(WT_IKEY) + ikey->size)); + WT_TRET(__split_safe_free(session, split_gen, 0, ref, sizeof(WT_REF))); /* * A note on error handling: if we completed the split, return success, @@ -1450,6 +1455,7 @@ __wt_split_multi(WT_SESSION_IMPL *session, WT_REF *ref, int exclusive) WT_PAGE_MODIFY *mod; WT_REF **ref_new; size_t parent_decr, parent_incr; + uint64_t split_gen; uint32_t i, new_entries; page = ref->page; @@ -1479,8 +1485,8 @@ __wt_split_multi(WT_SESSION_IMPL *session, WT_REF *ref, int exclusive) parent_decr += sizeof(WT_IKEY) + ikey->size; /* Split into the parent. */ - WT_ERR(__split_parent(session, - ref, ref_new, new_entries, parent_decr, parent_incr, exclusive, 1)); + WT_ERR(__split_parent(session, ref, ref_new, new_entries, + parent_decr, parent_incr, exclusive, 1, &split_gen)); __wt_free(session, ref_new); @@ -1503,9 +1509,10 @@ __wt_split_multi(WT_SESSION_IMPL *session, WT_REF *ref, int exclusive) * safe. */ if (ikey != NULL) - WT_TRET(__split_safe_free( - session, exclusive, ikey, sizeof(WT_IKEY) + ikey->size)); - WT_TRET(__split_safe_free(session, exclusive, ref, sizeof(WT_REF))); + WT_TRET(__split_safe_free(session, split_gen, exclusive, + ikey, sizeof(WT_IKEY) + ikey->size)); + WT_TRET(__split_safe_free(session, split_gen, exclusive, + ref, sizeof(WT_REF))); /* * A note on error handling: if we completed the split, return success, diff --git a/src/btree/bt_stat.c b/src/btree/bt_stat.c index d9ff2a6af1e..b7108b52395 100644 --- a/src/btree/bt_stat.c +++ b/src/btree/bt_stat.c @@ -45,8 +45,11 @@ __wt_btree_stat_init(WT_SESSION_IMPL *session, WT_CURSOR_STAT *cst) next_walk = NULL; while ((ret = - __wt_tree_walk(session, &next_walk, 0)) == 0 && next_walk != NULL) - WT_RET(__stat_page(session, next_walk->page, stats)); + __wt_tree_walk(session, &next_walk, 0)) == 0 && next_walk != NULL) { + WT_WITH_PAGE_INDEX(session, + ret = __stat_page(session, next_walk->page, stats)); + WT_RET(ret); + } return (ret == WT_NOTFOUND ? 0 : ret); } diff --git a/src/btree/col_srch.c b/src/btree/col_srch.c index 4c418f91de0..db1b565b439 100644 --- a/src/btree/col_srch.c +++ b/src/btree/col_srch.c @@ -49,6 +49,7 @@ restart: page = current->page; WT_ASSERT(session, current->key.recno == page->pg_intl_recno); + WT_ASSERT(session, session->split_gen != 0); pindex = WT_INTL_INDEX_COPY(page); base = pindex->entries; descent = pindex->index[base - 1]; diff --git a/src/btree/row_srch.c b/src/btree/row_srch.c index 036e11bec6d..9967c5ecb0c 100644 --- a/src/btree/row_srch.c +++ b/src/btree/row_srch.c @@ -195,6 +195,7 @@ restart: page = current->page; if (page->type != WT_PAGE_ROW_INT) break; + WT_ASSERT(session, session->split_gen != 0); pindex = WT_INTL_INDEX_COPY(page); /* @@ -487,6 +488,7 @@ restart: if (page->type != WT_PAGE_ROW_INT) break; + WT_ASSERT(session, session->split_gen != 0); pindex = WT_INTL_INDEX_COPY(page); descent = pindex->index[ __wt_random(session->rnd) % pindex->entries]; @@ -521,6 +523,7 @@ restart: */ cbt->ref = current; cbt->compare = 0; + WT_ASSERT(session, session->split_gen != 0); pindex = WT_INTL_INDEX_COPY(btree->root.page); cbt->slot = pindex->entries < 2 ? __wt_random(session->rnd) % page->pg_row_entries : 0; diff --git a/src/conn/conn_sweep.c b/src/conn/conn_sweep.c index 01f08aa5f07..a5bd8e1343c 100644 --- a/src/conn/conn_sweep.c +++ b/src/conn/conn_sweep.c @@ -32,14 +32,14 @@ __sweep(WT_SESSION_IMPL *session) dhandle_next = SLIST_NEXT(dhandle, l); if (WT_IS_METADATA(dhandle)) continue; - if (dhandle->session_inuse == 0 && dhandle->timeofdeath == 0) { + if (dhandle->session_inuse != 0 || + now <= dhandle->timeofdeath + WT_DHANDLE_SWEEP_WAIT) + continue; + if (dhandle->timeofdeath == 0) { dhandle->timeofdeath = now; WT_STAT_FAST_CONN_INCR(session, dh_conn_tod); continue; } - if (dhandle->session_inuse != 0 || - now <= dhandle->timeofdeath + WT_DHANDLE_SWEEP_WAIT) - continue; /* * We have a candidate for closing; if it's open, acquire an diff --git a/src/include/btmem.h b/src/include/btmem.h index 176d4733f7d..ef6f9b40414 100644 --- a/src/include/btmem.h +++ b/src/include/btmem.h @@ -192,7 +192,7 @@ struct __wt_page_modify { uint64_t inmem_split_txn; /* Dirty bytes added to the cache. */ - uint64_t bytes_dirty; + size_t bytes_dirty; /* * When pages are reconciled, the result is one or more replacement @@ -532,7 +532,7 @@ struct __wt_page { #define WT_READGEN_STEP 100 uint64_t read_gen; - uint64_t memory_footprint; /* Memory attached to the page */ + size_t memory_footprint; /* Memory attached to the page */ #define WT_PAGE_IS_INTERNAL(page) \ ((page)->type == WT_PAGE_COL_INT || (page)->type == WT_PAGE_ROW_INT) @@ -1004,11 +1004,18 @@ struct __wt_insert_head { * already have a split generation, leave it alone. If our caller is examining * an index, we don't want the oldest split generation to move forward and * potentially free it. + * + * Check that we haven't raced with a split_gen update after publishing: we + * rely on the published value not being missed when scanning for the oldest + * active split_gen. */ #define WT_ENTER_PAGE_INDEX(session) do { \ uint64_t __prev_split_gen = (session)->split_gen; \ if (__prev_split_gen == 0) \ - WT_PUBLISH((session)->split_gen, S2C(session)->split_gen) + do { \ + WT_PUBLISH((session)->split_gen, \ + S2C(session)->split_gen); \ + } while ((session)->split_gen != S2C(session)->split_gen) #define WT_LEAVE_PAGE_INDEX(session) \ if (__prev_split_gen == 0) \ diff --git a/src/include/btree.i b/src/include/btree.i index f2eee8b8999..a0cbb23f126 100644 --- a/src/include/btree.i +++ b/src/include/btree.i @@ -258,8 +258,7 @@ __wt_page_refp(WT_SESSION_IMPL *session, WT_PAGE_INDEX *pindex; uint32_t i; - WT_ASSERT(session, - WT_SESSION_TXN_STATE(session)->snap_min != WT_TXN_NONE); + WT_ASSERT(session, session->split_gen != 0); /* * Copy the parent page's index value: the page can split at any time, diff --git a/src/include/connection.h b/src/include/connection.h index ff34b014ecf..7b94a7ea94b 100644 --- a/src/include/connection.h +++ b/src/include/connection.h @@ -146,7 +146,7 @@ struct __wt_connection_impl { WT_FH *lock_fh; /* Lock file handle */ - uint64_t split_gen; /* Generation number for splits */ + volatile uint64_t split_gen; /* Generation number for splits */ /* * The connection keeps a cache of data handles. The set of handles diff --git a/src/include/cursor.i b/src/include/cursor.i index 8fa9790e096..d261635706e 100644 --- a/src/include/cursor.i +++ b/src/include/cursor.i @@ -164,8 +164,11 @@ __wt_cursor_dhandle_decr_use(WT_SESSION_IMPL *session) dhandle = session->dhandle; + /* If we close a handle with a time of death set, clear it. */ WT_ASSERT(session, dhandle->session_inuse > 0); - (void)WT_ATOMIC_SUB4(dhandle->session_inuse, 1); + if (WT_ATOMIC_SUB4(dhandle->session_inuse, 1) == 0 && + dhandle->timeofdeath != 0) + dhandle->timeofdeath = 0; } /* diff --git a/src/reconcile/rec_write.c b/src/reconcile/rec_write.c index f5925cb4d3d..be66309c77f 100644 --- a/src/reconcile/rec_write.c +++ b/src/reconcile/rec_write.c @@ -440,8 +440,11 @@ __wt_reconcile(WT_SESSION_IMPL *session, * Root pages are special, splits have to be done, we can't put it off * as the parent's problem any more. */ - if (__wt_ref_is_root(ref)) - return (__rec_root_write(session, page, flags)); + if (__wt_ref_is_root(ref)) { + WT_WITH_PAGE_INDEX(session, + ret = __rec_root_write(session, page, flags)); + return (ret); + } /* * Otherwise, mark the page's parent dirty. @@ -504,6 +507,7 @@ __rec_root_write(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t flags) WT_ILLEGAL_VALUE(session); } + WT_ASSERT(session, session->split_gen != 0); pindex = WT_INTL_INDEX_COPY(next); for (i = 0; i < mod->mod_multi_entries; ++i) { WT_ERR(__wt_multi_to_ref(session, diff --git a/test/suite/test_huffman01.py b/test/suite/test_huffman01.py new file mode 100644 index 00000000000..0c413025e1d --- /dev/null +++ b/test/suite/test_huffman01.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python +# +# Public Domain 2014-2015 MongoDB, Inc. +# Public Domain 2008-2014 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. + +import os +from suite_subprocess import suite_subprocess +from wtscenario import multiply_scenarios, number_scenarios +import wiredtiger, wttest + +# test_huffman01.py +# Huffman key and value configurations +# Basic smoke-test of huffman key and value settings. +class test_huffman01(wttest.WiredTigerTestCase, suite_subprocess): + """ + Test basic operations + """ + table_name = 'table:test_huff' + + huffkey = [ + ('none', dict(huffkey='huffman_key=none',kfile=None)), + ('english', dict(huffkey='huffman_key=english',kfile=None)), + ('English', dict(huffkey='huffman_key=English',kfile=None)), + ('utf8', dict(huffkey='huffman_key=utf8t8file',kfile='t8file')), + ('utf16', dict(huffkey='huffman_key=utf16t16file',kfile='t16file')), + ] + huffval = [ + ('none', dict(huffval=',huffman_value=none',vfile=None)), + ('english', dict(huffval=',huffman_value=english',vfile=None)), + ('English', dict(huffval=',huffman_value=English',vfile=None)), + ('utf8', dict(huffval=',huffman_value=utf8t8file',vfile='t8file')), + ('utf16', dict(huffval=',huffman_value=utf16t16file',vfile='t16file')), + ] + scenarios = number_scenarios(multiply_scenarios('.', huffkey, huffval)) + + def test_huffman(self): + dir = self.conn.get_home() + if self.kfile != None: + # For the UTF settings write some made-up frequency information. + f = open(dir + '/' + self.kfile, 'w') + f.write('48 546233\n49 460946\n') + f.close() + # if self.vfile != None and not os.path.exists(self.vfile): + if self.vfile != None: + f = open(dir + '/' + self.vfile, 'w') + # For the UTF settings write some made-up frequency information. + f.write('50 546233\n51 460946\n') + f.close() + config=self.huffkey + self.huffval + self.session.create(self.table_name, config) + +if __name__ == '__main__': + wttest.run() diff --git a/test/suite/test_huffman02.py b/test/suite/test_huffman02.py new file mode 100644 index 00000000000..d5fd83ab53e --- /dev/null +++ b/test/suite/test_huffman02.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# +# Public Domain 2014-2015 MongoDB, Inc. +# Public Domain 2008-2014 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. + +import os +from suite_subprocess import suite_subprocess +from wtscenario import multiply_scenarios, number_scenarios +import wiredtiger, wttest + +# test_huffman02.py +# Huffman key and value configurations with bad settings +class test_huffman02(wttest.WiredTigerTestCase, suite_subprocess): + """ + Test basic operations + """ + table_name = 'table:test_huff' + + huffkey = [ + ('none', dict(huffkey='huffman_key=none')), + ('english', dict(huffkey='huffman_key=english')), + ('bad', dict(huffkey='huffman_key=bad')), + ] + huffval = [ + ('bad', dict(huffval=',huffman_value=bad')), + ] + scenarios = number_scenarios(multiply_scenarios('.', huffkey, huffval)) + + def test_huffman(self): + gotException = False + expectMessage = 'illegal Huffman' + config=self.huffkey + self.huffval + with self.expectedStderrPattern(expectMessage): + try: + self.pr('expect an error message...') + self.session.create(self.table_name, config) + except wiredtiger.WiredTigerError as e: + gotException = True + self.pr('got expected exception: ' + str(e)) + self.assertTrue(str(e).find('nvalid argument') >= 0) + self.assertTrue(gotException, 'expected exception') + +if __name__ == '__main__': + wttest.run() |