diff options
author | Don Anderson <dda@ddanderson.com> | 2016-02-02 14:43:35 -0500 |
---|---|---|
committer | Don Anderson <dda@ddanderson.com> | 2016-02-02 14:43:35 -0500 |
commit | 3544728eb8be319cf93931251195ca77dd18c4ad (patch) | |
tree | aa1138ffa970e4af4851df964b60661d58f18b50 /ext | |
parent | faf504846ba81e991e5784166571c6fdcee8b493 (diff) | |
download | mongo-3544728eb8be319cf93931251195ca77dd18c4ad.tar.gz |
WT-2375 Use WT_EXTENSION API to unpack, for portability.
In addition, various naming cleanups and error path simplification.
Diffstat (limited to 'ext')
-rw-r--r-- | ext/collators/revint/revint_collator.c | 161 |
1 files changed, 76 insertions, 85 deletions
diff --git a/ext/collators/revint/revint_collator.c b/ext/collators/revint/revint_collator.c index 3cc251c6c4a..1e432842caf 100644 --- a/ext/collators/revint/revint_collator.c +++ b/ext/collators/revint/revint_collator.c @@ -27,121 +27,103 @@ */ #include <stdlib.h> - -#include <wiredtiger_ext.h> #include <errno.h> #include <stdint.h> +#include <wiredtiger_ext.h> /* - * Set up a collator used with indices having a single integer key, - * where the ordering is descending (reversed). + * A simple WiredTiger collator for indices having a single integer key, + * where the ordering is descending (reversed). This collator also + * requires that primary key be an integer. */ -/* - * 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(); -} +/* Local collator structure. */ +typedef struct { + WT_COLLATOR collator; /* Must come first */ + WT_EXTENSION_API *wt_api; /* Extension API */ +} REVINT_COLLATOR; /* - * collate_revint -- + * revint_compare -- * WiredTiger reverse integer collation, used for tests. */ static int -collate_revint(WT_COLLATOR *collator, +revint_compare(WT_COLLATOR *collator, WT_SESSION *session, const WT_ITEM *k1, const WT_ITEM *k2, int *cmp) { - WT_PACK_STREAM *s1, *s2; + const REVINT_COLLATOR *revint_collator; + WT_EXTENSION_API *wtapi; int ret; int64_t i1, i2, p1, p2; - (void)collator; /* Unused */ - (void)session; - - s1 = NULL; - s2 = NULL; + i1 = i2 = p1 = p2 = 0; + revint_collator = (const REVINT_COLLATOR *)collator; + wtapi = revint_collator->wt_api; /* * All indices using this collator have an integer key, and the - * primary key is also an integer. A collator is passed the + * primary key is also an integer. A collator is usually passed the * concatenation of index key and primary key (when available), - * hence we unpack using "ii". + * hence we initially unpack using "ii". + * + * A collator may also 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 not reverse the ordering + * when comparing primary keys. */ - 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"); + if ((ret = wtapi->struct_unpack(wtapi, session, + k1->data, k1->size, "ii", &i1, &p1)) != 0) { + /* could be missing primary key, try again without */ + if ((ret = wtapi->struct_unpack(wtapi, session, + k1->data, k1->size, "i", &i1)) != 0) + return (ret); + p1 = INT64_MIN; /* sort this first */ + } + if ((ret = wtapi->struct_unpack(wtapi, session, + k2->data, k2->size, "ii", &i2, &p2)) != 0) { + /* could be missing primary key, try again without */ + if ((ret = wtapi->struct_unpack(wtapi, session, + k2->data, k2->size, "i", &i2)) != 0) + return (ret); + p2 = INT64_MIN; /* sort this first */ + } /* 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"); + /* compare primary keys next, not reversed */ + else if (p1 < p2) + *cmp = -1; + else if (p1 > p2) + *cmp = 1; + else + *cmp = 0; /* index key and primary key are same */ return (0); } -static WT_COLLATOR revint_collator = { collate_revint, NULL, NULL }; +/* + * revint_terminate -- + * Terminate is called to free the collator and any associated memory. + */ +static int +revint_terminate(WT_COLLATOR *collator, WT_SESSION *session) +{ + (void)session; /* Unused parameters */ + + /* Free the allocated memory. */ + free(collator); + return (0); +} /* * wiredtiger_extension_init -- @@ -150,8 +132,17 @@ static WT_COLLATOR revint_collator = { collate_revint, NULL, NULL }; int wiredtiger_extension_init(WT_CONNECTION *connection, WT_CONFIG_ARG *config) { + REVINT_COLLATOR *revint_collator; + (void)config; /* Unused parameters */ + if ((revint_collator = calloc(1, sizeof(REVINT_COLLATOR))) == NULL) + return (errno); + + revint_collator->collator.compare = revint_compare; + revint_collator->collator.terminate = revint_terminate; + revint_collator->wt_api = connection->get_extension_api(connection); + return (connection->add_collator( - connection, "revint", &revint_collator, NULL)); + connection, "revint", &revint_collator->collator, NULL)); } |