diff options
author | Don Anderson <dda@ddanderson.com> | 2016-02-01 22:34:40 -0500 |
---|---|---|
committer | Don Anderson <dda@ddanderson.com> | 2016-02-01 22:34:40 -0500 |
commit | 9b87a2f1211d36231a765a8f363a1a90eda26f7c (patch) | |
tree | 9d7ecd4c7462e9aaaba6fc569921bd21ab1ca19c /ext | |
parent | 6195bb8c8ae6e6038351d43f33f88e216eec0a15 (diff) | |
download | mongo-9b87a2f1211d36231a765a8f363a1a90eda26f7c.tar.gz |
WT-2375 Added tests using revint, a reverse integer collator for testing.
Revint demonstrates how collators are expected to decode non-trivial key
formats and work in situations with duplicate keys. The new test uses
both a collator and an extractor.
Diffstat (limited to 'ext')
-rw-r--r-- | ext/collators/revint/Makefile.am | 10 | ||||
-rw-r--r-- | ext/collators/revint/revint_collator.c | 157 |
2 files changed, 167 insertions, 0 deletions
diff --git a/ext/collators/revint/Makefile.am b/ext/collators/revint/Makefile.am new file mode 100644 index 00000000000..8c85c6a4701 --- /dev/null +++ b/ext/collators/revint/Makefile.am @@ -0,0 +1,10 @@ +AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)/src/include + +noinst_LTLIBRARIES = libwiredtiger_revint_collator.la +libwiredtiger_revint_collator_la_SOURCES = revint_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_revint_collator_la_LDFLAGS = \ + -avoid-version -module -rpath /nowhere diff --git a/ext/collators/revint/revint_collator.c b/ext/collators/revint/revint_collator.c new file mode 100644 index 00000000000..ac4a51970bb --- /dev/null +++ b/ext/collators/revint/revint_collator.c @@ -0,0 +1,157 @@ +/*- + * Public Domain 2014-2016 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. + */ + +#include <stdlib.h> + +#include <wiredtiger_ext.h> +#include <errno.h> +#include <stdint.h> + +/* + * Set up a collator used with indices having a single integer key, + * where the ordering is descending (reversed). + */ + +/* + * collate_error -- + * Handle errors in the collator in a standard way. + */ +static void +collate_error(int ret, const char *description) +{ + fprintf(stderr, "revint_collator error: %s: %s\n", + wiredtiger_strerror(ret), description); + /* + * For errors, we call abort. Since this collator is used in testing + * WiredTiger, we want it to immediately fail hard. A product-ready + * version of this function would not abort. + */ + abort(); +} + +/* + * collate_revint -- + * WiredTiger reverse integer collation, used for tests. + */ +static int +collate_revint(WT_COLLATOR *collator, + WT_SESSION *session, const WT_ITEM *k1, const WT_ITEM *k2, int *cmp) +{ + WT_PACK_STREAM *s1, *s2; + int ret; + int64_t i1, i2, p1, p2; + + (void)collator; /* Unused */ + (void)session; + + s1 = NULL; + s2 = NULL; + + /* + * All indices using this collator have an integer key, and the + * primary key is also an integer. A collator is passed the + * concatenation of index key and primary key (when available), + * hence we unpack using "ii". + */ + if ((ret = wiredtiger_unpack_start(session, "ii", + k1->data, k1->size, &s1)) != 0 || + (ret = wiredtiger_unpack_start(session, "ii", + k2->data, k2->size, &s2)) != 0) + collate_error(ret, "unpack start"); + /* does not return */ + + if ((ret = wiredtiger_unpack_int(s1, &i1)) != 0) + collate_error(ret, "unpack index key 1"); + if ((ret = wiredtiger_unpack_int(s2, &i2)) != 0) + collate_error(ret, "unpack index key 2"); + + /* sorting is reversed */ + if (i1 < i2) + *cmp = 1; + else if (i1 > i2) + *cmp = -1; + else { + /* + * Compare primary keys next. + * + * Allow failures here. A collator may be called with an + * item that includes a index key and no primary key. Among + * items having the same index key, an item with no primary + * key should sort before an item with a primary key. The + * reason is that if the application calls WT_CURSOR::search + * on a index key for which there are more than one value, + * the search key will not yet have a primary key. We want + * to position the cursor at the 'first' matching index key + * so that repeated calls to WT_CURSOR::next will see them + * all. + * + * To keep this code simple, we do keep secondary sort of + * primary keys in forward (not reversed) order. + */ + if ((ret = wiredtiger_unpack_int(s1, &p1)) != 0) { + if (ret == ENOMEM) + p1 = INT64_MIN; /* sort this first */ + else + collate_error(ret, "unpack primary key 1"); + } + if ((ret = wiredtiger_unpack_int(s2, &p2)) != 0) { + if (ret == ENOMEM) + p2 = INT64_MIN; /* sort this first */ + else + collate_error(ret, "unpack primary key 2"); + } + + /* sorting is not reversed here */ + if (p1 < p2) + *cmp = -1; + else if (p1 > p2) + *cmp = 1; + else + *cmp = 0; /* index key and primary key are same */ + } + if ((ret = wiredtiger_pack_close(s1, NULL)) != 0 || + (ret = wiredtiger_pack_close(s2, NULL)) != 0) + collate_error(ret, "unpack close"); + + return (0); +} + +static WT_COLLATOR revint_collator = { collate_revint, NULL, NULL }; + +/* + * wiredtiger_extension_init -- + * WiredTiger revint collation extension. + */ +int +wiredtiger_extension_init(WT_CONNECTION *connection, WT_CONFIG_ARG *config) +{ + (void)config; /* Unused parameters */ + + return (connection->add_collator( + connection, "revint", &revint_collator, NULL)); +} |