summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorDon Anderson <dda@ddanderson.com>2016-02-02 14:43:35 -0500
committerDon Anderson <dda@ddanderson.com>2016-02-02 14:43:35 -0500
commit3544728eb8be319cf93931251195ca77dd18c4ad (patch)
treeaa1138ffa970e4af4851df964b60661d58f18b50 /ext
parentfaf504846ba81e991e5784166571c6fdcee8b493 (diff)
downloadmongo-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.c161
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));
}