Hi!
I implemented custom index collator as described in [Custom Collators for Indices] (http://source.wiredtiger.com/develop/custom_collators.html)
But looks like I need to consider the case when search on secondary key is performed and thus I have no primary key for the first key given to
::compare()
Could you please advise how I can do that?
Test that demonstrates the problem:
#include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <wiredtiger.h> #define WT_HOME "index_collator.db" #define WT_CALL(call) \ do { \ const int __rc = call; \ if (__rc != 0) { \ fprintf(stderr, # call " at (%s:%d) failed: %s [%d]\n", __FILE__, __LINE__, wiredtiger_strerror(__rc), __rc); \ exit(EXIT_FAILURE); \ } \ } while (0) static int compare_int(int a, int b) { return (a < b ? -1 : (a > b ? 1 : 0)); } static int index_compare(WT_COLLATOR *collator, WT_SESSION *session, const WT_ITEM *key1, const WT_ITEM *key2, int *cmp) { int rc; int ikey1 = 12345, pkey1 = 54321, ikey2 = 67890, pkey2 = 9876; WT_CALL(wiredtiger_struct_unpack(session, key1->data, key1->size, "ii", &ikey1, &pkey1)); WT_CALL(wiredtiger_struct_unpack(session, key2->data, key2->size, "ii", &ikey2, &pkey2)); printf("index_compare: ikey1 = %d, pkey1 = %d, ikey2 = %d, pkey2 = %d\n", ikey1, pkey1, ikey2, pkey2); if ((*cmp = compare_int(ikey1, ikey2)) != 0) return 0; *cmp = compare_int(pkey1, pkey2); return 0; } static WT_COLLATOR index_coll = { index_compare, NULL, NULL }; int main(void) { WT_CONNECTION *conn; WT_SESSION *session; WT_CURSOR *cursor; assert(system("rm -rf \"" WT_HOME "\" && mkdir \"" WT_HOME "\"") == 0); WT_CALL(wiredtiger_open(WT_HOME, NULL, "create", &conn)); WT_CALL(conn->open_session(conn, NULL, NULL, &session)); WT_CALL(conn->add_collator(conn, "index_coll", &index_coll, NULL)); WT_CALL(session->create(session, "table:main", "key_format=i,value_format=i,columns=(k,v)")); WT_CALL(session->create(session, "index:main:index", "columns=(v),collator=index_coll")); WT_CALL(session->open_cursor(session, "table:main", NULL, NULL, &cursor)); cursor->set_key(cursor, 13); cursor->set_value(cursor, 17); WT_CALL(cursor->insert(cursor)); WT_CALL(cursor->close(cursor)); WT_CALL(session->open_cursor(session, "index:main:index", NULL, NULL, &cursor)); while (cursor->next(cursor) == 0) { int ikey, val; WT_CALL(cursor->get_key(cursor, &ikey)); WT_CALL(cursor->get_value(cursor, &val)); printf("ikey = %d, value = %d\n", ikey, val); } cursor->set_key(cursor, 17); WT_CALL(cursor->search(cursor)); WT_CALL(cursor->close(cursor)); WT_CALL(conn->close(conn, NULL)); return 0; }
Running it I can get:
$ ./index_collator
ikey = 17, value = 17
wiredtiger_struct_unpack(session, key1->data, key1->size, "ii", &ikey1, &pkey1) at (index_collator.c:32) failed: Invalid argument [22]
$ ./index_collator
ikey = 17, value = 17
index_compare: ikey1 = 17, pkey1 = 2962, ikey2 = 17, pkey2 = 13
cursor->search(cursor) at (index_collator.c:79) failed: WT_NOTFOUND: item not found [-31803]
$ ./index_collator
ikey = 17, value = 17
index_compare: ikey1 = 17, pkey1 = -21, ikey2 = 17, pkey2 = 13
index_compare: ikey1 = 17, pkey1 = -21, ikey2 = 17, pkey2 = 13
index_compare: ikey1 = 17, pkey1 = -21, ikey2 = 17, pkey2 = 13
Thanks!
- is related to
-
WT-1723 WT_CURSOR::search() returned WT_NOTFOUND when 'suffix' index key collator is used
- Closed
-
WT-1781 Add length checks to the WT_PACK_STREAM API
- Closed
-
WT-1783 Use the configured collator when index cursor need to compare keys.
- Closed
-
WT-1826 Add explicit size checks to public pack/unpack code
- Closed